<commit_before>
// Get information from input box
console.log($('#crypto').val());

var keepGoing = 1;

// setup socket
var socket;
var namespace = '/feed';
if (socket == null) {
    socket = io.connect('//' + document.domain + ':' + location.port + namespace, { pingInterval: 5000, 'sync disconnect on unload': true });
}

// Make a box to show win losses
// function makeBox() {
//     var $div = $("

").appendTo('body');
//     $div.attr('id', 'holder');
// }

// var box = $('#holder');
// if (box == undefined) {
//     makeBox();
// }
// makeBox();
// get coin

// get value of coin

// set variables
var target;
var startBet;
var currency;
var startBalance = 0;
var currentBalance;
var origStart;

var minValue = 0.00000001;
// var smallestValue = 0.00000001;
// var smallestValue = 0.000008;
// var smallestValue = 0.00000001;
var smallestValue = 0.5;
var decimals = 8;
var currentBet = smallestValue;
var ladder = 0;
var maxLadder = 0;
var maxLadders = 20; // maximum number of steps to go before resetting
var increase = 1.1; // 10% increase
var timeOut = 300;
// var timeOut = 150;
var stopLoss; // if balance goes below this, quit

var totalWins = 0, totalLosses = 0;
var bet = smallestValue;
var stopGain; // If I make x% gains, stop also
var stopGainPercent = 100;

var equalizeNumber = 20;
var equalizeCounter = equalizeNumber;
var equalizeLosses = 0;
var needToEqualize = true;
var modNumber = 20;

var maxBigLosses = 10; // If get to this ladder and lose this many times, quit, eventually adjust with the % increase
var bigLosses = 0; // current big losses

var divisor = 100000000;
// var divisor = 60000;

(function setVariables() {
    target = "49"
    startBet = smallestValue;
    currency = "XP";
    // currency = "LTC";
})();

// get amount of coins
function getInitialBalance() {
    var values = {
        'target': target,
        'currency': currency,
        'bet': currentBet
    }
    socket.emit('dice_roll', values, function (callback) {
        console.log(callback);
        console.log(callback.data.balance);
        startBalance = callback.data.balance;
        currentBalance = startBalance;
        stopLoss = startBalance - startBalance * 0.0001; // 1/100th a percent of total value
        origStart = startBalance;
        stopGain = stopGainPercent * origStart; //
        console.log("Stop loss: " + stopLoss);
        smallestValue = startBalance / divisor; //millionth of start
        startAutoTrading(callback);
    });
}
getInitialBalance();

var lossesInARow = 0;

// start trading
function startAutoTrading(callback) {
    //console.log(callback);
    currentBalance = callback.data.balance;

    var tg = (currentBalance - startBalance).toFixed(decimals);
    if (ladder > maxLadder) maxLadder = ladder;

    console.log("Current Value: " + currentBalance +
        " Total gains: " + tg +
        ", gains percentage: " + ((((currentBalance - startBalance) / (startBalance)) * 100).toFixed(3)) + "%" +
        ", gains since beginning " + ((((currentBalance - origStart) / (origStart)) * 100).toFixed(3)) + "%");
    console.log("Total wins/losses: " + totalWins + "/" + totalLosses +
        ", win percentage: " + (((totalWins / (totalLosses + totalWins)) * 100).toFixed(3)) + "%" +
        ", longest ladder: " + maxLadder +
        ",  lossesInARow: " + lossesInARow +
        ",  Current Bet: " + bet);

    if (ladder % modNumber == 0 && ladder != 0 && callback.data.win == 0 && needToEqualize == true) {
        equalizeCounter = equalizeNumber;
        equalizeLosses = 0;
        console.log("Equalize");
        equalize(equalizeCounter, callback);
        return;
    }

    needToEqualize = true;
    // if win, reset to smallest increment
    if (callback.data.win == 1) {
        // console.log("Won!");
        totalWins++;
        lossesInARow = 0;
        // $('#winLoss').append("
Win
");
        lossesInARow = 0;
        ladder = 0;
        bet = smallestValue;
        needToEqualize = true;
    } else {
        // lost, get new value to bet
        // console.log("Lost");

        lossesInARow++;
        ladder++;
        totalLosses++;
        // $('#winLoss').append("
Lost
");
        upBet();
    }
    singleTrade();

    // needToEqualize = false;
}

function upBet() {
    // console.log("upBet");
    if (ladder == maxLadders) {
        bet = smallestValue;
        return;
    }
    bet = (bet * 2) * increase + smallestValue;
    bet = bet.toFixed(decimals);

    // if value has increased 20%, up the starting value by 5%
    if (currentBalance > startBalance * 1.001) {
        console.log("Adding 0.05% to base value because added 0.1% value to starting value");
        console.log("Old start: " + startBalance);
        startBalance *= 1.0005;
        console.warn("New start: " + startBalance + " Original start: " + origStart + ", percent increase since start:" + ((((currentBalance - origStart) / (origStart)) * 100).toFixed(3)) + "%");
        smallestValue = currentBalance / divisor; //millionth of current balance
    }
}

function equalize(numberLeft, origCallback) { // If all of these return a losing bet, exit, or start over
    var valuesTemp = {
        'target': target,
        'currency': currency,
        'bet': 0.00000001,
    }
    // console.log(values);
    socket.emit('dice_roll', valuesTemp, function (callback) {
        numberLeft--;
        if (callback.data.win == 0) {
            console.log("\tLost");
            equalizeLosses++
        } else {
            console.log("\tWon");
        }
        if (numberLeft == 0) {
            // if lost all of them, exit
            if (equalizeLosses >= equalizeNumber * .70) { // pass with 70% fail or better
                console.warn("After " + equalizeNumber + " losses, exiting since 70% failed");
                // keepGoing = 0;
                // return;
                // reset to start again
                bet = smallestValue;
                ladder = 0;
                lossesInARow = 0;
            }
            needToEqualize = false;
            lossesInARow++;
            upBet();
            startAutoTrading(origCallback);
        }
        else equalize(numberLeft, origCallback);
    });
}

// single trade
function singleTrade() {
    // console.log("singleTrade");
    // console.log("lossesInARow: " + lossesInARow);

    if (shouldIStop() == 0) {
        console.error("Stopped, original start balance was " + origStart + " current balance is " + currentBalance);
        return;
    }

    var values = {
        'target': target,
        'currency': currency,
        'bet': bet,
    }
    // console.log(values);
    socket.emit('dice_roll', values, function (data) {
        // console.log(data.result);
        //console.log(data);

        setTimeout(function () {
            startAutoTrading(data);
        }, timeOut)
    });
};

function shouldIStop() {
    if (keepGoing == 0 && ladder == 0) return 0; // wait till reach a win
    if (ladder >= maxLadders) {
        if (maxBigLosses <= bigLosses) {
            console.error("Quit because had " + bigLosses + " big losses");
            return 0;
        }
        bigLosses++;
        console.warn("Have had " + bigLosses + " big loss");
        bet = smallestValue;
        ladder = 0;
        lossesInARow = 0;
    }
    // if (currentBalance > stopLoss) return 0; // Lost enough to quit
    if (currentBalance < startBalance - startBalance * .05 || currentBalance < origStart - origStart * .05) {
        console.error("Quit because lost 5% of " + startBalance);
        return 0;
    }
    if (currentBalance > stopGain) {
        console.error("Quit because gained" + stopGainPercent + " percent increase from original start");
        return 0;
    }
    return 1;
}

// singleTrade();

// roller bot - chould just paste into the terminal or insert into page
// stop = % below start value that will stop the bot
// start at smallest increment
// max_value of value as a % of total value owned ~1/100,000th
// %increase - if lose, double and add x percent
// timeout - if lose, increase timeout, if win decrease + random
// if win, reset to beginning ladder/value
// track losses in a row, max/average
// track win/lose rate
// max_loss, something like 1% of total value, so this could run 100 times till it would go to 0, if it weren't to stop if it lost x percent from above
// track time running and current gain/loss percentage
// eventually scale up and down according to current total value
// if 15 losses in a row, kill, or alternately start a mode that just bets the minimum value ~50 times until the win/loss ratio returns to within 5% of 50%
// rolling quit value, if I gain x percent, readjust quit value to be higher (never lower) so I don't lose what I have already gained
<commit_msg>Adjust bet based on current value<commit_after>
// Get information from input box
console.log($('#crypto').val());

var keepGoing = 1;

// setup socket
var socket;
var namespace = '/feed';
if (socket == null) {
    socket = io.connect('//' + document.domain + ':' + location.port + namespace, { pingInterval: 5000, 'sync disconnect on unload': true });
}

// Make a box to show win losses
// function makeBox() {
//     var $div = $("

").appendTo('body');
//     $div.attr('id', 'holder');
// }

// var box = $('#holder');
// if (box == undefined) {
//     makeBox();
// }
// makeBox();
// get coin

// get value of coin

// set variables
var target;
var startBet;
var currency;
var startBalance = 0;
var currentBalance;
var origStart;

var minValue = 0.00000001;
// var smallestValue = 0.00000001;
// var smallestValue = 0.000008;
// var smallestValue = 0.00000001;
var smallestValue = 0.5;
var decimals = 8;
var currentBet = smallestValue;
var ladder = 0;
var maxLadder = 0;
var maxLadders = 8; // maximum number of steps to go before resetting
var increase = 1.1; // 10% increase
var timeOut = 500;
// var timeOut = 150;
var stopLoss; // if balance goes below this, quit

var totalWins = 0, totalLosses = 0;
var bet = smallestValue;
var stopGain; // If I make x% gains, stop also
var stopGainPercent = 10;

var equalizeNumber = 20;
var equalizeCounter = equalizeNumber;
var equalizeLosses = 0;
var needToEqualize = true;
var modNumber = 4;

var maxBigLosses = 10; // If get to this ladder and lose this many times, quit, eventually adjust with the % increase
var bigLosses = 0; // current big losses

var partOfWhole = 6000;

(function setVariables() {
    target = "49"
    startBet = smallestValue;
    currency = "XP";
    // currency = "LTC";
})();

// get amount of coins
function getInitialBalance() {
    var values = {
        'target': target,
        'currency': currency,
        'bet': currentBet
    }
    socket.emit('dice_roll', values, function (callback) {
        console.log(callback);
        console.log(callback.data.balance);
        startBalance = callback.data.balance;
        currentBalance = startBalance;
        stopLoss = startBalance - startBalance * 0.0001; // 1/100th a percent of total value
        origStart = startBalance;
        stopGain = stopGainPercent * origStart; //
        console.log("Stop loss: " + stopLoss);
        startAutoTrading(callback);
    });
}
getInitialBalance();

var lossesInARow = 0;

// start trading
function startAutoTrading(callback) {
    //console.log(callback);
    currentBalance = callback.data.balance;
    adjustBet();
    var tg = (currentBalance - startBalance).toFixed(decimals);
    if (ladder > maxLadder) maxLadder = ladder;

    console.log("Current Value: " + currentBalance +
        " Total gains: " + tg +
        ", gains percentage: " + ((((currentBalance - startBalance) / (startBalance)) * 100).toFixed(3)) + "%" +
        ", gains since beginning " + ((((currentBalance - origStart) / (origStart)) * 100).toFixed(3)) + "%");
    console.log("Total wins/losses: " + totalWins + "/" + totalLosses +
        ", win percentage: " + (((totalWins / (totalLosses + totalWins)) * 100).toFixed(3)) + "%" +
        ", longest ladder: " + maxLadder +
        ",  lossesInARow: " + lossesInARow +
        ",  Current Bet: " + bet);

    if (ladder % modNumber == 0 && ladder != 0 && callback.data.win == 0 && needToEqualize == true) {
        equalizeCounter = equalizeNumber;
        equalizeLosses = 0;
        console.log("Equalize");
        equalize(equalizeCounter, callback);
        return;
    }

    needToEqualize = true;

    // if win, reset to smallest increment
    if (callback.data.win == 1) {
        console.log("Won!");
        smallestValue = currentBalance / partOfWhole;
        smallestValue = (smallestValue).toFixed(8);
        console.log(smallestValue);
        totalWins++;
        lossesInARow = 0;
        // $('#winLoss').append("
Win
");
        lossesInARow = 0;
        ladder = 0;
        bet = smallestValue;
        needToEqualize = true;
    } else {
        // lost, get new value to bet
        // console.log("Lost");

        lossesInARow++;
        ladder++;
        totalLosses++;
        // $('#winLoss').append("
Lost
");
        upBet();
    }
    singleTrade();

    // needToEqualize = false;
}

function upBet() {
    // console.log("upBet");
    if (ladder == maxLadders) {
        bet = smallestValue;
        return;
    }
    bet = (bet * 2) * increase + smallestValue;
    bet = parseFloat(bet).toFixed(decimals);

}

function adjustBet() {
    // if value has increased 20%, up the starting value by 5%
    if (currentBalance > startBalance * 1.001) {
        console.log("Adding 0.05% to base value because added 0.1% value to starting value");
        console.log("Old start: " + startBalance);
        startBalance *= 1.0005;
        console.warn("New start: " + startBalance + " Original start: " + origStart + ", percent increase since start:" + ((((currentBalance - origStart) / (origStart)) * 100).toFixed(3)) + "%");
        smallestValue = currentBalance / partOfWhole; //millionth of current balance
    }
}

function equalize(numberLeft, origCallback) { // If all of these return a losing bet, exit, or start over
    var valuesTemp = {
        'target': target,
        'currency': currency,
        'bet': 0.00000001,
    }
    // console.log(values);
    socket.emit('dice_roll', valuesTemp, function (callback) {
        numberLeft--;
        if (callback.data.win == 0) {
            console.log("\tLost");
            equalizeLosses++
        } else {
            console.log("\tWon");
        }
        if (numberLeft == 0) {
            // if lost all of them, exit
            if (equalizeLosses >= equalizeNumber * .70) { // pass with 70% fail or better
                console.warn("After " + equalizeNumber + " losses, exiting since 70% failed");
                // keepGoing = 0;
                // return;
                // reset to start again
                bet = smallestValue;
                ladder = 0;
                lossesInARow = 0;
            }
            needToEqualize = false;
            lossesInARow++;
            upBet();
            startAutoTrading(origCallback);
        }
        else equalize(numberLeft, origCallback);
    });
}

// single trade
function singleTrade() {
    // console.log("singleTrade");
    // console.log("lossesInARow: " + lossesInARow);

    if (shouldIStop() == 0) {
        console.error("Stopped, original start balance was " + origStart + " current balance is " + currentBalance);
        return;
    }

    var values = {
        'target': target,
        'currency': currency,
        'bet': bet,
    }
    // console.log(values);
    socket.emit('dice_roll', values, function (data) {
        // console.log(data.result);
        //console.log(data);

        setTimeout(function () {
            startAutoTrading(data);
        }, timeOut)
    });
};

function shouldIStop() {
    if (keepGoing == 0 && ladder == 0) return 0; // wait till reach a win
    if (ladder >= maxLadders) {
        if (maxBigLosses <= bigLosses) {
            console.error("Quit because had " + bigLosses + " big losses");
            return 0;
        }
        bigLosses++;
        console.warn("Have had " + bigLosses + " big loss");
        bet = smallestValue;
        ladder = 0;
        lossesInARow = 0;
    }
    // if (currentBalance > stopLoss) return 0; // Lost enough to quit
    if (currentBalance < startBalance - startBalance * .05 || currentBalance < origStart - origStart * .05) {
        console.error("Quit because lost 5% of " + startBalance);
        return 0;
    }
    if (currentBalance > stopGain) {
        console.error("Quit because gained" + stopGainPercent + " percent increase from original start");
        return 0;
    }
    return 1;
}

// singleTrade();

// roller bot - chould just paste into the terminal or insert into page
// stop = % below start value that will stop the bot
// start at smallest increment
// max_value of value as a % of total value owned ~1/100,000th
// %increase - if lose, double and add x percent
// timeout - if lose, increase timeout, if win decrease + random
// if win, reset to beginning ladder/value
// track losses in a row, max/average
// track win/lose rate
// max_loss, something like 1% of total value, so this could run 100 times till it would go to 0, if it weren't to stop if it lost x percent from above
// track time running and current gain/loss percentage
// eventually scale up and down according to current total value
// if 15 losses in a row, kill, or alternately start a mode that just bets the minimum value ~50 times until the win/loss ratio returns to within 5% of 50%
// rolling quit value, if I gain x percent, readjust quit value to be higher (never lower) so I don't lose what I have already gained
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import { parse as parseQS } from 'querystring';
import thunk from 'redux-thunk';
import Translator from '@u-wave/translate';
import webApiRequest from '../redux/request';
import readApplicationConfig from '../utils/readApplicationConfig';
import * as reducers from './reducers';
import { setResetKey } from './actions';
import App from './containers/PasswordResetApp';
import english from '../../locale/en.yaml';

import './app.css';

const config = readApplicationConfig();
const key = document.querySelector('#reset-data').textContent;

const store = createStore(
  combineReducers(reducers),
  { config },
  applyMiddleware(
    thunk,
    webApiRequest(),
  ),
);

const qs = parseQS(window.location.search.slice(1));
store.dispatch(setResetKey(key || qs.key));

const translator = new Translator(english.uwave);

ReactDOM.render(
  (
    <Provider store={store}>
      <App translator={translator} />
    </Provider>
  ), document.querySelector('#app'),
);
<commit_msg>password-reset: render with React 18<commit_after>import React from 'react';
import { createRoot } from 'react-dom';
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import { parse as parseQS } from 'querystring';
import thunk from 'redux-thunk';
import Translator from '@u-wave/translate';
import webApiRequest from '../redux/request';
import readApplicationConfig from '../utils/readApplicationConfig';
import * as reducers from './reducers';
import { setResetKey } from './actions';
import PasswordResetApp from './containers/PasswordResetApp';
import english from '../../locale/en.yaml';
import './app.css';

const config = readApplicationConfig();
const key = document.querySelector('#reset-data').textContent;

const store = createStore(
  combineReducers(reducers),
  { config },
  applyMiddleware(
    thunk,
    webApiRequest(),
  ),
);

const qs = parseQS(window.location.search.slice(1));
store.dispatch(setResetKey(key || qs.key));

const translator = new Translator(english.uwave);

const root = createRoot(document.querySelector('#app'));
root.render((
  <Provider store={store}>
    <PasswordResetApp translator={translator} />
  </Provider>
));
<|endoftext|>


<commit_before>import { List } from 'immutable';
import * as l from '../lock/index';
import { clearCreds } from '../cred/index';

export function initPasswordless(m, opts) {
  return opts.send
    ? m.setIn(["passwordless", "opts", "send"], opts.send)
    : m;
}

function setResendStatus(m, value) {
  // TODO: check value
  return m.set("resendStatus", value);
}

export function setResendSuccess(m) {
  return setResendStatus(m, "success");
}

export function resendSuccess(m) {
  return resendStatus(m) == "success";
}

export function setResendFailed(m) {
  return setResendStatus(m, "failed");
}

export function resendFailed(m) {
  return resendStatus(m) == "failed";
}

export function resendOngoing(m) {
  return resendStatus(m) == "ongoing";
}

export function resend(m) {
  if (resendAvailable(m)) {
    return setResendStatus(m, "ongoing");
  } else {
    return m;
  }
}

function resendStatus(m) {
  return m.get("resendStatus", "waiting");
}

export function resendAvailable(m) {
  return resendStatus(m) == "waiting" || resendStatus(m) == "failed";
}

export function restartPasswordless(m) {
  let keys = [
    "passwordlessStarted",
    "resendStatus",  // only for link
  ];

  m = keys.reduce((r, v) => r.remove(v), m);
  m = clearCreds(m, ["vcode"]); // only for code

  return l.clearGlobalError(m);
}

export function send(m) {
  return m.getIn(["passwordless", "opts", "send"], "link");
}

export function isSendLink(m) {
  return send(m) === "link";
}

export function setPasswordlessStarted(m, value) {
  return m.set("passwordlessStarted", value);
}

export function passwordlessStarted(m) {
  return m.get("passwordlessStarted", false);
}
<commit_msg>Use data manipulation fns in passwordless mode<commit_after>import { List, Map } from 'immutable';
import * as l from '../lock/index';
import { clearCreds } from '../cred/index';
import { dataFns } from '../utils/data_utils';

const { get, initNS, tget, tremove, tset } = dataFns(["passwordless"]);

export function initPasswordless(m, opts) {
  // TODO: validate send option
  return opts.send
    ? initNS(m, Map({send: opts.send}))
    : m;
}

function setResendStatus(m, value) {
  // TODO: check value
  return tset(m, "resendStatus", value);
}

export function setResendSuccess(m) {
  return setResendStatus(m, "success");
}

export function resendSuccess(m) {
  return resendStatus(m) == "success";
}

export function setResendFailed(m) {
  return setResendStatus(m, "failed");
}

export function resendFailed(m) {
  return resendStatus(m) == "failed";
}

export function resendOngoing(m) {
  return resendStatus(m) == "ongoing";
}

export function resend(m) {
  if (resendAvailable(m)) {
    return setResendStatus(m, "ongoing");
  } else {
    return m;
  }
}

function resendStatus(m) {
  return tget("resendStatus", "waiting");
}

export function resendAvailable(m) {
  return resendStatus(m) == "waiting" || resendStatus(m) == "failed";
}

export function restartPasswordless(m) {
  // TODO: maybe we can take advantage of the transient fields
  m = tremove(m, "passwordlessStarted");
  m = tremove(m, "resendStatus")  // only for link
  m = clearCreds(m, ["vcode"]); // only for code

  return l.clearGlobalError(m);
}

export function send(m) {
  // TODO: maybe it's better to explicitly set send = "link" during
  // initialization.
  return get(m, "send", "link");
}

export function isSendLink(m) {
  return send(m) === "link";
}

export function setPasswordlessStarted(m, value) {
  return tset(m, "passwordlessStarted", value);
}

export function passwordlessStarted(m) {
  return tget(m, "passwordlessStarted", false);
}
<|endoftext|>


<commit_before>/**
 * Hilo
 * Copyright 2015 alibaba.com
 * Licensed under the MIT License
 */

/**
 * @language=en
 *
 *

 * demo:
 *

 * var domView = new Hilo.DOMElement({
 *     element: Hilo.createElement('div', {
 *         style: {
 *             backgroundColor: '#004eff',
 *             position: 'absolute'
 *         }
 *     }),
 *     width: 100,
 *     height: 100,
 *     x: 50,
 *     y: 70
 * }).addTo(stage);
 *

 * @name DOMElement
 * @class DOMElement is a wrapper of dom element.（The DOMElement's parent must be stage）
 * @augments View
 * @param {Object} properties create Objects properties. Contains all writable properties in this class. Special properties include:
 *

 *
element - dom element to wrap, required!

 *

 * @module hilo/view/DOMElement
 * @requires hilo/core/Hilo
 * @requires hilo/core/Class
 * @requires hilo/view/View
 * @requires hilo/view/Drawable
 */
/**
 * @language=zh
 *
 *

 * 使用示例:
 *

 * var domView = new Hilo.DOMElement({
 *     element: Hilo.createElement('div', {
 *         style: {
 *             backgroundColor: '#004eff',
 *             position: 'absolute'
 *         }
 *     }),
 *     width: 100,
 *     height: 100,
 *     x: 50,
 *     y: 70
 * }).addTo(stage);
 *

 * @name DOMElement
 * @class DOMElement是dom元素的包装。（ 注意：DOMElement 的父容器必须是 stage ）
 * @augments View
 * @param {Object} properties 创建对象的属性参数。可包含此类所有可写属性。特殊属性有：
 *

 *
element - 要包装的dom元素。必需。

 *

 * @module hilo/view/DOMElement
 * @requires hilo/core/Hilo
 * @requires hilo/core/Class
 * @requires hilo/view/View
 * @requires hilo/view/Drawable
 */
var DOMElement = Class.create(/** @lends DOMElement.prototype */{
    Extends: View,
    constructor: function(properties){
        properties = properties || {};
        this.id = this.id || properties.id || Hilo.getUid("DOMElement");
        DOMElement.superclass.constructor.call(this, properties);

        this.drawable = new Drawable();
        var elem = this.drawable.domElement = properties.element || Hilo.createElement('div');
        elem.id = this.id;

        if(this.pointerEnabled && !elem.style.pointerEvents){
            elem.style.pointerEvents = 'visible';
        }
    },

    /**
     * @language=en
     * Overwrite render method.
     * @private
     */
    /**
     * @language=zh
     * 覆盖渲染方法。
     * @private
     */
    _render: function(renderer, delta){
        if(!this.onUpdate || this.onUpdate(delta) !== false){
            renderer.transform(this);
            if(this.visible && this.alpha > 0){
                this.render(renderer, delta);
            }
        }
    },

    /**
     * @language=en
     * Overwrite render method.
     * @private
     */
    /**
     * @language=zh
     * 覆盖渲染方法。
     * @private
     */
    render: function(renderer, delta){
        if(renderer.renderType !== 'dom'){
            var canvas = renderer.canvas;
            var stage = this.parent;
            var domElementContainer = renderer._domElementContainer;
            if(!renderer._domElementContainer){
                domElementContainer = renderer._domElementContainer = Hilo.createElement('div', {
                    style:{
                        'position':'absolute',
                        'transform':'scale3d(' + stage.scaleX + ',' + stage.scaleY + ', 1)',
                        'transformOrigin':'0 0'
                    }
                });
                canvas.parentNode.insertBefore(renderer._domElementContainer, canvas.nextSibling);
            }

            var elem = this.drawable.domElement, depth = this.depth,
                nextElement = domElementContainer.childNodes[0], nextDepth;
            if(elem.parentNode) return;

            //draw dom element just after stage canvas
            while(nextElement && nextElement.nodeType != 3){
                nextDepth = parseInt(nextElement.style.zIndex) || 0;
                if(nextDepth <= 0 || nextDepth > depth){
                    break;
                }
                nextElement = nextElement.nextSibling;
            }
            domElementContainer.insertBefore(this.drawable.domElement, nextElement);
        }else{
            renderer.draw(this);
        }
    }
});<commit_msg>fix: add domElement container index<commit_after>/**
 * Hilo
 * Copyright 2015 alibaba.com
 * Licensed under the MIT License
 */

/**
 * @language=en
 *
 *

 * demo:
 *

 * var domView = new Hilo.DOMElement({
 *     element: Hilo.createElement('div', {
 *         style: {
 *             backgroundColor: '#004eff',
 *             position: 'absolute'
 *         }
 *     }),
 *     width: 100,
 *     height: 100,
 *     x: 50,
 *     y: 70
 * }).addTo(stage);
 *

 * @name DOMElement
 * @class DOMElement is a wrapper of dom element.（The DOMElement's parent must be stage）
 * @augments View
 * @param {Object} properties create Objects properties. Contains all writable properties in this class. Special properties include:
 *

 *
element - dom element to wrap, required!

 *

 * @module hilo/view/DOMElement
 * @requires hilo/core/Hilo
 * @requires hilo/core/Class
 * @requires hilo/view/View
 * @requires hilo/view/Drawable
 */
/**
 * @language=zh
 *
 *

 * 使用示例:
 *

 * var domView = new Hilo.DOMElement({
 *     element: Hilo.createElement('div', {
 *         style: {
 *             backgroundColor: '#004eff',
 *             position: 'absolute'
 *         }
 *     }),
 *     width: 100,
 *     height: 100,
 *     x: 50,
 *     y: 70
 * }).addTo(stage);
 *

 * @name DOMElement
 * @class DOMElement是dom元素的包装。（ 注意：DOMElement 的父容器必须是 stage ）
 * @augments View
 * @param {Object} properties 创建对象的属性参数。可包含此类所有可写属性。特殊属性有：
 *

 *
element - 要包装的dom元素。必需。

 *

 * @module hilo/view/DOMElement
 * @requires hilo/core/Hilo
 * @requires hilo/core/Class
 * @requires hilo/view/View
 * @requires hilo/view/Drawable
 */
var DOMElement = Class.create(/** @lends DOMElement.prototype */{
    Extends: View,
    constructor: function(properties){
        properties = properties || {};
        this.id = this.id || properties.id || Hilo.getUid("DOMElement");
        DOMElement.superclass.constructor.call(this, properties);

        this.drawable = new Drawable();
        var elem = this.drawable.domElement = properties.element || Hilo.createElement('div');
        elem.id = this.id;

        if(this.pointerEnabled && !elem.style.pointerEvents){
            elem.style.pointerEvents = 'visible';
        }
    },

    /**
     * @language=en
     * Overwrite render method.
     * @private
     */
    /**
     * @language=zh
     * 覆盖渲染方法。
     * @private
     */
    _render: function(renderer, delta){
        if(!this.onUpdate || this.onUpdate(delta) !== false){
            renderer.transform(this);
            if(this.visible && this.alpha > 0){
                this.render(renderer, delta);
            }
        }
    },

    /**
     * @language=en
     * Overwrite render method.
     * @private
     */
    /**
     * @language=zh
     * 覆盖渲染方法。
     * @private
     */
    render: function(renderer, delta){
        if(renderer.renderType !== 'dom'){
            var canvas = renderer.canvas;
            var stage = this.parent;
            var domElementContainer = renderer._domElementContainer;
            if(!renderer._domElementContainer){
                domElementContainer = renderer._domElementContainer = Hilo.createElement('div', {
                    style:{
                        'position':'absolute',
                        'transform':'scale3d(' + stage.scaleX + ',' + stage.scaleY + ', 1)',
                        'transformOrigin':'0 0',
                        'zIndex':'1'
                    }
                });
                canvas.parentNode.insertBefore(renderer._domElementContainer, canvas.nextSibling);
            }

            var elem = this.drawable.domElement, depth = this.depth,
                nextElement = domElementContainer.childNodes[0], nextDepth;
            if(elem.parentNode) return;

            //draw dom element just after stage canvas
            while(nextElement && nextElement.nodeType != 3){
                nextDepth = parseInt(nextElement.style.zIndex) || 0;
                if(nextDepth <= 0 || nextDepth > depth){
                    break;
                }
                nextElement = nextElement.nextSibling;
            }
            domElementContainer.insertBefore(this.drawable.domElement, nextElement);
        }else{
            renderer.draw(this);
        }
    }
});<|endoftext|>


<commit_before>import React,{ Component } from 'react'
import { connect } from 'dva'
import CSSModules from 'react-css-modules'
import styles from './page.less'
import { Link } from 'react-router'
import classNames from 'classnames'

class Help extends Component {

  constructor(props) {
    super(props)
    this.state = {
      questions : [
        {
          question: '如何退款？',
          answer : '审批成功后可拨打客服电话退款'
        },
        {
          question: '如何退款？',
          answer : '审批成功后可拨打客服电话退款审批成功后可拨打客服电话退款审批成功后可拨打客服电话退款审批成功后可拨打客服电话退款'
        },
        {
          question: '如何退款？',
          answer : '审批成功后可拨打客服电话退款'
        }
      ]
    }
  }

  render() {
    return

        {
          this.state.questions.map((item, index) =>

{item.question}

{item.answer}

          )
        }

  }
};

function mapStateToProps(state) {
  return state;
}

function mapDispatchToProps(dispatch) {
  return {

  }
}
Help.PropTypes = {
  enterAnimation: {
    duration: 2000,
    animation: "slideDown"
  },
  leaveAnimation:{
    duration: 2000,
    animation:"slideUp"
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(CSSModules(Help,styles,{allowMultiple:true}));
<commit_msg>faq  updata<commit_after>import React,{ Component } from 'react'
import { connect } from 'dva'
import CSSModules from 'react-css-modules'
import styles from './page.less'
import { Link } from 'react-router'
import classNames from 'classnames'

class Help extends Component {

  constructor(props) {
    super(props)
    this.state = {
      questions : [
        {
          question: '想了解下紫隆山葡萄酒的公司情况？',
          answer : '紫隆山葡萄酒厂坐落于吉林通化，创建于1997年。张总也曾邀约多位宝粉共同参观过酒厂，跟这所葡萄庄园结缘颇深。紫隆山品牌依托互联网平台的优势，打造出一个响当当的山葡萄酒品牌，带动了整个地区的山葡萄产业。'
        },
        {
          question: '项目回报率有多高？',
          answer : 'QBII项目本身就是作为对钱宝合格投资人的回馈，年化均比当前领取任务要高，而且可以省去天天做任务的繁琐过程。投资股权后，当您想了解当前收益时，随时可打开APP点击QBII板块，就可看到您当前的利润分红、股本收益等等，与钱宝一起投资风险共担。'
        },
        {
          question: '签署合同后，资金如何操作？',
          answer : '资金将直接从您的钱宝账户中扣款，打入QBII。您可在APP的QBII板块中看到。'
        },
        {
          question: '有意向投资，但现在大部分资金仍在任务中，没有结算怎么办？',
          answer : '如果您在投资生效后，当前钱宝账号中可提现资金少于投资资金，您可选择终止当前尚未结束任务，提前进行结算。按照任务的日收益计算，结算已完成的任务天数发放收益。如果您账号中有多笔任务，可由您选择结算哪一项任务，或委托钱宝自行结束。总之不会让您有任何损失，您可放心。'
        },
        {
          question: '必须要钱宝认证人签约合同吗？ 老人年纪大，可以代签吗？',
          answer : '必须要本人亲自签署，目前签署地点待定。但如果实在不方便出门，可先由工作人员这边记录，上门签署。'
        }
      ]
    }
  }

  render() {
    return

        {
          this.state.questions.map((item, index) =>

{item.question}

{item.answer}

          )
        }

  }
};

function mapStateToProps(state) {
  return state;
}

function mapDispatchToProps(dispatch) {
  return {

  }
}
Help.PropTypes = {
  enterAnimation: {
    duration: 2000,
    animation: "slideDown"
  },
  leaveAnimation:{
    duration: 2000,
    animation:"slideUp"
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(CSSModules(Help,styles,{allowMultiple:true}));
<|endoftext|>


<commit_before>module.exports = function substr (str, start, len) {
  //  discuss at: https://locutus.io/php/substr/
  // original by: Martijn Wieringa
  // bugfixed by: T.Wild
  // improved by: Onno Marsman (https://twitter.com/onnomarsman)
  // improved by: Brett Zamir (https://brett-zamir.me)
  //  revised by: Theriault (https://github.com/Theriault)
  //      note 1: Handles rare Unicode characters if 'unicode.semantics' ini (PHP6) is set to 'on'
  //   example 1: substr('abcdef', 0, -1)
  //   returns 1: 'abcde'
  //   example 2: substr(2, 0, -6)
  //   returns 2: false
  //   example 3: ini_set('unicode.semantics', 'on')
  //   example 3: substr('a\uD801\uDC00', 0, -1)
  //   returns 3: 'a'
  //   example 4: ini_set('unicode.semantics', 'on')
  //   example 4: substr('a\uD801\uDC00', 0, 2)
  //   returns 4: 'a\uD801\uDC00'
  //   example 5: ini_set('unicode.semantics', 'on')
  //   example 5: substr('a\uD801\uDC00', -1, 1)
  //   returns 5: '\uD801\uDC00'
  //   example 6: ini_set('unicode.semantics', 'on')
  //   example 6: substr('a\uD801\uDC00z\uD801\uDC00', -3, 2)
  //   returns 6: '\uD801\uDC00z'
  //   example 7: ini_set('unicode.semantics', 'on')
  //   example 7: substr('a\uD801\uDC00z\uD801\uDC00', -3, -1)
  //   returns 7: '\uD801\uDC00z'
  //        test: skip-3 skip-4 skip-5 skip-6 skip-7

  var _php_cast_string = require('../_helpers/_phpCastString') // eslint-disable-line camelcase

  str = _php_cast_string(str)

  var end = str.length
  var ini_get = require('../info/ini_get') // eslint-disable-line camelcase
  var surrogatePair = /[\uD800-\uDBFF][\uDC00-\uDFFF]/
  var multibyte = ini_get('unicode.semantics') === 'on' && surrogatePair.test(str)

  if (!multibyte) {
    // assumes there are no non-BMP characters;
    // if there may be such characters, then it is best to turn it on (critical in true XHTML/XML)
    if (start < 0) {
      start += end
    }
    if (typeof len !== 'undefined') {
      if (len < 0) {
        end = len + end
      } else {
        end = len + start
      }
    }

    // PHP returns false if start does not fall within the string.
    // PHP returns false if the calculated end comes before the calculated start.
    // PHP returns an empty string if start and end are the same.
    // Otherwise, PHP returns the portion of the string from start to end.
    if (start > str.length || start < 0 || start > end) {
      return false
    }

    return str.slice(start, end)
  }

  // Full-blown Unicode including non-Basic-Multilingual-Plane characters
  var i = 0
  var es = 0
  var el = 0
  var se = 0
  var ret = ''

  if (start < 0) {
    for (i = end - 1, es = (start += end); i >= es; i--) {
      if (/[\uDC00-\uDFFF]/.test(str.charAt(i)) && /[\uD800-\uDBFF]/.test(str.charAt(i - 1))) {
        start--
        es--
      }
    }
  } else {
    var surrogatePairs = RegExp(surrogatePair.source, 'g')
    while ((surrogatePairs.exec(str)) !== null) {
      var li = surrogatePairs.lastIndex
      if (li - 2 < start) {
        start++
      } else {
        break
      }
    }
  }

  if (start >= end || start < 0) {
    return false
  }
  if (len < 0) {
    for (i = end - 1, el = (end += len); i >= el; i--) {
      if (/[\uDC00-\uDFFF]/.test(str.charAt(i)) && /[\uD800-\uDBFF]/.test(str.charAt(i - 1))) {
        end--
        el--
      }
    }
    if (start > end) {
      return false
    }
    return str.slice(start, end)
  } else {
    se = start + len
    for (i = start; i < se; i++) {
      ret += str.charAt(i)
      if (/[\uD800-\uDBFF]/.test(str.charAt(i)) && /[\uDC00-\uDFFF]/.test(str.charAt(i + 1))) {
        // Go one further, since one of the "characters" is part of a surrogate pair
        se++
      }
    }
    return ret
  }
}
<commit_msg>Shorten substr implementation (#411)<commit_after>module.exports = function substr (input, start, len) {
  //  discuss at: https://locutus.io/php/substr/
  // original by: Martijn Wieringa
  // bugfixed by: T.Wild
  // improved by: Onno Marsman (https://twitter.com/onnomarsman)
  // improved by: Brett Zamir (https://brett-zamir.me)
  //  revised by: Theriault (https://github.com/Theriault)
  //  revised by: Rafał Kukawski
  //      note 1: Handles rare Unicode characters if 'unicode.semantics' ini (PHP6) is set to 'on'
  //   example 1: substr('abcdef', 0, -1)
  //   returns 1: 'abcde'
  //   example 2: substr(2, 0, -6)
  //   returns 2: false
  //   example 3: ini_set('unicode.semantics', 'on')
  //   example 3: substr('a\uD801\uDC00', 0, -1)
  //   returns 3: 'a'
  //   example 4: ini_set('unicode.semantics', 'on')
  //   example 4: substr('a\uD801\uDC00', 0, 2)
  //   returns 4: 'a\uD801\uDC00'
  //   example 5: ini_set('unicode.semantics', 'on')
  //   example 5: substr('a\uD801\uDC00', -1, 1)
  //   returns 5: '\uD801\uDC00'
  //   example 6: ini_set('unicode.semantics', 'on')
  //   example 6: substr('a\uD801\uDC00z\uD801\uDC00', -3, 2)
  //   returns 6: '\uD801\uDC00z'
  //   example 7: ini_set('unicode.semantics', 'on')
  //   example 7: substr('a\uD801\uDC00z\uD801\uDC00', -3, -1)
  //   returns 7: '\uD801\uDC00z'
  //        test: skip-3 skip-4 skip-5 skip-6 skip-7

  var _php_cast_string = require('../_helpers/_phpCastString') // eslint-disable-line camelcase

  input = _php_cast_string(input)

  var ini_get = require('../info/ini_get') // eslint-disable-line camelcase
  var multibyte = ini_get('unicode.semantics') === 'on'

  if (multibyte) {
    input = input.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[\s\S]/g) || []
  }

  var inputLength = input.length
  var end = inputLength

  if (start < 0) {
    start += end
  }

  if (typeof len !== 'undefined') {
    if (len < 0) {
      end = len + end
    } else {
      end = len + start
    }
  }

  if (start > inputLength || start < 0 || start > end) {
    return false
  }

  if (multibyte) {
    return input.slice(start, end).join('')
  }

  return input.slice(start, end)
}
<|endoftext|>


<commit_before>import React from 'react'
import 'styles/core.scss'
import Firebase from 'firebase'
import { connect } from 'react-redux'
import constants from 'utils/constants'
import { actions as quoteActions } from '../redux/modules/quote'
import {reduxForm} from 'redux-form'

const ref = new Firebase(constants.FIREBASE)
const quotesRef = ref.child('quotes')
export const fields = ['title', 'description', 'author', 'tags', 'category', 'image']

const mapStateToProps = (state, props) => ({
  auth: state.auth,
  quote: props.route.name === 'edit' ? state.quote : ''
})

export class QuotesNew extends React.Component {

  static propTypes = {
    auth: React.PropTypes.object,
    fields: React.PropTypes.object.isRequired,
    handleSubmit: React.PropTypes.func.isRequired,
    resetForm: React.PropTypes.func.isRequired,
    submitting: React.PropTypes.bool.isRequired,
    getQuote: React.PropTypes.func,
    route: React.PropTypes.object,
    statename: React.PropTypes.object,
    clearQuote: React.PropTypes.func,
    params: React.PropTypes.object
  }

  componentDidMount (state) {
    if (this.props.route.name === 'edit') {
      this.props.getQuote(this.props.params.id)
    }
  }

  handleFile (fieldName, e) {
    console.log(e)
    e.preventDefault()
    console.log(fieldName)
    //let fields = this.props.fields
    // convert files to an array
    //const files = [ ...e.target.files ];
    //fields[fieldName].handleChange(files);

  }

  handleSubmit (e) {
    e.preventDefault()

    let fields = this.props.fields
    let userId = this.props.auth.uid
    let image = fields.image.value[0]
    let imageBase64

    let fr = new FileReader()
    fr.onloadend = function (res) {
      console.log(res)
      imageBase64 = res.currentTarget.result

      if (this.props.route.name === 'new') {
        quotesRef.push({
          title: fields.title ? fields.title.value : '',
          text: fields.description ? fields.description.value : '',
          author: fields.author ? fields.author.value : '',
          category: fields.category ? fields.category.value : '',
          createdBy: userId,
          createdAt: new Date(),
          tags: fields.tags ? fields.tags.value : [],
          image: fields.image ? imageBase64 : ''
        })
      }

    }.bind(this)
    fr.readAsDataURL(image)

    //return

  }

  updateQuote (e) {
    let currentQuote = quotesRef.child(this.props.params.id)
    console.log(currentQuote)
  }

  render () {
    const {
      fields: {title, description, author, tags, category, image},
      resetForm,
      submitting
    } = this.props

    let header = this.props.route.name === 'edit' ? 'Edit quote' : 'New Quote'
    let btnLabel = this.props.route.name === 'edit' ? 'Update the quote' : 'Create new quote'
    // const { fields: { image } } = this.props;
    // pull out value so it isn't passed into the file input
    let { value, ...imageProps } = image;

    return (

        <form onSubmit={this.handleSubmit.bind(this)}>

{header}

            Title
            <input type='text' className='form-control' id='title' placeholder='Title (optional)' ref='title' {...title} />

            Description
            <textarea className='form-control' rows='4' id='description' ref='description' placeholder='text or description' {...description} />

            Author
            <input type='text' className='form-control' id='author' placeholder='author' ref='author' {...author} />

            Category
            <input type='text' className='form-control' id='category' placeholder='category (quote, joke, etc)' ref='category' {...category} />

            Tags
            <input type='text' className='form-control' id='tags' placeholder='tags (comma separated)' ref='tags' {...tags} />

            Background
            <input type='file' className='form-control' id='image' onChange={this.handleFile.bind(this, 'image')} placeholder='background image' ref='image' {...image} value={null} />

          <input type='submit' value={btnLabel} className='btn btn-primary' />
          <input type='button' value='Reset' className='btn btn-danger' onClick={resetForm} />
        </form>

    )
  }
}

QuotesNew = reduxForm({
  form: 'newQuote',
  fields,
  normalize: ['tags']
},
function (state, props) {
  if (props.route.name === 'edit') {
    return {initialValues: state.quote}
  }
}
)(QuotesNew)

export default connect(mapStateToProps, quoteActions)(QuotesNew)
<commit_msg>chore (using underscore for the fist element)<commit_after>import React from 'react'
import 'styles/core.scss'
import Firebase from 'firebase'
import { connect } from 'react-redux'
import constants from 'utils/constants'
import { actions as quoteActions } from '../redux/modules/quote'
import {reduxForm} from 'redux-form'

const ref = new Firebase(constants.FIREBASE)
const quotesRef = ref.child('quotes')
export const fields = ['title', 'description', 'author', 'tags', 'category', 'image']

const mapStateToProps = (state, props) => ({
  auth: state.auth,
  quote: props.route.name === 'edit' ? state.quote : ''
})

export class QuotesNew extends React.Component {

  static propTypes = {
    auth: React.PropTypes.object,
    fields: React.PropTypes.object.isRequired,
    handleSubmit: React.PropTypes.func.isRequired,
    resetForm: React.PropTypes.func.isRequired,
    submitting: React.PropTypes.bool.isRequired,
    getQuote: React.PropTypes.func,
    route: React.PropTypes.object,
    statename: React.PropTypes.object,
    clearQuote: React.PropTypes.func,
    params: React.PropTypes.object
  }

  componentDidMount (state) {
    if (this.props.route.name === 'edit') {
      this.props.getQuote(this.props.params.id)
    }
  }

  handleFile (fieldName, e) {
    console.log(e)
    e.preventDefault()
    console.log(fieldName)
    //let fields = this.props.fields
    // convert files to an array
    //const files = [ ...e.target.files ];
    //fields[fieldName].handleChange(files);

  }

  handleSubmit (e) {
    e.preventDefault()

    let fields = this.props.fields
    let userId = this.props.auth.uid
    let image = _.first(fields.image.value)
    let imageBase64
    let fr = new FileReader()

    fr.onloadend = function (res) {
      console.log(res)
      imageBase64 = res.currentTarget.result

      if (this.props.route.name === 'new') {
        quotesRef.push({
          title: fields.title ? fields.title.value : '',
          text: fields.description ? fields.description.value : '',
          author: fields.author ? fields.author.value : '',
          category: fields.category ? fields.category.value : '',
          createdBy: userId,
          createdAt: new Date(),
          tags: fields.tags ? fields.tags.value : [],
          image: fields.image ? imageBase64 : ''
        })
      } else {
        console.log('edit')
      }

    }.bind(this)
    fr.readAsDataURL(image)

  }

  updateQuote (e) {
    let currentQuote = quotesRef.child(this.props.params.id)
    console.log(currentQuote)
  }

  render () {
    const {
      fields: {title, description, author, tags, category, image},
      resetForm,
      submitting
    } = this.props

    let header = this.props.route.name === 'edit' ? 'Edit quote' : 'New Quote'
    let btnLabel = this.props.route.name === 'edit' ? 'Update the quote' : 'Create new quote'
    // const { fields: { image } } = this.props;
    // pull out value so it isn't passed into the file input
    let { value, ...imageProps } = image;

    return (

        <form onSubmit={this.handleSubmit.bind(this)}>

{header}

            Title
            <input type='text' className='form-control' id='title' placeholder='Title (optional)' ref='title' {...title} />

            Description
            <textarea className='form-control' rows='4' id='description' ref='description' placeholder='text or description' {...description} />

            Author
            <input type='text' className='form-control' id='author' placeholder='author' ref='author' {...author} />

            Category
            <input type='text' className='form-control' id='category' placeholder='category (quote, joke, etc)' ref='category' {...category} />

            Tags
            <input type='text' className='form-control' id='tags' placeholder='tags (comma separated)' ref='tags' {...tags} />

            Background
            <input type='file' className='form-control' id='image' onChange={this.handleFile.bind(this, 'image')} placeholder='background image' ref='image' {...image} value={null} />

          <input type='submit' value={btnLabel} className='btn btn-primary' />
          <input type='button' value='Reset' className='btn btn-danger' onClick={resetForm} />
        </form>

    )
  }
}

QuotesNew = reduxForm({
  form: 'newQuote',
  fields,
  normalize: ['tags']
},
function (state, props) {
  if (props.route.name === 'edit') {
    return {initialValues: state.quote}
  }
}
)(QuotesNew)

export default connect(mapStateToProps, quoteActions)(QuotesNew)
<|endoftext|>


<commit_before>import React from 'react'
import styles from '../../assets/stylesheets/styles.scss'

export default class HelpView extends React.PureComponent {
  render () {
    const bus = this.props.bus

    return (

How to Play

The game of Risk is played with two or more players on a map. The object of the
          game is for a player to defeat the other players on the map. Players take turns
          advancing their armies or attacking other countries.

During their turn, a player chooses one of their occupied countries and a
          neighbouring country. If a neighbouring country is occupied then the player
          will attack, otherwise the player will move armies into the unoccupied country.
          A player may only move or attack from an occupied country with two or more
          armies. During a turn a player can move or attack as many times as they wish.

At the end of their turn, a player is rewarded a number of additional armies.
          They can place these armies in any of their occupied countries.

Credits

Copyright © 2018 Josh Bassett

<button onClick={() => bus.emit('pause')}>Resume</button>

    )
  }
}
<commit_msg>Simplify copyright<commit_after>import React from 'react'
import styles from '../../assets/stylesheets/styles.scss'

export default class HelpView extends React.PureComponent {
  render () {
    const bus = this.props.bus

    return (

Risk

How to Play

The game of Risk is played with two or more players on a map. The object of the
          game is for a player to defeat the other players on the map. Players take turns
          advancing their armies or attacking other countries.

During their turn, a player chooses one of their occupied countries and a
          neighbouring country. If a neighbouring country is occupied then the player
          will attack, otherwise the player will move armies into the unoccupied country.
          A player may only move or attack from an occupied country with two or more
          armies. During a turn a player can move or attack as many times as they wish.

At the end of their turn, a player is rewarded a number of additional armies.
          They can place these armies in any of their occupied countries.

Credits

© 2018 Josh Bassett

<button onClick={() => bus.emit('pause')}>Resume</button>

    )
  }
}
<|endoftext|>


<commit_before>import {
  MONEY_RAISED_EXCLAMATION_POINT_V2,
  YAHOO_SEARCH_EXISTING_USERS,
  YAHOO_SEARCH_NEW_USERS,
  YAHOO_SEARCH_NEW_USERS_V2,
  SUPPORTING_CAUSE_CHIP,
  SFAC_EXTENSION_PROMPT,
  COLLEGE_AMBASSADOR_2022_NOTIF,
} from './experimentConstants'

// Consider a user "existing" if they join before this time.
const SEARCH_EXPERIMENT_EXISTING_USERS_CUTOFF_UNIX_TIME = 1651154400000 // 2pm UTC 28 April 2022

// Consider a user "new" if they join after this time. This should be
// later in the future than when the experiment goes live, because
// the experiment includes behavior during signup.
const SEARCH_EXPERIMENT_NEW_USERS_CUTOFF_UNIX_TIME = 1651165200000 // 5pm UTC 28 April 2022

// Consider a user "new" for V2 if they join after this time. This should be
// later in the future than when the experiment goes live, because
// the experiment includes behavior during signup.
const SEARCH_EXPERIMENT_NEW_USERS_V2_CUTOFF_UNIX_TIME = 1655843400000 // 20:30pm UTC 21 June 2022

// Cutoff time for search extension experiment. Users are considered
// new if they join after this time.
const SFAC_EXTENSION_PROMPT_CUTOFF_UNIX_TIME = 1662494400000 // 1600 UTC 6 September 2022

const features = {
  [MONEY_RAISED_EXCLAMATION_POINT_V2]: {
    defaultValue: false,
    rules: [
      /* Begin internal overrides */
      {
        condition: {
          v4BetaEnabled: true,
          [`internalExperimentOverrides.${MONEY_RAISED_EXCLAMATION_POINT_V2}`]: {
            $eq: true,
            $exists: true,
          },
        },
        force: true,
      },
      {
        condition: {
          v4BetaEnabled: true,
          [`internalExperimentOverrides.${MONEY_RAISED_EXCLAMATION_POINT_V2}`]: {
            $eq: false,
            $exists: true,
          },
        },
        force: false,
      },
      /* End internal overrides */
      {
        variations: [false, true],
        weights: [0.5, 0.5],
        coverage: 0.4,
        condition: {
          v4BetaEnabled: true,
        },
      },
    ],
  },
  [YAHOO_SEARCH_EXISTING_USERS]: {
    defaultValue: false,
    rules: [
      /* Begin internal overrides */
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          [`internalExperimentOverrides.${YAHOO_SEARCH_EXISTING_USERS}`]: {
            $eq: true,
            $exists: true,
          },
        },
        force: true,
      },
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          [`internalExperimentOverrides.${YAHOO_SEARCH_EXISTING_USERS}`]: {
            $eq: false,
            $exists: true,
          },
        },
        force: false,
      },
      /* End internal overrides */
      {
        variations: [false, true],
        weights: [0.5, 0.5],
        coverage: 1.0,
        condition: {
          joined: {
            $lt: SEARCH_EXPERIMENT_EXISTING_USERS_CUTOFF_UNIX_TIME,
          },
          v4BetaEnabled: {
            $eq: true,
          },
        },
      },
    ],
  },
  // TODO: remove and clean up references
  [YAHOO_SEARCH_NEW_USERS]: {
    defaultValue: 'Google',
    rules: [
      // Internal Overrides may not be useful here because we are assigning search engine on user creation.
      /* End internal overrides */
      {
        variations: ['Google', 'SearchForACause'],
        weights: [0.5, 0.5],
        coverage: 0.0,
        condition: {
          joined: {
            $gt: SEARCH_EXPERIMENT_NEW_USERS_CUTOFF_UNIX_TIME,
          },
          v4BetaEnabled: {
            $eq: true,
          },
        },
      },
    ],
  },
  [YAHOO_SEARCH_NEW_USERS_V2]: {
    defaultValue: 'Tooltip',
    rules: [
      /* Begin internal overrides */
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          [`internalExperimentOverrides.${YAHOO_SEARCH_NEW_USERS_V2}`]: {
            $eq: 'Control',
            $exists: true,
          },
        },
        force: 'Control',
      },
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          [`internalExperimentOverrides.${YAHOO_SEARCH_NEW_USERS_V2}`]: {
            $eq: 'Tooltip',
            $exists: true,
          },
        },
        force: 'Tooltip',
      },
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          [`internalExperimentOverrides.${YAHOO_SEARCH_NEW_USERS_V2}`]: {
            $eq: 'Notification',
            $exists: true,
          },
        },
        force: 'Notification',
      },
      /* End internal overrides */
      {
        variations: ['Control', 'Tooltip', 'Notification'],
        weights: [0.34, 0.33, 0.33],
        coverage: 0.0,
        condition: {
          joined: {
            $gt: SEARCH_EXPERIMENT_NEW_USERS_V2_CUTOFF_UNIX_TIME,
          },
          v4BetaEnabled: {
            $eq: true,
          },
        },
      },
    ],
  },
  [SFAC_EXTENSION_PROMPT]: {
    defaultValue: 'Control',
    rules: [
      /* Begin internal overrides */
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          tabs: {
            $gt: 3,
          },
          [`internalExperimentOverrides.${SFAC_EXTENSION_PROMPT}`]: {
            $eq: 'Control',
            $exists: true,
          },
        },
        force: 'Control',
      },
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          tabs: {
            $gt: 3,
          },
          [`internalExperimentOverrides.${SFAC_EXTENSION_PROMPT}`]: {
            $eq: 'Notification',
            $exists: true,
          },
        },
        force: 'Notification',
      },
      /* End internal overrides */
      {
        variations: ['Control', 'Notification'],
        weights: [0.5, 0.5],
        coverage: 100.0,
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          tabs: {
            $gt: 3,
          },
          joined: {
            $gt: SFAC_EXTENSION_PROMPT_CUTOFF_UNIX_TIME,
          },
        },
      },
    ],
  },
  // TODO: remove anytime after mid-August 2022.
  [SUPPORTING_CAUSE_CHIP]: {
    defaultValue: true,
  },
  // TODO: remove and clean up references
  [COLLEGE_AMBASSADOR_2022_NOTIF]: {
    defaultValue: false,
    rules: [
      // Show on local/dev for our team only.
      {
        condition: {
          isTabTeamMember: true,
          env: 'local',
        },
        force: false,
      },
      {
        condition: {
          isTabTeamMember: true,
          env: 'dev',
        },
        force: false,
      },
      {
        condition: {
          tabs: {
            $gte: 50,
          },
        },
        force: false,
      },
    ],
  },
}

export default features
<commit_msg>Fix Unix documentation error<commit_after>import {
  MONEY_RAISED_EXCLAMATION_POINT_V2,
  YAHOO_SEARCH_EXISTING_USERS,
  YAHOO_SEARCH_NEW_USERS,
  YAHOO_SEARCH_NEW_USERS_V2,
  SUPPORTING_CAUSE_CHIP,
  SFAC_EXTENSION_PROMPT,
  COLLEGE_AMBASSADOR_2022_NOTIF,
} from './experimentConstants'

// Consider a user "existing" if they join before this time.
const SEARCH_EXPERIMENT_EXISTING_USERS_CUTOFF_UNIX_TIME = 1651154400000 // 2pm UTC 28 April 2022

// Consider a user "new" if they join after this time. This should be
// later in the future than when the experiment goes live, because
// the experiment includes behavior during signup.
const SEARCH_EXPERIMENT_NEW_USERS_CUTOFF_UNIX_TIME = 1651165200000 // 5pm UTC 28 April 2022

// Consider a user "new" for V2 if they join after this time. This should be
// later in the future than when the experiment goes live, because
// the experiment includes behavior during signup.
const SEARCH_EXPERIMENT_NEW_USERS_V2_CUTOFF_UNIX_TIME = 1655843400000 // 20:30pm UTC 21 June 2022

// Cutoff time for search extension experiment. Users are considered
// new if they join after this time.
const SFAC_EXTENSION_PROMPT_CUTOFF_UNIX_TIME = 1662494400000 // 20:00 UTC 6 September 2022

const features = {
  [MONEY_RAISED_EXCLAMATION_POINT_V2]: {
    defaultValue: false,
    rules: [
      /* Begin internal overrides */
      {
        condition: {
          v4BetaEnabled: true,
          [`internalExperimentOverrides.${MONEY_RAISED_EXCLAMATION_POINT_V2}`]: {
            $eq: true,
            $exists: true,
          },
        },
        force: true,
      },
      {
        condition: {
          v4BetaEnabled: true,
          [`internalExperimentOverrides.${MONEY_RAISED_EXCLAMATION_POINT_V2}`]: {
            $eq: false,
            $exists: true,
          },
        },
        force: false,
      },
      /* End internal overrides */
      {
        variations: [false, true],
        weights: [0.5, 0.5],
        coverage: 0.4,
        condition: {
          v4BetaEnabled: true,
        },
      },
    ],
  },
  [YAHOO_SEARCH_EXISTING_USERS]: {
    defaultValue: false,
    rules: [
      /* Begin internal overrides */
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          [`internalExperimentOverrides.${YAHOO_SEARCH_EXISTING_USERS}`]: {
            $eq: true,
            $exists: true,
          },
        },
        force: true,
      },
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          [`internalExperimentOverrides.${YAHOO_SEARCH_EXISTING_USERS}`]: {
            $eq: false,
            $exists: true,
          },
        },
        force: false,
      },
      /* End internal overrides */
      {
        variations: [false, true],
        weights: [0.5, 0.5],
        coverage: 1.0,
        condition: {
          joined: {
            $lt: SEARCH_EXPERIMENT_EXISTING_USERS_CUTOFF_UNIX_TIME,
          },
          v4BetaEnabled: {
            $eq: true,
          },
        },
      },
    ],
  },
  // TODO: remove and clean up references
  [YAHOO_SEARCH_NEW_USERS]: {
    defaultValue: 'Google',
    rules: [
      // Internal Overrides may not be useful here because we are assigning search engine on user creation.
      /* End internal overrides */
      {
        variations: ['Google', 'SearchForACause'],
        weights: [0.5, 0.5],
        coverage: 0.0,
        condition: {
          joined: {
            $gt: SEARCH_EXPERIMENT_NEW_USERS_CUTOFF_UNIX_TIME,
          },
          v4BetaEnabled: {
            $eq: true,
          },
        },
      },
    ],
  },
  [YAHOO_SEARCH_NEW_USERS_V2]: {
    defaultValue: 'Tooltip',
    rules: [
      /* Begin internal overrides */
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          [`internalExperimentOverrides.${YAHOO_SEARCH_NEW_USERS_V2}`]: {
            $eq: 'Control',
            $exists: true,
          },
        },
        force: 'Control',
      },
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          [`internalExperimentOverrides.${YAHOO_SEARCH_NEW_USERS_V2}`]: {
            $eq: 'Tooltip',
            $exists: true,
          },
        },
        force: 'Tooltip',
      },
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          [`internalExperimentOverrides.${YAHOO_SEARCH_NEW_USERS_V2}`]: {
            $eq: 'Notification',
            $exists: true,
          },
        },
        force: 'Notification',
      },
      /* End internal overrides */
      {
        variations: ['Control', 'Tooltip', 'Notification'],
        weights: [0.34, 0.33, 0.33],
        coverage: 0.0,
        condition: {
          joined: {
            $gt: SEARCH_EXPERIMENT_NEW_USERS_V2_CUTOFF_UNIX_TIME,
          },
          v4BetaEnabled: {
            $eq: true,
          },
        },
      },
    ],
  },
  [SFAC_EXTENSION_PROMPT]: {
    defaultValue: 'Control',
    rules: [
      /* Begin internal overrides */
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          tabs: {
            $gt: 3,
          },
          [`internalExperimentOverrides.${SFAC_EXTENSION_PROMPT}`]: {
            $eq: 'Control',
            $exists: true,
          },
        },
        force: 'Control',
      },
      {
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          tabs: {
            $gt: 3,
          },
          [`internalExperimentOverrides.${SFAC_EXTENSION_PROMPT}`]: {
            $eq: 'Notification',
            $exists: true,
          },
        },
        force: 'Notification',
      },
      /* End internal overrides */
      {
        variations: ['Control', 'Notification'],
        weights: [0.5, 0.5],
        coverage: 100.0,
        condition: {
          v4BetaEnabled: {
            $eq: true,
          },
          tabs: {
            $gt: 3,
          },
          joined: {
            $gt: SFAC_EXTENSION_PROMPT_CUTOFF_UNIX_TIME,
          },
        },
      },
    ],
  },
  // TODO: remove anytime after mid-August 2022.
  [SUPPORTING_CAUSE_CHIP]: {
    defaultValue: true,
  },
  // TODO: remove and clean up references
  [COLLEGE_AMBASSADOR_2022_NOTIF]: {
    defaultValue: false,
    rules: [
      // Show on local/dev for our team only.
      {
        condition: {
          isTabTeamMember: true,
          env: 'local',
        },
        force: false,
      },
      {
        condition: {
          isTabTeamMember: true,
          env: 'dev',
        },
        force: false,
      },
      {
        condition: {
          tabs: {
            $gte: 50,
          },
        },
        force: false,
      },
    ],
  },
}

export default features
<|endoftext|>


<commit_before>define(["sugar-web/activity/activity"], function (activity) {

	// Manipulate the DOM only when it is ready.
	requirejs(['domReady!'], function (doc) {

		// Initialize the activity.
		activity.setup();
		var myHighestScore = 0;

		//Loads highest score from Journal
		loadHighScore();

		var $game = $('#canvas').blockrain({
      speed: 20,
      theme: 'candy',
	    autoplay: false,
	    autoplayRestart: true,
	    autoBlockWidth: true,
		  autoBlockSize: 24,
		  touchControls: true,
			highestScore: myHighestScore,
      onStart: function(){},
		  onRestart: function(){
				loadHighScore(); // loads highscore when game is restarted.
			},
		  onGameOver: function(score){
				saveHighestScore();
			},

		  onLine: function(lines, scoreIncrement, score){
				if (score > myHighestScore){
					myHighestScore = score;
				}
			},
		});

		// Save high score in Journal on Stop
		document.getElementById("stop-button").addEventListener('click', function (event) {
			saveHighestScore();
		});

		//Function to save high score
		function saveHighestScore() {
			console.log("writing...");
			var jsonData = JSON.stringify(myHighestScore);
			//console.log(jsonData);
			activity.getDatastoreObject().setDataAsText(jsonData);
			activity.getDatastoreObject().save(function (error) {
				if (error === null) {
					console.log("write done.");
				} else {
					console.log("write failed.");
				}
			});
		}

		//Function to load high score
		function loadHighScore() {
			activity.getDatastoreObject().loadAsText(function(error, metadata, data) {
				if (error == null && data != null) {
					myHighestScore = JSON.parse(data);
					console.log(myHighestScore);
				}
			});
		}

    function switchTheme(next) {
      var themes = Object.keys(BlockrainThemes);
      var currentTheme = $game.blockrain('theme');
      var currentIx = themes.indexOf(currentTheme);

      if( next ) { currentIx++; }
      else { currentIx--; }

      if( currentIx >= themes.length ){ currentIx = 0; }
      if( currentIx < 0 ){ currentIx = themes.length-1; }

      $game.blockrain('theme', themes[currentIx]);
    }

    document.getElementById("btn-next").onclick = function() {
        switchTheme(true);
    };

	});

});
<commit_msg>Add JS for the buttons<commit_after>define(["sugar-web/activity/activity"], function (activity) {

	// Manipulate the DOM only when it is ready.
	requirejs(['domReady!'], function (doc) {

		// Initialize the activity.
		activity.setup();
		var myHighestScore = 0;

		//Loads highest score from Journal
		loadHighScore();

		var $game = $('#canvas').blockrain({
      speed: 20,
      theme: 'candy',
	    autoplay: false,
	    autoplayRestart: true,
	    autoBlockWidth: true,
		  autoBlockSize: 24,
		  touchControls: true,
			highestScore: myHighestScore,
      onStart: function(){},
		  onRestart: function(){
				loadHighScore(); // loads highscore when game is restarted.
			},
		  onGameOver: function(score){
				saveHighestScore();
			},

		  onLine: function(lines, scoreIncrement, score){
				if (score > myHighestScore){
					myHighestScore = score;
				}
			},
		});

		// Switch to full screen when the full screen button is pressed
		document.getElementById("fullscreen-button").addEventListener('click', function() {
		  document.getElementById("main-toolbar").style.display = "none";
		  document.getElementById("canvas").style.top = "0px";
		  document.getElementById("unfullscreen-button").style.visibility = "visible";

		});

		//Return to normal size
		document.getElementById("unfullscreen-button").addEventListener('click', function() {
		  document.getElementById("main-toolbar").style.display = "block";
		  document.getElementById("canvas").style.top = "55px";
		  document.getElementById("unfullscreen-button").style.visibility = "hidden";
		});

		// Save high score in Journal on Stop
		document.getElementById("stop-button").addEventListener('click', function (event) {
			saveHighestScore();
		});

		//Function to save high score
		function saveHighestScore() {
			console.log("writing...");
			var jsonData = JSON.stringify(myHighestScore);
			//console.log(jsonData);
			activity.getDatastoreObject().setDataAsText(jsonData);
			activity.getDatastoreObject().save(function (error) {
				if (error === null) {
					console.log("write done.");
				} else {
					console.log("write failed.");
				}
			});
		}

		//Function to load high score
		function loadHighScore() {
			activity.getDatastoreObject().loadAsText(function(error, metadata, data) {
				if (error == null && data != null) {
					myHighestScore = JSON.parse(data);
					console.log(myHighestScore);
				}
			});
		}

    function switchTheme(next) {
      var themes = Object.keys(BlockrainThemes);
      var currentTheme = $game.blockrain('theme');
      var currentIx = themes.indexOf(currentTheme);

      if( next ) { currentIx++; }
      else { currentIx--; }

      if( currentIx >= themes.length ){ currentIx = 0; }
      if( currentIx < 0 ){ currentIx = themes.length-1; }

      $game.blockrain('theme', themes[currentIx]);
    }

    document.getElementById("btn-next").onclick = function() {
        switchTheme(true);
    };

	});

});
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the MIT license
 * If a copy of the MIT license was not distributed with this file, you can
 * obtain one at http://www.mozillapopcorn.org/butter-license.txt */

define( [ "util/dragndrop", "util/lang", "editor/editor", "text!layouts/plugin-list-editor.html" ],
  function( DragNDrop, LangUtils, Editor, EDITOR_LAYOUT ) {

  return function( butter ) {

    var _parentElement = LangUtils.domFragment( EDITOR_LAYOUT, ".plugin-list-editor" ),
        _containerElement = _parentElement.querySelector( ".plugin-container" );

    var _pluginArchetype = _containerElement.querySelector( ".butter-plugin-tile" );
    _pluginArchetype.parentNode.removeChild( _pluginArchetype );

    Editor.register( "plugin-list", null, function( rootElement, butter ) {
      rootElement = _parentElement;

      Editor.BaseEditor.extend( this, butter, rootElement, {
        open: function( parentElement ) {
        },
        close: function() {
        }
      });
    });

    butter.listen( "pluginadded", function( e ) {
      var element = _pluginArchetype.cloneNode( true ),
          iconImg = e.data.helper,
          icon = element.querySelector( ".butter-plugin-icon" ),
          text = element.querySelector( ".butter-plugin-label" ),
          pluginName = e.data.name;

      DragNDrop.helper( element, {
        start: function() {
          var targets = butter.targets;

          for ( var i = 0, l = targets.length; i < l; ++i ) {
            targets[ i ].view.blink();
          }
        },
        stop: function() {
          butter.currentMedia.pause();
        }
      });

      // request a new trackEvent on the currentMedia
      element.addEventListener( "dblclick", function() {
        butter.currentMedia.dispatch( "trackeventrequested", element );
      }, false );

      if ( iconImg ) {
        icon.style.backgroundImage = "url('" + iconImg.src + "')";
      }

      text.innerHTML = pluginName;

      element.setAttribute( "data-popcorn-plugin-type", e.data.type );
      element.setAttribute( "data-butter-draggable-type", "plugin" );

      _containerElement.appendChild( element );
    });

    // Open the plugin-list editor right after butter is finished starting up
    butter.listen( "ready", function() {
      butter.editor.openEditor( "plugin-list" );
    });
  };
});
<commit_msg>[#2416] Generate safe track events on double clicks<commit_after>/* This Source Code Form is subject to the terms of the MIT license
 * If a copy of the MIT license was not distributed with this file, you can
 * obtain one at http://www.mozillapopcorn.org/butter-license.txt */

define( [ "util/dragndrop", "util/lang", "editor/editor", "text!layouts/plugin-list-editor.html" ],
  function( DragNDrop, LangUtils, Editor, EDITOR_LAYOUT ) {

  return function( butter ) {

    var _parentElement = LangUtils.domFragment( EDITOR_LAYOUT, ".plugin-list-editor" ),
        _containerElement = _parentElement.querySelector( ".plugin-container" );

    var _pluginArchetype = _containerElement.querySelector( ".butter-plugin-tile" );
    _pluginArchetype.parentNode.removeChild( _pluginArchetype );

    Editor.register( "plugin-list", null, function( rootElement, butter ) {
      rootElement = _parentElement;

      Editor.BaseEditor.extend( this, butter, rootElement, {
        open: function( parentElement ) {
        },
        close: function() {
        }
      });
    });

    butter.listen( "pluginadded", function( e ) {
      var element = _pluginArchetype.cloneNode( true ),
          iconImg = e.data.helper,
          icon = element.querySelector( ".butter-plugin-icon" ),
          text = element.querySelector( ".butter-plugin-label" ),
          pluginName = e.data.name;

      DragNDrop.helper( element, {
        start: function() {
          var targets = butter.targets;

          for ( var i = 0, l = targets.length; i < l; ++i ) {
            targets[ i ].view.blink();
          }
        },
        stop: function() {
          butter.currentMedia.pause();
        }
      });

      // Generate Track Events from double clicks
      element.addEventListener( "dblclick", function() {
        butter.generateSafeTrackEvent( e.data.type, butter.currentTime );
      }, false );

      if ( iconImg ) {
        icon.style.backgroundImage = "url('" + iconImg.src + "')";
      }

      text.innerHTML = pluginName;

      element.setAttribute( "data-popcorn-plugin-type", e.data.type );
      element.setAttribute( "data-butter-draggable-type", "plugin" );

      _containerElement.appendChild( element );
    });

    // Open the plugin-list editor right after butter is finished starting up
    butter.listen( "ready", function() {
      butter.editor.openEditor( "plugin-list" );
    });
  };
});
<|endoftext|>


<commit_before>window.truth = function() {
    var that = {};
    var SYMBOL = /[a-zA-Z]\w*/;
    var DEBUG = false;

    var truthCombos = function(symbols) {
        if (! symbols) {
            return [{}];
        }

        var key;
        // get a key, any key
        $.each(symbols, function(k, v) {
            key = k;
            return false;
        });
        if (! key) {
            return [{}];
        }

        var tmp = jQuery.extend({}, symbols);
        delete tmp[key];
        var prev = truthCombos(tmp);

        var ret = [];
        $.each(prev, function(i) {
            var cur = jQuery.extend({}, prev[i]);
            cur[key] = true;
            ret.push(cur);
            cur = jQuery.extend({}, prev[i]);
            cur[key] = false;
            ret.push(cur);
        });

        return ret;
    };
    that.truthCombos = truthCombos;

    var displayAST = function(ast) {
        var elemGen = function(expr) {
            debug('displayAST', expr);
            if (! $.isArray(expr) ) {
                return $("
").text(expr);
            }

            var ret = $('
');
            $.each(expr, function(i) {
                ret.append(elemGen(expr[i]));
            });
            return ret;
        };

        $('#ast').empty().append('
Abstract Syntax Tree
', elemGen(ast));
    }

    var handleInput = function(val) {
        try {
            $('#nothing').empty();
            var tok = tokenize(val);
            var results = parse(tok);
            var ast = results[0];
            var sym = results[1];
            debug('ast', ast);
            debug('sym', sym);
            displayAST(ast);
            displaySym(sym);
            displayCombos(val, sym, ast, truthCombos(sym));
        } catch (e) {
            out('Unable to parse expression. ' + e);
            throw e;
        }
    }

    var displayCombos = function(expression, symbols, ast, combos) {
        $('#combo').empty();
        debug(combos);

        var ret = $('
');

        var header = $('
');
        var symArr = [];
        $.each(symbols, function(sym) {
            header.append($('').text(sym));
            symArr.push(sym);
        });
        header.append($('').text(expression));

        ret.append(header);
        $('#combo').append(ret);

        $.each(combos, function(i) {
            var cur = combos[i];
            var result = evalExpr(ast, cur);
            debug('evaluated', cur, result);
            var comboRow = $('
');
            $.each(symArr, function(j) {
                comboRow.append($('').text(cur[symArr[j]]));
            });
            comboRow.append($('').text(result));
            ret.append(comboRow);
        });
    }

    var isBoolean = function(val) {
        return (val === true) || (val === false);
    }

    var assertBoolean = function(val) {
        if (! isBoolean(val)) {
            throw new SyntaxError('Unbound symbol: ' + val);
        }
    }

    var evalExpr = function(ast, bindings) {
        var evalSym = function(index) {
            if ($.isArray(ast[index])) {
                return evalExpr(ast[index], bindings);
            }

            assertBoolean(bindings[ast[index]]);
            return bindings[ast[index]];
        };

        if (! ast) {
            throw new SyntaxError('Invalid expression: ' + ast);
        }

        if (! $.isArray(ast)) {
            return bindings[ast];
        }

        switch(ast[0]) {
        case '&':
            return evalSym(1) && evalSym(2);
            break;
        case '^':
            return (evalSym(1) || evalSym(2)) &&
                   (!(evalSym(1) && evalSym(2)));
            break;
        case '|':
            return evalSym(1) || evalSym(2);
            break;
        case '!':
        case '~':
            return ! evalSym(1);
            break;
        default:
            throw new SyntaxError('Unrecognized operator: ' + ast[0]);
        }
    }

    var out = function(val) {
        $('#output').text(val.toString());
    }

    var displaySym = function(symbols) {
        var title = $('
Symbols
');
        var symTable = $('
');
        $.each(symbols, function(sym) {
            symTable.append($('
').text(sym));
        });
        $('#sym').empty().append(title, symTable);
    }

    var main = function() {
        $('#apply').click(function() {
            handleInput($('#expr').val());
        });

        handleInput('!(a & (b | a))');
    }
    that.main = main;

    /**
     * Build an abstract syntax tree out of the given stream of tokens.
     */
    var parse = function(tokens) {
        debug('parse', tokens);
        if ((! tokens) || (tokens.length === 0)) {
            return [];
        }

        var pos = 0;
        var self = this;
        var symbols = {};

        var getCurToken = function() {
            return tokens[pos];
        };

        /**
         * Consume the next token and add it to the symbol table.
         */
        var consumeSymbol = function() {
            debug('consumeSymbol');
            var symbol = consumeToken();
            symbols[symbol] = true;
            return symbol;
        };

        var consumeToken = function(expected) {
            var curTok = getCurToken();
            debug('consumeToken', curTok);
            if (expected && (curTok !== expected)) {
                throw new SyntaxError('Did not encounter expected token. Expected: "' +
                                      expected + '" Actual: "' + curTok + '".');
            }

            pos++;
            return curTok;
        };

        var expr = function() {
            debug('expr', tokens, pos);
            if (getCurToken() == '!') {
                return [consumeToken(), subExpr()];
            }

            var a1 = subExpr();
            if (isBinaryOperator(getCurToken())) {
                return [consumeToken(), a1, subExpr()];
            }

            return a1;
        };

        var isBinaryOperator = function(tok) {
            return ((tok === '&') ||
                    (tok === '|') ||
                    (tok === '^'));
        };

        var subExpr = function() {
            debug('subExpr', tokens, pos);
            if (getCurToken() === '(') {
                consumeToken('(');
                var ret = expr();
                consumeToken(')');
                return ret;
            }

            if (! SYMBOL.test(getCurToken())) {
                throw new SyntaxError('Expecting symbol. Invalid symbol name: ' + getCurToken());
            }
            return consumeSymbol();
        };

        var ret = expr();
        if (pos < tokens.length) {
            throw new SyntaxError('Could not consume all tokens. Remaining tokens: ' +
                tokens.slice(pos, tokens.length));
        }

        return [ret, symbols];
    };
    that.parse = parse;

    var tokenize = function(str) {
        if ((! str) || (! str.replace(/\s/g, ''))) {
            return [];
        }

        var ret = str.split(/\b/);
        for (var i = 0; i < ret.length; i++) {
            // Remove whitespace from tokens
            ret[i] = ret[i].replace(/\s/g, '');

            if (ret[i].length === 0) {
                ret.splice(i, 1);
            } else if (! SYMBOL.test(ret[i])) {
                var arr = [];
                for (var j = 0; j < ret[i].length; j++) {
                    arr[j] = ret[i][j];
                }
                ret.splice.apply(ret, [i, 1].concat(arr));
            }
        }

        return ret;
    }
    that.tokenize = tokenize;

    var debug = function() {
        if (DEBUG) {
            console.log.apply(console, arguments);
        }
    }

    return that;
}();
<commit_msg>Encapsulate parse helper functions better.<commit_after>window.truth = function() {
    var that = {};
    var SYMBOL = /[a-zA-Z]\w*/;
    var DEBUG = true;

    var truthCombos = function(symbols) {
        if (! symbols) {
            return [{}];
        }

        var key;
        // get a key, any key
        $.each(symbols, function(k, v) {
            key = k;
            return false;
        });
        if (! key) {
            return [{}];
        }

        var tmp = jQuery.extend({}, symbols);
        delete tmp[key];
        var prev = truthCombos(tmp);

        var ret = [];
        $.each(prev, function(i) {
            var cur = jQuery.extend({}, prev[i]);
            cur[key] = true;
            ret.push(cur);
            cur = jQuery.extend({}, prev[i]);
            cur[key] = false;
            ret.push(cur);
        });

        return ret;
    };
    that.truthCombos = truthCombos;

    var displayAST = function(ast) {
        var elemGen = function(expr) {
            debug('displayAST', expr);
            if (! $.isArray(expr) ) {
                return $("
").text(expr);
            }

            var ret = $('
');
            $.each(expr, function(i) {
                ret.append(elemGen(expr[i]));
            });
            return ret;
        };

        $('#ast').empty().append('
Abstract Syntax Tree
', elemGen(ast));
    }

    var handleInput = function(val) {
        try {
            $('#nothing').empty();
            var tok = tokenize(val);
            var results = parse(tok);
            var ast = results[0];
            var sym = results[1];
            debug('ast', ast);
            debug('sym', sym);
            displayAST(ast);
            displaySym(sym);
            displayCombos(val, sym, ast, truthCombos(sym));
        } catch (e) {
            out('Unable to parse expression. ' + e);
            throw e;
        }
    }

    var displayCombos = function(expression, symbols, ast, combos) {
        $('#combo').empty();
        debug(combos);

        var ret = $('
');

        var header = $('
');
        var symArr = [];
        $.each(symbols, function(sym) {
            header.append($('').text(sym));
            symArr.push(sym);
        });
        header.append($('').text(expression));

        ret.append(header);
        $('#combo').append(ret);

        $.each(combos, function(i) {
            var cur = combos[i];
            var result = evalExpr(ast, cur);
            debug('evaluated', cur, result);
            var comboRow = $('
');
            $.each(symArr, function(j) {
                comboRow.append($('').text(cur[symArr[j]]));
            });
            comboRow.append($('').text(result));
            ret.append(comboRow);
        });
    }

    var isBoolean = function(val) {
        return (val === true) || (val === false);
    }

    var assertBoolean = function(val) {
        if (! isBoolean(val)) {
            throw new SyntaxError('Unbound symbol: ' + val);
        }
    }

    var evalExpr = function(ast, bindings) {
        var evalSym = function(index) {
            if ($.isArray(ast[index])) {
                return evalExpr(ast[index], bindings);
            }

            assertBoolean(bindings[ast[index]]);
            return bindings[ast[index]];
        };

        if (! ast) {
            throw new SyntaxError('Invalid expression: ' + ast);
        }

        if (! $.isArray(ast)) {
            return bindings[ast];
        }

        switch(ast[0]) {
        case '&':
            return evalSym(1) && evalSym(2);
            break;
        case '^':
            return (evalSym(1) || evalSym(2)) &&
                   (!(evalSym(1) && evalSym(2)));
            break;
        case '|':
            return evalSym(1) || evalSym(2);
            break;
        case '!':
        case '~':
            return ! evalSym(1);
            break;
        default:
            throw new SyntaxError('Unrecognized operator: ' + ast[0]);
        }
    }

    var out = function(val) {
        $('#output').text(val.toString());
    }

    var displaySym = function(symbols) {
        var title = $('
Symbols
');
        var symTable = $('
');
        $.each(symbols, function(sym) {
            symTable.append($('
').text(sym));
        });
        $('#sym').empty().append(title, symTable);
    }

    var main = function() {
        $('#apply').click(function() {
            handleInput($('#expr').val());
        });

        handleInput('!(a & (b | a))');
    }
    that.main = main;

    /**
     * Build an abstract syntax tree out of the given stream of tokens.
     */
    var parse = function() {
        var pos;
        var symbols;
        var tokens;

        var getCurToken = function() {
            return tokens[pos];
        };

        /**
         * Consume the next token and add it to the symbol table.
         */
        var consumeSymbol = function() {
            debug('consumeSymbol');
            var symbol = consumeToken();
            symbols[symbol] = true;
            return symbol;
        };

        var consumeToken = function(expected) {
            var curTok = getCurToken();
            debug('consumeToken', curTok, pos);
            if (expected && (curTok !== expected)) {
                throw new SyntaxError('Did not encounter expected token. Expected: "' +
                                      expected + '" Actual: "' + curTok + '".');
            }

            pos++;
            return curTok;
        };

        var expr = function() {
            debug('expr', tokens, pos);
            if (getCurToken() == '!') {
                return [consumeToken(), subExpr()];
            }

            var a1 = subExpr();
            if (isBinaryOperator(getCurToken())) {
                return [consumeToken(), a1, subExpr()];
            }

            return a1;
        };

        var isBinaryOperator = function(tok) {
            return ((tok === '&') ||
                    (tok === '|') ||
                    (tok === '^'));
        };

        var subExpr = function() {
            debug('subExpr', tokens, pos);
            if (getCurToken() === '(') {
                consumeToken('(');
                var ret = expr();
                consumeToken(')');
                return ret;
            }

            if (! SYMBOL.test(getCurToken())) {
                throw new SyntaxError('Expecting symbol. Invalid symbol name: ' + getCurToken());
            }
            return consumeSymbol();
        };

        return function(tok) {
            debug('parse', tok);
            if ((! tok) || (tok.length === 0)) {
                return [];
            }

            tokens = tok;
            pos = 0;
            symbols = {};
            var ret = expr();
            if (pos < tokens.length) {
                debug(tokens);
                debug(pos);
                debug(tokens[pos]);
                throw new SyntaxError('Could not consume all tokens. '
                    + 'Remaining tokens: ' + tokens.slice(pos, tokens.length));
            }

            return [ret, symbols];
        }
    }();
    that.parse = parse;

    var tokenize = function(str) {
        if ((! str) || (! str.replace(/\s/g, ''))) {
            return [];
        }

        var ret = str.split(/\b/);
        for (var i = 0; i < ret.length; i++) {
            // Remove whitespace from tokens
            ret[i] = ret[i].replace(/\s/g, '');

            if (ret[i].length === 0) {
                ret.splice(i, 1);
            } else if (! SYMBOL.test(ret[i])) {
                var arr = [];
                for (var j = 0; j < ret[i].length; j++) {
                    arr[j] = ret[i][j];
                }
                ret.splice.apply(ret, [i, 1].concat(arr));
            }
        }

        return ret;
    }
    that.tokenize = tokenize;

    var debug = function() {
        if (DEBUG) {
            console.log.apply(console, arguments);
        }
    }

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


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import Confirm from '../components/common/Confirm';

// @param {object} options The options object
// @param {string} [options.message] The message string
// @param {string} [options.description] The description string
// @param {string} [options.confirmLabel] The text for the OK button
// @param {string} [options.cancelLabel] The text for the Cancel button
// @param {function} [confirmCallback] The confirm callback
// @param {function} [cancelCallback] The cancel callback
const confirm = (options = {}, confirmCallback, cancelCallback) => {
    const el = document.body.appendChild(document.createElement('div'));
    const handleClose = (e) => {
        ReactDOM.unmountComponentAtNode(el);
        setTimeout(() => {
            el.remove();
        }, 0);
    };
    const handleConfirm = (e) => {
        confirmCallback && confirmCallback();
    };
    const handleCancel = (e) => {
        cancelCallback && cancelCallback();
    };

    ReactDOM.render(
        <Confirm
            {...options}
            onClose={handleClose}
            onConfirm={handleConfirm}
            onCancel={handleCancel}
        />,
        el
    );
};

export default confirm;
<commit_msg>Update confirm library<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import Confirm from '../components/common/Confirm';
import i18n from './i18n';

const noop = () => {};

// @param {object} options The options object
// @param {function} [ok] The callback for handling the [OK] button
// @param {function} [cancel] The callback for handling the [Cancel] button
const confirm = (options, ok = noop, cancel = noop) => {
    const {
        txtOK = i18n._('OK'),
        txtCancel = i18n._('Cancel'),
        ...props
    } = { ...options };

    //const el = document.body.appendChild(document.createElement('div'));
    const el = document.createElement('div');
    ReactDOM.render(
        <Confirm
            txtOK={txtOK}
            txtCancel={txtCancel}
            {...props}
            show={true}
            onOK={(event) => {
                ok(event);

                ReactDOM.unmountComponentAtNode(el);
                setTimeout(() => {
                    el.remove();
                }, 0);
            }}
            onCancel={(event) => {
                cancel(event);

                ReactDOM.unmountComponentAtNode(el);
                setTimeout(() => {
                    el.remove();
                }, 0);
            }}
        />,
        el
    );
};

export default confirm;
<|endoftext|>