<commit_before>import React, { Component } from 'react';
import apiFetch from '../actions/index';

export class InterestSignupForm extends Component {
    constructor (props) {
        super(props);
        this.state = {
            message: null,
            success: null,
            email: ""
        };
    }
    handleSubmit = (event) => {
        if(event) {
            //so tests don't get funky
            event.preventDefault();
            event.stopPropagation();
        }
        let d = new FormData();
        let email = this.state.email;
        d.append('email', email);
        return apiFetch('interest/signup',{
            method: 'POST',
            body: d
        }).then((response) => response.json())
            .then((json) => {
                this.setState({success: json.success});
                if(json.success === false) {
                    this.setState({message: json.message});
                    let message = json.message;
                    this.props.recordEvent("interestForm","submit_error", {message,email});
                }
                else {
                    this.setState({message: json.data});
                    //upon success, clear the form.
                    this.setState({email: ""});
                    this.props.recordEvent("interestForm","submit_success", {email})
                }
            });
    };
    changeEmail(event) {
        this.setState({email: event.target.value});
    }

    render () {
        let canSubmit = (this.state.email.length > 3);
        return (

Sign up for updates on when applications open!

              <form className="interestForm"onSubmit={this.handleSubmit.bind(this)}>
                  <input id="email" name="email" type="email" value={this.state.email} onChange={this.changeEmail.bind(this)} placeholder="Email"/>
                  <button type="submit" disabled={!canSubmit}>Submit</button>

{this.state.message}

              </form>

        );
    }
}

//now the redux integration layer
import { recordEvent } from '../actions/users';
import { connect } from 'react-redux'
function mapStateToProps (state) {
    return {};
}

const mapDispatchToProps = (dispatch, ownProps) => ({
    recordEvent: (event, subtitle, context) => {
        dispatch(recordEvent(event, subtitle, context));
    }
});

export default connect(mapStateToProps, mapDispatchToProps)(InterestSignupForm);
<commit_msg>stop interest form confirmation message from hiding<commit_after>import React, { Component } from 'react';
import apiFetch from '../actions/index';

export class InterestSignupForm extends Component {
    constructor (props) {
        super(props);
        this.state = {
            message: null,
            success: null,
            email: ""
        };
    }
    handleSubmit = (event) => {
        if(event) {
            //so tests don't get funky
            event.preventDefault();
            event.stopPropagation();
        }
        let d = new FormData();
        let email = this.state.email;
        d.append('email', email);
        return apiFetch('interest/signup',{
            method: 'POST',
            body: d
        }).then((response) => response.json())
            .then((json) => {
                this.setState({success: json.success});
                if(json.success === false) {
                    this.setState({message: json.message});
                    let message = json.message;
                    this.props.recordEvent("interestForm","submit_error", {message,email});
                }
                else {
                    this.setState({message: json.data});
                    //upon success, clear the form.
                    this.setState({email: ""});
                    this.props.recordEvent("interestForm","submit_success", {email})
                }
            });
    };
    changeEmail(event) {
        this.setState({email: event.target.value});
    }

    render () {
        let canSubmit = (this.state.email.length > 3);
        return (

Sign up for updates on when applications open!

              <form className="interestForm"onSubmit={this.handleSubmit.bind(this)}>
                  <input id="email" name="email" type="email" value={this.state.email} onChange={this.changeEmail.bind(this)} placeholder="Email"/>
                  <button type="submit" disabled={!canSubmit}>Submit</button>

{this.state.message}

              </form>

        );
    }
}

//now the redux integration layer
import { recordEvent } from '../actions/users';
import { connect } from 'react-redux'
function mapStateToProps (state) {
    return {};
}

const mapDispatchToProps = (dispatch, ownProps) => ({
    recordEvent: (event, subtitle, context) => {
        dispatch(recordEvent(event, subtitle, context));
    }
});

export default connect(mapStateToProps, mapDispatchToProps)(InterestSignupForm);
<|endoftext|>


<commit_before>import { TransactionTypes } from '../constants/transactions';
import { getFxRate } from '../lib/currency';
import errors from '../lib/errors';
import { toNegative } from '../lib/math';
import { exportToCSV } from '../lib/utils';
import models, { Op, sequelize } from '../models';
import { PayoutMethodTypes } from '../models/PayoutMethod';

/**
 * Export transactions as CSV
 * @param {*} transactions
 */
export function exportTransactions(transactions, attributes) {
  attributes = attributes || [
    'id',
    'createdAt',
    'amount',
    'currency',
    'description',
    'netAmountInCollectiveCurrency',
    'hostCurrency',
    'hostCurrencyFxRate',
    'paymentProcessorFeeInHostCurrency',
    'hostFeeInHostCurrency',
    'platformFeeInHostCurrency',
    'netAmountInHostCurrency',
  ];

  return exportToCSV(transactions, attributes);
}

/**
 * Get transactions between startDate and endDate for collectiveids
 * @param {*} collectiveids
 * @param {*} startDate
 * @param {*} endDate
 * @param {*} limit
 */
export function getTransactions(collectiveids, startDate = new Date('2015-01-01'), endDate = new Date(), options) {
  const where = options.where || {};
  const query = {
    where: {
      ...where,
      CollectiveId: { [Op.in]: collectiveids },
      createdAt: { [Op.gte]: startDate, [Op.lt]: endDate },
    },
    order: [['createdAt', 'DESC']],
  };
  if (options.limit) {
    query.limit = options.limit;
  }
  if (options.include) {
    query.include = options.include;
  }
  return models.Transaction.findAll(query);
}

export async function createFromPaidExpense(
  host,
  paymentMethod,
  expense,
  paymentResponses,
  UserId,
  paymentProcessorFeeInHostCurrency = 0,
  hostFeeInHostCurrency = 0,
  platformFeeInHostCurrency = 0,
  transactionData,
) {
  const hostCurrency = host.currency;
  let createPaymentResponse, executePaymentResponse;
  let paymentProcessorFeeInCollectiveCurrency = 0,
    hostFeeInCollectiveCurrency = 0,
    platformFeeInCollectiveCurrency = 0;
  let hostCurrencyFxRate = 1;
  const payoutMethod = await expense.getPayoutMethod();
  const payoutMethodType = payoutMethod ? payoutMethod.type : expense.getPayoutMethodTypeFromLegacy();

  // If PayPal
  if (paymentResponses) {
    createPaymentResponse = paymentResponses.createPaymentResponse;
    executePaymentResponse = paymentResponses.executePaymentResponse;

    switch (executePaymentResponse.paymentExecStatus) {
      case 'COMPLETED':
        break;

      case 'CREATED':
        /*
         * When we don't provide a preapprovalKey (paymentMethod.token) to payServices['paypal'](),
         * it creates a payKey that we can use to redirect the user to PayPal.com to manually approve that payment
         * TODO We should handle that case on the frontend
         */
        throw new errors.BadRequest(
          `Please approve this payment manually on ${createPaymentResponse.paymentApprovalUrl}`,
        );

      case 'ERROR':
        throw new errors.ServerError(
          `Error while paying the expense with PayPal: "${executePaymentResponse.payErrorList[0].error.message}". Please contact support@opencollective.com`,
        );

      default:
        throw new errors.ServerError(
          `Error while paying the expense with PayPal. Please contact support@opencollective.com`,
        );
    }

    const senderFees = createPaymentResponse.defaultFundingPlan.senderFees;
    paymentProcessorFeeInCollectiveCurrency = senderFees.amount * 100; // paypal sends this in float

    const currencyConversion = createPaymentResponse.defaultFundingPlan.currencyConversion || { exchangeRate: 1 };
    hostCurrencyFxRate = 1 / parseFloat(currencyConversion.exchangeRate); // paypal returns a float from host.currency to expense.currency
    paymentProcessorFeeInHostCurrency = Math.round(hostCurrencyFxRate * paymentProcessorFeeInCollectiveCurrency);
  } else if (payoutMethodType === PayoutMethodTypes.BANK_ACCOUNT) {
    // Notice this is the FX rate between Host and Collective, the user is not involved here and that's why TransferWise quote rate is irrelavant here.
    hostCurrencyFxRate = await getFxRate(expense.currency, host.currency);
    paymentProcessorFeeInHostCurrency = Math.round(transactionData.quote.fee * 100);
    paymentProcessorFeeInCollectiveCurrency = Math.round((1 / hostCurrencyFxRate) * paymentProcessorFeeInHostCurrency);
    hostFeeInCollectiveCurrency = Math.round((1 / hostCurrencyFxRate) * hostFeeInHostCurrency);
    platformFeeInCollectiveCurrency = Math.round((1 / hostCurrencyFxRate) * platformFeeInHostCurrency);
  } else {
    // If manual (add funds or manual reimbursement of an expense)
    hostCurrencyFxRate = await getFxRate(expense.currency, host.currency, expense.incurredAt || expense.createdAt);
    paymentProcessorFeeInCollectiveCurrency = Math.round((1 / hostCurrencyFxRate) * paymentProcessorFeeInHostCurrency);
    hostFeeInCollectiveCurrency = Math.round((1 / hostCurrencyFxRate) * hostFeeInHostCurrency);
    platformFeeInCollectiveCurrency = Math.round((1 / hostCurrencyFxRate) * platformFeeInHostCurrency);
  }

  // We assume that all expenses are in Collective currency
  // (otherwise, ledger breaks with a triple currency conversion)
  const transaction = {
    netAmountInCollectiveCurrency:
      -1 *
      (expense.amount +
        paymentProcessorFeeInCollectiveCurrency +
        hostFeeInCollectiveCurrency +
        platformFeeInCollectiveCurrency),
    hostCurrency,
    paymentProcessorFeeInHostCurrency: toNegative(paymentProcessorFeeInHostCurrency),
    hostFeeInHostCurrency: toNegative(hostFeeInHostCurrency),
    platformFeeInHostCurrency: toNegative(platformFeeInHostCurrency),
    ExpenseId: expense.id,
    type: TransactionTypes.DEBIT,
    amount: -expense.amount,
    currency: expense.currency,
    description: expense.description,
    CreatedByUserId: UserId,
    CollectiveId: expense.CollectiveId,
    HostCollectiveId: host.id,
    PaymentMethodId: paymentMethod ? paymentMethod.id : null,
    data: transactionData,
  };

  transaction.hostCurrencyFxRate = hostCurrencyFxRate;
  transaction.amountInHostCurrency = -Math.round(hostCurrencyFxRate * expense.amount); // amountInHostCurrency is an INTEGER (in cents)
  const user = await models.User.findByPk(UserId);
  transaction.FromCollectiveId = user.CollectiveId;
  return models.Transaction.createDoubleEntry(transaction);
}

/**
 * Calculate net amount of a transaction in the currency of the collective
 * Notes:
 * - fees are negative numbers
 * - netAmountInCollectiveCurrency * hostCurrencyFxRate = amountInHostCurrency
 *   Therefore, amountInHostCurrency / hostCurrencyFxRate= netAmountInCollectiveCurrency
 */
export function netAmount(tr) {
  const fees = tr.hostFeeInHostCurrency + tr.platformFeeInHostCurrency + tr.paymentProcessorFeeInHostCurrency || 0;
  return Math.round((tr.amountInHostCurrency + fees) / tr.hostCurrencyFxRate);
}

/**
 * Verify net amount of a transaction
 */
export function verify(tr) {
  if (tr.type === 'CREDIT' && tr.amount <= 0) {
    return 'amount <= 0';
  }
  if (tr.type === 'DEBIT' && tr.amount >= 0) {
    return 'amount >= 0';
  }
  if (tr.type === 'CREDIT' && tr.netAmountInCollectiveCurrency <= 0) {
    return 'netAmount <= 0';
  }
  if (tr.type === 'DEBIT' && tr.netAmountInCollectiveCurrency >= 0) {
    return 'netAmount >= 0';
  }
  const diff = Math.abs(netAmount(tr) - tr.netAmountInCollectiveCurrency);
  // if the difference is within one cent, it's most likely a rounding error (because of the number of decimals in the hostCurrencyFxRate)
  if (diff > 0 && diff < 10) {
    return 'netAmount diff';
  }
  return true;
}

/** Calculate how off a transaction is
 *
 * Which is pretty much the difference between transaction net amount
 * & netAmountInCollectiveCurrency */
export function difference(tr) {
  return netAmount(tr) - tr.netAmountInCollectiveCurrency;
}

/** Returnt he sum of transaction rows that match search.
 *
 * @param {Object} where is an object that contains all the fields
 *  that you want to use to narrow down the search against the
 *  transactions table. For example, if you want to sum up the
 *  donations of a user to a specific collective, use the following:
 * @example
 *  > const babel = await models.Collectives.findOne({ slug: 'babel' });
 *  > libransactions.sum({ FromCollectiveId: userCollective.id, CollectiveId: babel.id })
 * @return the sum of the column `amount`.
 */
export async function sum(where) {
  const totalAttr = sequelize.fn('COALESCE', sequelize.fn('SUM', sequelize.col('netAmountInCollectiveCurrency')), 0);
  const attributes = [[totalAttr, 'total']];
  const result = await models.Transaction.findOne({ attributes, where });
  return result.dataValues.total;
}
<commit_msg>chore: fix typo in transactions.js<commit_after>import { TransactionTypes } from '../constants/transactions';
import { getFxRate } from '../lib/currency';
import errors from '../lib/errors';
import { toNegative } from '../lib/math';
import { exportToCSV } from '../lib/utils';
import models, { Op, sequelize } from '../models';
import { PayoutMethodTypes } from '../models/PayoutMethod';

/**
 * Export transactions as CSV
 * @param {*} transactions
 */
export function exportTransactions(transactions, attributes) {
  attributes = attributes || [
    'id',
    'createdAt',
    'amount',
    'currency',
    'description',
    'netAmountInCollectiveCurrency',
    'hostCurrency',
    'hostCurrencyFxRate',
    'paymentProcessorFeeInHostCurrency',
    'hostFeeInHostCurrency',
    'platformFeeInHostCurrency',
    'netAmountInHostCurrency',
  ];

  return exportToCSV(transactions, attributes);
}

/**
 * Get transactions between startDate and endDate for collectiveids
 * @param {*} collectiveids
 * @param {*} startDate
 * @param {*} endDate
 * @param {*} limit
 */
export function getTransactions(collectiveids, startDate = new Date('2015-01-01'), endDate = new Date(), options) {
  const where = options.where || {};
  const query = {
    where: {
      ...where,
      CollectiveId: { [Op.in]: collectiveids },
      createdAt: { [Op.gte]: startDate, [Op.lt]: endDate },
    },
    order: [['createdAt', 'DESC']],
  };
  if (options.limit) {
    query.limit = options.limit;
  }
  if (options.include) {
    query.include = options.include;
  }
  return models.Transaction.findAll(query);
}

export async function createFromPaidExpense(
  host,
  paymentMethod,
  expense,
  paymentResponses,
  UserId,
  paymentProcessorFeeInHostCurrency = 0,
  hostFeeInHostCurrency = 0,
  platformFeeInHostCurrency = 0,
  transactionData,
) {
  const hostCurrency = host.currency;
  let createPaymentResponse, executePaymentResponse;
  let paymentProcessorFeeInCollectiveCurrency = 0,
    hostFeeInCollectiveCurrency = 0,
    platformFeeInCollectiveCurrency = 0;
  let hostCurrencyFxRate = 1;
  const payoutMethod = await expense.getPayoutMethod();
  const payoutMethodType = payoutMethod ? payoutMethod.type : expense.getPayoutMethodTypeFromLegacy();

  // If PayPal
  if (paymentResponses) {
    createPaymentResponse = paymentResponses.createPaymentResponse;
    executePaymentResponse = paymentResponses.executePaymentResponse;

    switch (executePaymentResponse.paymentExecStatus) {
      case 'COMPLETED':
        break;

      case 'CREATED':
        /*
         * When we don't provide a preapprovalKey (paymentMethod.token) to payServices['paypal'](),
         * it creates a payKey that we can use to redirect the user to PayPal.com to manually approve that payment
         * TODO We should handle that case on the frontend
         */
        throw new errors.BadRequest(
          `Please approve this payment manually on ${createPaymentResponse.paymentApprovalUrl}`,
        );

      case 'ERROR':
        throw new errors.ServerError(
          `Error while paying the expense with PayPal: "${executePaymentResponse.payErrorList[0].error.message}". Please contact support@opencollective.com`,
        );

      default:
        throw new errors.ServerError(
          `Error while paying the expense with PayPal. Please contact support@opencollective.com`,
        );
    }

    const senderFees = createPaymentResponse.defaultFundingPlan.senderFees;
    paymentProcessorFeeInCollectiveCurrency = senderFees.amount * 100; // paypal sends this in float

    const currencyConversion = createPaymentResponse.defaultFundingPlan.currencyConversion || { exchangeRate: 1 };
    hostCurrencyFxRate = 1 / parseFloat(currencyConversion.exchangeRate); // paypal returns a float from host.currency to expense.currency
    paymentProcessorFeeInHostCurrency = Math.round(hostCurrencyFxRate * paymentProcessorFeeInCollectiveCurrency);
  } else if (payoutMethodType === PayoutMethodTypes.BANK_ACCOUNT) {
    // Notice this is the FX rate between Host and Collective, the user is not involved here and that's why TransferWise quote rate is irrelevant here.
    hostCurrencyFxRate = await getFxRate(expense.currency, host.currency);
    paymentProcessorFeeInHostCurrency = Math.round(transactionData.quote.fee * 100);
    paymentProcessorFeeInCollectiveCurrency = Math.round((1 / hostCurrencyFxRate) * paymentProcessorFeeInHostCurrency);
    hostFeeInCollectiveCurrency = Math.round((1 / hostCurrencyFxRate) * hostFeeInHostCurrency);
    platformFeeInCollectiveCurrency = Math.round((1 / hostCurrencyFxRate) * platformFeeInHostCurrency);
  } else {
    // If manual (add funds or manual reimbursement of an expense)
    hostCurrencyFxRate = await getFxRate(expense.currency, host.currency, expense.incurredAt || expense.createdAt);
    paymentProcessorFeeInCollectiveCurrency = Math.round((1 / hostCurrencyFxRate) * paymentProcessorFeeInHostCurrency);
    hostFeeInCollectiveCurrency = Math.round((1 / hostCurrencyFxRate) * hostFeeInHostCurrency);
    platformFeeInCollectiveCurrency = Math.round((1 / hostCurrencyFxRate) * platformFeeInHostCurrency);
  }

  // We assume that all expenses are in Collective currency
  // (otherwise, ledger breaks with a triple currency conversion)
  const transaction = {
    netAmountInCollectiveCurrency:
      -1 *
      (expense.amount +
        paymentProcessorFeeInCollectiveCurrency +
        hostFeeInCollectiveCurrency +
        platformFeeInCollectiveCurrency),
    hostCurrency,
    paymentProcessorFeeInHostCurrency: toNegative(paymentProcessorFeeInHostCurrency),
    hostFeeInHostCurrency: toNegative(hostFeeInHostCurrency),
    platformFeeInHostCurrency: toNegative(platformFeeInHostCurrency),
    ExpenseId: expense.id,
    type: TransactionTypes.DEBIT,
    amount: -expense.amount,
    currency: expense.currency,
    description: expense.description,
    CreatedByUserId: UserId,
    CollectiveId: expense.CollectiveId,
    HostCollectiveId: host.id,
    PaymentMethodId: paymentMethod ? paymentMethod.id : null,
    data: transactionData,
  };

  transaction.hostCurrencyFxRate = hostCurrencyFxRate;
  transaction.amountInHostCurrency = -Math.round(hostCurrencyFxRate * expense.amount); // amountInHostCurrency is an INTEGER (in cents)
  const user = await models.User.findByPk(UserId);
  transaction.FromCollectiveId = user.CollectiveId;
  return models.Transaction.createDoubleEntry(transaction);
}

/**
 * Calculate net amount of a transaction in the currency of the collective
 * Notes:
 * - fees are negative numbers
 * - netAmountInCollectiveCurrency * hostCurrencyFxRate = amountInHostCurrency
 *   Therefore, amountInHostCurrency / hostCurrencyFxRate= netAmountInCollectiveCurrency
 */
export function netAmount(tr) {
  const fees = tr.hostFeeInHostCurrency + tr.platformFeeInHostCurrency + tr.paymentProcessorFeeInHostCurrency || 0;
  return Math.round((tr.amountInHostCurrency + fees) / tr.hostCurrencyFxRate);
}

/**
 * Verify net amount of a transaction
 */
export function verify(tr) {
  if (tr.type === 'CREDIT' && tr.amount <= 0) {
    return 'amount <= 0';
  }
  if (tr.type === 'DEBIT' && tr.amount >= 0) {
    return 'amount >= 0';
  }
  if (tr.type === 'CREDIT' && tr.netAmountInCollectiveCurrency <= 0) {
    return 'netAmount <= 0';
  }
  if (tr.type === 'DEBIT' && tr.netAmountInCollectiveCurrency >= 0) {
    return 'netAmount >= 0';
  }
  const diff = Math.abs(netAmount(tr) - tr.netAmountInCollectiveCurrency);
  // if the difference is within one cent, it's most likely a rounding error (because of the number of decimals in the hostCurrencyFxRate)
  if (diff > 0 && diff < 10) {
    return 'netAmount diff';
  }
  return true;
}

/** Calculate how off a transaction is
 *
 * Which is pretty much the difference between transaction net amount
 * & netAmountInCollectiveCurrency */
export function difference(tr) {
  return netAmount(tr) - tr.netAmountInCollectiveCurrency;
}

/** Returnt he sum of transaction rows that match search.
 *
 * @param {Object} where is an object that contains all the fields
 *  that you want to use to narrow down the search against the
 *  transactions table. For example, if you want to sum up the
 *  donations of a user to a specific collective, use the following:
 * @example
 *  > const babel = await models.Collectives.findOne({ slug: 'babel' });
 *  > libransactions.sum({ FromCollectiveId: userCollective.id, CollectiveId: babel.id })
 * @return the sum of the column `amount`.
 */
export async function sum(where) {
  const totalAttr = sequelize.fn('COALESCE', sequelize.fn('SUM', sequelize.col('netAmountInCollectiveCurrency')), 0);
  const attributes = [[totalAttr, 'total']];
  const result = await models.Transaction.findOne({ attributes, where });
  return result.dataValues.total;
}
<|endoftext|>


<commit_before>// JavaScript Document

// Avoid `console` errors in browsers that lack a console.
if (!(window.console && console.log)) {
	(function() {
		var noop = function() {};
		var methods = ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'markTimeline', 'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'];
		var length = methods.length;
		var console = window.console = {};
		while (length--) {
			console[methods[length]] = noop;
		}
	}());
}

/**
#####################################
#                                   #
#    Project Namespace              #
#                                   #
#####################################
*/
var Brandung = Brandung || {};

/**
 * set folder path
 * @type {string}
 */
Brandung.folderPath = '%%public%%/js/';

/**
 * IE <= 8 detection
 * feature detection for IE <= IE8
 * @type {boolean}
 */
Brandung.IE8 = (document.all && !document.addEventListener) ? true : false;

/**
#####################################
#                                   #
#    Load project dependencies and  #
#    proceed                        #
#                                   #
#####################################
*/
// Check If we have an IE8, if so just create a new Deferred to be able to call $.then()
// for all modern browsers load the main plugins via basket
Brandung.DeferMainPlugins = Brandung.IE8 ? jQuery.Deferred() : basket.require(
	{
		url : Brandung.folderPath + 'libs/vendor/jquery/jquery.min.js',
		unique : '1.11.0'
	},
	{
		url : Brandung.folderPath + 'libs/vendor/modernizr/modernizr.custom.min.js',
		unique : '2.8.1'
	}
);

// Just resolve the main deferred if we have an ie8, because jquery and modernizr are already loaded
if(Brandung.IE8) {
	Brandung.DeferMainPlugins.resolve();
}

Brandung.DeferMainPlugins.then(function () {
	(function($) {
		// The same as above except that we are creating a real deferred by using the $.when method in IE8
		// for all modern browsers load the load plugin via basket
		Brandung.DeferLoadPlugin = Brandung.IE8 ? $.when($.getScript(Brandung.folderPath + 'libs/bra/loadmodule/jquery.loadmodule.min.js')) : basket.require(
			{
				url : Brandung.folderPath + 'libs/bra/loadmodule/jquery.loadmodule.min.js',
				unique : '1.0.0'
			}
		);

		Brandung.DeferLoadPlugin.then(function () {
			/**
			 #####################################
			 #                                   #
			 #    mobile stuff functions         #
			 #                                   #
			 #####################################
			 */
			Brandung.Mobile = {

				init: function () {
					// Place here all functions that need to be invoked on every page load
				}

			};

			/**
			 * check orientation
			 *
			 * add orientation class to body tag
			 */
			Brandung.Mobile.checkOrientation = function () {

				if (window.orientation != 0) {
					$('body').removeClass('portrait').addClass('landscape');
				} else {
					$('body').removeClass('landscape').addClass('portrait');
				}

			};

			/**
			 * get media device selector
			 */
			if (Brandung.IE8) {
				Brandung.Mobile.mediaDevice = 'desktop';
			} else {
				Brandung.Mobile.mediaDevice = window.getComputedStyle(document.body, ':after').getPropertyValue('content');
			}

			Brandung.Mobile.getWindowWidth = function () {
				if (Brandung.IE8) {  // feature detection for IE <= IE8
					Brandung.Mobile.mediaDevice = 'desktop';
				} else {
					Brandung.Mobile.mediaDevice = window.getComputedStyle(document.body, ':after').getPropertyValue('content');
				}
			};

			// add event listener
			$(window).load(function () {
				Brandung.Mobile.getWindowWidth();
				Brandung.Mobile.checkOrientation();
			});

			$(window).resize(function () {
				// call function only on desktop devices
				if ((!Modernizr.touch && window.orientation != 0) || (Modernizr.touch && window.orientation != 0)) {
					Brandung.Mobile.getWindowWidth();
				}
			});

			$(window).bind('orientationchange', function () {
				Brandung.Mobile.checkOrientation();
			});

			/**
			 #####################################
			 #                                   #
			 #      jQuery plugins object        #
			 #                                   #
			 #####################################
			 */
			Brandung.Plugins = {

				init: function () {
					// load plugin scripts
					Brandung.Plugins.loadScripts();
				}

			};

			/**
			 * load scripts
			 */
			Brandung.Plugins.loadScripts = function () {

				/** Loading plugin
				 *
				 * @param {array} - List of dependency paths (js and css)
				 * @param {function} - callback function, when all dependencies are available
				 * @param {string|int} - if this parameter changes, the dependencies will be refetched
				 * from the server
				 */

				// dummy call
				//	$('[SELECTOR]').loadModule([
				//		Brandung.folderPath + '[PATH_TO_JS_SOURCE]'
				//	],
				//	function () {
				//		// do something after script has been loaded
				//	}, 'unique');

				// load hotfix files
				$('body').loadModule([
					Brandung.folderPath + 'hotfix.js',
					'%%public%%/css/hotfix.css'
				], function () {
				}, new Date().getTime());

				// loader helper.js on mobile devices
				if(Brandung.Mobile.mediaDevice === 'smartphone') {
					$('body').loadModule([
						Brandung.folderPath + 'libs/vendor/h5bp/helper.js'
					], function () {
						// init MBP helper functions
						MBP.scaleFix();
						MBP.hideUrlBar();
					}, 'unique');
				}

			};

			/**
			 #####################################
			 #                                   #
			 #        helper functions           #
			 #                                   #
			 #####################################
			 */
			Brandung.Helpers = {

				init: function () {
					// Place here all functions that need to be invoked on every page load
				}

			};

			/**
			 #####################################
			 #                                   #
			 #        global functions           #
			 #                                   #
			 #####################################
			 */
			Brandung.Functions = {

				init: function () {
					// Place here all functions that need to be invoked on every page load
				}

			};

			// snippets placeholer
			// --- start|bra-pb: js ---
			// --- end|bra-pb: js ---

			/**
			 #####################################
			 #                                   #
			 #         document ready            #
			 #                                   #
			 #####################################
			 */
			$(function () {
				// init objects
				Brandung.Mobile.init();
				Brandung.Plugins.init();
				Brandung.Helpers.init();
				Brandung.Functions.init();
			});
		}, function(err) { console.error(err); });
	})(jQuery);
}, function(err) { console.error(err); });
<commit_msg>add jQuery CDN host<commit_after>// JavaScript Document

// Avoid `console` errors in browsers that lack a console.
if (!(window.console && console.log)) {
	(function() {
		var noop = function() {};
		var methods = ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'markTimeline', 'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'];
		var length = methods.length;
		var console = window.console = {};
		while (length--) {
			console[methods[length]] = noop;
		}
	}());
}

/**
#####################################
#                                   #
#    Project Namespace              #
#                                   #
#####################################
*/
var Brandung = Brandung || {};

/**
 * set folder path
 * @type {string}
 */
Brandung.folderPath = '%%public%%/js/';

/**
 * IE <= 8 detection
 * feature detection for IE <= IE8
 * @type {boolean}
 */
Brandung.IE8 = (document.all && !document.addEventListener) ? true : false;

/**
#####################################
#                                   #
#    Load project dependencies and  #
#    proceed                        #
#                                   #
#####################################
*/
// Check If we have an IE8, if so just create a new Deferred to be able to call $.then()
// for all modern browsers load the main plugins via basket
Brandung.DeferMainPlugins = Brandung.IE8 ? jQuery.Deferred() : basket.require(
	{
		url : '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js',
		unique : '1.11.0'
	},
	{
		url : Brandung.folderPath + 'libs/vendor/modernizr/modernizr.custom.min.js',
		unique : '2.8.1'
	}
);

// Just resolve the main deferred if we have an ie8, because jquery and modernizr are already loaded
if(Brandung.IE8) {
	Brandung.DeferMainPlugins.resolve();
}

Brandung.DeferMainPlugins.then(function () {
	(function($) {
		// The same as above except that we are creating a real deferred by using the $.when method in IE8
		// for all modern browsers load the load plugin via basket
		Brandung.DeferLoadPlugin = Brandung.IE8 ? $.when($.getScript(Brandung.folderPath + 'libs/bra/loadmodule/jquery.loadmodule.min.js')) : basket.require(
			{
				url : Brandung.folderPath + 'libs/bra/loadmodule/jquery.loadmodule.min.js',
				unique : '1.0.0'
			}
		);

		Brandung.DeferLoadPlugin.then(function () {
			/**
			 #####################################
			 #                                   #
			 #    mobile stuff functions         #
			 #                                   #
			 #####################################
			 */
			Brandung.Mobile = {

				init: function () {
					// Place here all functions that need to be invoked on every page load
				}

			};

			/**
			 * check orientation
			 *
			 * add orientation class to body tag
			 */
			Brandung.Mobile.checkOrientation = function () {

				if (window.orientation != 0) {
					$('body').removeClass('portrait').addClass('landscape');
				} else {
					$('body').removeClass('landscape').addClass('portrait');
				}

			};

			/**
			 * get media device selector
			 */
			if (Brandung.IE8) {
				Brandung.Mobile.mediaDevice = 'desktop';
			} else {
				Brandung.Mobile.mediaDevice = window.getComputedStyle(document.body, ':after').getPropertyValue('content');
			}

			Brandung.Mobile.getWindowWidth = function () {
				if (Brandung.IE8) {  // feature detection for IE <= IE8
					Brandung.Mobile.mediaDevice = 'desktop';
				} else {
					Brandung.Mobile.mediaDevice = window.getComputedStyle(document.body, ':after').getPropertyValue('content');
				}
			};

			// add event listener
			$(window).load(function () {
				Brandung.Mobile.getWindowWidth();
				Brandung.Mobile.checkOrientation();
			});

			$(window).resize(function () {
				// call function only on desktop devices
				if ((!Modernizr.touch && window.orientation != 0) || (Modernizr.touch && window.orientation != 0)) {
					Brandung.Mobile.getWindowWidth();
				}
			});

			$(window).bind('orientationchange', function () {
				Brandung.Mobile.checkOrientation();
			});

			/**
			 #####################################
			 #                                   #
			 #      jQuery plugins object        #
			 #                                   #
			 #####################################
			 */
			Brandung.Plugins = {

				init: function () {
					// load plugin scripts
					Brandung.Plugins.loadScripts();
				}

			};

			/**
			 * load scripts
			 */
			Brandung.Plugins.loadScripts = function () {

				/** Loading plugin
				 *
				 * @param {array} - List of dependency paths (js and css)
				 * @param {function} - callback function, when all dependencies are available
				 * @param {string|int} - if this parameter changes, the dependencies will be refetched
				 * from the server
				 */

				// dummy call
				//	$('[SELECTOR]').loadModule([
				//		Brandung.folderPath + '[PATH_TO_JS_SOURCE]'
				//	],
				//	function () {
				//		// do something after script has been loaded
				//	}, 'unique');

				// load hotfix files
				$('body').loadModule([
					Brandung.folderPath + 'hotfix.js',
					'%%public%%/css/hotfix.css'
				], function () {
				}, new Date().getTime());

				// loader helper.js on mobile devices
				if(Brandung.Mobile.mediaDevice === 'smartphone') {
					$('body').loadModule([
						Brandung.folderPath + 'libs/vendor/h5bp/helper.js'
					], function () {
						// init MBP helper functions
						MBP.scaleFix();
						MBP.hideUrlBar();
					}, 'unique');
				}

			};

			/**
			 #####################################
			 #                                   #
			 #        helper functions           #
			 #                                   #
			 #####################################
			 */
			Brandung.Helpers = {

				init: function () {
					// Place here all functions that need to be invoked on every page load
				}

			};

			/**
			 #####################################
			 #                                   #
			 #        global functions           #
			 #                                   #
			 #####################################
			 */
			Brandung.Functions = {

				init: function () {
					// Place here all functions that need to be invoked on every page load
				}

			};

			// snippets placeholer
			// --- start|bra-pb: js ---
			// --- end|bra-pb: js ---

			/**
			 #####################################
			 #                                   #
			 #         document ready            #
			 #                                   #
			 #####################################
			 */
			$(function () {
				// init objects
				Brandung.Mobile.init();
				Brandung.Plugins.init();
				Brandung.Helpers.init();
				Brandung.Functions.init();
			});
		}, function(err) { console.error(err); });
	})(jQuery);
}, function(err) { console.error(err); });
<|endoftext|>


<commit_before>angular.module('materialscommons').factory("processEdit", processEdit);

function processEdit() {
    /**
     * fillSetUp: will read all the setup values from process
     * and place inside template.
     *
     */
    function setUp(template, process) {
        process.setup[0].properties.forEach(function(property) {
            var i = _.indexOf(template.setup[0].properties, function(template_property) {
                return template_property.property.attribute === property.attribute
            });
            if (i > -1) {
                template.setup[0].properties[i].property.value = property.value;
                template.setup[0].properties[i].property.name = property.name;
                template.setup[0].properties[i].property.description = property.description;
                template.setup[0].properties[i].property.unit = property.unit;
                template.setup[0].properties[i].property.id = property.id;
                template.setup[0].properties[i].property.setup_id = property.setup_id;
                template.setup[0].properties[i].property._type = property._type;
                template.setup[0].properties[i].property.attribute = property.attribute;

                // If selection type then modify the choices when Other is selected, since the
                // user may have modified the value of other. We need to do this otherwise the
                // default other in the choices will update the value and the user will lose what
                // they set.
                if (property._type === 'selection') {
                    if (property.value.name === 'Other') {
                        let otherChoicesIndex = _.indexOf(template.setup[0].properties[i].property.choices,
                            (c) => c.name === 'Other');
                        if (otherChoicesIndex !== -1) {
                            template.setup[0].properties[i].property.choices[otherChoicesIndex].value = property.value.value;
                        }
                    }
                }
            }
        });
        process.setup = template.setup;
        return process;
    }

    function samples(process) {
        //process.input_samples = process.input_samples;
        return process;
    }

    function files(process) {
        //process['input_files'] = process.input_files.map(function(file) {
        //    return {id: file.id, name: file.name}
        //});
        //process['output_files'] = process.output_files.map(function(file) {
        //    return {id: file.id, name: file.name}
        //});
        return process;
    }

    function addCompositionToMeasurements(prop, measurements) {
        for (let i = 0; i < measurements.length; i++) {
            let measurement = measurements[i];
            if (measurement.property.attribute === 'composition') {
                measurement.property.unit = prop.unit;
                measurement.property.value = prop.value;
                break;
            }
        }
    }

    function setupMeasurements(process, templateMeasurements, template) {
        if (template.category === 'create_samples') {
            // Hack, just extract the composition from one of the samples to display as the measurements.
            let foundComposition = false;
            for (let i = 0; i < process.output_samples.length; i++) {
                let sample = process.output_samples[i];
                for (let k = 0; k < sample.properties.length; k++) {
                    let prop = sample.properties[k];
                    if (prop.attribute === 'composition') {
                        addCompositionToMeasurements(prop.best_measure[0], templateMeasurements);
                        foundComposition = true;
                    }
                }
                if (foundComposition) {
                    break;
                }
            }
        }
        process.measurements = templateMeasurements;
    }

    return {
        fillProcess: function(template, process) {
            process = setUp(template, process);
            process = samples(process);
            process = files(process);
            console.log("process-edit.service - fillProcess - just before setupMeasurements",process);
            setupMeasurements(process, template.measurements, template);
            console.log("process-edit.service - fillProcess - just after setupMeasurements",process);
            if (!('output_samples' in process)) {
                process.output_samples = [];
            }
            if (!('transformed_samples' in process)) {
                process.transformed_samples = [];
            }
            return process;
        },

        addToSamplesFiles: function(files, process) {
            files.forEach(function(f) {
                var i = _.indexOf(process.samples_files, function(item) {
                    return f.id === item.id && f.sample_id == item.sample_id;
                });
                if (i !== -1) {
                    process.samples_files.splice(i, 1);
                    process.samples_files.push({
                        id: f.id,
                        command: f.command,
                        name: f.name,
                        sample_id: f.sample_id
                    });
                } else {
                    if (f.command) {
                        process.samples_files.push({
                            id: f.id,
                            command: f.command,
                            name: f.name,
                            sample_id: f.sample_id
                        });
                    }
                }
            });
            return process;
        },

        refreshSample: function(files, sample) {
            files.forEach(function(f) {
                if (f.command) {
                    var i = _.indexOf(sample.files, function(item) {
                        return f.id === item.id && f.sample_id == sample.id;
                    });
                    if (i !== -1) {
                        sample.files.splice(i, 1);
                        sample.files.push({
                            id: f.id,
                            command: f.command,
                            name: f.name,
                            sample_id: f.sample_id,
                            linked: f.linked
                        });
                    } else {
                        sample.files.push({
                            id: f.id,
                            command: f.command,
                            name: f.name,
                            sample_id: f.sample_id,
                            linked: f.linked
                        });
                    }
                }
            });
            return sample;
        }
    };
}<commit_msg>Remove console statements.<commit_after>angular.module('materialscommons').factory("processEdit", processEdit);

function processEdit() {
    /**
     * fillSetUp: will read all the setup values from process
     * and place inside template.
     *
     */
    function setUp(template, process) {
        process.setup[0].properties.forEach(function(property) {
            var i = _.indexOf(template.setup[0].properties, function(template_property) {
                return template_property.property.attribute === property.attribute
            });
            if (i > -1) {
                template.setup[0].properties[i].property.value = property.value;
                template.setup[0].properties[i].property.name = property.name;
                template.setup[0].properties[i].property.description = property.description;
                template.setup[0].properties[i].property.unit = property.unit;
                template.setup[0].properties[i].property.id = property.id;
                template.setup[0].properties[i].property.setup_id = property.setup_id;
                template.setup[0].properties[i].property._type = property._type;
                template.setup[0].properties[i].property.attribute = property.attribute;

                // If selection type then modify the choices when Other is selected, since the
                // user may have modified the value of other. We need to do this otherwise the
                // default other in the choices will update the value and the user will lose what
                // they set.
                if (property._type === 'selection') {
                    if (property.value.name === 'Other') {
                        let otherChoicesIndex = _.indexOf(template.setup[0].properties[i].property.choices,
                            (c) => c.name === 'Other');
                        if (otherChoicesIndex !== -1) {
                            template.setup[0].properties[i].property.choices[otherChoicesIndex].value = property.value.value;
                        }
                    }
                }
            }
        });
        process.setup = template.setup;
        return process;
    }

    function samples(process) {
        //process.input_samples = process.input_samples;
        return process;
    }

    function files(process) {
        //process['input_files'] = process.input_files.map(function(file) {
        //    return {id: file.id, name: file.name}
        //});
        //process['output_files'] = process.output_files.map(function(file) {
        //    return {id: file.id, name: file.name}
        //});
        return process;
    }

    function addCompositionToMeasurements(prop, measurements) {
        for (let i = 0; i < measurements.length; i++) {
            let measurement = measurements[i];
            if (measurement.property.attribute === 'composition') {
                measurement.property.unit = prop.unit;
                measurement.property.value = prop.value;
                break;
            }
        }
    }

    function setupMeasurements(process, templateMeasurements, template) {
        if (template.category === 'create_samples') {
            // Hack, just extract the composition from one of the samples to display as the measurements.
            let foundComposition = false;
            for (let i = 0; i < process.output_samples.length; i++) {
                let sample = process.output_samples[i];
                for (let k = 0; k < sample.properties.length; k++) {
                    let prop = sample.properties[k];
                    if (prop.attribute === 'composition') {
                        addCompositionToMeasurements(prop.best_measure[0], templateMeasurements);
                        foundComposition = true;
                    }
                }
                if (foundComposition) {
                    break;
                }
            }
        }
        process.measurements = templateMeasurements;
    }

    return {
        fillProcess: function(template, process) {
            process = setUp(template, process);
            process = samples(process);
            process = files(process);
            setupMeasurements(process, template.measurements, template);
            if (!('output_samples' in process)) {
                process.output_samples = [];
            }
            if (!('transformed_samples' in process)) {
                process.transformed_samples = [];
            }
            return process;
        },

        addToSamplesFiles: function(files, process) {
            files.forEach(function(f) {
                var i = _.indexOf(process.samples_files, function(item) {
                    return f.id === item.id && f.sample_id == item.sample_id;
                });
                if (i !== -1) {
                    process.samples_files.splice(i, 1);
                    process.samples_files.push({
                        id: f.id,
                        command: f.command,
                        name: f.name,
                        sample_id: f.sample_id
                    });
                } else {
                    if (f.command) {
                        process.samples_files.push({
                            id: f.id,
                            command: f.command,
                            name: f.name,
                            sample_id: f.sample_id
                        });
                    }
                }
            });
            return process;
        },

        refreshSample: function(files, sample) {
            files.forEach(function(f) {
                if (f.command) {
                    var i = _.indexOf(sample.files, function(item) {
                        return f.id === item.id && f.sample_id == sample.id;
                    });
                    if (i !== -1) {
                        sample.files.splice(i, 1);
                        sample.files.push({
                            id: f.id,
                            command: f.command,
                            name: f.name,
                            sample_id: f.sample_id,
                            linked: f.linked
                        });
                    } else {
                        sample.files.push({
                            id: f.id,
                            command: f.command,
                            name: f.name,
                            sample_id: f.sample_id,
                            linked: f.linked
                        });
                    }
                }
            });
            return sample;
        }
    };
}<|endoftext|>


<commit_before>import { sequelize, Device } from '../../index';

describe('Device', () => {
  it('should be a valid model', () => {
    expect(Device).toBeDefined();
    expect(Device.rawAttributes).toBeDefined();
  });

  it('should have date attributes', () => {
    expect(Device.rawAttributes.createdAt).toBeDefined();
    expect(Device.rawAttributes.updatedAt).toBeDefined();

    // eslint-disable-next-line no-underscore-dangle
    expect(Device._timestampAttributes.createdAt).toBe('createdAt');
    // eslint-disable-next-line no-underscore-dangle
    expect(Device._timestampAttributes.updatedAt).toBe('updatedAt');
  });

  it('should have a primary key', () => {
    expect(Device.rawAttributes.id).toBeDefined();
    expect(Device.rawAttributes.id.primaryKey).toBe(true);
  });

  it('should have a "identifierForVendor" attribute', () => {
    expect(Device.rawAttributes.identifierForVendor).toBeDefined();
  });

  it('should have a "name" attribute', () => {
    expect(Device.rawAttributes.name).toBeDefined();
  });

  describe('Instance', () => {
    const name = 'location-A';

    beforeEach(() => sequelize
      .sync({ force: true })
      .then(() => Device.create({ name })));

    it('should find a device', () => Device.findAll()
      .then(devices => expect(devices).toHaveLength(1)));

    it('should find the device', () => Device.findOne({ where: { name } })
      .then((device) => {
        expect(device).toBeDefined();
        expect(device).toBeInstanceOf(Object);
        expect(device.name).toBeDefined();
        expect(device.name).toBe(name);
      }));

    it('should edit the device', () => Device.findOne({ where: { name } })
      .then((device) => {
        device.identifierForVendor = '5'; // eslint-disable-line no-param-reassign

        return device.save();
      })
      .then(() => Device.findOne({ where: { name } }))
      .then((device) => {
        expect(device).toBeDefined();
        expect(device.name).toBe(name);
        expect(device.identifierForVendor).toBe('5');
      }));

    it('should delete the device', () => Device.findOne({ where: { name } })
      .then(device => device.destroy())
      .then(() => Device.findAll())
      .then(devices => expect(devices).toHaveLength(0)));
  });
});
<commit_msg>More order!!<commit_after>import { sequelize, Device } from '../../index';

describe('Device', () => {
  describe('Class', () => {
    it('should be a valid model', () => {
      expect(Device).toBeDefined();
      expect(Device.rawAttributes).toBeDefined();
    });

    it('should have date attributes', () => {
      expect(Device.rawAttributes.createdAt).toBeDefined();
      expect(Device.rawAttributes.updatedAt).toBeDefined();

      // eslint-disable-next-line no-underscore-dangle
      expect(Device._timestampAttributes.createdAt).toBe('createdAt');
      // eslint-disable-next-line no-underscore-dangle
      expect(Device._timestampAttributes.updatedAt).toBe('updatedAt');
    });

    it('should have a primary key', () => {
      expect(Device.rawAttributes.id).toBeDefined();
      expect(Device.rawAttributes.id.primaryKey).toBe(true);
    });

    it('should have a "identifierForVendor" attribute', () => {
      expect(Device.rawAttributes.identifierForVendor).toBeDefined();
    });

    it('should have a "name" attribute', () => {
      expect(Device.rawAttributes.name).toBeDefined();
    });
  });

  describe('Instance', () => {
    const name = 'location-A';

    beforeEach(() => sequelize
      .sync({ force: true })
      .then(() => Device.create({ name })));

    describe('Basic', () => {
      it('should find a device', () => Device.findAll()
        .then(devices => expect(devices).toHaveLength(1)));

      it('should find the device', () => Device.findOne({ where: { name } })
        .then((device) => {
          expect(device).toBeDefined();
          expect(device).toBeInstanceOf(Object);
          expect(device.name).toBeDefined();
          expect(device.name).toBe(name);
        }));

      it('should edit the device', () => Device.findOne({ where: { name } })
        .then((device) => {
          device.identifierForVendor = '5'; // eslint-disable-line no-param-reassign

          return device.save();
        })
        .then(() => Device.findOne({ where: { name } }))
        .then((device) => {
          expect(device).toBeDefined();
          expect(device.name).toBe(name);
          expect(device.identifierForVendor).toBe('5');
        }));

      it('should delete the device', () => Device.findOne({ where: { name } })
        .then(device => device.destroy())
        .then(() => Device.findAll())
        .then(devices => expect(devices).toHaveLength(0)));
    });
  });
});
<|endoftext|>


<commit_before>const questionTypes = {
  audioUpload: 'Audio Record',
  fileUpload: 'File Upload',
  movableWordSandbox: 'Movable Word -- Sandbox',
  movableWordSentence: 'Movable Word -- Sentence',
  movableFillBlank: 'Movable Word -- Fill in the Blank',
  shortAnswer: 'Short Answer',
  imageSequence: 'Image Sequence',
  multipleChoice: 'Multiple Choice',
  reflection: 'Multiple Choice -- Reflection',
  multipleAnswer: 'Multiple Choice -- Multiple Select',
  multipleReflection: 'Multiple Choice -- Multiple Select & Reflection',
  dragAndDrop: 'Drag and Drop',
};

const feedback = {
  correctFeedback: 'Correct Feedback',
  incorrectFeedback: 'Incorrect Feedback',
  feedback: 'Feedback'
};

export default {
  en: {
    name: 'English',
    dir: 'ltr',
    addImage: {
      addImage: 'Add Image'
    },
    addOption:{
      addOption: 'Add Option'
    },
    addQuestionButton: {
      addQuestion: 'Add Question'
    },
    assessmentForm: {
      singlePageAssessment: 'Single page assessment',
      nameRequired: 'Name is required in order to edit',
      placeholder: 'Untitled Assessment'
    },
    audioLimit: {
      rangeWarning: 'Please enter a positive number under'
    },
    backButton: {
      back: 'Back'
    },
    bankListHeader: {
      name: 'Name',
      published: 'Published'
    },
    commonAddOption: {
      addOption: 'Add Option',
    },
    editAssessment: {
      confirm: 'Are you sure you want to delete this item?'
    },
    editorUploadModal: {
      cancel: 'Cancel',
      ok: 'OK',
      error: 'Error',
      insert: 'Insert',
      audioFile: 'Select an Audio file',
      imgFile: 'Select an Image',
      videoFile: 'Select a Video file',

    },
    imageOption: {
      NA: 'N/A'
    },
    imageSequence: {
      ...feedback,
    },
    mcAddOption: {
      addOption: 'Add Option'
    },
    movableFillBlank: {
      ...feedback
    },
    movableWordSentanceOption: {
      NA: 'N/A',
      newOption: 'New Option'
    },
    movableWordSentence: {
      ...feedback
    },
    multipleChoice: {
      ...feedback
    },
    multipleChoiceOptions: {
      optionText: 'Option Text'
    },
    mwSandbox: {
      feedback: 'Feedback',
    },
    navigationBarContent: {
      new: 'NEW',
      publish: 'Publish',
      unpublish: 'Unpublish',
      preview: 'Preview Assessment',
      assessment: 'Assessment',
    },
    newItemForm: {
      addQuestion: 'Add Question',
      name: 'Name',
      cancel: 'Cancel',
      saveNewQuestion: 'Save New Question',
      ...questionTypes
    },
    optionFeedback: {
      feedback: 'Feedback',
    },
    previewHeader: {
      closePreview: 'Close Preview'
    },
    previewQuestion: {
      fileUpload: {
        chooseFile: 'Choose File'
      },
      audioUpload: {
        stop: 'Stop',
        record: 'Record',
      }
    },
    reorderHeader: {
      done: 'Done'
    },
    saveOption: {
      saveOptions: 'Save Options'
    },
    settingsCheckbox: {
      maintainChoiceOrder: 'Maintain choice order',
      multipleAnswer: 'Multiple answer',
      reflection: 'Reflection'
    },
    shortAnswer: {
      answerBox: 'Answer Box',
      small: 'Small',
      medium: 'Medium',
      large: 'Large',
      box: 'Box',
      feedback: 'Feedback'
    },
    question: {
      confirm: 'Are you sure you want to delete this option?'
    },
    questionHeader: {
      question: 'Question'
    },
    questionSettings: {
      name: 'Name',
      english: 'English',
      hindi: 'Hindi',
      telugu: 'Telugu'
    },
    questionText: {
      instructions: 'To insert blank, add [ _ ] where you want the blank to show up.',
      fitbPlaceholder: 'Fill in the [ _ ] Text',
      otherPlaceholder: 'Question Text'
    },
    dragAndDrop: {
      draggableAnswers: 'Draggable answers'
    },
    addZoneDropDown: {
      byRegion: 'by region',
      byImage: 'by image',
    },
    dragArea: {
      addImage: 'Add Image',
    },
    dropObject: {
      label: 'Label',
      selectAnswer: 'Select Answer'
    },
    dropZone: {
      label: 'Label',
    },
    targetMenu: {
      replace: 'Replace Image',
      targetImage: 'Target Image',
      addSnap: 'Add Snap Zone',
      addDrop: 'Add Drop Zone',
      addImage: 'Add Image',
      showZones: 'Show Zones',
    },
    targetPlaceholder: {
      addImg: 'Add Target Image',
    },
  }
};
<commit_msg>words that are different than they used to be (#378)<commit_after>const questionTypes = {
  audioUpload: 'Audio Record',
  fileUpload: 'File Upload',
  movableWordSandbox: 'Movable Word -- Sandbox',
  movableWordSentence: 'Movable Word -- Sentence',
  movableFillBlank: 'Movable Word -- Fill in the Blank',
  shortAnswer: 'Short Answer',
  imageSequence: 'Image Sequence',
  multipleChoice: 'Multiple Choice',
  reflection: 'Multiple Choice -- Reflection',
  multipleAnswer: 'Multiple Choice -- Multiple Select',
  multipleReflection: 'Multiple Choice -- Multiple Select & Reflection',
  dragAndDrop: 'Drag and Drop',
};

const feedback = {
  correctFeedback: 'Correct Feedback',
  incorrectFeedback: 'Incorrect Feedback',
  feedback: 'Feedback'
};

export default {
  en: {
    name: 'English',
    dir: 'ltr',
    addImage: {
      addImage: 'Add Image'
    },
    addOption:{
      addOption: 'Add Option'
    },
    addQuestionButton: {
      addQuestion: 'Add Question'
    },
    assessmentForm: {
      singlePageAssessment: 'Single page assessment',
      nameRequired: 'Name is required in order to edit',
      placeholder: 'Untitled Assessment'
    },
    audioLimit: {
      rangeWarning: 'Please enter a positive number under'
    },
    backButton: {
      back: 'Back'
    },
    bankListHeader: {
      name: 'Name',
      published: 'Published'
    },
    commonAddOption: {
      addOption: 'Add Option',
    },
    editAssessment: {
      confirm: 'Are you sure you want to delete this item?'
    },
    editorUploadModal: {
      cancel: 'Cancel',
      ok: 'OK',
      error: 'Error',
      insert: 'Insert',
      audioFile: 'Select an Audio file',
      imgFile: 'Select an Image',
      videoFile: 'Select a Video file',

    },
    imageOption: {
      NA: 'N/A'
    },
    imageSequence: {
      ...feedback,
    },
    mcAddOption: {
      addOption: 'Add Option'
    },
    movableFillBlank: {
      ...feedback
    },
    movableWordSentanceOption: {
      NA: 'N/A',
      newOption: 'New Option'
    },
    movableWordSentence: {
      ...feedback
    },
    multipleChoice: {
      ...feedback
    },
    multipleChoiceOptions: {
      optionText: 'Option Text'
    },
    mwSandbox: {
      feedback: 'Feedback',
    },
    navigationBarContent: {
      new: 'NEW',
      publish: 'Publish',
      unpublish: 'Unpublish',
      preview: 'Preview Assessment',
      assessment: 'Assessment',
    },
    newItemForm: {
      addQuestion: 'Add Question',
      name: 'Name',
      cancel: 'Cancel',
      saveNewQuestion: 'Save New Question',
      ...questionTypes
    },
    optionFeedback: {
      feedback: 'Feedback',
    },
    previewHeader: {
      closePreview: 'Close Preview'
    },
    previewQuestion: {
      fileUpload: {
        chooseFile: 'Choose File'
      },
      audioUpload: {
        stop: 'Stop',
        record: 'Record',
      }
    },
    reorderHeader: {
      done: 'Done'
    },
    saveOption: {
      saveOptions: 'Save Order'
    },
    settingsCheckbox: {
      maintainChoiceOrder: 'Maintain choice order',
      multipleAnswer: 'Multiple answer',
      reflection: 'Reflection'
    },
    shortAnswer: {
      answerBox: 'Answer Box',
      small: 'Small',
      medium: 'Medium',
      large: 'Large',
      box: 'Box',
      feedback: 'Feedback'
    },
    question: {
      confirm: 'Are you sure you want to delete this option?'
    },
    questionHeader: {
      question: 'Question'
    },
    questionSettings: {
      name: 'Name',
      english: 'English',
      hindi: 'Hindi',
      telugu: 'Telugu'
    },
    questionText: {
      instructions: 'To insert blank, add [ _ ] where you want the blank to show up.',
      fitbPlaceholder: 'Fill in the [ _ ] Text',
      otherPlaceholder: 'Question Text'
    },
    dragAndDrop: {
      draggableAnswers: 'Draggable answers'
    },
    addZoneDropDown: {
      byRegion: 'by region',
      byImage: 'by image',
    },
    dragArea: {
      addImage: 'Add Image',
    },
    dropObject: {
      label: 'Label',
      selectAnswer: 'Select Answer'
    },
    dropZone: {
      label: 'Label',
    },
    targetMenu: {
      replace: 'Replace Image',
      targetImage: 'Target Image',
      addSnap: 'Add Snap Zone',
      addDrop: 'Add Drop Zone',
      addImage: 'Add Image',
      showZones: 'Show Zones',
    },
    targetPlaceholder: {
      addImg: 'Add Target Image',
    },
  }
};
<|endoftext|>


<commit_before>var CoolToJSDemo;
(function (CoolToJSDemo) {
    'use strict';

    // faking the transpilation process for now

    var coolProgramExample = '\
class Main inherits IO {\n\
    main() : Object {\n\
        out_string("Hello, world.\\n")\n\
    };\n\
};\
';

    var coolProgramExampleForDebugging = '\
something here else\n\
if\n\
sdf45\n\
';

    var generatedJavaScriptExample = '\
// note that this generated code (and its output)\n\
// is currently hardcoded while the transpiler\n\
// is being built\n\
\n\
function __outputFunction(output) {\n\
    document.getElementById(\'output\').innerHTML += output;\n\
}\n\
\n\
__outputFunction("Hello, world.\\n");\
';

    var outputExample = 'Hello, world.\n';

    var coolEditor = CodeMirror(document.getElementById('cool-editor'), {
        value: coolProgramExampleForDebugging,
        mode: 'javascript',
        lineNumbers: true,
        indentUnit: 4,
    });

    var generatedJavaScriptEditor = CodeMirror(document.getElementById('generated-javascript'), {
        mode: 'javascript',
        lineNumbers: true,
        indentUnit: 4,
        readOnly: true
    });

    var hasBeenTranspiled = false;
    document.getElementById('transpile-button').onclick = function () {

        CoolToJS.Transpile({
            coolProgramSources: coolEditor.getValue(),
            outputFunction: function (output) {
                document.getElementById('output').innerHTML += output;
            }
        });

        generatedJavaScriptEditor.setValue(generatedJavaScriptExample);
        hasBeenTranspiled = true;
    };

    document.getElementById('play-button').onclick = function () {
        if (hasBeenTranspiled) {
            eval(generatedJavaScriptEditor.getValue());
        }
    };

})(CoolToJSDemo || (CoolToJSDemo = {}));<commit_msg>clear output before running<commit_after>var CoolToJSDemo;
(function (CoolToJSDemo) {
    'use strict';

    // faking the transpilation process for now

    var coolProgramExample = '\
class Main inherits IO {\n\
    main() : Object {\n\
        out_string("Hello, world.\\n")\n\
    };\n\
};\
';

    var coolProgramExampleForDebugging = '\
something here else\n\
if\n\
sdf45\n\
';

    var generatedJavaScriptExample = '\
// note that this generated code (and its output)\n\
// is currently hardcoded while the transpiler\n\
// is being built\n\
\n\
function __outputFunction(output) {\n\
    document.getElementById(\'output\').innerHTML += output;\n\
}\n\
\n\
__outputFunction("Hello, world.\\n");\
';

    var outputExample = 'Hello, world.\n';

    var coolEditor = CodeMirror(document.getElementById('cool-editor'), {
        value: coolProgramExampleForDebugging,
        mode: 'javascript',
        lineNumbers: true,
        indentUnit: 4,
    });

    var generatedJavaScriptEditor = CodeMirror(document.getElementById('generated-javascript'), {
        mode: 'javascript',
        lineNumbers: true,
        indentUnit: 4,
        readOnly: true
    });

    var hasBeenTranspiled = false;
    document.getElementById('transpile-button').onclick = function () {

        CoolToJS.Transpile({
            coolProgramSources: coolEditor.getValue(),
            outputFunction: function (output) {
                document.getElementById('output').innerHTML += output;
            }
        });

        generatedJavaScriptEditor.setValue(generatedJavaScriptExample);
        hasBeenTranspiled = true;
    };

    document.getElementById('play-button').onclick = function () {
        if (hasBeenTranspiled) {
            document.getElementById('output').innerHTML = '';
            eval(generatedJavaScriptEditor.getValue());
        }
    };

})(CoolToJSDemo || (CoolToJSDemo = {}));<|endoftext|>


<commit_before>//  pag190
const collectionSum = (collection) => {
  const iterator = collection[Symbol.iterator]();
  let eachIteration,
    sum = 0;
  while ((eachIteration = iterator.next()), !eachIteration.done) {
    sum += eachIteration.value;
  }
  return sum;
};
console.log('const collectionSum = (collection) => {\n  const iterator = collection[Symbol.iterator]();\n  let eachIteration, sum = 0;\n  while ((eachIteration = iterator.next()), !eachIteration.done) {\n    sum += eachIteration.value;\n  }\n  return sum;\n}');
console.log(collectionSum([1, 2, 3]));

//  pag197
const filterWith = (fn, iterable) => {
  const iterator = iterable[Symbol.iterator]();
  return {
    next() {
      do {
        const { done, value } = iterator.next();
      } while (!done && !fn(value));
      return { done, value };
    },
  };
};
console.log('const filterWith = (fn, iterable) => {\n  const iterator = iterable[Symbol.iterator]();\n  return {\n    next () {\n      do {\n        const { done, value } = iterator.next();\n      } while(!done && !fn(value));\n      return { done,value };\n    }\n  }\n');

//  pag203
console.log('recursive iterators');
console.log('Iterators maintain state, that\'s what they do. Generators have to manage the exact same amount of state.');

const isIterable = (something) => !!something[Symbol.iterator];

const generate = (iterable) => {
  for (const element of iterable) {
    if (isIterable(element)) {
      generate(element);
    } else {
      console.log(element);
    }
  }
};

generate([1, [2, [3, 4], 5]]);

//  pag205
// const fibonacci = () => {
//   let a,b;
//
//   console.log(a = 0);
//   console.log(b = 1);
//
//   while (true) {
//     [a, b] = [b, a + b];
//     console.log(b);
//   }
// }
console.log('const fibonacci = () => {\n  let a,b;\n  console.log(a = 0);\n  console.log(b = 1);\n  while (true) {\n    [a, b] = [b, a + b];\n    console.log(b);\n  }\n}');

console.log('another way');

// let a, b, state = 0;
//
// const fibonacci = () => {
//   switch (state) {
//     case 0:
//       state = 1;
//       return a = 0;
//     case 1:
//       state = 2;
//       return b = 1;
//     case 2:
//       [a, b] = [b, a + b];
//       return b;
//   }
// }

console.log('let a, b, state = 0;\n\nconst fibonacci = () => {\n  switch (state) {\n    case 0:\n      state = 1;\n      return a = 0;\n    case 1:\n      state = 2;\n      return b = 1;\n    case 2:\n      [a, b] = [b, a + b];\n      return b;\n  }\n}');

//  pag207
console.log('Javascrit generators');
console.log('An iterator written in a generator style is called generator.');
console.log('We declate the function using the function * syntax');
console.log('We do not return values or outputs them to the console. We "yeild" the value using the yield keyword.');

function* empty() {}

console.log(empty().next());

function* only(something) {
  yield something;
}

const yooo = only('yoo');

console.log('const yooo = only("yoo");');
console.log(yooo.next());
console.log(yooo.next());

const oneTwoThree = function* () {
  yield 1;
  yield 2;
  yield 3;
};

console.log('const oneTwoThree = function * () {\n  yield 1;\n  yield 2;\n  yield 3;\n}');
console.log(oneTwoThree().next());
console.log(oneTwoThree().next());
console.log(oneTwoThree().next());
console.log(oneTwoThree().next());

const iterator123 = oneTwoThree();
console.log('const iterator123 = oneTwoThree();');
console.log(iterator123.next());
console.log(iterator123.next());
console.log(iterator123.next());
console.log(iterator123.next());

console.log('Generators behave very differently form normal functions, what happens semantically');
console.log('1. We call oneTwoThree() and get an iterator');
console.log('2. The iterator is in a nascent or in a "newBorn" state.');
console.log('3. When we call interator.next(), the bpdy of our generator  begins to be evaluated.');
console.log('4.The body of our generators runs until it returns, ends, or encounters a yield statement, which is yield 1.');
console.log('- The iterator suspends its execution.');
console.log('- the iterator wraps 1 in {done: false, value: 1} and returns that from the call to the .next().');
console.log('- The rest of the program continues along its way until it ,+makes another call to iterator .next().');
console.log('- The iterator resumes execution from the point where it yieled last value.');
console.log('5.The body of our generators runs until it returns, ends, or encounters a yield statement, which is yield 2.');
console.log('- The iterator suspends its execution.');
console.log('- the iterator wraps 2 in {done: false, value: 2} and returns that from the call to the .next().');
console.log('- The rest of the program continues along its way until it ,+makes another call to iterator .next().');
console.log('- The iterator resumes execution from the point where it yieled last value.');
console.log('6.The body of our generators runs until it returns, ends, or encounters a yield statement, which is yield 2.');
console.log('- The iterator suspends its execution.');
console.log('- the iterator wraps 3 in {done: false, value: 3} and returns that from the call to the .next().');
console.log('- The rest of the program continues along its way until it ,+makes another call to iterator .next().');
console.log('- The iterator resumes execution from the point where it yieled last value.');
console.log('6.The body of our generators runs until it returns, ends, or encounters a yield statement, there are no more lines of code, so it ends');
console.log('- the iterator return {done: true} from the call to .next(), and every call to this iterator\'s .next() methods will return {done: true} from now on.');
console.log('This behaviour is not unique to javascript, generators are called coroutines in other languages.');
console.log('Coroutine are computer program components the generalize subroutines for nonpreemptive multitasking, by allowin multiples entry points for suspending and resuming execution at certaint locations. Coroutines are well-suited for implementing more familiar program components such as cooperative tasks, exeptions, event loop, iterators, inifite lists and pipes.');

const threeNumbers = {
  [Symbol.iterator]: function * () {
    yield 1;
    yield 2;
    yield 3;
  }
};

console.log('const threeNumbers = {\n  [Symbol.iterator]: function * () {\n    yield 1;\n    yield 2;\n    yield 3;\n  }\n};');
console.log('[...threeNumbers]');
console.log([...threeNumbers]);

// const fibonacci = {
//   [Symbol.iterator]: () => {
//     let a = 0, b = 1, state = 0;

//     return {
//       next: () => {
//         switch (state) {
//           case 0:
//             state = 1;
//             return {value: a};
//           case 1:
//             state = 2;
//             return {value: b};
//           case 2:
//             [a, b] = [b, a + b];
//             return {value: b};
//         }
//       }
//     }
//   }
// }

// for (let n of fibonacci) {
//   console.log(n);
// }

console.log('const fibonacci = {\n  [Symbol.iterator]: () => {\n    let a = 0, b = 1, state = 0;\n    return {\n      next: () => {\n        switch (state) {\n          case 0:\n            state = 1;\n            return {value: a};\n          case 1:\n            state = 2;\n            return {value: b};\n          case 2:\n            [a, b] = [b, a + b];\n            return {value: b};\n        }\n      }\n    }\n  }\n}\nfor (let n of fibonacci) {\n  console.log(n);\n');

// const mapWith = (fn, iterable) => {
//   ({
//     [Symbol.iterator]: () => {
//       const iterator = iterable[Symbol.iterator]();
//       return {
//         next: () => {
//           const {done, value} = iterator.next();
//           return ({ done: done, value: done ? undefined : fn(value)});
//         }
//       }
//     }
//   })
// }

console.log('const mapWith = (fn, iterable) => {\n  ({\n    [Symbol.iterator]: () => {\n      const iterator = iterable[Symbol.iterator]();\n      return {\n        next: () => {\n          const {done, value} = iterator.next();\n          return ({ done: done, value: done ? undefined : fn(value)});\n        }\n      }\n    }\n  })\n}');

console.log('Or you can do this way');

// function * mapWith (fn, iterable) {
//   for (const element of iterable) {
//     yield fn(element);
//   }
// }

console.log('function * mapWith (fn, iterable) {\n  for (const element of iterable) {\n    yield fn(element);\n  }\n}');<commit_msg>[new] added the last pages<commit_after>//  pag190
const collectionSum = (collection) => {
  const iterator = collection[Symbol.iterator]();
  let eachIteration,
    sum = 0;
  while ((eachIteration = iterator.next()), !eachIteration.done) {
    sum += eachIteration.value;
  }
  return sum;
};
console.log('const collectionSum = (collection) => {\n  const iterator = collection[Symbol.iterator]();\n  let eachIteration, sum = 0;\n  while ((eachIteration = iterator.next()), !eachIteration.done) {\n    sum += eachIteration.value;\n  }\n  return sum;\n}');
console.log(collectionSum([1, 2, 3]));

//  pag197
const filterWith = (fn, iterable) => {
  const iterator = iterable[Symbol.iterator]();
  return {
    next() {
      do {
        const { done, value } = iterator.next();
      } while (!done && !fn(value));
      return { done, value };
    },
  };
};
console.log('const filterWith = (fn, iterable) => {\n  const iterator = iterable[Symbol.iterator]();\n  return {\n    next () {\n      do {\n        const { done, value } = iterator.next();\n      } while(!done && !fn(value));\n      return { done,value };\n    }\n  }\n');

//  pag203
console.log('recursive iterators');
console.log('Iterators maintain state, that\'s what they do. Generators have to manage the exact same amount of state.');

const isIterable = (something) => !!something[Symbol.iterator];

const generate = (iterable) => {
  for (const element of iterable) {
    if (isIterable(element)) {
      generate(element);
    } else {
      console.log(element);
    }
  }
};

generate([1, [2, [3, 4], 5]]);

//  pag205
// const fibonacci = () => {
//   let a,b;
//
//   console.log(a = 0);
//   console.log(b = 1);
//
//   while (true) {
//     [a, b] = [b, a + b];
//     console.log(b);
//   }
// }
console.log('const fibonacci = () => {\n  let a,b;\n  console.log(a = 0);\n  console.log(b = 1);\n  while (true) {\n    [a, b] = [b, a + b];\n    console.log(b);\n  }\n}');

console.log('another way');

// let a, b, state = 0;
//
// const fibonacci = () => {
//   switch (state) {
//     case 0:
//       state = 1;
//       return a = 0;
//     case 1:
//       state = 2;
//       return b = 1;
//     case 2:
//       [a, b] = [b, a + b];
//       return b;
//   }
// }

console.log('let a, b, state = 0;\n\nconst fibonacci = () => {\n  switch (state) {\n    case 0:\n      state = 1;\n      return a = 0;\n    case 1:\n      state = 2;\n      return b = 1;\n    case 2:\n      [a, b] = [b, a + b];\n      return b;\n  }\n}');

//  pag207
console.log('Javascrit generators');
console.log('An iterator written in a generator style is called generator.');
console.log('We declate the function using the function * syntax');
console.log('We do not return values or outputs them to the console. We "yeild" the value using the yield keyword.');

function* empty() {}

console.log(empty().next());

function* only(something) {
  yield something;
}

const yooo = only('yoo');

console.log('const yooo = only("yoo");');
console.log(yooo.next());
console.log(yooo.next());

const oneTwoThree = function* () {
  yield 1;
  yield 2;
  yield 3;
};

console.log('const oneTwoThree = function * () {\n  yield 1;\n  yield 2;\n  yield 3;\n}');
console.log(oneTwoThree().next());
console.log(oneTwoThree().next());
console.log(oneTwoThree().next());
console.log(oneTwoThree().next());

const iterator123 = oneTwoThree();
console.log('const iterator123 = oneTwoThree();');
console.log(iterator123.next());
console.log(iterator123.next());
console.log(iterator123.next());
console.log(iterator123.next());

console.log('Generators behave very differently form normal functions, what happens semantically');
console.log('1. We call oneTwoThree() and get an iterator');
console.log('2. The iterator is in a nascent or in a "newBorn" state.');
console.log('3. When we call interator.next(), the bpdy of our generator  begins to be evaluated.');
console.log('4.The body of our generators runs until it returns, ends, or encounters a yield statement, which is yield 1.');
console.log('- The iterator suspends its execution.');
console.log('- the iterator wraps 1 in {done: false, value: 1} and returns that from the call to the .next().');
console.log('- The rest of the program continues along its way until it ,+makes another call to iterator .next().');
console.log('- The iterator resumes execution from the point where it yieled last value.');
console.log('5.The body of our generators runs until it returns, ends, or encounters a yield statement, which is yield 2.');
console.log('- The iterator suspends its execution.');
console.log('- the iterator wraps 2 in {done: false, value: 2} and returns that from the call to the .next().');
console.log('- The rest of the program continues along its way until it ,+makes another call to iterator .next().');
console.log('- The iterator resumes execution from the point where it yieled last value.');
console.log('6.The body of our generators runs until it returns, ends, or encounters a yield statement, which is yield 2.');
console.log('- The iterator suspends its execution.');
console.log('- the iterator wraps 3 in {done: false, value: 3} and returns that from the call to the .next().');
console.log('- The rest of the program continues along its way until it ,+makes another call to iterator .next().');
console.log('- The iterator resumes execution from the point where it yieled last value.');
console.log('6.The body of our generators runs until it returns, ends, or encounters a yield statement, there are no more lines of code, so it ends');
console.log('- the iterator return {done: true} from the call to .next(), and every call to this iterator\'s .next() methods will return {done: true} from now on.');
console.log('This behaviour is not unique to javascript, generators are called coroutines in other languages.');
console.log('Coroutine are computer program components the generalize subroutines for nonpreemptive multitasking, by allowin multiples entry points for suspending and resuming execution at certaint locations. Coroutines are well-suited for implementing more familiar program components such as cooperative tasks, exeptions, event loop, iterators, inifite lists and pipes.');

const threeNumbers = {
  [Symbol.iterator]: function * () {
    yield 1;
    yield 2;
    yield 3;
  }
};

console.log('const threeNumbers = {\n  [Symbol.iterator]: function * () {\n    yield 1;\n    yield 2;\n    yield 3;\n  }\n};');
console.log('[...threeNumbers]');
console.log([...threeNumbers]);

// const fibonacci = {
//   [Symbol.iterator]: () => {
//     let a = 0, b = 1, state = 0;

//     return {
//       next: () => {
//         switch (state) {
//           case 0:
//             state = 1;
//             return {value: a};
//           case 1:
//             state = 2;
//             return {value: b};
//           case 2:
//             [a, b] = [b, a + b];
//             return {value: b};
//         }
//       }
//     }
//   }
// }

// for (let n of fibonacci) {
//   console.log(n);
// }

console.log('const fibonacci = {\n  [Symbol.iterator]: () => {\n    let a = 0, b = 1, state = 0;\n    return {\n      next: () => {\n        switch (state) {\n          case 0:\n            state = 1;\n            return {value: a};\n          case 1:\n            state = 2;\n            return {value: b};\n          case 2:\n            [a, b] = [b, a + b];\n            return {value: b};\n        }\n      }\n    }\n  }\n}\nfor (let n of fibonacci) {\n  console.log(n);\n');

// const mapWith = (fn, iterable) => {
//   ({
//     [Symbol.iterator]: () => {
//       const iterator = iterable[Symbol.iterator]();
//       return {
//         next: () => {
//           const {done, value} = iterator.next();
//           return ({ done: done, value: done ? undefined : fn(value)});
//         }
//       }
//     }
//   })
// }

console.log('const mapWith = (fn, iterable) => {\n  ({\n    [Symbol.iterator]: () => {\n      const iterator = iterable[Symbol.iterator]();\n      return {\n        next: () => {\n          const {done, value} = iterator.next();\n          return ({ done: done, value: done ? undefined : fn(value)});\n        }\n      }\n    }\n  })\n}');

console.log('Or you can do this way');

// function * mapWith (fn, iterable) {
//   for (const element of iterable) {
//     yield fn(element);
//   }
// }

console.log('function * mapWith (fn, iterable) {\n  for (const element of iterable) {\n    yield fn(element);\n  }\n}');

const EMPTY = {
  isEmpty: () => true,
}
const isEmpty = (node) => node === EMPTY;
const stack =  {
    array: [],
    index: -1,
    push: function (value) {
      return this.array[this.index += 1] = value;
    },
    [Symbol.iterator]: function() {
      let iterationIndex = this.index;
      return {
        next: () => {
          if(iterationIndex > this.index) {
            iterationIndex = this.index;
          }
          if (iterationIndex < 0) {
            return {done: true};
          }
          else {
            return {done: false, value: this.array[iterationIndex--]};
          }
        }
      }
    },
    from: function(iterable) {
      for (let element of iterable) {
        this.push(element);
      }

      return this.array;
    },
    first: function() {
      return this[Symbol.iterator]().next().value;
    },
  };

stack.from([1,2,3,4,5])
.map((x) => {
  console.log(`squaring ${x}`);
  return x * x;
})
.filter((x) => {
  console.log(`filtering ${x}`);
  return x % 2 ==0
})

//  pag262
// function * zip(...iterables) {
//   const iterators = iterables.map((iterable) => iterables[Symbol.iterator]());
//   while (true) {
//     const pairs = iterators.map((j) => j.next()),
//     dones = pairs.map((p) => p.done),
//     values = pairs.map((p) => p.value);

//     if (dones.indexOf(true) >= 0) break;
//     yield values;
//   }
// }
console.log('Run multiple array, stop when the first stops');
console.log('function * zip(...iterables) {\n  const iterators = iterables.map((iterable) => iterables[Symbol.iterator]());\n  while (true) {\n    const pairs = iterators.map((j) => j.next()),\n    dones = pairs.map((p) => p.done),\n    values = pairs.map((p) => p.value);\n    if (dones.indexOf(true) >= 0) break;\n    yield values;\n  }\n}');

//  pag263
const first = (iterable) => iterable[Symbol.iterator]().next().value;

console.log(first([1,2,6]));
<|endoftext|>


<commit_before>/**
 * --------------------------------------------------------------------
 * jQuery-Plugin "pngFix"
 * Version: 1.2, 09.03.2009
 * by Andreas Eberhard, andreas.eberhard@gmail.com
 *                      http://jquery.andreaseberhard.de/
 *
 * Copyright (c) 2007 Andreas Eberhard
 * Licensed under GPL (http://www.opensource.org/licenses/gpl-license.php)
 *
 * Changelog:
 *    09.03.2009 Version 1.2
 *    - Update for jQuery 1.3.x, removed @ from selectors
 *    11.09.2007 Version 1.1
 *    - removed noConflict
 *    - added png-support for input type=image
 *    - 01.08.2007 CSS background-image support extension added by Scott Jehl, scott@filamentgroup.com, http://www.filamentgroup.com
 *    31.05.2007 initial Version 1.0
 * --------------------------------------------------------------------
 * @example $(function(){$(document).pngFix();});
 * @desc Fixes all PNG's in the document on document.ready
 *
 * jQuery(function(){jQuery(document).pngFix();});
 * @desc Fixes all PNG's in the document on document.ready when using noConflict
 *
 * @example $(function(){$('div.examples').pngFix();});
 * @desc Fixes all PNG's within div with class examples
 *
 * @example $(function(){$('div.examples').pngFix( { blankgif:'ext.gif' } );});
 * @desc Fixes all PNG's within div with class examples, provides blank gif for input with png
 * --------------------------------------------------------------------
 */

(function($) {

jQuery.fn.pngFix = function(settings) {

	// Settings
	settings = jQuery.extend({
		blankgif: 'blank.gif'
	}, settings);

	var ie55 = (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf("MSIE 5.5") != -1);
	var ie6 = (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf("MSIE 6.0") != -1);

	if (jQuery.browser.msie && (ie55 || ie6)) {

		//fix images with png-source
		jQuery(this).find("img[src$=.png]").each(function() {

			jQuery(this).attr('width',jQuery(this).width());
			jQuery(this).attr('height',jQuery(this).height());

			var prevStyle = '';
			var strNewHTML = '';
			var imgId = (jQuery(this).attr('id')) ? 'id="' + jQuery(this).attr('id') + '" ' : '';
			var imgClass = (jQuery(this).attr('class')) ? 'class="' + jQuery(this).attr('class') + '" ' : '';
			var imgTitle = (jQuery(this).attr('title')) ? 'title="' + jQuery(this).attr('title') + '" ' : '';
			var imgAlt = (jQuery(this).attr('alt')) ? 'alt="' + jQuery(this).attr('alt') + '" ' : '';
			var imgAlign = (jQuery(this).attr('align')) ? 'float:' + jQuery(this).attr('align') + ';' : '';
			var imgHand = (jQuery(this).parent().attr('href')) ? 'cursor:hand;' : '';
			if (this.style.border) {
				prevStyle += 'border:'+this.style.border+';';
				this.style.border = '';
			}
			if (this.style.padding) {
				prevStyle += 'padding:'+this.style.padding+';';
				this.style.padding = '';
			}
			if (this.style.margin) {
				prevStyle += 'margin:'+this.style.margin+';';
				this.style.margin = '';
			}
			var imgStyle = (this.style.cssText);

			strNewHTML += '';
			if (prevStyle != ''){
				strNewHTML = '' + strNewHTML + '';
			}

			jQuery(this).hide();
			jQuery(this).after(strNewHTML);

		});

		// fix css background pngs
		jQuery(this).find("*").each(function(){
			var bgIMG = jQuery(this).css('background-image');
			if(bgIMG.indexOf(".png")!=-1){
				var iebg = bgIMG.split('url("')[1].split('")')[0];
				jQuery(this).css('background-image', 'none');
				jQuery(this).get(0).runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + iebg + "',sizingMethod='scale')";
			}
		});

		//fix input with png-source
		jQuery(this).find("input[src$=.png]").each(function() {
			var bgIMG = jQuery(this).attr('src');
			jQuery(this).get(0).runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader' + '(src=\'' + bgIMG + '\', sizingMethod=\'scale\');';
   		jQuery(this).attr('src', settings.blankgif)
		});

	}

	return jQuery;

};

})(jQuery);
<commit_msg>comment $.jquery.browser (was removed from jquery 1.9)<commit_after>/**
 * --------------------------------------------------------------------
 * jQuery-Plugin "pngFix"
 * Version: 1.2, 09.03.2009
 * by Andreas Eberhard, andreas.eberhard@gmail.com
 *                      http://jquery.andreaseberhard.de/
 *
 * Copyright (c) 2007 Andreas Eberhard
 * Licensed under GPL (http://www.opensource.org/licenses/gpl-license.php)
 *
 * Changelog:
 *    09.03.2009 Version 1.2
 *    - Update for jQuery 1.3.x, removed @ from selectors
 *    11.09.2007 Version 1.1
 *    - removed noConflict
 *    - added png-support for input type=image
 *    - 01.08.2007 CSS background-image support extension added by Scott Jehl, scott@filamentgroup.com, http://www.filamentgroup.com
 *    31.05.2007 initial Version 1.0
 * --------------------------------------------------------------------
 * @example $(function(){$(document).pngFix();});
 * @desc Fixes all PNG's in the document on document.ready
 *
 * jQuery(function(){jQuery(document).pngFix();});
 * @desc Fixes all PNG's in the document on document.ready when using noConflict
 *
 * @example $(function(){$('div.examples').pngFix();});
 * @desc Fixes all PNG's within div with class examples
 *
 * @example $(function(){$('div.examples').pngFix( { blankgif:'ext.gif' } );});
 * @desc Fixes all PNG's within div with class examples, provides blank gif for input with png
 * --------------------------------------------------------------------
 */

(function($) {

jQuery.fn.pngFix = function(settings) {

	// Settings
	settings = jQuery.extend({
		blankgif: 'blank.gif'
	}, settings);

	var ie55 = (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf("MSIE 5.5") != -1);
	var ie6 = (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf("MSIE 6.0") != -1);

	// jQuery.browser was removed from jquery 1.9
	//if (jQuery.browser.msie && (ie55 || ie6)) {
	if (ie55 || ie6) {

		//fix images with png-source
		jQuery(this).find("img[src$=.png]").each(function() {

			jQuery(this).attr('width',jQuery(this).width());
			jQuery(this).attr('height',jQuery(this).height());

			var prevStyle = '';
			var strNewHTML = '';
			var imgId = (jQuery(this).attr('id')) ? 'id="' + jQuery(this).attr('id') + '" ' : '';
			var imgClass = (jQuery(this).attr('class')) ? 'class="' + jQuery(this).attr('class') + '" ' : '';
			var imgTitle = (jQuery(this).attr('title')) ? 'title="' + jQuery(this).attr('title') + '" ' : '';
			var imgAlt = (jQuery(this).attr('alt')) ? 'alt="' + jQuery(this).attr('alt') + '" ' : '';
			var imgAlign = (jQuery(this).attr('align')) ? 'float:' + jQuery(this).attr('align') + ';' : '';
			var imgHand = (jQuery(this).parent().attr('href')) ? 'cursor:hand;' : '';
			if (this.style.border) {
				prevStyle += 'border:'+this.style.border+';';
				this.style.border = '';
			}
			if (this.style.padding) {
				prevStyle += 'padding:'+this.style.padding+';';
				this.style.padding = '';
			}
			if (this.style.margin) {
				prevStyle += 'margin:'+this.style.margin+';';
				this.style.margin = '';
			}
			var imgStyle = (this.style.cssText);

			strNewHTML += '';
			if (prevStyle != ''){
				strNewHTML = '' + strNewHTML + '';
			}

			jQuery(this).hide();
			jQuery(this).after(strNewHTML);

		});

		// fix css background pngs
		jQuery(this).find("*").each(function(){
			var bgIMG = jQuery(this).css('background-image');
			if(bgIMG.indexOf(".png")!=-1){
				var iebg = bgIMG.split('url("')[1].split('")')[0];
				jQuery(this).css('background-image', 'none');
				jQuery(this).get(0).runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + iebg + "',sizingMethod='scale')";
			}
		});

		//fix input with png-source
		jQuery(this).find("input[src$=.png]").each(function() {
			var bgIMG = jQuery(this).attr('src');
			jQuery(this).get(0).runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader' + '(src=\'' + bgIMG + '\', sizingMethod=\'scale\');';
   		jQuery(this).attr('src', settings.blankgif)
		});

	}

	return jQuery;

};

})(jQuery);
<|endoftext|>


<commit_before>jQuery(document).ready(function($){
	$(".nav .brand").click(function(){
		if(!$(".nav ul").attr("class"))
		{
			$(".nav ul").attr("class","open");
			$(".short").addClass("open");
		}else{
			$(".nav ul").attr("class","");
			$(".short").removeClass("open");
		}
	})
})<commit_msg>添加在线编辑器<commit_after>jQuery(document).ready(function($){
	$(".nav .brand").click(function(){
		if(!$(".nav ul").attr("class"))
		{
			$(".nav ul").attr("class","open");
			$(".short").addClass("open");
		}else{
			$(".nav ul").attr("class","");
			$(".short").removeClass("open");
		}
	})
})

var defaults = {
	width: "100%",
	height: 50,
	border: 1
}
var editor = function( id ){
	this.settings = {};
	this.create( id , arguments[1] || null);
};

editor.prototype = {
	attr: function(id, proper) {
		return this.getProper( this.getElement(id) , proper , arguments[2] || null);
	},
	getProper: function( element, proper, value) {
		if(typeof proper === "string" && value === null)
		{
			return element[proper];
		}else if(value !== null){
			element[proper] = value;
		}else if(typeof proper === "object") {
			for (var key in proper) {
				if (proper.hasOwnProperty(key)) {
					element[key] = proper[key];
				}
			}
		}
	},
	css: function( id , proper ) {
		return this.getProper( this.getElement(id).style , proper , arguments[2] || null);
	},
	create: function( id ) {
		this.textBox = this.getElement(id);
		this.hidetTextBox();
		this.extend( defaults, arguments[1] || null );
		this.addEditor();
		this.write();
	},
	hidetTextBox: function() {
		this.css( this.textBox , "display" ,"none");
	},
	addEditor: function() {
		var edit = document.createElement('iframe');
		this.attr(edit, {
			'id': 'editor',
			'frameBorder': this.settings.border
		});
		this.css(edit, {
			'width': this.tostring( this.settings.width , "px"),
			'height': this.tostring( this.settings.height , "px")
		});
		this.inertNext(edit , this.textBox);
		this.win = edit.contentWindow;
		this.doc = this.win.document;
		this.doc.designMode = 'On';
		this.doc.contentEditable = true;
	},
	inertNext: function( newElement , element ) {
		var parent = element.parentNode;
   		if( parent.lastChild == element ) {
			parent.appendChild( newElement );
		}else {
			parent.insertBefore( newElement, element.nextSibling );
		}
	},
	tostring: function(value , after ) {
		if(typeof value === "string") {
			return value;
		}else {
			return value + after;
		}
	},
	extend: function() {
		for (var i = 0,len = arguments.length; i < len; i++) {
			var arg = arguments[i];
			if(typeof arg === "object") {
				for (var key in arg) {
					if (arg.hasOwnProperty(key)) {
						this.settings[key] = arg[key];
					}
				}
			}
		}
	},
	getElement: function( id ) {
		return typeof(id) === "string" ? document.getElementById(id) : id;
	},
	getSet: function(key) {
		return this.settings[key];
	},
	getHtml: function() {
		return this.doc.body.innerHTML;
	},
	getString: function() {

	},
	write: function() {
		this.doc.open();
		this.doc.writeln('<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />');
		this.doc.close();
	},
}

<|endoftext|>