<commit_before>/**
 * Google Analytics / TestPilot Metrics
 */
const TRACKING_ID = 'UA-35433268-79';

const KINTO_SERVER = 'https://kinto.dev.mozaws.net/v1';
// XXX: Read this from Kinto fxa-params
const FXA_CLIENT_ID = 'c6d74070a481bc10';
const FXA_OAUTH_SERVER = 'https://oauth-latest-keys.dev.lcip.org/v1';
const FXA_PROFILE_SERVER = 'https://latest-keys.dev.lcip.org/profile/v1';
const FXA_SCOPES = ['profile', 'https://identity.mozilla.org/apps/notes'];
const timeouts = {};

// Kinto sync and encryption

const client = new Kinto({remote: KINTO_SERVER, bucket: 'default'});

// Analytics

const analytics = new TestPilotGA({
  tid: TRACKING_ID,
  ds: 'addon',
  an: 'Notes Experiment',
  aid: 'notes@mozilla.com',
  av: browser.runtime.getManifest().version
});

function sendMetrics(event, context = {}) {
  // This function debounce sending metrics.
  const later = function() {
    timeouts[event] = null;

    return analytics.sendEvent('notes', event, {
      cm1: context.characters,
      cm2: context.lineBreaks,
      cm3: null,  // Size of the change
      cd1: context.syncEnabled,
      cd2: context.usesSize,
      cd3: context.usesBold,
      cd4: context.usesItalics,
      cd5: context.usesStrikethrough,
      cd6: context.usesList,
      cd7: null, // Firefox UI used to open, close notepad
      cd8: null, // reason editing session ended
    });
  };
  clearTimeout(timeouts[event]);
  timeouts[event] = setTimeout(later, 20000);
}

function authenticate() {
  const fxaKeysUtil = new fxaCryptoRelier.OAuthUtils({
    oauthServer: FXA_OAUTH_SERVER
  });
    chrome.runtime.sendMessage({
      action: 'sync-opening'
    });
  fxaKeysUtil.launchWebExtensionKeyFlow(FXA_CLIENT_ID, {
    redirectUri: browser.identity.getRedirectURL(),
    scopes: FXA_SCOPES,
  }).then((loginDetails) => {
    const key = loginDetails.keys['https://identity.mozilla.org/apps/notes'];
    const credentials = {
      access_token: loginDetails.access_token,
      refresh_token: loginDetails.refresh_token,
      key,
      metadata: {
        server: FXA_OAUTH_SERVER,
        client_id: FXA_CLIENT_ID,
        scope: FXA_SCOPES
      }
    };
    console.log('Login succeeded', credentials);

    fxaFetchProfile(FXA_PROFILE_SERVER, credentials.access_token).then((profile) => {
      browser.storage.local.set({credentials}).then(() => {
        chrome.runtime.sendMessage({
          action: 'sync-authenticated',
          credentials,
          profile
        });
      });
    });
  }, (err) => {
    console.error('login failed', err);
    chrome.runtime.sendMessage({
      action: 'authenticated',
      err: err
    });
    throw err;
  });
}
browser.runtime.onMessage.addListener(function(eventData) {
  const credentials = new BrowserStorageCredentials(browser.storage.local);
  switch (eventData.action) {
    case 'authenticate':
      credentials.get()
        .then(result => {
          if (!result) {
            sendMetrics('webext-button-authenticate', eventData.context);
            authenticate();
          } else {
            chrome.runtime.sendMessage({
              action: 'text-syncing'
            });
            loadFromKinto(client, credentials);
          }
        });
      break;
    case 'disconnected':
      sendMetrics('webext-button-disconnect', eventData.context);
      credentials.clear();
      break;
    case 'kinto-load':
      loadFromKinto(client, credentials);
      break;
    case 'kinto-save':
      saveToKinto(client, credentials, eventData.content);
      break;
    case 'metrics-changed':
      sendMetrics('changed', eventData.context);
      break;
    case 'metrics-drag-n-drop':
      sendMetrics('drag-n-drop', eventData.context);
      break;
    case 'metrics-migrated':
      sendMetrics('metrics-migrated', eventData.context);
      break;
    case 'metrics-migrated-before':
      sendMetrics('metrics-migrated-before', eventData.context);
      break;
    case 'theme-changed':
      sendMetrics('theme-changed', eventData.content);
      browser.runtime.sendMessage({
        action: 'theme-changed'
      });
      break;
    case 'link-clicked':
      sendMetrics('link-clicked', eventData.content);
      break;
  }
});

// Handle opening and closing the add-on.
function connected(p) {
  sendMetrics('open');

  p.onDisconnect.addListener(() => {
    sendMetrics('close');
  });
}
browser.runtime.onConnect.addListener(connected);

const defaultTheme = {
  theme: 'default'
};

browser.storage.local.get()
  .then((storedSettings) => {
    // if no theme setting exists...
    if (!storedSettings.theme)
      // set defaultTheme as initial theme in local storage
      browser.storage.local.set(defaultTheme);
});
<commit_msg>Switch scope from .org to .com<commit_after>/**
 * Google Analytics / TestPilot Metrics
 */
const TRACKING_ID = 'UA-35433268-79';

const KINTO_SERVER = 'https://kinto.dev.mozaws.net/v1';
// XXX: Read this from Kinto fxa-params
const FXA_CLIENT_ID = 'c6d74070a481bc10';
const FXA_OAUTH_SERVER = 'https://oauth-latest-keys.dev.lcip.org/v1';
const FXA_PROFILE_SERVER = 'https://latest-keys.dev.lcip.org/profile/v1';
const FXA_SCOPES = ['profile', 'https://identity.mozilla.com/apps/notes'];
const timeouts = {};

// Kinto sync and encryption

const client = new Kinto({remote: KINTO_SERVER, bucket: 'default'});

// Analytics

const analytics = new TestPilotGA({
  tid: TRACKING_ID,
  ds: 'addon',
  an: 'Notes Experiment',
  aid: 'notes@mozilla.com',
  av: browser.runtime.getManifest().version
});

function sendMetrics(event, context = {}) {
  // This function debounce sending metrics.
  const later = function() {
    timeouts[event] = null;

    return analytics.sendEvent('notes', event, {
      cm1: context.characters,
      cm2: context.lineBreaks,
      cm3: null,  // Size of the change
      cd1: context.syncEnabled,
      cd2: context.usesSize,
      cd3: context.usesBold,
      cd4: context.usesItalics,
      cd5: context.usesStrikethrough,
      cd6: context.usesList,
      cd7: null, // Firefox UI used to open, close notepad
      cd8: null, // reason editing session ended
    });
  };
  clearTimeout(timeouts[event]);
  timeouts[event] = setTimeout(later, 20000);
}

function authenticate() {
  const fxaKeysUtil = new fxaCryptoRelier.OAuthUtils({
    oauthServer: FXA_OAUTH_SERVER
  });
    chrome.runtime.sendMessage({
      action: 'sync-opening'
    });
  fxaKeysUtil.launchWebExtensionKeyFlow(FXA_CLIENT_ID, {
    redirectUri: browser.identity.getRedirectURL(),
    scopes: FXA_SCOPES,
  }).then((loginDetails) => {
    const key = loginDetails.keys['https://identity.mozilla.org/apps/notes'];
    const credentials = {
      access_token: loginDetails.access_token,
      refresh_token: loginDetails.refresh_token,
      key,
      metadata: {
        server: FXA_OAUTH_SERVER,
        client_id: FXA_CLIENT_ID,
        scope: FXA_SCOPES
      }
    };
    console.log('Login succeeded', credentials);

    fxaFetchProfile(FXA_PROFILE_SERVER, credentials.access_token).then((profile) => {
      browser.storage.local.set({credentials}).then(() => {
        chrome.runtime.sendMessage({
          action: 'sync-authenticated',
          credentials,
          profile
        });
      });
    });
  }, (err) => {
    console.error('login failed', err);
    chrome.runtime.sendMessage({
      action: 'authenticated',
      err: err
    });
    throw err;
  });
}
browser.runtime.onMessage.addListener(function(eventData) {
  const credentials = new BrowserStorageCredentials(browser.storage.local);
  switch (eventData.action) {
    case 'authenticate':
      credentials.get()
        .then(result => {
          if (!result) {
            sendMetrics('webext-button-authenticate', eventData.context);
            authenticate();
          } else {
            chrome.runtime.sendMessage({
              action: 'text-syncing'
            });
            loadFromKinto(client, credentials);
          }
        });
      break;
    case 'disconnected':
      sendMetrics('webext-button-disconnect', eventData.context);
      credentials.clear();
      break;
    case 'kinto-load':
      loadFromKinto(client, credentials);
      break;
    case 'kinto-save':
      saveToKinto(client, credentials, eventData.content);
      break;
    case 'metrics-changed':
      sendMetrics('changed', eventData.context);
      break;
    case 'metrics-drag-n-drop':
      sendMetrics('drag-n-drop', eventData.context);
      break;
    case 'metrics-migrated':
      sendMetrics('metrics-migrated', eventData.context);
      break;
    case 'metrics-migrated-before':
      sendMetrics('metrics-migrated-before', eventData.context);
      break;
    case 'theme-changed':
      sendMetrics('theme-changed', eventData.content);
      browser.runtime.sendMessage({
        action: 'theme-changed'
      });
      break;
    case 'link-clicked':
      sendMetrics('link-clicked', eventData.content);
      break;
  }
});

// Handle opening and closing the add-on.
function connected(p) {
  sendMetrics('open');

  p.onDisconnect.addListener(() => {
    sendMetrics('close');
  });
}
browser.runtime.onConnect.addListener(connected);

const defaultTheme = {
  theme: 'default'
};

browser.storage.local.get()
  .then((storedSettings) => {
    // if no theme setting exists...
    if (!storedSettings.theme)
      // set defaultTheme as initial theme in local storage
      browser.storage.local.set(defaultTheme);
});
<|endoftext|>


<commit_before>/**
 * locale.js
 * handles internationalization (i18n)
 *
 */
import { addLocaleData } from 'react-intl'
import i18next from 'i18next'
import i18nextXhr from 'i18next-xhr-backend'
import { API_URL } from './config'
import { observeStore } from '../store'

// Add react-intl files for all the languages we support (added manually for now)
import ar from 'react-intl/locale-data/ar'
import es from 'react-intl/locale-data/es'
import de from 'react-intl/locale-data/de'
import fi from 'react-intl/locale-data/fi'
import fr from 'react-intl/locale-data/fr'
import ja from 'react-intl/locale-data/ja'
import pl from 'react-intl/locale-data/pl'
import pt from 'react-intl/locale-data/pt'
import sv from 'react-intl/locale-data/sv'
import zh from 'react-intl/locale-data/zh'

// Add react-intl locale data
addLocaleData([...ar, ...es, ...de, ...fi, ...fr, ...ja, ...pl, ...pt, ...sv, ...zh])

export function initLocale (experimental) {
  // Current language is the one set by Streetmix or is the browser default, if unset
  let locale

  if (experimental) {
    // Default language is set by browser, or is English if undetermined
    const defaultLocale = navigator.language || 'en'

    try {
      locale = JSON.parse(window.localStorage.getItem('locale')) || defaultLocale
    } catch (err) {
      locale = defaultLocale
    }
  } else {
    locale = 'en'
  }

  doTheI18n(locale)
  initLocaleChangedListener()
  initRtlChangedListener()
}

function initLocaleChangedListener () {
  const select = (state) => state.locale.locale
  const onChange = (locale) => doTheI18n

  return observeStore(select, onChange)
}

// right-to-left languages support
function initRtlChangedListener () {
  const select = (state) => state.app.contentDirection
  const onChange = (direction) => {
    document.body.dir = direction
  }

  return observeStore(select, onChange)
}

function doTheI18n (locale) {
  const options = {
    lng: locale,
    ns: ['main', 'segment-info'],
    defaultNS: 'main',
    fallbackLng: 'en',
    returnEmptyString: false,
    load: 'all',
    backend: {
      loadPath: API_URL + 'v1/translate/{lng}/{ns}'
    },
    interpolation: {
      prefix: '{',
      suffix: '}',
      // Do not escape characters automatically. React already escapes strings,
      // so we want to avoid double-escaping output.
      escapeValue: false
    }
  }

  const callback = function (err, t) {
    if (err) {
      console.log(err)
      return
    }
    const els = document.querySelectorAll('[data-i18n]')
    for (let i = 0, j = els.length; i < j; i++) {
      const key = els[i].getAttribute('data-i18n')
      let translation = ''
      for (let ns of options.ns) {
        translation = translation || t(key, { ns: options.ns[ns] })
      }
      els[i].textContent = translation
    }
  }

  i18next
    .use(i18nextXhr)
    .init(options, callback)
}

export function t (key, fallback, options) {
  const text = i18next.t(key, options)
  if (!text || text === key) {
    return fallback
  } else {
    return text
  }
}
<commit_msg>locales: shim t() to use redux store<commit_after>/**
 * locale.js
 * handles internationalization (i18n)
 *
 */
import { addLocaleData } from 'react-intl'
import i18next from 'i18next'
import i18nextXhr from 'i18next-xhr-backend'
import { API_URL } from './config'
import store, { observeStore } from '../store'

// Add react-intl files for all the languages we support (added manually for now)
import ar from 'react-intl/locale-data/ar'
import es from 'react-intl/locale-data/es'
import de from 'react-intl/locale-data/de'
import fi from 'react-intl/locale-data/fi'
import fr from 'react-intl/locale-data/fr'
import ja from 'react-intl/locale-data/ja'
import pl from 'react-intl/locale-data/pl'
import pt from 'react-intl/locale-data/pt'
import sv from 'react-intl/locale-data/sv'
import zh from 'react-intl/locale-data/zh'

// Add react-intl locale data
addLocaleData([...ar, ...es, ...de, ...fi, ...fr, ...ja, ...pl, ...pt, ...sv, ...zh])

export function initLocale (experimental) {
  // Current language is the one set by Streetmix or is the browser default, if unset
  let locale

  if (experimental) {
    // Default language is set by browser, or is English if undetermined
    const defaultLocale = navigator.language || 'en'

    try {
      locale = JSON.parse(window.localStorage.getItem('locale')) || defaultLocale
    } catch (err) {
      locale = defaultLocale
    }
  } else {
    locale = 'en'
  }

  doTheI18n(locale)
  initLocaleChangedListener()
  initRtlChangedListener()
}

function initLocaleChangedListener () {
  const select = (state) => state.locale.locale
  const onChange = (locale) => doTheI18n

  return observeStore(select, onChange)
}

// right-to-left languages support
function initRtlChangedListener () {
  const select = (state) => state.app.contentDirection
  const onChange = (direction) => {
    document.body.dir = direction
  }

  return observeStore(select, onChange)
}

function doTheI18n (locale) {
  const options = {
    lng: locale,
    ns: ['main', 'segment-info'],
    defaultNS: 'main',
    fallbackLng: 'en',
    returnEmptyString: false,
    load: 'all',
    backend: {
      loadPath: API_URL + 'v1/translate/{lng}/{ns}'
    },
    interpolation: {
      prefix: '{',
      suffix: '}',
      // Do not escape characters automatically. React already escapes strings,
      // so we want to avoid double-escaping output.
      escapeValue: false
    }
  }

  const callback = function (err, t) {
    if (err) {
      console.log(err)
      return
    }
    const els = document.querySelectorAll('[data-i18n]')
    for (let i = 0, j = els.length; i < j; i++) {
      const key = els[i].getAttribute('data-i18n')
      let translation = ''
      for (let ns of options.ns) {
        translation = translation || t(key, { ns: options.ns[ns] })
      }
      els[i].textContent = translation
    }
  }

  i18next
    .use(i18nextXhr)
    .init(options, callback)
}

export function t (key, fallback, options = {}) {
  const messages = store.getState().locale.messages
  if (options.ns === 'segment-info') {
    return messages['segmentInfo.' + key] || fallback
  } else {
    return messages[key] || fallback
  }
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';

import Link from 'react-router-dom/Link';
import Redirect from 'react-router-dom/Redirect';

import {api} from './../utils/Api';

class TopBar extends Component {

    constructor(props) {
        super(props);
        this.state = {
            fetchingToken: false,
        }
    }

    twitterLoginStart = (event) => {

        localStorage.removeItem('oath_token');
        localStorage.removeItem('oauth_secret');
        localStorage.removeItem('user');

        // http://stackoverflow.com/questions/4068373/center-a-popup-window-on-screen
        let dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left;
        let dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top;

        let width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
        let height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;

        let left = ((width / 2) - (570 / 2)) + dualScreenLeft;
        let top = ((height / 2) - (520 / 2)) + dualScreenTop;
        window.open(
            'http://votingapp.com:8000/auth/twitter/login',
            '_blank',
            'location=yes,height=570,width=520,scrollbars=yes,status=yes,top=' + top + ',left=' + left + ''
        );
        this.twitterLogin();
    }

    twitterLogin(){
        /*Remove login text while loggging in is in process*/
        let user = localStorage.getItem('user');
        if(user !== '' && typeof user !== 'undefined' && user !== null){
            this.setState({
                fetchingToken: true,
            });
        }
        api.handleTwitterLogin()
            .then((response) =>{
                if(response === 'error'){
                    setTimeout(() => {
                        this.twitterLogin();
                    }, 50);
                }
                else if(response === 'success'){
                    this.setState({
                        fetchingToken: false,
                    });
                }
            })
    }

    render() {
        return (

                        <Link to="/">

                                Sentio - a Voting App

                        </Link>

                    {
                        api.isLoggedIn()
                        ? (

                                    Hello, {api.getUsername()}

                                    <Link
                                        to="/mypolls">
                                        My Polls
                                    </Link>

                                    <Link
                                        to="/create">
                                        New Poll
                                    </Link>

                                    <Link
                                        to="/logout">
                                        Logout
                                    </Link>

                        )
                        : (

                                {
                                    this.state.fetchingToken
                                    ?(

                                            <Redirect push to="/" />

                                    )
                                    :(

                                            Login

                                    )
                                }

                        )
                    }

        );
    }
}

TopBar.propTypes = {
    className: PropTypes.string,
};

export default TopBar;<commit_msg>added Polls link to topbar<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';

import Link from 'react-router-dom/Link';
import Redirect from 'react-router-dom/Redirect';

import {api} from './../utils/Api';

class TopBar extends Component {

    constructor(props) {
        super(props);
        this.state = {
            fetchingToken: false,
        }
    }

    twitterLoginStart = (event) => {

        localStorage.removeItem('oath_token');
        localStorage.removeItem('oauth_secret');
        localStorage.removeItem('user');

        // http://stackoverflow.com/questions/4068373/center-a-popup-window-on-screen
        let dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left;
        let dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top;

        let width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
        let height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;

        let left = ((width / 2) - (570 / 2)) + dualScreenLeft;
        let top = ((height / 2) - (520 / 2)) + dualScreenTop;
        window.open(
            'http://votingapp.com:8000/auth/twitter/login',
            '_blank',
            'location=yes,height=570,width=520,scrollbars=yes,status=yes,top=' + top + ',left=' + left + ''
        );
        this.twitterLogin();
    }

    twitterLogin(){
        /*Remove login text while loggging in is in process*/
        let user = localStorage.getItem('user');
        if(user !== '' && typeof user !== 'undefined' && user !== null){
            this.setState({
                fetchingToken: true,
            });
        }
        api.handleTwitterLogin()
            .then((response) =>{
                if(response === 'error'){
                    setTimeout(() => {
                        this.twitterLogin();
                    }, 50);
                }
                else if(response === 'success'){
                    this.setState({
                        fetchingToken: false,
                    });
                }
            })
    }

    render() {
        return (

                        <Link to="/">

                                Sentio - a Voting App

                        </Link>

                    {
                        api.isLoggedIn()
                        ? (

                                    Hello, {api.getUsername()}

                                    <Link
                                        to="/">
                                        Polls
                                    </Link>

                                    <Link
                                        to="/mypolls">
                                        My Polls
                                    </Link>

                                    <Link
                                        to="/create">
                                        New Poll
                                    </Link>

                                    <Link
                                        to="/logout">
                                        Logout
                                    </Link>

                        )
                        : (
                            this.state.fetchingToken
                            ?(

                                        <Redirect push to="/" />

                            )
                            :(

                                        <Link
                                            to="/">
                                            Polls
                                        </Link>

                                        Login

                            )
                        )
                    }

        );
    }
}

TopBar.propTypes = {
    className: PropTypes.string,
};

export default TopBar;<|endoftext|>


<commit_before>/**
 * A Display object handles the graphics of the program. It will create/recreate
 * the board. It will handle creating the menu. Chiefly it creates listeners
 * to collect user input and redirects that input to the correct methods.
 * @param  {CutObject}     root The all containing ParentNode in cut. Everything
 *                              must eventually be appended to root or something
 *                              else that was appended to root.
 * @param  {Player[]}      players an array that contains all the players in
 *                                 this current game.
 * @param  {Configuration} config The current configuration for the game. Is
 *                                used to create the board with the current
 *                                configuration details.
 */
function Display(root,players,config){
    this._createBoard  = _createBoard;
    this._createButton = _createButton;
    this.update        = update;
    this.explodeShell  = explodeShell;
    this.explodeBomb   = explodeBomb;
    var selectedRow;
    var selectedCol;
    var _player;
    var currentTurn = 0;
    var board = players[0].getBoard();
    var gameScreen = Cut.create()
                        .appendTo(root)
                        .pin("align", .5);
    var column;
    var _displayGrid = []
    for (var i = 0; i < config.height; ++i) {
        _displayGrid.push([]);
        for (var j = 0; j < config.width; ++j) {
            _displayGrid[i].push(null);
        }
    }
    function makeCutImage(shell, parent){
        var temp = Cut.image("base:color_" + shell.color)
                              .appendTo(parent)
                              .pin("pivot", 0.5);
        var overlay = Cut.image("dice" +shell.magnitude+":").appendTo(temp).pin("pivot",0.5)

        return temp;
    }
    /**
     * Creates the graphical representation of the board owned by player.
     * @param  {Player} player The player whose board is currently being
     *                         graphically built by the renderer.
     */
    function _createBoard(player) {
        _player = player;
        var j = 0, i = 0, count = 0;
        var boardNode = Cut.create();
        boardNode.appendTo(gameScreen);
        column = Cut.column()
                    .appendTo(root)
                    .pin("align", 0.5)
                    .spacing(2)
                    .pin({
                        scaleX : 2,
                        scaleY : 2
                    });
        for (i = 0; i < config.height; ++i) {
            var row = Cut.row().appendTo(column).spacing(2);
            for (j = 0; j < config.width; ++j) {
                // colors as frames
                var temp = board.get(i, j);

                if(temp.special === null){
                    var cell = makeCutImage(temp,row);
                    _displayGrid[i][j] = cell;
                    // var cell = Cut.image("base:color_" + temp.color)
                    //               .appendTo(row)
                    //               .pin("pivot", 0.5);
                    cell._index = count++;
                    cell._row     = i;
                    cell._col     = j;
                    //userInput.setInput(cell);
                    // cell.on(Cut.Mouse.CLICK, function(point) {
                    //     this.pin({
                    //         scaleX : 1.3,
                    //         scaleY : 1.3
                    //     });
                    //     var coord = new Util.Coord(this._row,this._col);
                    //     player.selectShell(coord.row, coord.col);
                    // });
                    cell.on(Cut.Mouse.START, function(point) {
                        selectedCol = this._col;
                        selectedRow = this._row;
                    });
                    cell.on(Cut.Mouse.END, function(point) {
                        if(selectedRow === null){
                            return;
                        }
                        else if(selectedRow === this._row &&
                                selectedCol === this._col){
                            this.pin({
                                scaleX : 1.3,
                                scaleY : 1.3
                            });
                            var coord = new Util.Coord(this._row,this._col);
                            player.selectShell(coord.row, coord.col);
                        }
                        else{
                            player.selectShell(selectedRow, selectedCol);
                            player.selectShell(this._row, this._col);
                            selectedRow = null;
                            selectedCol = null;
                        }
                    });
                }
                else{
                    var currentBomb = temp.special;
                    var BombColor = currentBomb.color;
                    if(currentBomb.cornerShell === temp){
                        var bombCorner = Cut.image("base:color_trans")
                            .appendTo(row)
                            .pin("align", 0);
                        _displayGrid[i][j] = bombCorner;
                        bombCorner._row     = i;
                        bombCorner._col     = j;
                        var bomb = Cut.image("base:color_"+BombColor)
                            .appendTo(bombCorner)
                            .pin("align", 0)
                            .pin({
                                scaleX : 2.10,
                                scaleY : 2.10,
                                textureAlpha : 100
                        });
                        bomb._row     = i;
                        bomb._col     = j;
                        bomb._radius  = currentBomb.blastRad;
                        bomb._color   = BombColor
                        bomb.on(Cut.Mouse.CLICK,function(point) {
                            explode(this._row,this._col,this._radius,this._color)
                        });
                        var ticker = Cut.string("ascii_nimbus_black:")
                            .appendTo(bomb)
                            .pin("align", .5)
                            .spacing(.7)
                            .value(currentBomb.explosionTurn - currentTurn)
                            .pin({
                                scale : .10
                            });

                    }
                    else{
                        var invis = Cut.image("base:color_trans")
                           .appendTo(row)
                           .pin("align", 0);
                        _displayGrid[i][j] = invis;
                    }
                }
            }
        }
    }
    /**
     * Graphically updates the board. First deletes the current graphical
     * representation of the board. Then recreates it now that is has been
     * altered by gametype.
     */
    function update(turnCount) {
        currentTurn = turnCount;
        column.remove();
        if(turnCount <= config.allottedTurns){
            _createBoard(players[0]);
        }
        else{
            _createBoard(players[0]);
            endGame()
        }
    }
    /*function explode(row,col,radius){
        console.log("this col");
        console.log(col);
        var cell = _displayGrid[row-radius][col-radius];
        var explode = Cut.image("base:color_red")
            .appendTo(cell)
            .pin("align", 0)
            .pin({alpha:1,textureAlpha : 1});

        var tween = explode.tween(duration = 200, delay = 0);
        tween.pin({
            scaleX : (radius+4)+(1/radius)+.1,
            scaleY : (radius+4)+(1/radius)+.1
        })
    }*/
    function explode(row,col,radius,color){
        for(var i = row-radius;i <= row + radius+1;i++){
            for(var j = col-radius;j <= col + radius+1;j++){
                if (i <  0 || j <  0 || i >= config.height || j >= config.width){
                }
                else{
                    var cell = _displayGrid[i][j];
                    splode(cell,color);
                }

            }
        }
    }
    function showRadius(row,col,radius,color){
        for(var i = row-radius;i <= row + radius+1;i++){
            for(var j = col-radius;j <= col + radius+1;j++){
                var cell = _displayGrid[i][j];
                splode(cell);

            }
        }
    }
    function splode(cell,color){
        if(cell === undefined){return;}
        var bomb = Cut.image("base:color_"+color).appendTo(cell)
            .pin("align", .5).pin({scale:0});
            var tween = bomb.tween(duration = 400, delay = 0);
            tween.pin({
                scale: 1,
                alpha: 1
            })
            tween.then(function(){
                bomb.remove()
            });
    }
    function explodeShell(row,col){
        var cell = _displayGrid[row][col];
        var tween = cell.tween(duration = 400, delay = 0);
        tween.pin({
            scale: 0,
        })
    }
    function explodeBomb(row,col,color){
        var cell  = _displayGrid[row][col];
        var bomb  = cell.first();
        // var splosion = Cut.image("base:color_" +color).appendTo(cell)
        // .pin("pivot", .5).pin({
        //     scale:0,
        //     textureAlpha: 1

        // });
        // var tween = splosion.tween(duration = 400, delay = 0);
        // tween.pin({
        //     scale: 2,
        // })
        // tween = splosion.tween(duration = 400, delay = 400);
        // tween.pin({
        //     scale: 0,
        // })
        var tween = bomb.tween(duration = 400, delay = 0);
        tween.pin({
            scale: 0,
        })
    }
    this.growShell = function(row,col,shell){
        var cell = _displayGrid[row][col];
        var tween = cell.tween(duration = 500, delay = 0);
        tween.pin({
            textureAlpha: 0,
        })
        tween.then(function() {
            var next = cell.next(visible = false);
            var parent = cell.parent()
            cell.remove();
            if(next != null){
                var newCell = Cut.image("base:color_" +shell.color).insertBefore(next).pin("pivot", .5)
                    .pin({scale:0});
            }
            else{
                var newCell = Cut.image("base:color_" +shell.color).appendTo(parent).pin("pivot", .5)
                    .pin({scale:0});
            }

            var tween = newCell.tween(duration = 400, delay = 1000);
            tween.pin({
                scale: 1,
            })
            tween.then(function() {
                var overlay = Cut.image("dice" +shell.magnitude+":").appendTo(newCell).pin("pivot",0.5)
            });
            _displayGrid[row][col] = newCell;
            newCell.row = row;
            newCell.col = col;
            newCell.on(Cut.Mouse.START, function(point) {
                        selectedCol = this._col;
                        selectedRow = this._row;
                    });
            newCell.on(Cut.Mouse.END, function(point) {
                if(selectedRow === null){
                    return;
                }
                else if(selectedRow === this._row &&
                        selectedCol === this._col){
                    this.pin({
                        scaleX : 1.3,
                        scaleY : 1.3
                    });
                    var coord = new Util.Coord(this._row,this._col);
                    player.selectShell(coord.row, coord.col);
                }
                else{
                    player.selectShell(selectedRow, selectedCol);
                    player.selectShell(this._row, this._col);
                    selectedRow = null;
                    selectedCol = null;
                }
            });
        });

    }
    function endGame(){
        console.log("ENDGAME");
    }

}
<commit_msg>actually fixed the listeners on grown shells<commit_after>/**
 * A Display object handles the graphics of the program. It will create/recreate
 * the board. It will handle creating the menu. Chiefly it creates listeners
 * to collect user input and redirects that input to the correct methods.
 * @param  {CutObject}     root The all containing ParentNode in cut. Everything
 *                              must eventually be appended to root or something
 *                              else that was appended to root.
 * @param  {Player[]}      players an array that contains all the players in
 *                                 this current game.
 * @param  {Configuration} config The current configuration for the game. Is
 *                                used to create the board with the current
 *                                configuration details.
 */
function Display(root,players,config){
    this._createBoard  = _createBoard;
    this._createButton = _createButton;
    this.update        = update;
    this.explodeShell  = explodeShell;
    this.explodeBomb   = explodeBomb;
    var selectedRow;
    var selectedCol;
    var _player;
    var currentTurn = 0;
    var board = players[0].getBoard();
    var gameScreen = Cut.create()
                        .appendTo(root)
                        .pin("align", .5);
    var column;
    var _displayGrid = []
    for (var i = 0; i < config.height; ++i) {
        _displayGrid.push([]);
        for (var j = 0; j < config.width; ++j) {
            _displayGrid[i].push(null);
        }
    }
    function makeCutImage(shell, parent){
        var temp = Cut.image("base:color_" + shell.color)
                              .appendTo(parent)
                              .pin("pivot", 0.5);
        var overlay = Cut.image("dice" +shell.magnitude+":").appendTo(temp).pin("pivot",0.5)

        return temp;
    }
    /**
     * Creates the graphical representation of the board owned by player.
     * @param  {Player} player The player whose board is currently being
     *                         graphically built by the renderer.
     */
    function _createBoard(player) {
        _player = player;
        var j = 0, i = 0, count = 0;
        var boardNode = Cut.create();
        boardNode.appendTo(gameScreen);
        column = Cut.column()
                    .appendTo(root)
                    .pin("align", 0.5)
                    .spacing(2)
                    .pin({
                        scaleX : 2,
                        scaleY : 2
                    });
        for (i = 0; i < config.height; ++i) {
            var row = Cut.row().appendTo(column).spacing(2);
            for (j = 0; j < config.width; ++j) {
                // colors as frames
                var temp = board.get(i, j);

                if(temp.special === null){
                    var cell = makeCutImage(temp,row);
                    _displayGrid[i][j] = cell;
                    // var cell = Cut.image("base:color_" + temp.color)
                    //               .appendTo(row)
                    //               .pin("pivot", 0.5);
                    cell._index = count++;
                    cell._row     = i;
                    cell._col     = j;
                    //userInput.setInput(cell);
                    // cell.on(Cut.Mouse.CLICK, function(point) {
                    //     this.pin({
                    //         scaleX : 1.3,
                    //         scaleY : 1.3
                    //     });
                    //     var coord = new Util.Coord(this._row,this._col);
                    //     player.selectShell(coord.row, coord.col);
                    // });
                    cell.on(Cut.Mouse.START, function(point) {
                        selectedCol = this._col;
                        selectedRow = this._row;
                    });
                    cell.on(Cut.Mouse.END, function(point) {
                        if(selectedRow === null){
                            return;
                        }
                        else if(selectedRow === this._row &&
                                selectedCol === this._col){
                            this.pin({
                                scaleX : 1.3,
                                scaleY : 1.3
                            });
                            var coord = new Util.Coord(this._row,this._col);
                            player.selectShell(coord.row, coord.col);
                        }
                        else{
                            player.selectShell(selectedRow, selectedCol);
                            player.selectShell(this._row, this._col);
                            selectedRow = null;
                            selectedCol = null;
                        }
                    });
                }
                else{
                    var currentBomb = temp.special;
                    var BombColor = currentBomb.color;
                    if(currentBomb.cornerShell === temp){
                        var bombCorner = Cut.image("base:color_trans")
                            .appendTo(row)
                            .pin("align", 0);
                        _displayGrid[i][j] = bombCorner;
                        bombCorner._row     = i;
                        bombCorner._col     = j;
                        var bomb = Cut.image("base:color_"+BombColor)
                            .appendTo(bombCorner)
                            .pin("align", 0)
                            .pin({
                                scaleX : 2.10,
                                scaleY : 2.10,
                                textureAlpha : 100
                        });
                        bomb._row     = i;
                        bomb._col     = j;
                        bomb._radius  = currentBomb.blastRad;
                        bomb._color   = BombColor
                        bomb.on(Cut.Mouse.CLICK,function(point) {
                            explode(this._row,this._col,this._radius,this._color)
                        });
                        var ticker = Cut.string("ascii_nimbus_black:")
                            .appendTo(bomb)
                            .pin("align", .5)
                            .spacing(.7)
                            .value(currentBomb.explosionTurn - currentTurn)
                            .pin({
                                scale : .10
                            });

                    }
                    else{
                        var invis = Cut.image("base:color_trans")
                           .appendTo(row)
                           .pin("align", 0);
                        _displayGrid[i][j] = invis;
                    }
                }
            }
        }
    }
    /**
     * Graphically updates the board. First deletes the current graphical
     * representation of the board. Then recreates it now that is has been
     * altered by gametype.
     */
    function update(turnCount) {
        currentTurn = turnCount;
        column.remove();
        if(turnCount <= config.allottedTurns){
            _createBoard(players[0]);
        }
        else{
            _createBoard(players[0]);
            endGame()
        }
    }
    /*function explode(row,col,radius){
        console.log("this col");
        console.log(col);
        var cell = _displayGrid[row-radius][col-radius];
        var explode = Cut.image("base:color_red")
            .appendTo(cell)
            .pin("align", 0)
            .pin({alpha:1,textureAlpha : 1});

        var tween = explode.tween(duration = 200, delay = 0);
        tween.pin({
            scaleX : (radius+4)+(1/radius)+.1,
            scaleY : (radius+4)+(1/radius)+.1
        })
    }*/
    function explode(row,col,radius,color){
        for(var i = row-radius;i <= row + radius+1;i++){
            for(var j = col-radius;j <= col + radius+1;j++){
                if (i <  0 || j <  0 || i >= config.height || j >= config.width){
                }
                else{
                    var cell = _displayGrid[i][j];
                    splode(cell,color);
                }

            }
        }
    }
    function showRadius(row,col,radius,color){
        for(var i = row-radius;i <= row + radius+1;i++){
            for(var j = col-radius;j <= col + radius+1;j++){
                var cell = _displayGrid[i][j];
                splode(cell);

            }
        }
    }
    function splode(cell,color){
        if(cell === undefined){return;}
        var bomb = Cut.image("base:color_"+color).appendTo(cell)
            .pin("align", .5).pin({scale:0});
            var tween = bomb.tween(duration = 400, delay = 0);
            tween.pin({
                scale: 1,
                alpha: 1
            })
            tween.then(function(){
                bomb.remove()
            });
    }
    function explodeShell(row,col){
        var cell = _displayGrid[row][col];
        var tween = cell.tween(duration = 400, delay = 0);
        tween.pin({
            scale: 0,
        })
    }
    function explodeBomb(row,col,color){
        var cell  = _displayGrid[row][col];
        var bomb  = cell.first();
        // var splosion = Cut.image("base:color_" +color).appendTo(cell)
        // .pin("pivot", .5).pin({
        //     scale:0,
        //     textureAlpha: 1

        // });
        // var tween = splosion.tween(duration = 400, delay = 0);
        // tween.pin({
        //     scale: 2,
        // })
        // tween = splosion.tween(duration = 400, delay = 400);
        // tween.pin({
        //     scale: 0,
        // })
        var tween = bomb.tween(duration = 400, delay = 0);
        tween.pin({
            scale: 0,
        })
    }
    this.growShell = function(row,col,shell){
        var cell = _displayGrid[row][col];
        var tween = cell.tween(duration = 500, delay = 0);
        tween.pin({
            textureAlpha: 0,
        })
        tween.then(function() {
            var next = cell.next(visible = false);
            var parent = cell.parent()
            cell.remove();
            if(next != null){
                var newCell = Cut.image("base:color_" +shell.color).insertBefore(next).pin("pivot", .5)
                    .pin({scale:0});
            }
            else{
                var newCell = Cut.image("base:color_" +shell.color).appendTo(parent).pin("pivot", .5)
                    .pin({scale:0});
            }

            var tween = newCell.tween(duration = 400, delay = 1000);
            tween.pin({
                scale: 1,
            })
            tween.then(function() {
                var overlay = Cut.image("dice" +shell.magnitude+":").appendTo(newCell).pin("pivot",0.5)
            });
            _displayGrid[row][col] = newCell;
            newCell.row = row;
            newCell.col = col;
            newCell.on(Cut.Mouse.START, function(point) {
                console.log("start")
                selectedCol = this.col;
                selectedRow = this.row;
            });
            newCell.on(Cut.Mouse.END, function(point) {
                console.log("end")
                if(selectedRow === null){
                    return;
                }
                else if(selectedRow === this.row &&
                        selectedCol === this.col){
                    this.pin({
                        scaleX : 1.3,
                        scaleY : 1.3
                    });
                    var coord = new Util.Coord(this.row,this.col);
                    player.selectShell(coord.row, coord.col);
                }
                else{
                    player.selectShell(selectedRow, selectedCol);
                    player.selectShell(this.row, this.col);
                    selectedRow = null;
                    selectedCol = null;
                }
            });
        });

    }
    function endGame(){
        console.log("ENDGAME");
    }

}
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc filter
 * @name filter
 * @function
 *
 * @description
 * Selects a subset of items from `array` and returns it as a new array.
 *
 * @param {Array} array The source array.
 * @param {string|Object|function()} expression The predicate to be used for selecting items from
 *   `array`.
 *
 *   Can be one of:
 *
 *   - `string`: The string is evaluated as an expression and the resulting value is used for substring match against
 *     the contents of the `array`. All strings or objects with string properties in `array` that contain this string
 *     will be returned. The predicate can be negated by prefixing the string with `!`.
 *
 *   - `Object`: A pattern object can be used to filter specific properties on objects contained
 *     by `array`. For example `{name:"M", phone:"1"}` predicate will return an array of items
 *     which have property `name` containing "M" and property `phone` containing "1". A special
 *     property name `$` can be used (as in `{$:"text"}`) to accept a match against any
 *     property of the object. That's equivalent to the simple substring match with a `string`
 *     as described above.
 *
 *   - `function(value)`: A predicate function can be used to write arbitrary filters. The function is
 *     called for each element of `array`. The final result is an array of those elements that
 *     the predicate returned true for.
 *
 * @param {function(actual, expected)|true|undefined} comparator Comparator which is used in
 *     determining if the expected value (from the filter expression) and actual value (from
 *     the object in the array) should be considered a match.
 *
 *   Can be one of:
 *
 *     - `function(actual, expected)`:
 *       The function will be given the object value and the predicate value to compare and
 *       should return true if the item should be included in filtered result.
 *
 *     - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`.
 *       this is essentially strict comparison of expected and actual.
 *
 *     - `false|undefined`: A short hand for a function which will look for a substring match in case
 *       insensitive way.
 *
 * @example
   <example>
     <file name="index.html">

       Search: <input ng-model="searchText">

Name	Phone

           {{friend.name}}
           {{friend.phone}}

       Any: <input ng-model="search.$">

       Name only <input ng-model="search.name">

       Phone only <input ng-model="search.phone">

       Equality <input type="checkbox" ng-model="strict">

Name	Phone

           {{friendObj.name}}
           {{friendObj.phone}}

     </file>
     <file name="protractor.js" type="protractor">
       var expectFriendNames = function(expectedNames, key) {
         element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) {
           arr.forEach(function(wd, i) {
             expect(wd.getText()).toMatch(expectedNames[i]);
           });
         });
       };

       it('should search across all fields when filtering with a string', function() {
         var searchText = element(by.model('searchText'));
         searchText.clear();
         searchText.sendKeys('m');
         expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend');

         searchText.clear();
         searchText.sendKeys('76');
         expectFriendNames(['John', 'Julie'], 'friend');
       });

       it('should search in specific fields when filtering with a predicate object', function() {
         var searchAny = element(by.model('search.$'));
         searchAny.clear();
         searchAny.sendKeys('i');
         expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj');
       });
       it('should use a equal comparison when comparator is true', function() {
         var searchName = element(by.model('search.name'));
         var strict = element(by.model('strict'));
         searchName.clear();
         searchName.sendKeys('Julie');
         strict.click();
         expectFriendNames(['Julie'], 'friendObj');
       });
     </file>
   </example>
 */
function filterFilter() {
  return function(array, expression, comparator) {
    if (!isArray(array)) return array;

    var comparatorType = typeof(comparator),
        predicates = [];

    predicates.check = function(value) {
      for (var j = 0; j < predicates.length; j++) {
        if(!predicates[j](value)) {
          return false;
        }
      }
      return true;
    };

    if (comparatorType !== 'function') {
      if (comparatorType === 'boolean' && comparator) {
        comparator = function(obj, text) {
          return angular.equals(obj, text);
        };
      } else {
        comparator = function(obj, text) {
          if (obj && text && typeof obj === 'object' && typeof text === 'object') {
            for (var objKey in obj) {
              if (objKey.charAt(0) !== '$' && hasOwnProperty.call(obj, objKey) &&
                  comparator(obj[objKey], text[objKey])) {
                return true;
              }
            }
            return false;
          }
          text = (''+text).toLowerCase();
          return (''+obj).toLowerCase().indexOf(text) > -1;
        };
      }
    }

    var search = function(obj, text){
      if (typeof text == 'string' && text.charAt(0) === '!') {
        return !search(obj, text.substr(1));
      }
      switch (typeof obj) {
        case "boolean":
        case "number":
        case "string":
          return comparator(obj, text);
        case "object":
          switch (typeof text) {
            case "object":
              return comparator(obj, text);
            default:
              for ( var objKey in obj) {
                if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) {
                  return true;
                }
              }
              break;
          }
          return false;
        case "array":
          for ( var i = 0; i < obj.length; i++) {
            if (search(obj[i], text)) {
              return true;
            }
          }
          return false;
        default:
          return false;
      }
    };
    switch (typeof expression) {
      case "boolean":
      case "number":
      case "string":
        // Set up expression object and fall through
        expression = {$:expression};
        // jshint -W086
      case "object":
        // jshint +W086
        for (var key in expression) {
          (function(path) {
            if (typeof expression[path] == 'undefined') return;
            predicates.push(function(value) {
              return search(path == '$' ? value : (value && value[path]), expression[path]);
            });
          })(key);
        }
        break;
      case 'function':
        predicates.push(expression);
        break;
      default:
        return array;
    }
    var filtered = [];
    for ( var j = 0; j < array.length; j++) {
      var value = array[j];
      if (predicates.check(value)) {
        filtered.push(value);
      }
    }
    return filtered;
  };
}
<commit_msg>docs(filter): description formatting fix<commit_after>'use strict';

/**
 * @ngdoc filter
 * @name filter
 * @function
 *
 * @description
 * Selects a subset of items from `array` and returns it as a new array.
 *
 * @param {Array} array The source array.
 * @param {string|Object|function()} expression The predicate to be used for selecting items from
 *   `array`.
 *
 *   Can be one of:
 *
 *   - `string`: The string is evaluated as an expression and the resulting value is used for substring match against
 *     the contents of the `array`. All strings or objects with string properties in `array` that contain this string
 *     will be returned. The predicate can be negated by prefixing the string with `!`.
 *
 *   - `Object`: A pattern object can be used to filter specific properties on objects contained
 *     by `array`. For example `{name:"M", phone:"1"}` predicate will return an array of items
 *     which have property `name` containing "M" and property `phone` containing "1". A special
 *     property name `$` can be used (as in `{$:"text"}`) to accept a match against any
 *     property of the object. That's equivalent to the simple substring match with a `string`
 *     as described above.
 *
 *   - `function(value)`: A predicate function can be used to write arbitrary filters. The function is
 *     called for each element of `array`. The final result is an array of those elements that
 *     the predicate returned true for.
 *
 * @param {function(actual, expected)|true|undefined} comparator Comparator which is used in
 *     determining if the expected value (from the filter expression) and actual value (from
 *     the object in the array) should be considered a match.
 *
 *   Can be one of:
 *
 *   - `function(actual, expected)`:
 *     The function will be given the object value and the predicate value to compare and
 *     should return true if the item should be included in filtered result.
 *
 *   - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`.
 *     this is essentially strict comparison of expected and actual.
 *
 *   - `false|undefined`: A short hand for a function which will look for a substring match in case
 *     insensitive way.
 *
 * @example
   <example>
     <file name="index.html">

       Search: <input ng-model="searchText">

Name	Phone

           {{friend.name}}
           {{friend.phone}}

       Any: <input ng-model="search.$">

       Name only <input ng-model="search.name">

       Phone only <input ng-model="search.phone">

       Equality <input type="checkbox" ng-model="strict">

Name	Phone

           {{friendObj.name}}
           {{friendObj.phone}}

     </file>
     <file name="protractor.js" type="protractor">
       var expectFriendNames = function(expectedNames, key) {
         element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) {
           arr.forEach(function(wd, i) {
             expect(wd.getText()).toMatch(expectedNames[i]);
           });
         });
       };

       it('should search across all fields when filtering with a string', function() {
         var searchText = element(by.model('searchText'));
         searchText.clear();
         searchText.sendKeys('m');
         expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend');

         searchText.clear();
         searchText.sendKeys('76');
         expectFriendNames(['John', 'Julie'], 'friend');
       });

       it('should search in specific fields when filtering with a predicate object', function() {
         var searchAny = element(by.model('search.$'));
         searchAny.clear();
         searchAny.sendKeys('i');
         expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj');
       });
       it('should use a equal comparison when comparator is true', function() {
         var searchName = element(by.model('search.name'));
         var strict = element(by.model('strict'));
         searchName.clear();
         searchName.sendKeys('Julie');
         strict.click();
         expectFriendNames(['Julie'], 'friendObj');
       });
     </file>
   </example>
 */
function filterFilter() {
  return function(array, expression, comparator) {
    if (!isArray(array)) return array;

    var comparatorType = typeof(comparator),
        predicates = [];

    predicates.check = function(value) {
      for (var j = 0; j < predicates.length; j++) {
        if(!predicates[j](value)) {
          return false;
        }
      }
      return true;
    };

    if (comparatorType !== 'function') {
      if (comparatorType === 'boolean' && comparator) {
        comparator = function(obj, text) {
          return angular.equals(obj, text);
        };
      } else {
        comparator = function(obj, text) {
          if (obj && text && typeof obj === 'object' && typeof text === 'object') {
            for (var objKey in obj) {
              if (objKey.charAt(0) !== '$' && hasOwnProperty.call(obj, objKey) &&
                  comparator(obj[objKey], text[objKey])) {
                return true;
              }
            }
            return false;
          }
          text = (''+text).toLowerCase();
          return (''+obj).toLowerCase().indexOf(text) > -1;
        };
      }
    }

    var search = function(obj, text){
      if (typeof text == 'string' && text.charAt(0) === '!') {
        return !search(obj, text.substr(1));
      }
      switch (typeof obj) {
        case "boolean":
        case "number":
        case "string":
          return comparator(obj, text);
        case "object":
          switch (typeof text) {
            case "object":
              return comparator(obj, text);
            default:
              for ( var objKey in obj) {
                if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) {
                  return true;
                }
              }
              break;
          }
          return false;
        case "array":
          for ( var i = 0; i < obj.length; i++) {
            if (search(obj[i], text)) {
              return true;
            }
          }
          return false;
        default:
          return false;
      }
    };
    switch (typeof expression) {
      case "boolean":
      case "number":
      case "string":
        // Set up expression object and fall through
        expression = {$:expression};
        // jshint -W086
      case "object":
        // jshint +W086
        for (var key in expression) {
          (function(path) {
            if (typeof expression[path] == 'undefined') return;
            predicates.push(function(value) {
              return search(path == '$' ? value : (value && value[path]), expression[path]);
            });
          })(key);
        }
        break;
      case 'function':
        predicates.push(expression);
        break;
      default:
        return array;
    }
    var filtered = [];
    for ( var j = 0; j < array.length; j++) {
      var value = array[j];
      if (predicates.check(value)) {
        filtered.push(value);
      }
    }
    return filtered;
  };
}
<|endoftext|>


<commit_before>var should = require('should');
var helper = require('../helper');
var manager;
var testData;

function getData() {
    var store = testData.stores["ST-FNG"];
    var bank = testData.banks["BA-BCA"];                    //BCA, MANDIRI, BRI, dkk
    var cardType = testData.cardTypes["CT-VISA"];           //CARD, MASTERCARD, VISA
    var paymentType = testData.paymentTypes["PA-CARD"];     //CASH, CARD, PARTIAL
    var variant = testData.variants["UT-AV1"];

    var Payment = require('bateeq-models').pos.Payment;
    var PaymentItem = require('bateeq-models').pos.PaymentItem;
    var PaymentDetail = require('bateeq-models').pos.PaymentDetail;
    var payment = new Payment();

    var now = new Date();
    var stamp = now / 1000 | 0;
    var code = stamp.toString(36);

    payment.code = code;
    payment.date = now;
    payment.totalProduct = 1;
    payment.subTotal = 0;
    payment.discount = 0;
    payment.grandTotal = 0;
    payment.reference = '';
    payment.remark = '';

    payment.storeId = store._id;
    payment.store = store;

    payment.items.push(new PaymentItem({
        articleVariantId: variant._id,
        articleVariant: variant,
        quantity: 1,
        price: 100000,
        discount1: 0.1,
        discount2: 0.05,
        margin: 0,
        specialDiscount: 0,
        total: 100000
    }));

    var paymentTotal = 0;
    for(var i of payment.items) {
        paymentTotal += i.total;
    }

    payment.paymentDetail = new PaymentDetail({
        paymentTypeId : paymentType._id,
        paymentType : paymentType,
        voucherId : {},
        voucher : {},
        bankId : bank._id,
        bank : bank,
        cardTypeId : cardType._id,
        cardType : cardType,
        card : 'Credit', //Debit | Credit
        cardNumber : '1000200030004000',
        cardName : 'CardName',
        cashAmount : paymentTotal,
        cardAmount : 0
    })
    return payment;
}

before('#00. connect db', function(done) {
    helper.getDb()
        .then(db => {
            var data = require("../data");
            data(db)
                .then(result => {
                    var PaymentManager = require('../../src/managers/pos/pos-payment-doc-manager');
                    manager = new PaymentManager(db, {
                        username: 'unit-test'
                    });
                    testData = result;
                    done();
                });
        })
        .catch(e => {
            done(e);
        });
});

var createdId;
var createdData;
it('#01. should success when create new data Cash Payment Type', function(done) {
    var data = getData();
    manager.create(data)
        .then(id => {
            id.should.be.Object();
            createdId = id;
            done();
        })
        .catch(e => {
            done(e);
        });
});

it(`#02. should success when get created data with id Cash Payment Type`, function(done) {
    manager.getSingleByQuery({
            _id: createdId
        })
        .then(data => {
            createdData = data;
            done();
        })
        .catch(e => {
            done(e);
        })
});

it(`#03. should success when update created data Cash Payment Type`, function(done) {
    createdData.remark += '[updated]';
    manager.update(createdData)
        .then(id => {
            createdId.toString().should.equal(id.toString());
            done();
        })
        .catch(e => {
            done(e);
        });
});

it(`#04. should success when get updated data with id Cash Payment Type`, function(done) {
    manager.getSingleByQuery({
            _id: createdId
        })
        .then(data => {
            data.remark.should.equal(createdData.remark);
            data.items.length.should.equal(1);
            done();
        })
        .catch(e => {
            done(e);
        })
});

it(`#05. should success when delete data Cash Payment Type`, function(done) {
    manager.delete(createdData)
        .then(id => {
            createdId.toString().should.equal(id.toString());
            done();
        })
        .catch(e => {
            done(e);
        });
});

it(`#06. should _deleted=true Cash Payment Type`, function(done) {
    manager.getSingleByQuery({
            _id: createdId
        })
        .then(data => {
            data._deleted.should.be.Boolean();
            data._deleted.should.equal(true);
            done();
        })
        .catch(e => {
            done(e);
        })
});

// it('#07. should error when create new data with same code Cash Payment Type', function(done) {
//     var data = Object.assign({}, createdData);
//     delete data._id;
//     manager.create(data)
//         .then(id => {
//             id.should.be.Object();
//             createdId = id;
//             done("Should not be able to create data with same code Cash Payment Type");
//         })
//         .catch(e => {
//             try {
//                 e.errors.should.have.property('code');
//                 done();
//             }
//             catch (xe) {
//                 done(xe);
//             };
//         })
// }); <commit_msg>update test payment<commit_after>var should = require('should');
var helper = require('../helper');
var manager;
var testData;

function getData() {
    var store = testData.stores["ST-FNG"];
    var bank = testData.banks["BA-BCA"];                    //BCA, MANDIRI, BRI, dkk
    var cardType = testData.cardTypes["CT-VISA"];           //CARD, MASTERCARD, VISA
    var paymentType = testData.paymentTypes["PA-CARD"];     //CASH, CARD, PARTIAL
    var variant = testData.variants["UT-AV1"];

    var Payment = require('bateeq-models').pos.Payment;
    var PaymentItem = require('bateeq-models').pos.PaymentItem;
    var PaymentDetail = require('bateeq-models').pos.PaymentDetail;
    var payment = new Payment();

    var now = new Date();
    var stamp = now / 1000 | 0;
    var code = stamp.toString(36);

    payment.code = code;
    payment.date = now;
    payment.discount = 0;
    payment.reference = '';
    payment.remark = '';

    payment.storeId = store._id;
    payment.store = store;

    payment.items.push(new PaymentItem({
        articleVariantId: variant._id,
        articleVariant: variant,
        quantity: 1,
        price: 100000,
        discount1: 0,
        discount2: 0,
        margin: 0,
        specialDiscount: 0,
        total: 100000
    }));

    var paymentTotal = 0;
    for(var i of payment.items) {
        paymentTotal += i.total;
    }

    payment.paymentDetail = new PaymentDetail({
        paymentTypeId : paymentType._id,
        paymentType : paymentType,
        voucherId : {},
        voucher : {},
        bankId : bank._id,
        bank : bank,
        cardTypeId : cardType._id,
        cardType : cardType,
        card : 'Credit', //Debit | Credit
        cardNumber : '1000200030004000',
        cardName : 'CardName',
        cashAmount : 0,
        cardAmount : paymentTotal
    })
    return payment;
}

before('#00. connect db', function(done) {
    helper.getDb()
        .then(db => {
            var data = require("../data");
            data(db)
                .then(result => {
                    var PaymentManager = require('../../src/managers/pos/pos-payment-doc-manager');
                    manager = new PaymentManager(db, {
                        username: 'unit-test'
                    });
                    testData = result;
                    done();
                });
        })
        .catch(e => {
            done(e);
        });
});

var createdId;
var createdData;
it('#01. should success when create new data Cash Payment Type', function(done) {
    var data = getData();
    manager.create(data)
        .then(id => {
            id.should.be.Object();
            createdId = id;
            done();
        })
        .catch(e => {
            done(e);
        });
});

it(`#02. should success when get created data with id Cash Payment Type`, function(done) {
    manager.getSingleByQuery({
            _id: createdId
        })
        .then(data => {
            createdData = data;
            done();
        })
        .catch(e => {
            done(e);
        })
});

it(`#03. should success when update created data Cash Payment Type`, function(done) {
    createdData.remark += '[updated]';
    manager.update(createdData)
        .then(id => {
            createdId.toString().should.equal(id.toString());
            done();
        })
        .catch(e => {
            done(e);
        });
});

it(`#04. should success when get updated data with id Cash Payment Type`, function(done) {
    manager.getSingleByQuery({
            _id: createdId
        })
        .then(data => {
            data.remark.should.equal(createdData.remark);
            data.items.length.should.equal(1);
            done();
        })
        .catch(e => {
            done(e);
        })
});

it(`#05. should success when delete data Cash Payment Type`, function(done) {
    manager.delete(createdData)
        .then(id => {
            createdId.toString().should.equal(id.toString());
            done();
        })
        .catch(e => {
            done(e);
        });
});

it(`#06. should _deleted=true Cash Payment Type`, function(done) {
    manager.getSingleByQuery({
            _id: createdId
        })
        .then(data => {
            data._deleted.should.be.Boolean();
            data._deleted.should.equal(true);
            done();
        })
        .catch(e => {
            done(e);
        })
});

// it('#07. should error when create new data with same code Cash Payment Type', function(done) {
//     var data = Object.assign({}, createdData);
//     delete data._id;
//     manager.create(data)
//         .then(id => {
//             id.should.be.Object();
//             createdId = id;
//             done("Should not be able to create data with same code Cash Payment Type");
//         })
//         .catch(e => {
//             try {
//                 e.errors.should.have.property('code');
//                 done();
//             }
//             catch (xe) {
//                 done(xe);
//             };
//         })
// }); <|endoftext|>


<commit_before>describe('bootcode dependencies', function () {
    this.timeout(60 * 1000);

    var env = require('../../lib/environment'),
        Bundle = require('../../lib/bundle'),
        currentDependencies;

    before(function (done) {
        process && process.stdout.write('  -- building dependencies, please wait... ');
        Bundle.load(env).listDependencies(function (err, dependencies) {
            currentDependencies = dependencies;
            console.log(err ? 'failed' : 'done');
            return done(err);
        });
    });

    it('should not change', function () {
        expect(currentDependencies).to.eql([
            'ajv',
            'ansi-styles',
            'array-uniq',
            'assert',
            'assertion-error',
            'atob',
            'backbone',
            'base64-js',
            'boolbase',
            'browserify',
            'btoa',
            'buffer',
            'chai',
            'chai-postman',
            'chalk',
            'charset',
            'check-error',
            'cheerio',
            'color-convert',
            'color-name',
            'core-util-is',
            'crypto-js',
            'css-select',
            'css-what',
            'csv-parse',
            'deep-eql',
            'dom-serializer',
            'domelementtype',
            'domhandler',
            'domutils',
            'entities',
            'escape-html',
            'escape-string-regexp',
            'events',
            'fast-deep-equal',
            'fast-json-stable-stringify',
            'file-type',
            'get-func-name',
            'has-flag',
            'htmlparser2',
            'http-reasons',
            'iconv-lite',
            'ieee754',
            'inherits',
            'isarray',
            'jquery',
            'json-schema-traverse',
            'liquid-json',
            'lodash',
            'lodash.assignin',
            'lodash.bind',
            'lodash.clonedeep',
            'lodash.defaults',
            'lodash.escaperegexp',
            'lodash.filter',
            'lodash.flatten',
            'lodash.foreach',
            'lodash.isplainobject',
            'lodash.isstring',
            'lodash.map',
            'lodash.merge',
            'lodash.mergewith',
            'lodash.pick',
            'lodash.reduce',
            'lodash.reject',
            'lodash.some',
            'lodash3',
            'marked',
            'mime-db',
            'mime-format',
            'mime-types',
            'moment',
            'nth-check',
            'number-is-nan',
            'os-browserify',
            'path-browserify',
            'pathval',
            'postcss',
            'postman-collection',
            'postman-sandbox',
            'postman-url-encoder',
            'process',
            'process-nextick-args',
            'punycode',
            'querystring-es3',
            'readable-stream',
            'safe-buffer',
            'safer-buffer',
            'sanitize-html',
            'sax',
            'semver',
            'source-map',
            'srcset',
            'stream-browserify',
            'string_decoder',
            'supports-color',
            'timers-browserify',
            'tv4',
            'type-detect',
            'underscore',
            'uniscope',
            'uri-js',
            'url',
            'util',
            'util-deprecate',
            'uuid',
            'xml2js',
            'xmlbuilder',
            'xtend'
        ]);
    });
});
<commit_msg>Test: add tough-cookie to bootcode-dependencies<commit_after>describe('bootcode dependencies', function () {
    this.timeout(60 * 1000);

    var env = require('../../lib/environment'),
        Bundle = require('../../lib/bundle'),
        currentDependencies;

    before(function (done) {
        process && process.stdout.write('  -- building dependencies, please wait... ');
        Bundle.load(env).listDependencies(function (err, dependencies) {
            currentDependencies = dependencies;
            console.log(err ? 'failed' : 'done');
            return done(err);
        });
    });

    it('should not change', function () {
        expect(currentDependencies).to.eql([
            'ajv',
            'ansi-styles',
            'array-uniq',
            'assert',
            'assertion-error',
            'atob',
            'backbone',
            'base64-js',
            'boolbase',
            'browserify',
            'btoa',
            'buffer',
            'chai',
            'chai-postman',
            'chalk',
            'charset',
            'check-error',
            'cheerio',
            'color-convert',
            'color-name',
            'core-util-is',
            'crypto-js',
            'css-select',
            'css-what',
            'csv-parse',
            'deep-eql',
            'dom-serializer',
            'domelementtype',
            'domhandler',
            'domutils',
            'entities',
            'escape-html',
            'escape-string-regexp',
            'events',
            'fast-deep-equal',
            'fast-json-stable-stringify',
            'file-type',
            'get-func-name',
            'has-flag',
            'htmlparser2',
            'http-reasons',
            'iconv-lite',
            'ieee754',
            'inherits',
            'ip-regex',
            'isarray',
            'jquery',
            'json-schema-traverse',
            'liquid-json',
            'lodash',
            'lodash.assignin',
            'lodash.bind',
            'lodash.clonedeep',
            'lodash.defaults',
            'lodash.escaperegexp',
            'lodash.filter',
            'lodash.flatten',
            'lodash.foreach',
            'lodash.isplainobject',
            'lodash.isstring',
            'lodash.map',
            'lodash.merge',
            'lodash.mergewith',
            'lodash.pick',
            'lodash.reduce',
            'lodash.reject',
            'lodash.some',
            'lodash3',
            'marked',
            'mime-db',
            'mime-format',
            'mime-types',
            'moment',
            'nth-check',
            'number-is-nan',
            'os-browserify',
            'path-browserify',
            'pathval',
            'postcss',
            'postman-collection',
            'postman-sandbox',
            'postman-url-encoder',
            'process',
            'process-nextick-args',
            'psl',
            'punycode',
            'querystring-es3',
            'readable-stream',
            'safe-buffer',
            'safer-buffer',
            'sanitize-html',
            'sax',
            'semver',
            'source-map',
            'srcset',
            'stream-browserify',
            'string_decoder',
            'supports-color',
            'timers-browserify',
            'tough-cookie',
            'tv4',
            'type-detect',
            'underscore',
            'uniscope',
            'uri-js',
            'url',
            'util',
            'util-deprecate',
            'uuid',
            'xml2js',
            'xmlbuilder',
            'xtend'
        ]);
    });
});
<|endoftext|>


<commit_before>// needs jQuery, jQuery-ui, jQuery-ui smoothness CSS theme
// (or we could make our own styling for the autocomplete menu and would just need the first two).

$(function() {

  var config = {
    // text input element to which we're attaching this autoComplete handler.
    attachTo: ".mention",
    // route to which we make our JSON request.
    route: "/mock",
    // characters required after @ for autocomplete to fire.
    minLength: 3,
    // attribute within each individual object in the backend response that gets us the username.
    resAtt: "username",
    // attribute name on our query object (backend needs to know this to get to the search term).
    reqAtt: "search"
  };

  //
  // ------------------- autoComplete handler starts from here --------------
  //

  $( config.attachTo )
    .bind( "keydown", onKeyDown)
    .autocomplete({
      source: getData,
      search: autoCompleteWhen,
      focus: function() {
        return false;
      },
      select: insertValue
    });

  //
  // ----------------------- helper functions ---------------------------
  //

  // handle data response here (need .label and .value for each autocomplete object)
  function formatResponse(data) {
    return data.map(function(obj) {
      var ret_obj = {};
      ret_obj.label = "@" + obj[config.resAtt];
      ret_obj.value = obj[config.resAtt];
      return ret_obj;
    });
  }
  function split( val ) {
    return val.split( /\s*@/ );
  }
  function extractLast( term ) {
    return split( term ).pop();
  }
  function getData(request, response) {
    var term = extractLast( request.term );
    var query= {};
    query[config.reqAtt] = term;
    $.getJSON( config.route, query, function(data) {
      var formattedData = formatResponse(data);
      if (term.indexOf(" ") !== -1) {
        response();
        return;
      }
      response(formattedData);
    });
  }
  function insertValue( event, ui ) {
    var terms = this.value.split( /\s+@/ );
    // special case; don't add a space before @ if the mention is the first thing user enters.
    if (terms.length === 1) {this.value = "@" + ui.item.value + " "; return false;}
    terms.pop();
    terms.push( ui.item.value );
    this.value = terms.join( " @" ) + " ";
    return false;
  }
  function autoCompleteWhen() {
    var term = extractLast( this.value );
    if (split(this.value).length === 1 || term.length < config.minLength) return false;
  }
  function onKeyDown(event) {
    if ( event.keyCode === $.ui.keyCode.TAB &&
        $( this ).autocomplete( "instance" ).menu.active ) {
      event.preventDefault();
    }
  }
});
<commit_msg>set $ to global for testing<commit_after>/*global $:false */

// needs jQuery, jQuery-ui, jQuery-ui smoothness CSS theme
// (or we could make our own styling for the autocomplete menu and would just need the first two).

$(function() {

  var config = {
    // text input element to which we're attaching this autoComplete handler.
    attachTo: ".mention",
    // route to which we make our JSON request.
    route: "/mock",
    // characters required after @ for autocomplete to fire.
    minLength: 3,
    // attribute within each individual object in the backend response that gets us the username.
    resAtt: "username",
    // attribute name on our query object (backend needs to know this to get to the search term).
    reqAtt: "search"
  };

  //
  // ------------------- autoComplete handler starts from here --------------
  //

  $( config.attachTo )
    .bind( "keydown", onKeyDown)
    .autocomplete({
      source: getData,
      search: autoCompleteWhen,
      focus: function() {
        return false;
      },
      select: insertValue
    });

  //
  // ----------------------- helper functions ---------------------------
  //

  // handle data response here (need .label and .value for each autocomplete object)
  function formatResponse(data) {
    return data.map(function(obj) {
      var ret_obj = {};
      ret_obj.label = "@" + obj[config.resAtt];
      ret_obj.value = obj[config.resAtt];
      return ret_obj;
    });
  }
  function split( val ) {
    return val.split( /\s*@/ );
  }
  function extractLast( term ) {
    return split( term ).pop();
  }
  function getData(request, response) {
    var term = extractLast( request.term );
    var query= {};
    query[config.reqAtt] = term;
    $.getJSON( config.route, query, function(data) {
      var formattedData = formatResponse(data);
      if (term.indexOf(" ") !== -1) {
        response();
        return;
      }
      response(formattedData);
    });
  }
  function insertValue( event, ui ) {
    var terms = this.value.split( /\s+@/ );
    // special case; don't add a space before @ if the mention is the first thing user enters.
    if (terms.length === 1) {this.value = "@" + ui.item.value + " "; return false;}
    terms.pop();
    terms.push( ui.item.value );
    this.value = terms.join( " @" ) + " ";
    return false;
  }
  function autoCompleteWhen() {
    var term = extractLast( this.value );
    if (split(this.value).length === 1 || term.length < config.minLength) return false;
  }
  function onKeyDown(event) {
    if ( event.keyCode === $.ui.keyCode.TAB &&
        $( this ).autocomplete( "instance" ).menu.active ) {
      event.preventDefault();
    }
  }
});
<|endoftext|>


<commit_before>import EmberRouter from '@ember/routing/router';
import config from 'dummy/config/environment';

export default class Router extends EmberRouter {
  location = config.locationType;
  rootURL = config.rootURL;
}

Router.map(function() {
  this.route('examples', { path: '/examples' });
  this.route('usage', { path: '/usage' });
  this.route('index', { path: '/' });
});

export default Router;
<commit_msg>Fixup double export in dummy router<commit_after>import EmberRouter from '@ember/routing/router';
import config from 'dummy/config/environment';

export default class Router extends EmberRouter {
  location = config.locationType;
  rootURL = config.rootURL;
}

Router.map(function () {
  this.route('examples', { path: '/examples' });
  this.route('usage', { path: '/usage' });
  this.route('index', { path: '/' });
});
<|endoftext|>


<commit_before>const test = require('tape');
const setup = require('./setup');
const config = require('./config');
test('downloader', t => {
	setup.resetTestDataDir();
	t.timeoutAfter(30e3);
	const app = setup.createApp();
	setup.waitForLoad(app, t, {online: true})
		.then(() => app.browserWindow.focus())
		.then(() => app.client.waitUntilTextExists('#downloader', 'Go to Downloader'))
		.then(() => app.client.moveToObject('#downloader'))
		.then(() => setup.wait())
		.then(() => app.client.click('#downloader'))
		.then(() => setup.wait(6e3))
		.then(() => {
			app.electron.clipboard.writeText('https://cdn.rawgit.com/willyb321/media_mate/4c10674eaa76d9006b2ad4826a8c69b888386c39/tests/resources/downloader_test.rss')
				.electron.clipboard.readText().then(function (clipboardText) {
					app.client.moveToObject('#rss')
						.then(() => setup.wait())
						.then(() => app.client.click('#rss'))
						.then(() => setup.wait())
						.then(() => app.client.element('#rss').setValue(clipboardText))
						.then(() => app.client.moveToObject('#title'))
						.then(() => setup.wait())
						.then(() => app.client.click('#dupecount'))
						.then(() => setup.wait(2e3))
						.then(() => app.client.executeAsync(async function (done) {
							let swalcon = await getSwalConfirmButton()
							swalcon.id = 'downloaderSwalConfirmBut'
							done({id: swalcon.id});
						})
							.then(result => {
								console.log(result);
								t.equal(result.value.id, 'downloaderSwalConfirmBut', 'Sweetalert ok button\'s id was set to "downloaderSwalConfirmBut"')
							}))
						.then(() => setup.screenshotCreateOrCompare(app, t, 'downloader-sweetalert'))
						.then(() => setup.wait())
						.then(() => app.client.click('#downloaderSwalConfirmBut'))
						.then(() => setup.wait(3e3))
						.then(() => setup.screenshotCreateOrCompare(app, t, 'downloader-downloads'))
						.then(() => app.webContents.executeJavaScript('insertDlPath()'))
						.then(() => setup.copy(`${__dirname}/resources/top.gear.s24e07.hdtv.x264-mtb.mp4`, `${config.TEST_DIR_DOWNLOAD}/top.gear.s24e07.hdtv.x264-mtb.mp4`))
						.then(() => setup.endTest(app, t),
							err => setup.endTest(app, t, err || 'error'));
				});
		});
});
<commit_msg>fancy arrow functions<commit_after>const test = require('tape');
const setup = require('./setup');
const config = require('./config');
test('downloader', t => {
	setup.resetTestDataDir();
	t.timeoutAfter(30e3);
	const app = setup.createApp();
	setup.waitForLoad(app, t, {online: true})
		.then(() => app.browserWindow.focus())
		.then(() => app.client.waitUntilTextExists('#downloader', 'Go to Downloader'))
		.then(() => app.client.moveToObject('#downloader'))
		.then(() => setup.wait())
		.then(() => app.client.click('#downloader'))
		.then(() => setup.wait(6e3))
		.then(() => {
			app.electron.clipboard.writeText('https://cdn.rawgit.com/willyb321/media_mate/4c10674eaa76d9006b2ad4826a8c69b888386c39/tests/resources/downloader_test.rss')
				.electron.clipboard.readText().then(function (clipboardText) {
					app.client.moveToObject('#rss')
						.then(() => setup.wait())
						.then(() => app.client.click('#rss'))
						.then(() => setup.wait())
						.then(() => app.client.element('#rss').setValue(clipboardText))
						.then(() => app.client.moveToObject('#title'))
						.then(() => setup.wait())
						.then(() => app.client.click('#dupecount'))
						.then(() => setup.wait(2e3))
						.then(() => app.client.executeAsync(async function (done) {
							let swalcon = await getSwalConfirmButton()
							swalcon.id = 'downloaderSwalConfirmBut'
							done({id: swalcon.id});
						}))
						.then(result => t.equal(result.value.id, 'downloaderSwalConfirmBut', 'Sweetalert ok button\'s id was set to "downloaderSwalConfirmBut"'))
						.then(() => setup.screenshotCreateOrCompare(app, t, 'downloader-sweetalert'))
						.then(() => setup.wait())
						.then(() => app.client.click('#downloaderSwalConfirmBut'))
						.then(() => setup.wait(3e3))
						.then(() => setup.screenshotCreateOrCompare(app, t, 'downloader-downloads'))
						.then(() => app.webContents.executeJavaScript('insertDlPath()'))
						.then(() => setup.copy(`${__dirname}/resources/top.gear.s24e07.hdtv.x264-mtb.mp4`, `${config.TEST_DIR_DOWNLOAD}/top.gear.s24e07.hdtv.x264-mtb.mp4`))
						.then(() => setup.endTest(app, t),
							err => setup.endTest(app, t, err || 'error'));
				});
		});
});
<|endoftext|>


<commit_before>/* global describe, expect, fallback, it */

describe('tests.unit.core.init', function() {
	it('should be a Function', function() {
		var test = fallback.init;
		expect(test).to.be.a('function');
	});

	it('to always return `true`', function() {
		var test = fallback.init();
		expect(test).to.equal(true);
	});

	it('should always be initialized', function() {
		expect(fallback.inited).to.equal(true);
	});
});
<commit_msg>Fixing core unit tests<commit_after>/* global describe, expect, fallback, it */

describe('tests.unit.core.init', function() {
	it('should be a Function', function() {
		var test = fallback.init;
		expect(test).to.be.a('function');
	});
});
<|endoftext|>


<commit_before>angular.module('oauth.salesforce', ['oauth.utils'])
  .factory('$ngCordovaSalesforce', salesforce);

function salesforce($q, $http, $cordovaOauthUtility) {
  return { signin: oauthSalesforce };

  /*
   * Sign into the Salesforce service
   *
   * Suggestion: use salesforce oauth with forcetk.js(as SDK)
   *
   * @param    string loginUrl (such as: https://login.salesforce.com ; please notice community login)
   * @param    string clientId (copy from connection app info)
   * @param    string redirectUri (callback url in connection app info)
   * @return   promise
   */
  function oauthSalesforce(loginUrl, clientId) {
    var redirectUri = 'http://localhost/callback';
    var getAuthorizeUrl = function (loginUrl, clientId, redirectUri) {
      return loginUrl+'services/oauth2/authorize?display=touch'+
        '&response_type=token&client_id='+escape(clientId)+
        '&redirect_uri='+escape(redirectUri);
    };
    var startWith = function(string, str) {
      return (string.substr(0, str.length) === str);
    };

    var deferred = $q.defer();
    if(window.cordova) {
      if($cordovaOauthUtility.isInAppBrowserInstalled()) {
        var browserRef = window.cordova.InAppBrowser.open(getAuthorizeUrl(loginUrl, clientId, redirectUri), "_blank", "location=no,clearsessioncache=yes,clearcache=yes");
        browserRef.addEventListener("loadstart", function(event) {
          if(startWith(event.url, redirectUri)) {
              var oauthResponse = {};

              var fragment = (event.url).split('#')[1];

              if (fragment) {
                var nvps = fragment.split('&');
                for (var nvp in nvps) {
                  var parts = nvps[nvp].split('=');
                  oauthResponse[parts[0]] = unescape(parts[1]);
                }
              }

              if (typeof oauthResponse === 'undefined' ||
                typeof oauthResponse.access_token === 'undefined') {
                deferred.reject("Problem authenticating");
              } else {
                deferred.resolve(oauthResponse);
              }
              setTimeout(function() {
                browserRef.close();
              }, 10);
          }
        });
        browserRef.addEventListener('exit', function(event) {
          deferred.reject("The sign in flow was canceled");
        });
      } else {
        deferred.reject("Could not find InAppBrowser plugin");
      }
    } else {
      deferred.reject("Cannot authenticate via a web browser");
    }
    return deferred.promise;
  }
}

salesforce.$inject = ['$q', '$http', '$cordovaOauthUtility'];
<commit_msg>IIFE salesforce<commit_after>(function() {
  'use strict';

  angular.module('oauth.salesforce', ['oauth.utils'])
    .factory('$ngCordovaSalesforce', salesforce);

  function salesforce($q, $http, $cordovaOauthUtility) {
    return { signin: oauthSalesforce };

    /*
     * Sign into the Salesforce service
     *
     * Suggestion: use salesforce oauth with forcetk.js(as SDK)
     *
     * @param    string loginUrl (such as: https://login.salesforce.com ; please notice community login)
     * @param    string clientId (copy from connection app info)
     * @param    string redirectUri (callback url in connection app info)
     * @return   promise
     */
    function oauthSalesforce(loginUrl, clientId) {
      var redirectUri = 'http://localhost/callback';
      var getAuthorizeUrl = function (loginUrl, clientId, redirectUri) {
        return loginUrl+'services/oauth2/authorize?display=touch'+
          '&response_type=token&client_id='+escape(clientId)+
          '&redirect_uri='+escape(redirectUri);
      };
      var startWith = function(string, str) {
        return (string.substr(0, str.length) === str);
      };

      var deferred = $q.defer();
      if(window.cordova) {
        if($cordovaOauthUtility.isInAppBrowserInstalled()) {
          var browserRef = window.cordova.InAppBrowser.open(getAuthorizeUrl(loginUrl, clientId, redirectUri), "_blank", "location=no,clearsessioncache=yes,clearcache=yes");
          browserRef.addEventListener("loadstart", function(event) {
            if(startWith(event.url, redirectUri)) {
                var oauthResponse = {};

                var fragment = (event.url).split('#')[1];

                if (fragment) {
                  var nvps = fragment.split('&');
                  for (var nvp in nvps) {
                    var parts = nvps[nvp].split('=');
                    oauthResponse[parts[0]] = unescape(parts[1]);
                  }
                }

                if (typeof oauthResponse === 'undefined' ||
                  typeof oauthResponse.access_token === 'undefined') {
                  deferred.reject("Problem authenticating");
                } else {
                  deferred.resolve(oauthResponse);
                }
                setTimeout(function() {
                  browserRef.close();
                }, 10);
            }
          });
          browserRef.addEventListener('exit', function(event) {
            deferred.reject("The sign in flow was canceled");
          });
        } else {
          deferred.reject("Could not find InAppBrowser plugin");
        }
      } else {
        deferred.reject("Cannot authenticate via a web browser");
      }
      return deferred.promise;
    }
  }

  salesforce.$inject = ['$q', '$http', '$cordovaOauthUtility'];
})();
<|endoftext|>