<commit_before>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class paymium extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'paymium',
            'name': 'Paymium',
            'countries': [ 'FR', 'EU' ],
            'rateLimit': 2000,
            'version': 'v1',
            'has': {
                'CORS': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/27790564-a945a9d4-5ff9-11e7-9d2d-b635763f2f24.jpg',
                'api': 'https://paymium.com/api',
                'www': 'https://www.paymium.com',
                'fees': 'https://www.paymium.com/page/help/fees',
                'doc': [
                    'https://github.com/Paymium/api-documentation',
                    'https://www.paymium.com/page/developers',
                ],
            },
            'api': {
                'public': {
                    'get': [
                        'countries',
                        'data/{id}/ticker',
                        'data/{id}/trades',
                        'data/{id}/depth',
                        'bitcoin_charts/{id}/trades',
                        'bitcoin_charts/{id}/depth',
                    ],
                },
                'private': {
                    'get': [
                        'merchant/get_payment/{uuid}',
                        'user',
                        'user/addresses',
                        'user/addresses/{btc_address}',
                        'user/orders',
                        'user/orders/{uuid}',
                        'user/price_alerts',
                    ],
                    'post': [
                        'user/orders',
                        'user/addresses',
                        'user/payment_requests',
                        'user/price_alerts',
                        'merchant/create_payment',
                    ],
                    'delete': [
                        'user/orders/{uuid}/cancel',
                        'user/price_alerts/{id}',
                    ],
                },
            },
            'markets': {
                'BTC/EUR': { 'id': 'eur', 'symbol': 'BTC/EUR', 'base': 'BTC', 'quote': 'EUR', 'baseId': 'btc', 'quoteId': 'eur' },
            },
            'fees': {
                'trading': {
                    'maker': 0.002,
                    'taker': 0.002,
                },
            },
        });
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        const response = await this.privateGetUser (params);
        const result = { 'info': response };
        const currencies = Object.keys (this.currencies);
        for (let i = 0; i < currencies.length; i++) {
            const code = currencies[i];
            const currencyId = this.currencyId (code);
            const free = 'balance_' + currencyId;
            if (free in response) {
                const account = this.account ();
                const used = 'locked_' + currencyId;
                account['free'] = this.safeFloat (response, free);
                account['used'] = this.safeFloat (response, used);
                result[code] = account;
            }
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        const request = {
            'id': this.marketId (symbol),
        };
        const response = await this.publicGetDataIdDepth (this.extend (request, params));
        return this.parseOrderBook (response, undefined, 'bids', 'asks', 'price', 'amount');
    }

    async fetchTicker (symbol, params = {}) {
        const request = {
            'id': this.marketId (symbol),
        };
        const ticker = await this.publicGetDataIdTicker (this.extend (request, params));
        const timestamp = this.safeTimestamp (ticker, 'at');
        const vwap = this.safeFloat (ticker, 'vwap');
        const baseVolume = this.safeFloat (ticker, 'volume');
        let quoteVolume = undefined;
        if (baseVolume !== undefined && vwap !== undefined) {
            quoteVolume = baseVolume * vwap;
        }
        const last = this.safeFloat (ticker, 'price');
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'high'),
            'low': this.safeFloat (ticker, 'low'),
            'bid': this.safeFloat (ticker, 'bid'),
            'bidVolume': undefined,
            'ask': this.safeFloat (ticker, 'ask'),
            'askVolume': undefined,
            'vwap': vwap,
            'open': this.safeFloat (ticker, 'open'),
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': undefined,
            'percentage': this.safeFloat (ticker, 'variation'),
            'average': undefined,
            'baseVolume': baseVolume,
            'quoteVolume': quoteVolume,
            'info': ticker,
        };
    }

    parseTrade (trade, market) {
        const timestamp = this.safeTimestamp (trade, 'created_at_int');
        const id = this.safeString (trade, 'uuid');
        let symbol = undefined;
        if (market !== undefined) {
            symbol = market['symbol'];
        }
        const side = this.safeString (trade, 'side');
        const price = this.safeFloat (trade, 'price');
        const amountField = 'traded_' + market['base'].toLowerCase ();
        const amount = this.safeFloat (trade, amountField);
        let cost = undefined;
        if (price !== undefined) {
            if (amount !== undefined) {
                cost = amount * price;
            }
        }
        return {
            'info': trade,
            'id': id,
            'order': undefined,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': symbol,
            'type': undefined,
            'side': side,
            'takerOrMaker': undefined,
            'price': price,
            'amount': amount,
            'cost': cost,
            'fee': undefined,
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        const market = this.market (symbol);
        const request = {
            'id': market['id'],
        };
        const response = await this.publicGetDataIdTrades (this.extend (request, params));
        return this.parseTrades (response, market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        const request = {
            'type': this.capitalize (type) + 'Order',
            'currency': this.marketId (symbol),
            'direction': side,
            'amount': amount,
        };
        if (type !== 'market') {
            request['price'] = price;
        }
        const response = await this.privatePostUserOrders (this.extend (request, params));
        return {
            'info': response,
            'id': response['uuid'],
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        const request = {
            'UUID': id,
        };
        return await this.privateDeleteUserOrdersUUIDCancel (this.extend (request, params));
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + this.version + '/' + this.implodeParams (path, params);
        const query = this.omit (params, this.extractParams (path));
        if (api === 'public') {
            if (Object.keys (query).length) {
                url += '?' + this.urlencode (query);
            }
        } else {
            this.checkRequiredCredentials ();
            const nonce = this.nonce ().toString ();
            let auth = nonce + url;
            headers = {
                'Api-Key': this.apiKey,
                'Api-Nonce': nonce,
            };
            if (method === 'POST') {
                if (Object.keys (query).length) {
                    body = this.json (query);
                    auth += body;
                    headers['Content-Type'] = 'application/json';
                }
            } else {
                if (Object.keys (query).length) {
                    const queryString = this.urlencode (query);
                    auth += queryString;
                    url += '?' + queryString;
                }
            }
            headers['Api-Signature'] = this.hmac (this.encode (auth), this.encode (this.secret)),
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        const response = await this.fetch2 (path, api, method, params, headers, body);
        if ('errors' in response) {
            throw new ExchangeError (this.id + ' ' + this.json (response));
        }
        return response;
    }
};
<commit_msg>paymium private GET sign minor edit #6763<commit_after>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class paymium extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'paymium',
            'name': 'Paymium',
            'countries': [ 'FR', 'EU' ],
            'rateLimit': 2000,
            'version': 'v1',
            'has': {
                'CORS': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/27790564-a945a9d4-5ff9-11e7-9d2d-b635763f2f24.jpg',
                'api': 'https://paymium.com/api',
                'www': 'https://www.paymium.com',
                'fees': 'https://www.paymium.com/page/help/fees',
                'doc': [
                    'https://github.com/Paymium/api-documentation',
                    'https://www.paymium.com/page/developers',
                ],
            },
            'api': {
                'public': {
                    'get': [
                        'countries',
                        'data/{id}/ticker',
                        'data/{id}/trades',
                        'data/{id}/depth',
                        'bitcoin_charts/{id}/trades',
                        'bitcoin_charts/{id}/depth',
                    ],
                },
                'private': {
                    'get': [
                        'merchant/get_payment/{uuid}',
                        'user',
                        'user/addresses',
                        'user/addresses/{btc_address}',
                        'user/orders',
                        'user/orders/{uuid}',
                        'user/price_alerts',
                    ],
                    'post': [
                        'user/orders',
                        'user/addresses',
                        'user/payment_requests',
                        'user/price_alerts',
                        'merchant/create_payment',
                    ],
                    'delete': [
                        'user/orders/{uuid}/cancel',
                        'user/price_alerts/{id}',
                    ],
                },
            },
            'markets': {
                'BTC/EUR': { 'id': 'eur', 'symbol': 'BTC/EUR', 'base': 'BTC', 'quote': 'EUR', 'baseId': 'btc', 'quoteId': 'eur' },
            },
            'fees': {
                'trading': {
                    'maker': 0.002,
                    'taker': 0.002,
                },
            },
        });
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        const response = await this.privateGetUser (params);
        const result = { 'info': response };
        const currencies = Object.keys (this.currencies);
        for (let i = 0; i < currencies.length; i++) {
            const code = currencies[i];
            const currencyId = this.currencyId (code);
            const free = 'balance_' + currencyId;
            if (free in response) {
                const account = this.account ();
                const used = 'locked_' + currencyId;
                account['free'] = this.safeFloat (response, free);
                account['used'] = this.safeFloat (response, used);
                result[code] = account;
            }
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        const request = {
            'id': this.marketId (symbol),
        };
        const response = await this.publicGetDataIdDepth (this.extend (request, params));
        return this.parseOrderBook (response, undefined, 'bids', 'asks', 'price', 'amount');
    }

    async fetchTicker (symbol, params = {}) {
        const request = {
            'id': this.marketId (symbol),
        };
        const ticker = await this.publicGetDataIdTicker (this.extend (request, params));
        const timestamp = this.safeTimestamp (ticker, 'at');
        const vwap = this.safeFloat (ticker, 'vwap');
        const baseVolume = this.safeFloat (ticker, 'volume');
        let quoteVolume = undefined;
        if (baseVolume !== undefined && vwap !== undefined) {
            quoteVolume = baseVolume * vwap;
        }
        const last = this.safeFloat (ticker, 'price');
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'high'),
            'low': this.safeFloat (ticker, 'low'),
            'bid': this.safeFloat (ticker, 'bid'),
            'bidVolume': undefined,
            'ask': this.safeFloat (ticker, 'ask'),
            'askVolume': undefined,
            'vwap': vwap,
            'open': this.safeFloat (ticker, 'open'),
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': undefined,
            'percentage': this.safeFloat (ticker, 'variation'),
            'average': undefined,
            'baseVolume': baseVolume,
            'quoteVolume': quoteVolume,
            'info': ticker,
        };
    }

    parseTrade (trade, market) {
        const timestamp = this.safeTimestamp (trade, 'created_at_int');
        const id = this.safeString (trade, 'uuid');
        let symbol = undefined;
        if (market !== undefined) {
            symbol = market['symbol'];
        }
        const side = this.safeString (trade, 'side');
        const price = this.safeFloat (trade, 'price');
        const amountField = 'traded_' + market['base'].toLowerCase ();
        const amount = this.safeFloat (trade, amountField);
        let cost = undefined;
        if (price !== undefined) {
            if (amount !== undefined) {
                cost = amount * price;
            }
        }
        return {
            'info': trade,
            'id': id,
            'order': undefined,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': symbol,
            'type': undefined,
            'side': side,
            'takerOrMaker': undefined,
            'price': price,
            'amount': amount,
            'cost': cost,
            'fee': undefined,
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        const market = this.market (symbol);
        const request = {
            'id': market['id'],
        };
        const response = await this.publicGetDataIdTrades (this.extend (request, params));
        return this.parseTrades (response, market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        const request = {
            'type': this.capitalize (type) + 'Order',
            'currency': this.marketId (symbol),
            'direction': side,
            'amount': amount,
        };
        if (type !== 'market') {
            request['price'] = price;
        }
        const response = await this.privatePostUserOrders (this.extend (request, params));
        return {
            'info': response,
            'id': response['uuid'],
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        const request = {
            'UUID': id,
        };
        return await this.privateDeleteUserOrdersUUIDCancel (this.extend (request, params));
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + this.version + '/' + this.implodeParams (path, params);
        const query = this.omit (params, this.extractParams (path));
        if (api === 'public') {
            if (Object.keys (query).length) {
                url += '?' + this.urlencode (query);
            }
        } else {
            this.checkRequiredCredentials ();
            const nonce = this.nonce ().toString ();
            let auth = nonce + url;
            headers = {
                'Api-Key': this.apiKey,
                'Api-Nonce': nonce,
            };
            if (method === 'POST') {
                if (Object.keys (query).length) {
                    body = this.json (query);
                    auth += body;
                    headers['Content-Type'] = 'application/json';
                }
            } else {
                if (Object.keys (query).length) {
                    const queryString = this.urlencode (query);
                    auth += queryString;
                    url += '?' + queryString;
                }
            }
            headers['Api-Signature'] = this.hmac (this.encode (auth), this.encode (this.secret));
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        const response = await this.fetch2 (path, api, method, params, headers, body);
        if ('errors' in response) {
            throw new ExchangeError (this.id + ' ' + this.json (response));
        }
        return response;
    }
};
<|endoftext|>


<commit_before>/*-------------------------------------------------------+
| ICA Event Registration Module                          |
| Copyright (C) 2016 SYSTOPIA                            |
+--------------------------------------------------------+
| This program is released as free software under the    |
| Affero GPL license. You can redistribute it and/or     |
| modify it under the terms of this license which you    |
| can read by viewing the included agpl.txt or online    |
| at www.gnu.org/licenses/agpl.html. Removal of this     |
| copyright header is strictly prohibited without        |
| written permission from the original author(s).        |
+--------------------------------------------------------*/

// General prefill functions
(function($) {
  $(document).ready(function(){

    function setRegistrantBatchName() {
      setBatchName("registrant");
    }

    function setPartnerBatchName() {
      setBatchName("partner");
    }

    function setBatchName(prefix) {
      var title      = $("input[name='submitted[" + prefix + "_formal_title]']").val();
      var first_name = $("input[name='submitted[" + prefix + "_first_name]']").val();
      var last_name  = $("input[name='submitted[" + prefix + "_last_name]']").val();
      var badge_name = title + " " + first_name + " " + last_name;

      $("input[name='submitted[" + prefix + "_badge]']").val(badge_name.trim());
    }

    function setOrganisationBatchName() {
      var organisation_name = $("input[name='submitted[organisation_organization_name]']").val();
      var badge_name = organisation_name.trim().substring(0, 32);
      $("input[name='submitted[registrant_organisation_badge]']").val(badge_name);
    }

    $("input[name='submitted[registrant_formal_title]']").change(setRegistrantBatchName);
    $("input[name='submitted[registrant_first_name]']").change(setRegistrantBatchName);
    $("input[name='submitted[registrant_last_name]']").change(setRegistrantBatchName);
    $("input[name='submitted[partner_formal_title]']").change(setPartnerBatchName);
    $("input[name='submitted[partner_first_name]']").change(setPartnerBatchName);
    $("input[name='submitted[partner_last_name]']").change(setPartnerBatchName);
    $("input[name='submitted[organisation_organization_name]']").change(setOrganisationBatchName);
  });
})(jQuery);

// Matrix prefill functions
(function($) {
  $(document).ready(function(){
    // matrix mapping
    var matrix_triggers = {
      '2': 'registrant_',
      '4': 'registrant_',
      '3': 'registrant_',
      '13': 'partner_',
      '14': 'partner_',
      '15': 'partner_'
    };

    var matrix_index = {
      'registrant_formal_title': 2,
      'registrant_first_name': 4,
      'registrant_last_name': 3,
      'registrant_badge_name': 5,
      'partner_formal_title': 13,
      'partner_first_name': 14,
      'partner_last_name': 15,
      'partner_badge_name': 16,
    };

    function getFieldValue(field_key, row) {
      var index = matrix_index[field_key];
      if (index) {
        var selector = "input[name='submitted[group_registration_table][" + row + "][" + index + "]']";
        console.log("getting " + selector);
        return $(selector).val();
      } else {
        return null;
      }
    }

    function setFieldValue(field_key, row, value) {
      var index = matrix_index[field_key];
      if (index) {
        var selector = "input[name='submitted[group_registration_table][" + row + "][" + index + "]']";
        console.log("setting " + selector + " to " + value);
        $(selector).val(value);
      }
    }

    function processMatrixFieldChange(e) {
      console.log(e.target.name);
      if (e.target.name.match("submitted\\[group_registration_table\\]\\[[\\d+]\\]\\[[\\d+]\\]")) {
        var ids = e.target.name.match("[\\d+]\\]\\[[\\d+]")[0].split("][");
        var row = ids[0];
        var index = ids[1];
        if (matrix_triggers[index]) {
          var prefix = matrix_triggers[index];
          var formal_title = getFieldValue(prefix + 'formal_title', row);
          var first_name   = getFieldValue(prefix + 'first_name', row);
          var last_name    = getFieldValue(prefix + 'last_name', row);

          var badge_name = title + " " + first_name + " " + last_name;
          setFieldValue(prefix + 'badge_name', row, badge_name);
        }
      }
    }
  });
})(jQuery);

<commit_msg>matrix profile fixes<commit_after>/*-------------------------------------------------------+
| ICA Event Registration Module                          |
| Copyright (C) 2016 SYSTOPIA                            |
+--------------------------------------------------------+
| This program is released as free software under the    |
| Affero GPL license. You can redistribute it and/or     |
| modify it under the terms of this license which you    |
| can read by viewing the included agpl.txt or online    |
| at www.gnu.org/licenses/agpl.html. Removal of this     |
| copyright header is strictly prohibited without        |
| written permission from the original author(s).        |
+--------------------------------------------------------*/

// General prefill functions
(function($) {
  $(document).ready(function(){

    function setRegistrantBatchName() {
      setBatchName("registrant");
    }

    function setPartnerBatchName() {
      setBatchName("partner");
    }

    function setBatchName(prefix) {
      var title      = $("input[name='submitted[" + prefix + "_formal_title]']").val();
      var first_name = $("input[name='submitted[" + prefix + "_first_name]']").val();
      var last_name  = $("input[name='submitted[" + prefix + "_last_name]']").val();
      var badge_name = title + " " + first_name + " " + last_name;

      $("input[name='submitted[" + prefix + "_badge]']").val(badge_name.trim());
    }

    function setOrganisationBatchName() {
      var organisation_name = $("input[name='submitted[organisation_organization_name]']").val();
      var badge_name = organisation_name.trim().substring(0, 32);
      $("input[name='submitted[registrant_organisation_badge]']").val(badge_name);
    }

    $("input[name='submitted[registrant_formal_title]']").change(setRegistrantBatchName);
    $("input[name='submitted[registrant_first_name]']").change(setRegistrantBatchName);
    $("input[name='submitted[registrant_last_name]']").change(setRegistrantBatchName);
    $("input[name='submitted[partner_formal_title]']").change(setPartnerBatchName);
    $("input[name='submitted[partner_first_name]']").change(setPartnerBatchName);
    $("input[name='submitted[partner_last_name]']").change(setPartnerBatchName);
    $("input[name='submitted[organisation_organization_name]']").change(setOrganisationBatchName);
  });
})(jQuery);

// Matrix prefill functions
(function($) {
  $(document).ready(function(){
    // matrix mapping
    var matrix_triggers = {
      '2': 'registrant_',
      '4': 'registrant_',
      '3': 'registrant_',
      '13': 'partner_',
      '14': 'partner_',
      '15': 'partner_'
    };

    var matrix_index = {
      'registrant_formal_title': 2,
      'registrant_first_name': 4,
      'registrant_last_name': 3,
      'registrant_badge_name': 5,
      'partner_formal_title': 13,
      'partner_first_name': 14,
      'partner_last_name': 15,
      'partner_badge_name': 16,
    };

    function getFieldValue(field_key, row) {
      var index = matrix_index[field_key];
      if (index) {
        var selector = "input[name='submitted[group_registration_table][" + row + "][" + index + "]']";
        console.log("getting " + selector);
        return $(selector).val();
      } else {
        return null;
      }
    }

    function setFieldValue(field_key, row, value) {
      var index = matrix_index[field_key];
      if (index) {
        var selector = "input[name='submitted[group_registration_table][" + row + "][" + index + "]']";
        console.log("setting " + selector + " to " + value);
        $(selector).val(value);
      }
    }

    function processMatrixFieldChange(e) {
      console.log(e.target.name);
      if (e.target.name.match("submitted\\[group_registration_table\\]\\[[\\d+]\\]\\[[\\d+]\\]")) {
        var ids = e.target.name.match("[\\d+]\\]\\[[\\d+]")[0].split("][");
        var row = ids[0];
        var index = ids[1];
        if (matrix_triggers[index]) {
          var prefix = matrix_triggers[index];
          var formal_title = getFieldValue(prefix + 'formal_title', row);
          var first_name   = getFieldValue(prefix + 'first_name', row);
          var last_name    = getFieldValue(prefix + 'last_name', row);

          var badge_name = title + " " + first_name + " " + last_name;
          setFieldValue(prefix + 'badge_name', row, badge_name);
        }
      }
    }

    // catch ALL change events on table for processing
    $("table[id^=edit-group_registration_table]").change(processMatrixFieldChange);
  });
})(jQuery);

<|endoftext|>


<commit_before>/**
 * Created by Rammer on 21/10/2017.
 */
"use strict";

const PREVIEW_WIDTH = '15px';

let frame = document.createElement('canvas');
frame.style.width = PREVIEW_WIDTH;
frame.style.height = '100%';
frame.style.display = 'block';
frame.style.position = 'fixed';
frame.zIndex = 1000;
frame.style.top = 0;
frame.style.bottom = 0;
frame.style.right = 0;
document.body.appendChild(frame);

let frameContext = frame.getContext('2d');

let updateFrame = () => {
  let clientHeight = document.documentElement.clientHeight;
  let pageHeight = document.documentElement.getBoundingClientRect().height;
  let heightRatio = clientHeight / pageHeight;

  let frameTop = ((window.scrollY * heightRatio) + 0.5) | 0;
  let frameHeight = ((clientHeight * heightRatio) + 0.5) | 0;

  frame.height = clientHeight;
  frameContext.strokeStyle = '#0ff';
  frameContext.strokeRect(1, frameTop, frame.width - 2, frameHeight);
};

let doUpdate = () => {
  updateRequested = false;
  updateFrame();
  // TODO: 21/10/2017 update stripe
};

let updateRequested = false;
let requestUpdate = () => {
  if (!updateRequested) {
    updateRequested = true;
    requestAnimationFrame(doUpdate);
  }
};

window.addEventListener('scroll', requestUpdate);
window.addEventListener('resize', requestUpdate);

let clientHeight = document.documentElement.clientHeight;
let pageHeight = document.documentElement.getBoundingClientRect().height;
let heightRatio = clientHeight / pageHeight;
console.log(clientHeight, pageHeight, heightRatio);
<commit_msg>[add] draw strips in preview sidebar<commit_after>/**
 * Created by Rammer on 21/10/2017.
 */
"use strict";

const PREVIEW_WIDTH = '15px';

let stripe = document.createElement('canvas');
stripe.style.width = PREVIEW_WIDTH;
stripe.style.height = '100%';
stripe.style.display = 'block';
stripe.style.position = 'fixed';
stripe.style.background = '#fff';
stripe.style.borderLeft = "1px solid #ccc";
stripe.zIndex = 1000;
stripe.style.top = 0;
stripe.style.bottom = 0;
stripe.style.right = 0;
document.body.appendChild(stripe);

let stripeContext = stripe.getContext('2d');

let updateStripe = (hlNodes) => {
  let clientHeight = document.documentElement.clientHeight;
  let pageHeight = document.documentElement.getBoundingClientRect().height;
  let heightRatio = clientHeight / pageHeight;
  let scrollY = window.scrollY;

  stripe.height = clientHeight;
  stripeContext.fillStyle = '#f0f';
  let lastMarkY = 0;
  hlNodes.forEach(n => {
    let rect = n.getBoundingClientRect();
    let markY = (((scrollY + rect.top) * heightRatio) + 0.5) | 0;
    if (markY && markY !== lastMarkY) {
      lastMarkY = markY;
      stripeContext.fillRect(0, markY, stripe.width, (((rect.height * heightRatio) + 0.5) | 0) || 1);
    }
  });
};

let frame = document.createElement('canvas');
frame.style.width = PREVIEW_WIDTH;
frame.style.height = '100%';
frame.style.display = 'block';
frame.style.position = 'fixed';
frame.zIndex = 1000;
frame.style.top = 0;
frame.style.bottom = 0;
frame.style.right = 0;
document.body.appendChild(frame);

let frameContext = frame.getContext('2d');

let updateFrame = () => {
  let clientHeight = document.documentElement.clientHeight;
  let pageHeight = document.documentElement.getBoundingClientRect().height;
  let heightRatio = clientHeight / pageHeight;

  let frameTop = ((window.scrollY * heightRatio) + 0.5) | 0;
  let frameHeight = ((clientHeight * heightRatio) + 0.5) | 0;

  frame.height = clientHeight;
  frameContext.strokeStyle = '#0ff';
  frameContext.strokeRect(1, frameTop, frame.width - 2, frameHeight);
};

let doUpdate = () => {
  updateRequested = false;
  updateFrame();
  // TODO: 21/10/2017 update stripe
};

let updateRequested = false;
let requestUpdate = () => {
  if (!updateRequested) {
    updateRequested = true;
    requestAnimationFrame(doUpdate);
  }
};

window.addEventListener('scroll', requestUpdate);
window.addEventListener('resize', requestUpdate);

// for test
let clientHeight = document.documentElement.clientHeight;
let pageHeight = document.documentElement.getBoundingClientRect().height;
let heightRatio = clientHeight / pageHeight;
console.log(clientHeight, pageHeight, heightRatio);

const highlightNodes = document.getElementsByTagName('h4');
updateStripe(Array.from(highlightNodes));
<|endoftext|>


<commit_before>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { InvalidNonce, OrderNotFound, InvalidOrder, InsufficientFunds, AuthenticationError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class qryptos extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'qryptos',
            'name': 'QRYPTOS',
            'countries': [ 'CN', 'TW' ],
            'version': '2',
            'rateLimit': 1000,
            'has': {
                'CORS': false,
                'fetchTickers': true,
                'fetchOrder': true,
                'fetchOrders': true,
                'fetchOpenOrders': true,
                'fetchClosedOrders': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/30953915-b1611dc0-a436-11e7-8947-c95bd5a42086.jpg',
                'api': 'https://api.qryptos.com',
                'www': 'https://www.qryptos.com',
                'doc': [
                    'https://developers.quoine.com',
                    'https://developers.quoine.com/v2',
                ],
                'fees': 'https://qryptos.zendesk.com/hc/en-us/articles/115007858167-Fees',
            },
            'api': {
                'public': {
                    'get': [
                        'products',
                        'products/{id}',
                        'products/{id}/price_levels',
                        'executions',
                        'ir_ladders/{currency}',
                    ],
                },
                'private': {
                    'get': [
                        'accounts/balance',
                        'accounts/main_asset',
                        'crypto_accounts',
                        'executions/me',
                        'fiat_accounts',
                        'loan_bids',
                        'loans',
                        'orders',
                        'orders/{id}',
                        'orders/{id}/trades',
                        'orders/{id}/executions',
                        'trades',
                        'trades/{id}/loans',
                        'trading_accounts',
                        'trading_accounts/{id}',
                    ],
                    'post': [
                        'fiat_accounts',
                        'loan_bids',
                        'orders',
                    ],
                    'put': [
                        'loan_bids/{id}/close',
                        'loans/{id}',
                        'orders/{id}',
                        'orders/{id}/cancel',
                        'trades/{id}',
                        'trades/{id}/close',
                        'trades/close_all',
                        'trading_accounts/{id}',
                    ],
                },
            },
            'skipJsonOnStatusCodes': [401],
            'exceptions': {
                'messages': {
                    'API Authentication failed': AuthenticationError,
                    'Nonce is too small': InvalidNonce,
                    'Order not found': OrderNotFound,
                    'user': {
                        'not_enough_free_balance': InsufficientFunds,
                    },
                    'quantity': {
                        'less_than_order_size': InvalidOrder,
                    },
                },
            },
        });
    }

    async fetchMarkets () {
        let markets = await this.publicGetProducts ();
        let result = [];
        for (let p = 0; p < markets.length; p++) {
            let market = markets[p];
            let id = market['id'].toString ();
            let base = market['base_currency'];
            let quote = market['quoted_currency'];
            let symbol = base + '/' + quote;
            let maker = this.safeFloat (market, 'maker_fee');
            let taker = this.safeFloat (market, 'taker_fee');
            let active = !market['disabled'];
            let minAmount = undefined;
            let minPrice = undefined;
            if (base === 'BTC') {
                minAmount = 0.001;
            } else if (base === 'ETH') {
                minAmount = 0.01;
            }
            if (quote === 'BTC') {
                minPrice = 0.00000001;
            } else if (quote === 'ETH' || quote === 'USD' || quote === 'JPY') {
                minPrice = 0.00001;
            }
            let limits = {
                'amount': { 'min': minAmount },
                'price': { 'min': minPrice },
                'cost': { 'min': undefined },
            };
            if (typeof minPrice !== 'undefined')
                if (typeof minAmount !== 'undefined')
                    limits['cost']['min'] = minPrice * minAmount;
            let precision = {
                'amount': undefined,
                'price': undefined,
            };
            if (typeof minAmount !== 'undefined')
                precision['amount'] = -Math.log10 (minAmount);
            if (typeof minPrice !== 'undefined')
                precision['price'] = -Math.log10 (minPrice);
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'maker': maker,
                'taker': taker,
                'limits': limits,
                'precision': precision,
                'active': active,
                'info': market,
            });
        }
        return result;
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let balances = await this.privateGetAccountsBalance (params);
        let result = { 'info': balances };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let currency = balance['currency'];
            let total = parseFloat (balance['balance']);
            let account = {
                'free': total,
                'used': 0.0,
                'total': total,
            };
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let orderbook = await this.publicGetProductsIdPriceLevels (this.extend ({
            'id': this.marketId (symbol),
        }, params));
        return this.parseOrderBook (orderbook, undefined, 'buy_price_levels', 'sell_price_levels');
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = this.milliseconds ();
        let last = undefined;
        if ('last_traded_price' in ticker) {
            if (ticker['last_traded_price']) {
                let length = ticker['last_traded_price'].length;
                if (length > 0)
                    last = parseFloat (ticker['last_traded_price']);
            }
        }
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'high_market_ask'),
            'low': this.safeFloat (ticker, 'low_market_bid'),
            'bid': this.safeFloat (ticker, 'market_bid'),
            'ask': this.safeFloat (ticker, 'market_ask'),
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': last,
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': this.safeFloat (ticker, 'volume_24h'),
            'quoteVolume': undefined,
            'info': ticker,
        };
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let tickers = await this.publicGetProducts (params);
        let result = {};
        for (let t = 0; t < tickers.length; t++) {
            let ticker = tickers[t];
            let base = ticker['base_currency'];
            let quote = ticker['quoted_currency'];
            let symbol = base + '/' + quote;
            let market = this.markets[symbol];
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let ticker = await this.publicGetProductsId (this.extend ({
            'id': market['id'],
        }, params));
        return this.parseTicker (ticker, market);
    }

    parseTrade (trade, market) {
        let timestamp = trade['created_at'] * 1000;
        return {
            'info': trade,
            'id': trade['id'].toString (),
            'order': undefined,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': trade['taker_side'],
            'price': parseFloat (trade['price']),
            'amount': parseFloat (trade['quantity']),
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {
            'product_id': market['id'],
        };
        if (typeof limit !== 'undefined')
            request['limit'] = limit;
        let response = await this.publicGetExecutions (this.extend (request, params));
        return this.parseTrades (response['models'], market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let order = {
            'order_type': type,
            'product_id': this.marketId (symbol),
            'side': side,
            'quantity': amount,
        };
        if (type === 'limit')
            order['price'] = price;
        let response = await this.privatePostOrders (this.extend (order, params));
        return this.parseOrder (response);
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let result = await this.privatePutOrdersIdCancel (this.extend ({
            'id': id,
        }, params));
        let order = this.parseOrder (result);
        if (order['status'] === 'closed')
            throw new OrderNotFound (this.id + ' ' + this.json (order));
        return order;
    }

    parseOrder (order, market = undefined) {
        let timestamp = order['created_at'] * 1000;
        let marketId = this.safeString (order, 'product_id');
        if (typeof marketId !== 'undefined') {
            if (marketId in this.markets_by_id)
                market = this.markets_by_id[market];
        }
        let status = undefined;
        if ('status' in order) {
            if (order['status'] === 'live') {
                status = 'open';
            } else if (order['status'] === 'filled') {
                status = 'closed';
            } else if (order['status'] === 'cancelled') { // 'll' intended
                status = 'canceled';
            }
        }
        let amount = parseFloat (order['quantity']);
        let filled = parseFloat (order['filled_quantity']);
        let price = parseFloat (order['price']);
        let symbol = undefined;
        if (market) {
            symbol = market['symbol'];
        }
        return {
            'id': order['id'].toString (),
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'type': order['order_type'],
            'status': status,
            'symbol': symbol,
            'side': order['side'],
            'price': price,
            'amount': amount,
            'filled': filled,
            'remaining': amount - filled,
            'trades': undefined,
            'fee': {
                'currency': undefined,
                'cost': parseFloat (order['order_fee']),
            },
            'info': order,
        };
    }

    async fetchOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let order = await this.privateGetOrdersId (this.extend ({
            'id': id,
        }, params));
        return this.parseOrder (order);
    }

    async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = undefined;
        let request = {};
        if (symbol) {
            market = this.market (symbol);
            request['product_id'] = market['id'];
        }
        let status = this.safeValue (params, 'status');
        if (status) {
            params = this.omit (params, 'status');
            if (status === 'open') {
                request['status'] = 'live';
            } else if (status === 'closed') {
                request['status'] = 'filled';
            } else if (status === 'canceled') {
                request['status'] = 'cancelled';
            }
        }
        let result = await this.privateGetOrders (this.extend (request, params));
        let orders = result['models'];
        return this.parseOrders (orders, market, since, limit);
    }

    fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        return this.fetchOrders (symbol, since, limit, this.extend ({ 'status': 'open' }, params));
    }

    fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        return this.fetchOrders (symbol, since, limit, this.extend ({ 'status': 'closed' }, params));
    }

    nonce () {
        return this.milliseconds ();
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = '/' + this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        headers = {
            'X-Quoine-API-Version': this.version,
            'Content-Type': 'application/json',
        };
        if (api === 'public') {
            if (Object.keys (query).length)
                url += '?' + this.urlencode (query);
        } else {
            this.checkRequiredCredentials ();
            if (method === 'GET') {
                if (Object.keys (query).length)
                    url += '?' + this.urlencode (query);
            } else if (Object.keys (query).length) {
                body = this.json (query);
            }
            let nonce = this.nonce ();
            let request = {
                'path': url,
                'nonce': nonce,
                'token_id': this.apiKey,
                'iat': Math.floor (nonce / 1000), // issued at
            };
            headers['X-Quoine-Auth'] = this.jwt (request, this.secret);
        }
        url = this.urls['api'] + url;
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    handleErrors (code, reason, url, method, headers, body, response = undefined) {
        if (code >= 200 && code <= 299)
            return;
        const messages = this.exceptions['messages'];
        if (code === 401) {
            // expected non-json response
            if (body in messages)
                throw new messages[body] (this.id + ' ' + body);
            else
                return;
        }
        if (typeof response === 'undefined')
            if ((body[0] === '{') || (body[0] === '['))
                response = JSON.parse (body);
            else
                return;
        const feedback = this.id + ' ' + this.json (response);
        if (code === 404) {
            // { "message": "Order not found" }
            const message = this.safeString (response, 'message');
            if (message in messages)
                throw new messages[message] (feedback);
        } else if (code === 422) {
            // array of error messages is returned in 'user' or 'quantity' property of 'errors' object, e.g.:
            // { "errors": { "user": ["not_enough_free_balance"] }}
            // { "errors": { "quantity": ["less_than_order_size"] }}
            if ('errors' in response) {
                const errors = response['errors'];
                const errorTypes = ['user', 'quantity'];
                for (let i = 0; i < errorTypes.length; i++) {
                    const errorType = errorTypes[i];
                    if (errorType in errors) {
                        const errorMessages = errors[errorType];
                        for (let j = 0; j < errorMessages.length; j++) {
                            const message = errorMessages[j];
                            if (message in messages[errorType])
                                throw new messages[errorType][message] (feedback);
                        }
                    }
                }
            }
        }
    }
};
<commit_msg>a fix for a fix for qryptos #1876<commit_after>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { InvalidNonce, OrderNotFound, InvalidOrder, InsufficientFunds, AuthenticationError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class qryptos extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'qryptos',
            'name': 'QRYPTOS',
            'countries': [ 'CN', 'TW' ],
            'version': '2',
            'rateLimit': 1000,
            'has': {
                'CORS': false,
                'fetchTickers': true,
                'fetchOrder': true,
                'fetchOrders': true,
                'fetchOpenOrders': true,
                'fetchClosedOrders': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/30953915-b1611dc0-a436-11e7-8947-c95bd5a42086.jpg',
                'api': 'https://api.qryptos.com',
                'www': 'https://www.qryptos.com',
                'doc': [
                    'https://developers.quoine.com',
                    'https://developers.quoine.com/v2',
                ],
                'fees': 'https://qryptos.zendesk.com/hc/en-us/articles/115007858167-Fees',
            },
            'api': {
                'public': {
                    'get': [
                        'products',
                        'products/{id}',
                        'products/{id}/price_levels',
                        'executions',
                        'ir_ladders/{currency}',
                    ],
                },
                'private': {
                    'get': [
                        'accounts/balance',
                        'accounts/main_asset',
                        'crypto_accounts',
                        'executions/me',
                        'fiat_accounts',
                        'loan_bids',
                        'loans',
                        'orders',
                        'orders/{id}',
                        'orders/{id}/trades',
                        'orders/{id}/executions',
                        'trades',
                        'trades/{id}/loans',
                        'trading_accounts',
                        'trading_accounts/{id}',
                    ],
                    'post': [
                        'fiat_accounts',
                        'loan_bids',
                        'orders',
                    ],
                    'put': [
                        'loan_bids/{id}/close',
                        'loans/{id}',
                        'orders/{id}',
                        'orders/{id}/cancel',
                        'trades/{id}',
                        'trades/{id}/close',
                        'trades/close_all',
                        'trading_accounts/{id}',
                    ],
                },
            },
            'skipJsonOnStatusCodes': [401],
            'exceptions': {
                'messages': {
                    'API Authentication failed': AuthenticationError,
                    'Nonce is too small': InvalidNonce,
                    'Order not found': OrderNotFound,
                    'user': {
                        'not_enough_free_balance': InsufficientFunds,
                    },
                    'quantity': {
                        'less_than_order_size': InvalidOrder,
                    },
                },
            },
        });
    }

    async fetchMarkets () {
        let markets = await this.publicGetProducts ();
        let result = [];
        for (let p = 0; p < markets.length; p++) {
            let market = markets[p];
            let id = market['id'].toString ();
            let base = market['base_currency'];
            let quote = market['quoted_currency'];
            let symbol = base + '/' + quote;
            let maker = this.safeFloat (market, 'maker_fee');
            let taker = this.safeFloat (market, 'taker_fee');
            let active = !market['disabled'];
            let minAmount = undefined;
            let minPrice = undefined;
            if (base === 'BTC') {
                minAmount = 0.001;
            } else if (base === 'ETH') {
                minAmount = 0.01;
            }
            if (quote === 'BTC') {
                minPrice = 0.00000001;
            } else if (quote === 'ETH' || quote === 'USD' || quote === 'JPY') {
                minPrice = 0.00001;
            }
            let limits = {
                'amount': { 'min': minAmount },
                'price': { 'min': minPrice },
                'cost': { 'min': undefined },
            };
            if (typeof minPrice !== 'undefined')
                if (typeof minAmount !== 'undefined')
                    limits['cost']['min'] = minPrice * minAmount;
            let precision = {
                'amount': undefined,
                'price': undefined,
            };
            if (typeof minAmount !== 'undefined')
                precision['amount'] = -Math.log10 (minAmount);
            if (typeof minPrice !== 'undefined')
                precision['price'] = -Math.log10 (minPrice);
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'maker': maker,
                'taker': taker,
                'limits': limits,
                'precision': precision,
                'active': active,
                'info': market,
            });
        }
        return result;
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let balances = await this.privateGetAccountsBalance (params);
        let result = { 'info': balances };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let currency = balance['currency'];
            let total = parseFloat (balance['balance']);
            let account = {
                'free': total,
                'used': 0.0,
                'total': total,
            };
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let orderbook = await this.publicGetProductsIdPriceLevels (this.extend ({
            'id': this.marketId (symbol),
        }, params));
        return this.parseOrderBook (orderbook, undefined, 'buy_price_levels', 'sell_price_levels');
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = this.milliseconds ();
        let last = undefined;
        if ('last_traded_price' in ticker) {
            if (ticker['last_traded_price']) {
                let length = ticker['last_traded_price'].length;
                if (length > 0)
                    last = parseFloat (ticker['last_traded_price']);
            }
        }
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'high_market_ask'),
            'low': this.safeFloat (ticker, 'low_market_bid'),
            'bid': this.safeFloat (ticker, 'market_bid'),
            'ask': this.safeFloat (ticker, 'market_ask'),
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': last,
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': this.safeFloat (ticker, 'volume_24h'),
            'quoteVolume': undefined,
            'info': ticker,
        };
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let tickers = await this.publicGetProducts (params);
        let result = {};
        for (let t = 0; t < tickers.length; t++) {
            let ticker = tickers[t];
            let base = ticker['base_currency'];
            let quote = ticker['quoted_currency'];
            let symbol = base + '/' + quote;
            let market = this.markets[symbol];
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let ticker = await this.publicGetProductsId (this.extend ({
            'id': market['id'],
        }, params));
        return this.parseTicker (ticker, market);
    }

    parseTrade (trade, market) {
        let timestamp = trade['created_at'] * 1000;
        return {
            'info': trade,
            'id': trade['id'].toString (),
            'order': undefined,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': trade['taker_side'],
            'price': parseFloat (trade['price']),
            'amount': parseFloat (trade['quantity']),
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {
            'product_id': market['id'],
        };
        if (typeof limit !== 'undefined')
            request['limit'] = limit;
        let response = await this.publicGetExecutions (this.extend (request, params));
        return this.parseTrades (response['models'], market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let order = {
            'order_type': type,
            'product_id': this.marketId (symbol),
            'side': side,
            'quantity': amount,
        };
        if (type === 'limit')
            order['price'] = price;
        let response = await this.privatePostOrders (this.extend (order, params));
        return this.parseOrder (response);
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let result = await this.privatePutOrdersIdCancel (this.extend ({
            'id': id,
        }, params));
        let order = this.parseOrder (result);
        if (order['status'] === 'closed')
            throw new OrderNotFound (this.id + ' ' + this.json (order));
        return order;
    }

    parseOrder (order, market = undefined) {
        let timestamp = order['created_at'] * 1000;
        let marketId = this.safeString (order, 'product_id');
        if (typeof marketId !== 'undefined') {
            if (marketId in this.markets_by_id)
                market = this.markets_by_id[marketId];
        }
        let status = undefined;
        if ('status' in order) {
            if (order['status'] === 'live') {
                status = 'open';
            } else if (order['status'] === 'filled') {
                status = 'closed';
            } else if (order['status'] === 'cancelled') { // 'll' intended
                status = 'canceled';
            }
        }
        let amount = parseFloat (order['quantity']);
        let filled = parseFloat (order['filled_quantity']);
        let price = parseFloat (order['price']);
        let symbol = undefined;
        if (market) {
            symbol = market['symbol'];
        }
        return {
            'id': order['id'].toString (),
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'type': order['order_type'],
            'status': status,
            'symbol': symbol,
            'side': order['side'],
            'price': price,
            'amount': amount,
            'filled': filled,
            'remaining': amount - filled,
            'trades': undefined,
            'fee': {
                'currency': undefined,
                'cost': parseFloat (order['order_fee']),
            },
            'info': order,
        };
    }

    async fetchOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let order = await this.privateGetOrdersId (this.extend ({
            'id': id,
        }, params));
        return this.parseOrder (order);
    }

    async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = undefined;
        let request = {};
        if (symbol) {
            market = this.market (symbol);
            request['product_id'] = market['id'];
        }
        let status = this.safeValue (params, 'status');
        if (status) {
            params = this.omit (params, 'status');
            if (status === 'open') {
                request['status'] = 'live';
            } else if (status === 'closed') {
                request['status'] = 'filled';
            } else if (status === 'canceled') {
                request['status'] = 'cancelled';
            }
        }
        let result = await this.privateGetOrders (this.extend (request, params));
        let orders = result['models'];
        return this.parseOrders (orders, market, since, limit);
    }

    fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        return this.fetchOrders (symbol, since, limit, this.extend ({ 'status': 'open' }, params));
    }

    fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        return this.fetchOrders (symbol, since, limit, this.extend ({ 'status': 'closed' }, params));
    }

    nonce () {
        return this.milliseconds ();
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = '/' + this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        headers = {
            'X-Quoine-API-Version': this.version,
            'Content-Type': 'application/json',
        };
        if (api === 'public') {
            if (Object.keys (query).length)
                url += '?' + this.urlencode (query);
        } else {
            this.checkRequiredCredentials ();
            if (method === 'GET') {
                if (Object.keys (query).length)
                    url += '?' + this.urlencode (query);
            } else if (Object.keys (query).length) {
                body = this.json (query);
            }
            let nonce = this.nonce ();
            let request = {
                'path': url,
                'nonce': nonce,
                'token_id': this.apiKey,
                'iat': Math.floor (nonce / 1000), // issued at
            };
            headers['X-Quoine-Auth'] = this.jwt (request, this.secret);
        }
        url = this.urls['api'] + url;
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    handleErrors (code, reason, url, method, headers, body, response = undefined) {
        if (code >= 200 && code <= 299)
            return;
        const messages = this.exceptions['messages'];
        if (code === 401) {
            // expected non-json response
            if (body in messages)
                throw new messages[body] (this.id + ' ' + body);
            else
                return;
        }
        if (typeof response === 'undefined')
            if ((body[0] === '{') || (body[0] === '['))
                response = JSON.parse (body);
            else
                return;
        const feedback = this.id + ' ' + this.json (response);
        if (code === 404) {
            // { "message": "Order not found" }
            const message = this.safeString (response, 'message');
            if (message in messages)
                throw new messages[message] (feedback);
        } else if (code === 422) {
            // array of error messages is returned in 'user' or 'quantity' property of 'errors' object, e.g.:
            // { "errors": { "user": ["not_enough_free_balance"] }}
            // { "errors": { "quantity": ["less_than_order_size"] }}
            if ('errors' in response) {
                const errors = response['errors'];
                const errorTypes = ['user', 'quantity'];
                for (let i = 0; i < errorTypes.length; i++) {
                    const errorType = errorTypes[i];
                    if (errorType in errors) {
                        const errorMessages = errors[errorType];
                        for (let j = 0; j < errorMessages.length; j++) {
                            const message = errorMessages[j];
                            if (message in messages[errorType])
                                throw new messages[errorType][message] (feedback);
                        }
                    }
                }
            }
        }
    }
};
<|endoftext|>


<commit_before>'use strict'
/**
 * A Super Lightweight promise/A+ implementation
 * @author: Draucpid
 */

let isFun = a => typeof a === 'function'
let isObj = a => a && typeof a === 'object'

let $nextTick = typeof process === 'object' ? process.nextTick : setTimeout

const STATE = {
  PENDING: 0,
  FULFILLED: 2,
  REJECTED: 4
}

let ensureCallOn = function (tobe, msg) {
  if (this !== tobe) {
    throw new TypeError(msg)
  }
}

let ensureCallAs = function (superclass, msg) {
  if (this.constructor !== superclass) {
    throw new TypeError(msg)
  }
};

(function (root, factory) {
  if (typeof module === 'object' && typeof module.exports === 'object') {
    module.exports = factory(root)
  } else if (typeof define === 'function' && define.amd) {
    define('light-promise', [], () => factory(root))
  } else {
    root.Promise != null && (root.Promise = factory(root))
  }
})(this, function (root) {
  // 2.3 The Promise Resolution Procedure
  let resolveX = function (promise, x) {
    // 2.3.1 If promise and x refer to the same object, reject promise with a TypeError as the reason
    if (promise === x) {
      promise._fireReject(new TypeError())
      // 2.3.2 If x is a promise, adopt its state:
    } else if (x instanceof Promise) {
      switch (x.state) {
        // 2.3.2.1 If x is pending, promise must remain pending until x is fulfilled or rejected.
        case STATE.PENDING:
          x.then(promise.resolve, promise.reject)
          break
        // 2.3.2.2 If/when x is fulfilled, fulfill promise with the same value.
        case STATE.FULFILLED:
          promise._fireResolve(x.value)
          break
        // 2.3.2.3 If/when x is rejected, reject promise with the same reason.
        case STATE.REJECTED:
          promise._fireReject(x.reason)
          break
      }
      // 2.3.3 Otherwise, if x is an object or function,
    } else if (isObj(x) || isFun(x)) {
      // 2.3.3.1 Let then be x.then.
      try {
        var xThen = x.then
      } catch (e) {
        // 2.3.3.2 If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason.
        promise._fireReject(e)
        return
      }

      // 2.3.3.3 If then is a function, call it with x as this, first argument resolvePromise,
      // and second argument rejectPromise, where:
      if (isFun(xThen)) {
        // 2.3.3.3.1 If/when resolvePromise is called with a value y, run [[Resolve]](promise, y).
        // 2.3.3.3.2 If/when rejectPromise is called with a reason r, reject promise with r.
        // 2.3.3.3.3 If both resolvePromise and rejectPromise are called,
        //           or multiple calls to the same argument are made,
        //           the first call takes precedence, and any further calls are ignored.
        let called = false
        let resolvePromise = function (y) {
          if (!called) {
            called = true
            resolveX(promise, y)
          }
        }
        let rejectPromise = function (r) {
          if (!called) {
            called = true
            promise._fireReject(r)
          }
        }

        try {
          return xThen.call(x, resolvePromise, rejectPromise)
        } catch (e) { // 2.3.3.3.4 If calling then throws an exception e,
          // 2.3.3.3.4.1 If resolvePromise or rejectPromise have been called, ignore it.
          // 2.3.3.3.4.2 Otherwise, reject promise with e as the reason.
          if (!called) {
            promise._fireReject(e)
          }
        }
      } else {
        // 2.3.3.4 If then is not a function, fulfill promise with x.
        promise._fireResolve(x)
      }
    } else {
      // 2.3.4 If x is not an object or function, fulfill promise with x.
      promise._fireResolve(x)
    }
  }

  class Promise {
    constructor (executor) {
      if (executor && !isFun(executor)) {
        throw new TypeError('executor must be a function')
      }

      if (this.state != null) {
        throw new TypeError('promise create error')
      }

      this.state = STATE.PENDING
      this.onFulfilled = []
      this.onRejected = []
      this.onFulfilled.num = this.onRejected.num = 0
      this.resolve = this.resolve.bind(this)
      this.reject = this.reject.bind(this)

      try {
        executor && executor(this.resolve, this.reject)
      } catch (e) {
        this.reject(e)
      }
      return this
    }

    then (onFulfilled, onRejected) {
      ensureCallAs.call(this, Promise, 'then should be called on a promise object')
      let next = new Promise()

      $nextTick(() => {
        if (isFun(onFulfilled)) {
          this.onFulfilled.num += 1
          this.onFulfilled.push({fun: onFulfilled, next})
        } else {
          this.onFulfilled.push({fun: null, next})
        }

        if (isFun(onRejected)) {
          this.onRejected.num += 1
          this.onRejected.push({fun: onRejected, next})
        } else {
          this.onRejected.push({fun: null, next})
        }

        switch (this.state) {
          case STATE.FULFILLED:
            this._fireResolve(this.value)
            break
          case STATE.REJECTED:
            this._fireReject(this.reason)
            break
        }
      })
      return next
    }

    catch (onRejected) {
      return this.then(null, onRejected)
    }

    resolve (value) {
      if (this.state !== STATE.FULFILLED) { resolveX(this, value) }
      return this
    }

    reject (reason) {
      if (this.state !== STATE.REJECTED) { this._fireReject(reason) }
      return this
    }

    _fireResolve (value) {
      this.value = value
      this.state = STATE.FULFILLED
      $nextTick(() => {
        let _onFulfilled = [].concat(this.onFulfilled)
        if (this.onFulfilled.num) {
          this.onFulfilled.length = 0
          this.onFulfilled.num = 0
          for (let i = 0; i < _onFulfilled.length; i++) {
            let ful = _onFulfilled[i]
            let {fun, next} = ful
            if (!fun) { return }
            try {
              let rs = fun(this.value)
              next && resolveX(next, rs)
            } catch (e) {
              next.reject(e)
            }
          }
        } else {
          this.onFulfilled.length = 0
          for (let j = 0; j < _onFulfilled.length; j++) {
            var ful = _onFulfilled[j]
            ful.next.resolve(this.value)
          }
        }
      })
    }

    _fireReject (reason) {
      this.reason = reason
      this.state = STATE.REJECTED
      $nextTick(() => {
        let _onRejected = [].concat(this.onRejected)
        if (this.onRejected.num) {
          this.onRejected.length = 0
          this.onRejected.num = 0
          for (let i = 0; i < _onRejected.length; i++) {
            let rej = _onRejected[i]
            let {fun, next} = rej
            if (!fun) { return }
            try {
              let rs = fun(this.reason)
              next && resolveX(next, rs)
            } catch (e) {
              next.reject(e)
            }
          }
        } else {
          this.onRejected.length = 0
          for (let j = 0; j < _onRejected.length; j++) {
            var rej = _onRejected[j]
            rej.next.reject(this.reason)
          }
        }
      }, 0)
    }

    static resolve (value) {
      ensureCallOn.call(this, Promise, 'Promise.resolve should be called on Promise')
      if (value instanceof Promise && value.constructor === this) {
        return value
      }
      return new Promise().resolve(value)
    }

    static reject (reason) {
      ensureCallOn.call(this, Promise, 'Promise.reject should be called on Promise')
      return new Promise().reject(reason)
    }

    static all (promises) {
      ensureCallOn.call(this, Promise, 'Promise.all should be called on Promise')
      if (!Array.isArray(promises)) {
        return Promise.reject(new TypeError('Promise.all only receive an array'))
      }
      if (promises.length === 0) {
        return Promise.resolve([])
      }

      return new Promise(function (resolve, reject) {
        let result = new Array(promises.length)
        let finish = 0
        let done = false
        for (let i = 0; i < promises.length; i++) {
          let cur = promises[i];
          (i =>
            cur.then(rs => {
              if (!done) {
                result[i] = rs
                if (++finish === promises.length) {
                  done = true
                  resolve(result)
                }
              }
            }, err => {
              if (!done) {
                done = true
                reject(err)
              }
            }))(i)
        }
      })
    }

    static race (promises) {
      ensureCallOn.call(this, Promise, 'Promise.race should be called on Promise')
      if (!Array.isArray(promises)) {
        return Promise.reject(new TypeError('Promise.race only receive an array'))
      }
      return new Promise(function (resolve, reject) {
        let done = false
        for (let i = 0; i < promises.length; i++) {
          let cur = promises[i]
          switch (cur.state) {
            case STATE.FULFILLED:
              return resolve(cur.value)
            case STATE.REJECTED:
              return reject(cur.reason)
          }
          cur.then((rs) => {
            if (!done) {
              done = true
              resolve(rs)
            }
          }, (err) => {
            if (!done) {
              done = true
              reject(err)
            }
          })
        }
      })
    }
  }
  return Promise
})
<commit_msg>revert debug code<commit_after>'use strict'
/**
 * A Super Lightweight promise/A+ implementation
 * @author: Draucpid
 */

let isFun = a => typeof a === 'function'
let isObj = a => a && typeof a === 'object'

let $nextTick = typeof process === 'object' ? process.nextTick : setTimeout

const STATE = {
  PENDING: 0,
  FULFILLED: 2,
  REJECTED: 4
}

let ensureCallOn = function (tobe, msg) {
  if (this !== tobe) {
    throw new TypeError(msg)
  }
}

let ensureCallAs = function (superclass, msg) {
  if (this.constructor !== superclass) {
    throw new TypeError(msg)
  }
};

(function (root, factory) {
  if (typeof module === 'object' && typeof module.exports === 'object') {
    module.exports = factory(root)
  } else if (typeof define === 'function' && define.amd) {
    define('light-promise', [], () => factory(root))
  } else {
    root.Promise == null && (root.Promise = factory(root))
  }
})(this, function (root) {
  // 2.3 The Promise Resolution Procedure
  let resolveX = function (promise, x) {
    // 2.3.1 If promise and x refer to the same object, reject promise with a TypeError as the reason
    if (promise === x) {
      promise._fireReject(new TypeError())
      // 2.3.2 If x is a promise, adopt its state:
    } else if (x instanceof Promise) {
      switch (x.state) {
        // 2.3.2.1 If x is pending, promise must remain pending until x is fulfilled or rejected.
        case STATE.PENDING:
          x.then(promise.resolve, promise.reject)
          break
        // 2.3.2.2 If/when x is fulfilled, fulfill promise with the same value.
        case STATE.FULFILLED:
          promise._fireResolve(x.value)
          break
        // 2.3.2.3 If/when x is rejected, reject promise with the same reason.
        case STATE.REJECTED:
          promise._fireReject(x.reason)
          break
      }
      // 2.3.3 Otherwise, if x is an object or function,
    } else if (isObj(x) || isFun(x)) {
      // 2.3.3.1 Let then be x.then.
      try {
        var xThen = x.then
      } catch (e) {
        // 2.3.3.2 If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason.
        promise._fireReject(e)
        return
      }

      // 2.3.3.3 If then is a function, call it with x as this, first argument resolvePromise,
      // and second argument rejectPromise, where:
      if (isFun(xThen)) {
        // 2.3.3.3.1 If/when resolvePromise is called with a value y, run [[Resolve]](promise, y).
        // 2.3.3.3.2 If/when rejectPromise is called with a reason r, reject promise with r.
        // 2.3.3.3.3 If both resolvePromise and rejectPromise are called,
        //           or multiple calls to the same argument are made,
        //           the first call takes precedence, and any further calls are ignored.
        let called = false
        let resolvePromise = function (y) {
          if (!called) {
            called = true
            resolveX(promise, y)
          }
        }
        let rejectPromise = function (r) {
          if (!called) {
            called = true
            promise._fireReject(r)
          }
        }

        try {
          return xThen.call(x, resolvePromise, rejectPromise)
        } catch (e) { // 2.3.3.3.4 If calling then throws an exception e,
          // 2.3.3.3.4.1 If resolvePromise or rejectPromise have been called, ignore it.
          // 2.3.3.3.4.2 Otherwise, reject promise with e as the reason.
          if (!called) {
            promise._fireReject(e)
          }
        }
      } else {
        // 2.3.3.4 If then is not a function, fulfill promise with x.
        promise._fireResolve(x)
      }
    } else {
      // 2.3.4 If x is not an object or function, fulfill promise with x.
      promise._fireResolve(x)
    }
  }

  class Promise {
    constructor (executor) {
      if (executor && !isFun(executor)) {
        throw new TypeError('executor must be a function')
      }

      if (this.state != null) {
        throw new TypeError('promise create error')
      }

      this.state = STATE.PENDING
      this.onFulfilled = []
      this.onRejected = []
      this.onFulfilled.num = this.onRejected.num = 0
      this.resolve = this.resolve.bind(this)
      this.reject = this.reject.bind(this)

      try {
        executor && executor(this.resolve, this.reject)
      } catch (e) {
        this.reject(e)
      }
      return this
    }

    then (onFulfilled, onRejected) {
      ensureCallAs.call(this, Promise, 'then should be called on a promise object')
      let next = new Promise()

      $nextTick(() => {
        if (isFun(onFulfilled)) {
          this.onFulfilled.num += 1
          this.onFulfilled.push({fun: onFulfilled, next})
        } else {
          this.onFulfilled.push({fun: null, next})
        }

        if (isFun(onRejected)) {
          this.onRejected.num += 1
          this.onRejected.push({fun: onRejected, next})
        } else {
          this.onRejected.push({fun: null, next})
        }

        switch (this.state) {
          case STATE.FULFILLED:
            this._fireResolve(this.value)
            break
          case STATE.REJECTED:
            this._fireReject(this.reason)
            break
        }
      })
      return next
    }

    catch (onRejected) {
      return this.then(null, onRejected)
    }

    resolve (value) {
      if (this.state !== STATE.FULFILLED) { resolveX(this, value) }
      return this
    }

    reject (reason) {
      if (this.state !== STATE.REJECTED) { this._fireReject(reason) }
      return this
    }

    _fireResolve (value) {
      this.value = value
      this.state = STATE.FULFILLED
      $nextTick(() => {
        let _onFulfilled = [].concat(this.onFulfilled)
        if (this.onFulfilled.num) {
          this.onFulfilled.length = 0
          this.onFulfilled.num = 0
          for (let i = 0; i < _onFulfilled.length; i++) {
            let ful = _onFulfilled[i]
            let {fun, next} = ful
            if (!fun) { return }
            try {
              let rs = fun(this.value)
              next && resolveX(next, rs)
            } catch (e) {
              next.reject(e)
            }
          }
        } else {
          this.onFulfilled.length = 0
          for (let j = 0; j < _onFulfilled.length; j++) {
            var ful = _onFulfilled[j]
            ful.next.resolve(this.value)
          }
        }
      })
    }

    _fireReject (reason) {
      this.reason = reason
      this.state = STATE.REJECTED
      $nextTick(() => {
        let _onRejected = [].concat(this.onRejected)
        if (this.onRejected.num) {
          this.onRejected.length = 0
          this.onRejected.num = 0
          for (let i = 0; i < _onRejected.length; i++) {
            let rej = _onRejected[i]
            let {fun, next} = rej
            if (!fun) { return }
            try {
              let rs = fun(this.reason)
              next && resolveX(next, rs)
            } catch (e) {
              next.reject(e)
            }
          }
        } else {
          this.onRejected.length = 0
          for (let j = 0; j < _onRejected.length; j++) {
            var rej = _onRejected[j]
            rej.next.reject(this.reason)
          }
        }
      }, 0)
    }

    static resolve (value) {
      ensureCallOn.call(this, Promise, 'Promise.resolve should be called on Promise')
      if (value instanceof Promise && value.constructor === this) {
        return value
      }
      return new Promise().resolve(value)
    }

    static reject (reason) {
      ensureCallOn.call(this, Promise, 'Promise.reject should be called on Promise')
      return new Promise().reject(reason)
    }

    static all (promises) {
      ensureCallOn.call(this, Promise, 'Promise.all should be called on Promise')
      if (!Array.isArray(promises)) {
        return Promise.reject(new TypeError('Promise.all only receive an array'))
      }
      if (promises.length === 0) {
        return Promise.resolve([])
      }

      return new Promise(function (resolve, reject) {
        let result = new Array(promises.length)
        let finish = 0
        let done = false
        for (let i = 0; i < promises.length; i++) {
          let cur = promises[i];
          (i =>
            cur.then(rs => {
              if (!done) {
                result[i] = rs
                if (++finish === promises.length) {
                  done = true
                  resolve(result)
                }
              }
            }, err => {
              if (!done) {
                done = true
                reject(err)
              }
            }))(i)
        }
      })
    }

    static race (promises) {
      ensureCallOn.call(this, Promise, 'Promise.race should be called on Promise')
      if (!Array.isArray(promises)) {
        return Promise.reject(new TypeError('Promise.race only receive an array'))
      }
      return new Promise(function (resolve, reject) {
        let done = false
        for (let i = 0; i < promises.length; i++) {
          let cur = promises[i]
          switch (cur.state) {
            case STATE.FULFILLED:
              return resolve(cur.value)
            case STATE.REJECTED:
              return reject(cur.reason)
          }
          cur.then((rs) => {
            if (!done) {
              done = true
              resolve(rs)
            }
          }, (err) => {
            if (!done) {
              done = true
              reject(err)
            }
          })
        }
      })
    }
  }
  return Promise
})
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

foam.CLASS({
  name: 'Something',

  requires: [
    'foam.util.Timer'
  ],

  properties: [
    {
      name: 'value',
      value: 'aaaa'
    },
    {
      name: 'timer',
      factory: function() {
        return this.Timer.create();
      }
    }
  ],

  methods: [
    function init() {
      this.timer.start();
      this.timer.propertyChange.sub('second', this.onTimer);
    }
  ],

  listeners: [
    function onTimer() {
      this.value = this.value === 'aaaa' ? 'bbbb' : 'aaaa';
    }
  ]
});

var timer = foam.util.Timer.create();
timer.start();

var E = foam.__context__.E.bind(foam.__context__);

E('b').add(
  'bold',
  E('br'),
  'HTML Injection Attempt',
  E('br')
);

E().
  add('Entities: ').
  add('foo').
  nbsp().
  entity('amp').
  add(' bar ').
  entity('lt').
  entity('quot').
  entity("#039").
  tag('br').
  write();

E('b').add(
  'color: ',
  E('font').attrs({color: 'red'}).add('red', E('br'))).write();

var e = E('font').add('click me', E('br'));
console.log('id: ', e.id);
e.write();
e.attrs({color: 'orange'}).
  style({
    fontWeight: 'bold',
    fontSize:  '24pt'
  }).
  on('click', function() { console.log('clicked'); });

var e13 = E('div').add(
  'dynamic function: ',
  foam.core.ExpressionSlot.create({
    args: [ timer.second$ ],
    fn: function(s) {
      return s % 2 ?
        E('span').add('PI', 'NG').style({color: 'aqua'}) :
        E('span').add('PONG').style({color: 'orange'});
    }
  }),
  E('br'),
  'dynamic value: ', timer.i$,
  E('br'));
e13.write();

var e2 = E('font').add('on click (before)', E('br')).on('click', function() { console.log('clicked, before'); });
e2.write();

var e2b = E('font').add('on click (after)');
e2b.write();
e2b.on('click', function() { console.log('clicked, after'); });

E('br').write();

var e3 = E('div').add('first line, added before');
e3.write();
e3.add(E('br'),'second line, added after', E('br'));

E('div').add('add style before').style({color: 'blue'}).write();

var e5 = E('div').add('add style after');
e5.write();
e5.style({color: 'blue'});

E('br').write();

E('div').add('add class before').cssClass('important').write();

var e7 = E('div').add('add class after');
e7.write();
e7.cssClass('important');

E('font').add(E('br'), 'set attr before').attrs({color: 'blue'}).write();

var e11 = E('font').add(E('br'), 'set attr after', E('br'));
e11.write();
e11.attrs({color: 'blue'});

 var e = E('div').add(
   E('span').add("hello "),
   E('span').add("!")).write();
 e.insertBefore(E('span').add('world'), e.children[1]);

var e = E('div').add(
  E('span').add("hello "),
  E('span').add("!"));
e.insertBefore(E('span').add('world'), e.children[1]);
e.write();

var e = E('div').add(
  E('span').add("hello "),
  E('span').add("!")).write();
e.insertAfter(E('span').add('world'), e.children[0]);

var e = E('div').add(
  E('span').add("hello "),
  E('span').add("!"));
e.insertAfter(E('span').add('world'), e.children[0]);
e.write();

var e = E('div').add(
  E('span').add("hello "),
  E('span').add("!"));
e.addBefore(e.children[1], E('span').add('there '), E('span').add('world'));
e.write();

var oldChild = E().add('First Child').style({color: 'red'});
var newChild = E().add('Second Child').style({color: 'green'});
var e = E('div').tag('br').add(oldChild).tag('br').write();
e.replaceChild(newChild, oldChild);

foam.CLASS({
  name: 'RedElement',
  extends: 'foam.u2.Element',
  methods: [ function init() { this.SUPER(); this.style({color: 'red'}); } ]
});

RedElement.create().add('red element').write();

var i = E('image').attrs({
  displayWidth: 200,
  displayHeight: 200,
  data: 'Dragon.png'
});

i.write();

foam.CLASS({
  name: 'Person',
  properties: [ 'firstName', 'lastName', 'age' ]
});

var p = Person.create({firstName: 'John', lastName: 'Doe', age: 42});

foam.u2.DetailView.create({
  data: p
}).write();

foam.u2.DetailView.create({
  data: p
}).write();
<commit_msg>Added DetailView test to u2/Demo.<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

foam.CLASS({
  name: 'Something',

  requires: [
    'foam.util.Timer'
  ],

  properties: [
    {
      name: 'value',
      value: 'aaaa'
    },
    {
      name: 'timer',
      factory: function() {
        return this.Timer.create();
      }
    }
  ],

  methods: [
    function init() {
      this.timer.start();
      this.timer.propertyChange.sub('second', this.onTimer);
    }
  ],

  listeners: [
    function onTimer() {
      this.value = this.value === 'aaaa' ? 'bbbb' : 'aaaa';
    }
  ]
});

var timer = foam.util.Timer.create();
timer.start();

var E = foam.__context__.E.bind(foam.__context__);

E('b').add(
  'bold',
  E('br'),
  'HTML Injection Attempt',
  E('br')
);

E().
  add('Entities: ').
  add('foo').
  nbsp().
  entity('amp').
  add(' bar ').
  entity('lt').
  entity('quot').
  entity("#039").
  tag('br').
  write();

E('b').add(
  'color: ',
  E('font').attrs({color: 'red'}).add('red', E('br'))).write();

var e = E('font').add('click me', E('br'));
console.log('id: ', e.id);
e.write();
e.attrs({color: 'orange'}).
  style({
    fontWeight: 'bold',
    fontSize:  '24pt'
  }).
  on('click', function() { console.log('clicked'); });

var e13 = E('div').add(
  'dynamic function: ',
  foam.core.ExpressionSlot.create({
    args: [ timer.second$ ],
    fn: function(s) {
      return s % 2 ?
        E('span').add('PI', 'NG').style({color: 'aqua'}) :
        E('span').add('PONG').style({color: 'orange'});
    }
  }),
  E('br'),
  'dynamic value: ', timer.i$,
  E('br'));
e13.write();

var e2 = E('font').add('on click (before)', E('br')).on('click', function() { console.log('clicked, before'); });
e2.write();

var e2b = E('font').add('on click (after)');
e2b.write();
e2b.on('click', function() { console.log('clicked, after'); });

E('br').write();

var e3 = E('div').add('first line, added before');
e3.write();
e3.add(E('br'),'second line, added after', E('br'));

E('div').add('add style before').style({color: 'blue'}).write();

var e5 = E('div').add('add style after');
e5.write();
e5.style({color: 'blue'});

E('br').write();

E('div').add('add class before').cssClass('important').write();

var e7 = E('div').add('add class after');
e7.write();
e7.cssClass('important');

E('font').add(E('br'), 'set attr before').attrs({color: 'blue'}).write();

var e11 = E('font').add(E('br'), 'set attr after', E('br'));
e11.write();
e11.attrs({color: 'blue'});

 var e = E('div').add(
   E('span').add("hello "),
   E('span').add("!")).write();
 e.insertBefore(E('span').add('world'), e.children[1]);

var e = E('div').add(
  E('span').add("hello "),
  E('span').add("!"));
e.insertBefore(E('span').add('world'), e.children[1]);
e.write();

var e = E('div').add(
  E('span').add("hello "),
  E('span').add("!")).write();
e.insertAfter(E('span').add('world'), e.children[0]);

var e = E('div').add(
  E('span').add("hello "),
  E('span').add("!"));
e.insertAfter(E('span').add('world'), e.children[0]);
e.write();

var e = E('div').add(
  E('span').add("hello "),
  E('span').add("!"));
e.addBefore(e.children[1], E('span').add('there '), E('span').add('world'));
e.write();

var oldChild = E().add('First Child').style({color: 'red'});
var newChild = E().add('Second Child').style({color: 'green'});
var e = E('div').tag('br').add(oldChild).tag('br').write();
e.replaceChild(newChild, oldChild);

foam.CLASS({
  name: 'RedElement',
  extends: 'foam.u2.Element',
  methods: [ function init() { this.SUPER(); this.style({color: 'red'}); } ]
});

RedElement.create().add('red element').write();

var i = E('image').attrs({
  displayWidth: 200,
  displayHeight: 200,
  data: 'Dragon.png'
});

i.write();

foam.CLASS({
  name: 'Person',
  properties: [ 'firstName', 'lastName', 'age' ]
});

var p = Person.create({firstName: 'John', lastName: 'Doe', age: 42});

var Y =  foam.__context__.createSubContext({data: p});
console.log('data: ', Y.data);

var s = p.firstName$;
var input = foam.u2.tag.Input.create({data: 'william'});
var input2 = foam.u2.tag.Input.create({data: 'john'});
input.data$ = input2.data$;
input.write();
input2.write();

Person.FIRST_NAME.toE(Y).write();
Person.FIRST_NAME.toE(Y).write();

var e = Y.E('div').add('simple: ').add(Person.FIRST_NAME, Person.LAST_NAME);
e.write();

var e2 = Y.E('div').add('simple2: ').add(Person.getAxiomsByClass(foam.core.Property));
e2.write();

foam.u2.DetailView.create({
  data: p
}).write();

var dv2 = foam.u2.DetailView.create({
  data: p
}).write();
<|endoftext|>


<commit_before>const Command = require('../Command')

module.exports =
class AnnounceChannelCommand extends Command {
  constructor (client) {
    super(client, {
      name: 'support',
      properName: 'Support',
      aliases: ['server'],
      userPermissions: [],
      description: 'Posts an invite link to the Official RoVer Discord where you can easily get help.'
    })
  }

  async fn (msg) {
    try {
      msg.author.send('Having trouble? You can join our official support discord here: discord.gg/7yfwrat, or you can check out the documentation here: https://rover.link/#readme')
      if (msg.member) { // Wouldn't want to say this if it's in a DM conversation
        msg.reply('Sent you a DM with information.')
      }
    } catch(e) {
      msg.reply('I can\'t seem to message you - please make sure your DMs are enabled!')
    }
  }
}
<commit_msg>Fix style issues<commit_after>const Command = require('../Command')

module.exports =
class AnnounceChannelCommand extends Command {
  constructor (client) {
    super(client, {
      name: 'support',
      properName: 'Support',
      aliases: ['server'],
      userPermissions: [],
      description: 'Posts an invite link to the Official RoVer Discord where you can easily get help.'
    })
  }

  async fn (msg) {
    try {
      msg.author.send('Having trouble? You can join our official support discord here: discord.gg/7yfwrat, or you can check out the documentation here: https://rover.link/#readme')
      if (msg.member) { // Wouldn't want to say this if it's in a DM conversation
        msg.reply('Sent you a DM with information.')
      }
    } catch (e) {
      msg.reply("I can't seem to message you - please make sure your DMs are enabled!")
    }
  }
}
<|endoftext|>