<commit_before>import * as rrb from "rrb-vector";

import { error } from "./error";

import { seq, from, of, first, isSeq, foldLeft as seqFoldLeft, zeroOrOne, exactlyOne, isExactlyOne } from "./seq";

// TODO option: call ensureDoc and handle everything via VNode (i.e. persistent or not)
import { ensureDoc } from "./doc";

import { list } from "./access";

import { isArray, isUndef, isList } from "./util";

var List = rrb.empty.constructor;

List.prototype.__is_List = true;

List.prototype._type = 5;

List.prototype["@@transducer/init"] = function(){
	return rrb.empty;
};

List.prototype["@@transducer/step"] = function(l,x) {
	return l.push(x);
};

List.prototype["@@transducer/result"] = function(l) {
	return l;
};

rrb.TreeIterator.prototype["@@transducer/init"] = function(){
	return rrb.empty;
};

rrb.TreeIterator.prototype["@@transducer/step"] = function(l,x) {
	return l.push(x);
};

rrb.TreeIterator.prototype["@@transducer/result"] = function(l) {
	return l;
};

export default function array(...a) {
	var l = a.length;
	if(l===0){
		return seq(rrb.empty);
	}
	if(l==1){
		const s = a[0];
		if (isSeq(s)) return s;
		if (isList(s)) return of(s);
		if (isArray(s)) return of(rrb.fromArray(s));
		// TODO VNode conversion
		if (list()(s)) return of(s.toArray());
		return rrb.empty.push(s);
	}
	return join(seq(a.map(of)).concatAll().map(a => array(a)));
}

export function join($a) {
	if ($a === undefined) return error("XPTY0004");
	// assume a sequence of vectors
	return $a.reduce(function(pre,cur){
		// TODO force persistent cx
		if(list()(cur)) cur = cur.toArray();
		if(!isList(cur)) return error("XPTY0004","One of the items for array:join is not an array.");
		return rrb.concat(pre,cur);
	},rrb.empty);
}

function _checked($a, fn, ...args) {
	if ($a === undefined) return error("XPTY0004");
	return exactlyOne($a).concatMap(a => !isList(a) ? error("XPTY0004","The provided item is not an array.") : seq(fn.bind(a,a).apply(a, args)));
}

// TODO iterator to Observable using transducer protocol
// at the completion of the operation, create a new list
// array:transform($input, ... functions) => zeroOrOne()
// for now:
export function head($a) {
	return _checked($a, rrb.get,0);
}

export function tail($a) {
	return _checked($a, rrb.slice,1);
}

export function size($a) {
	return _checked($a, List.prototype.count);
}

export function subarray($a,$s,$l) {
	return exactlyOne($a).concatMap(a => seq($s).concatMap(s => {
		s = s.valueOf() - 1;
		return isUndef($l) ? rrb.slice(a,s) : seq($l).map(l => rrb.slice(a,s,Math.max(s + Number(l),0)));
	}));
}

const _singleOrSeq = ($v,fn) => {
	$v = seq($v);
	return isExactlyOne($v).switchMap(test => test ? $v.map(fn) : fn($v));
};

const _insertBefore = (a,i,v) => a.slice(0,i).push(v).concat(a.slice(i));

export function insertBefore($a, $i, $v) {
	return seq($i).concatMap(i => _checked($a, a => _singleOrSeq($v,_insertBefore.bind(a,a,i - 1))).concatAll());
}

const _remove = (a, i) => a.slice(0,i - 1).concat(a.slice(i));

export function remove($a,$i) {
	return seq($i).concatMap(i => _checked($a, a => _remove(a,i < 1 ? 1 : i)));
}

export function append($a,$v) {
	return _checked($a,a => _singleOrSeq($v,rrb.push.bind(a,a))).concatAll();
}

export function reverse($a) {
	return _checked($a,function(a){
		return rrb.fromArray(a.toJS(true).reverse());
	});
}

export function flatten($a) {
	return $a.concatAll();
}

export function get($a,$i) {
	if(isUndef($i)) return error("XPST0017");
	return exactlyOne($i).concatMap(i => _checked($a,function(a){
		if(a.size) return a.get(i - 1);
		//return seq();
	}));
}

export function foldLeft($a,$z,$f){
	if(isUndef($f)) {
		$f = $z;
		$z = undefined;
	}
	return seqFoldLeft(flatten(exactlyOne($a)),$z,$f);
}
<commit_msg>join any sequence<commit_after>import * as rrb from "rrb-vector";

import { error } from "./error";

import { seq, from, of, first, isSeq, foldLeft as seqFoldLeft, zeroOrOne, exactlyOne, isExactlyOne } from "./seq";

// TODO option: call ensureDoc and handle everything via VNode (i.e. persistent or not)
import { ensureDoc } from "./doc";

import { list } from "./access";

import { isArray, isUndef, isList } from "./util";

var List = rrb.empty.constructor;

List.prototype.__is_List = true;

List.prototype._type = 5;

List.prototype["@@transducer/init"] = function(){
	return rrb.empty;
};

List.prototype["@@transducer/step"] = function(l,x) {
	return l.push(x);
};

List.prototype["@@transducer/result"] = function(l) {
	return l;
};

rrb.TreeIterator.prototype["@@transducer/init"] = function(){
	return rrb.empty;
};

rrb.TreeIterator.prototype["@@transducer/step"] = function(l,x) {
	return l.push(x);
};

rrb.TreeIterator.prototype["@@transducer/result"] = function(l) {
	return l;
};

export default function array(...a) {
	var l = a.length;
	if(l===0){
		return seq(rrb.empty);
	}
	if(l==1){
		const s = a[0];
		if (isSeq(s)) return join(s);
		if (isList(s)) return of(s);
		if (isArray(s)) return of(rrb.fromArray(s));
		// TODO VNode conversion
		if (list()(s)) return of(s.toArray());
		return rrb.empty.push(s);
	}
	return join(seq(a.map(of)).concatAll().map(a => array(a)));
}

export function join($a) {
	if ($a === undefined) return error("XPTY0004");
	// assume a sequence of vectors
	return $a.reduce(function(pre,cur){
		// TODO force persistent cx
		if(list()(cur)) cur = cur.toArray();
		if(!isList(cur)) return error("XPTY0004","One of the items for array:join is not an array.");
		return rrb.concat(pre,cur);
	},rrb.empty);
}

function _checked($a, fn, ...args) {
	if ($a === undefined) return error("XPTY0004");
	return exactlyOne($a).concatMap(a => !isList(a) ? error("XPTY0004","The provided item is not an array.") : seq(fn.bind(a,a).apply(a, args)));
}

// TODO iterator to Observable using transducer protocol
// at the completion of the operation, create a new list
// array:transform($input, ... functions) => zeroOrOne()
// for now:
export function head($a) {
	return _checked($a, rrb.get,0);
}

export function tail($a) {
	return _checked($a, rrb.slice,1);
}

export function size($a) {
	return _checked($a, List.prototype.count);
}

export function subarray($a,$s,$l) {
	return exactlyOne($a).concatMap(a => seq($s).concatMap(s => {
		s = s.valueOf() - 1;
		return isUndef($l) ? rrb.slice(a,s) : seq($l).map(l => rrb.slice(a,s,Math.max(s + Number(l),0)));
	}));
}

const _singleOrSeq = ($v,fn) => {
	$v = seq($v);
	return isExactlyOne($v).switchMap(test => test ? $v.map(fn) : fn($v));
};

const _insertBefore = (a,i,v) => a.slice(0,i).push(v).concat(a.slice(i));

export function insertBefore($a, $i, $v) {
	return seq($i).concatMap(i => _checked($a, a => _singleOrSeq($v,_insertBefore.bind(a,a,i - 1))).concatAll());
}

const _remove = (a, i) => a.slice(0,i - 1).concat(a.slice(i));

export function remove($a,$i) {
	return seq($i).concatMap(i => _checked($a, a => _remove(a,i < 1 ? 1 : i)));
}

export function append($a,$v) {
	return _checked($a,a => _singleOrSeq($v,rrb.push.bind(a,a))).concatAll();
}

export function reverse($a) {
	return _checked($a,function(a){
		return rrb.fromArray(a.toJS(true).reverse());
	});
}

export function flatten($a) {
	return $a.concatAll();
}

export function get($a,$i) {
	if(isUndef($i)) return error("XPST0017");
	return exactlyOne($i).concatMap(i => _checked($a,function(a){
		if(a.size) return a.get(i - 1);
		//return seq();
	}));
}

export function foldLeft($a,$z,$f){
	if(isUndef($f)) {
		$f = $z;
		$z = undefined;
	}
	return seqFoldLeft(flatten(exactlyOne($a)),$z,$f);
}
<|endoftext|>


<commit_before>/**
 * Smaller version of the async library constructs.
 *
 */
function _noop() { /* empty */ }

/**
 * Iterates an array in series.
 *
 * @param {any[]} array - Array to iterate.
 * @param {function} iterator - Function to call for each element.
 * @param {function} callback - Function to call when done, or on error.
 */
export function eachSeries(array, iterator, callback) {
    let i = 0;
    const len = array.length;

    (function next(err) {
        if (err || i === len) {
            if (callback) {
                callback(err);
            }

            return;
        }

        iterator(array[i++], next);
    })();
}

/**
 * Ensures a function is only called once.
 *
 * @param {function} fn - The function to wrap.
 * @return {function} The wrapping function.
 */
function onlyOnce(fn) {
    return function onceWrapper() {
        if (fn === null) {
            throw new Error('Callback was already called.');
        }

        const callFn = fn;

        fn = null;
        callFn.apply(this, arguments);
    };
}

/**
 * Async queue implementation,
 *
 * @param {function} worker - The worker function to call for each task.
 * @param {number} concurrency - How many workers to run in parrallel.
 * @return {*} The async queue object.
 */
export function queue(worker, concurrency) {
    if (concurrency == null) { // eslint-disable-line no-eq-null,eqeqeq
        concurrency = 1;
    }
    else if (concurrency === 0) {
        throw new Error('Concurrency must not be zero');
    }

    let workers = 0;
    const q = {
        _tasks: [],
        concurrency,
        saturated: _noop,
        unsaturated: _noop,
        buffer: concurrency / 4,
        empty: _noop,
        drain: _noop,
        error: _noop,
        started: false,
        paused: false,
        push(data, callback) {
            _insert(data, false, callback);
        },
        kill() {
            workers = 0;
            q.drain = _noop;
            q.started = false;
            q._tasks = [];
        },
        unshift(data, callback) {
            _insert(data, true, callback);
        },
        process() {
            while (!q.paused && workers < q.concurrency && q._tasks.length) {
                const task = q._tasks.shift();

                if (q._tasks.length === 0) {
                    q.empty();
                }

                workers += 1;

                if (workers === q.concurrency) {
                    q.saturated();
                }

                worker(task.data, onlyOnce(_next(task)));
            }
        },
        length() {
            return q._tasks.length;
        },
        running() {
            return workers;
        },
        idle() {
            return q._tasks.length + workers === 0;
        },
        pause() {
            if (q.paused === true) {
                return;
            }

            q.paused = true;
        },
        resume() {
            if (q.paused === false) {
                return;
            }

            q.paused = false;

            // Need to call q.process once per concurrent
            // worker to preserve full concurrency after pause
            for (let w = 1; w <= q.concurrency; w++) {
                q.process();
            }
        },
    };

    function _insert(data, insertAtFront, callback) {
        if (callback != null && typeof callback !== 'function') { // eslint-disable-line no-eq-null,eqeqeq
            throw new Error('task callback must be a function');
        }

        q.started = true;

        if (data == null && q.idle()) { // eslint-disable-line no-eq-null,eqeqeq
            // call drain immediately if there are no tasks
            setTimeout(() => q.drain(), 1);

            return;
        }

        const item = {
            data,
            callback: typeof callback === 'function' ? callback : _noop,
        };

        if (insertAtFront) {
            q._tasks.unshift(item);
        }
        else {
            q._tasks.push(item);
        }

        setTimeout(() => q.process(), 1);
    }

    function _next(task) {
        return function next() {
            workers -= 1;

            task.callback.apply(task, arguments);

            if (arguments[0] != null) { // eslint-disable-line no-eq-null,eqeqeq
                q.error(arguments[0], task.data);
            }

            if (workers <= (q.concurrency - q.buffer)) {
                q.unsaturated();
            }

            if (q.idle()) {
                q.drain();
            }

            q.process();
        };
    }

    return q;
}
<commit_msg>Fixes any[] to be Array.<*><commit_after>/**
 * Smaller version of the async library constructs.
 *
 */
function _noop() { /* empty */ }

/**
 * Iterates an array in series.
 *
 * @param {Array.<*>} array - Array to iterate.
 * @param {function} iterator - Function to call for each element.
 * @param {function} callback - Function to call when done, or on error.
 */
export function eachSeries(array, iterator, callback) {
    let i = 0;
    const len = array.length;

    (function next(err) {
        if (err || i === len) {
            if (callback) {
                callback(err);
            }

            return;
        }

        iterator(array[i++], next);
    })();
}

/**
 * Ensures a function is only called once.
 *
 * @param {function} fn - The function to wrap.
 * @return {function} The wrapping function.
 */
function onlyOnce(fn) {
    return function onceWrapper() {
        if (fn === null) {
            throw new Error('Callback was already called.');
        }

        const callFn = fn;

        fn = null;
        callFn.apply(this, arguments);
    };
}

/**
 * Async queue implementation,
 *
 * @param {function} worker - The worker function to call for each task.
 * @param {number} concurrency - How many workers to run in parrallel.
 * @return {*} The async queue object.
 */
export function queue(worker, concurrency) {
    if (concurrency == null) { // eslint-disable-line no-eq-null,eqeqeq
        concurrency = 1;
    }
    else if (concurrency === 0) {
        throw new Error('Concurrency must not be zero');
    }

    let workers = 0;
    const q = {
        _tasks: [],
        concurrency,
        saturated: _noop,
        unsaturated: _noop,
        buffer: concurrency / 4,
        empty: _noop,
        drain: _noop,
        error: _noop,
        started: false,
        paused: false,
        push(data, callback) {
            _insert(data, false, callback);
        },
        kill() {
            workers = 0;
            q.drain = _noop;
            q.started = false;
            q._tasks = [];
        },
        unshift(data, callback) {
            _insert(data, true, callback);
        },
        process() {
            while (!q.paused && workers < q.concurrency && q._tasks.length) {
                const task = q._tasks.shift();

                if (q._tasks.length === 0) {
                    q.empty();
                }

                workers += 1;

                if (workers === q.concurrency) {
                    q.saturated();
                }

                worker(task.data, onlyOnce(_next(task)));
            }
        },
        length() {
            return q._tasks.length;
        },
        running() {
            return workers;
        },
        idle() {
            return q._tasks.length + workers === 0;
        },
        pause() {
            if (q.paused === true) {
                return;
            }

            q.paused = true;
        },
        resume() {
            if (q.paused === false) {
                return;
            }

            q.paused = false;

            // Need to call q.process once per concurrent
            // worker to preserve full concurrency after pause
            for (let w = 1; w <= q.concurrency; w++) {
                q.process();
            }
        },
    };

    function _insert(data, insertAtFront, callback) {
        if (callback != null && typeof callback !== 'function') { // eslint-disable-line no-eq-null,eqeqeq
            throw new Error('task callback must be a function');
        }

        q.started = true;

        if (data == null && q.idle()) { // eslint-disable-line no-eq-null,eqeqeq
            // call drain immediately if there are no tasks
            setTimeout(() => q.drain(), 1);

            return;
        }

        const item = {
            data,
            callback: typeof callback === 'function' ? callback : _noop,
        };

        if (insertAtFront) {
            q._tasks.unshift(item);
        }
        else {
            q._tasks.push(item);
        }

        setTimeout(() => q.process(), 1);
    }

    function _next(task) {
        return function next() {
            workers -= 1;

            task.callback.apply(task, arguments);

            if (arguments[0] != null) { // eslint-disable-line no-eq-null,eqeqeq
                q.error(arguments[0], task.data);
            }

            if (workers <= (q.concurrency - q.buffer)) {
                q.unsaturated();
            }

            if (q.idle()) {
                q.drain();
            }

            q.process();
        };
    }

    return q;
}
<|endoftext|>


<commit_before>import React, {PropTypes} from 'react'
import classNames from 'classnames'
import Dropdown from 'src/shared/components/Dropdown'
import LoadingDots from 'src/shared/components/LoadingDots'
import {QUERY_TEMPLATES} from 'src/data_explorer/constants'

const ENTER = 13
const ESCAPE = 27
const {
  func,
  shape,
  string,
} = PropTypes
const RawQueryEditor = React.createClass({
  propTypes: {
    query: string.isRequired,
    onUpdate: func.isRequired,
    config: shape().isRequired,
  },

  getInitialState() {
    return {
      value: this.props.query,
    }
  },

  componentWillReceiveProps(nextProps) {
    if (this.props.query !== nextProps.query) {
      this.setState({value: nextProps.query})
    }
  },

  handleKeyDown(e) {
    if (e.keyCode === ENTER) {
      e.preventDefault()
      this.handleUpdate()
    } else if (e.keyCode === ESCAPE) {
      this.setState({value: this.state.value}, () => {
        this.editor.blur()
      })
    }
  },

  handleChange() {
    this.setState({
      value: this.editor.value,
    })
  },

  handleUpdate() {
    this.props.onUpdate(this.state.value)
  },

  handleChooseTemplate(template) {
    this.setState({value: template.query})
  },

  render() {
    const {config: {status}} = this.props
    const {value} = this.state

    return (

        <textarea
          className="raw-text--field"
          onChange={this.handleChange}
          onKeyDown={this.handleKeyDown}
          onBlur={this.handleUpdate}
          ref={(editor) => this.editor = editor}
          value={value}
          placeholder="Enter a query or select database, measurement, and field below and have us build one for you..."
          autoComplete="off"
          spellCheck="false"
        />
        {this.renderStatus(status)}
        <Dropdown items={QUERY_TEMPLATES} selected={'Query Templates'} onChoose={this.handleChooseTemplate} className="query-template"/>

    )
  },

  renderStatus(status) {
    if (!status) {
      return (

      )
    }

    if (status.loading) {
      return (

          <LoadingDots />

      )
    }

    return (

        {status.error || status.warn || status.success}

    )
  },
})

export default RawQueryEditor
<commit_msg>Add missing propTypes<commit_after>import React, {PropTypes} from 'react'
import classNames from 'classnames'
import Dropdown from 'src/shared/components/Dropdown'
import LoadingDots from 'src/shared/components/LoadingDots'
import {QUERY_TEMPLATES} from 'src/data_explorer/constants'

const ENTER = 13
const ESCAPE = 27
const {
  func,
  shape,
  string,
} = PropTypes
const RawQueryEditor = React.createClass({
  propTypes: {
    query: string.isRequired,
    onUpdate: func.isRequired,
    config: shape({
      status: shape({
        error: string,
        loading: string,
        success: string,
        warn: string,
      }),
    }).isRequired,
  },

  getInitialState() {
    return {
      value: this.props.query,
    }
  },

  componentWillReceiveProps(nextProps) {
    if (this.props.query !== nextProps.query) {
      this.setState({value: nextProps.query})
    }
  },

  handleKeyDown(e) {
    if (e.keyCode === ENTER) {
      e.preventDefault()
      this.handleUpdate()
    } else if (e.keyCode === ESCAPE) {
      this.setState({value: this.state.value}, () => {
        this.editor.blur()
      })
    }
  },

  handleChange() {
    this.setState({
      value: this.editor.value,
    })
  },

  handleUpdate() {
    this.props.onUpdate(this.state.value)
  },

  handleChooseTemplate(template) {
    this.setState({value: template.query})
  },

  render() {
    const {config: {status}} = this.props
    const {value} = this.state

    return (

        <textarea
          className="raw-text--field"
          onChange={this.handleChange}
          onKeyDown={this.handleKeyDown}
          onBlur={this.handleUpdate}
          ref={(editor) => this.editor = editor}
          value={value}
          placeholder="Enter a query or select database, measurement, and field below and have us build one for you..."
          autoComplete="off"
          spellCheck="false"
        />
        {this.renderStatus(status)}
        <Dropdown items={QUERY_TEMPLATES} selected={'Query Templates'} onChoose={this.handleChooseTemplate} className="query-template"/>

    )
  },

  renderStatus(status) {
    if (!status) {
      return (

      )
    }

    if (status.loading) {
      return (

          <LoadingDots />

      )
    }

    return (

        {status.error || status.warn || status.success}

    )
  },
})

export default RawQueryEditor
<|endoftext|>


<commit_before>/*jshint node:true */

/**
Automatically throttles and blacklists naughty requests.

@module middleware/auto-throttle
**/

"use strict";

var config = require('../../conf'),
    path   = require('path'),
    stats  = require('../stats');

module.exports = function (req, res, next) {
    if (req.isCDN || !config.autoThrottle) {
        next();
        return;
    }

    var file        = stats.file(req.path),
        referrer    = stats.referrer(req.canonicalReferrer),
        naughtiness = Math.max(file.naughtiness, referrer.naughtiness);

    res.set('RawGit-Naughtiness', naughtiness);

    if (naughtiness >= 3) {
        evil(req, res);
        return;
    }

    if (naughtiness >= 1) {
        // Let this request stew a while (up to about 20 seconds) before we
        // respond with an error.
        setTimeout(function () {
            blacklist(req, res);
        }, 20000 * naughtiness);

        return;
    }

    if (naughtiness >= 0.5) {
        // Let this request stew a while (up to about 20 seconds) before we
        // respond.
        res.set('RawGit-Message', "Please enhance your calm or this request will be blacklisted soon.");

        setTimeout(next, 20000 * naughtiness);
        return;
    }

    next();
};

// -- Private Functions --------------------------------------------------------

function blacklist(req, res) {
    res.set({
        'Cache-Control'     : 'max-age=86400', // one day
        'RawGit-Blacklisted': 'yup'
    });

    if (req.accepts('html')) {
        res.sendfile(path.join(config.publicDir, '/errors/blacklisted.html'));
        return;
    }

    res.type('txt').send('This request has been blacklisted. Stop abusing rawgit.com or worse things will happen soon.');
}

function evil(req, res) {
    res.set({
        'Cache-Control'     : 'max-age=15778476', // 6 months
        'RawGit-Blacklisted': 'yup'
    });

    switch (path.extname(req.path).toLowerCase()) {
    case '.css':
        res.sendfile(path.join(config.publicDir, '/css/evil.css'));
        return;

    case '.html': // fallthrough
    case '.htm':
        res.sendfile(path.join(config.publicDir, '/evil.html'));
        return;

    case '.js':
        res.sendfile(path.join(config.publicDir, '/js/evil.js'));
        return;

    default:
        res.type('txt').send('This request has been blacklisted. Stop abusing rawgit.com.');
    }
}
<commit_msg>Don't track artificial naughtiness delays in New Relic.<commit_after>/*jshint node:true */

/**
Automatically throttles and blacklists naughty requests.

@module middleware/auto-throttle
**/

"use strict";

var config = require('../../conf'),
    path   = require('path'),
    stats  = require('../stats');

if (process.env.RAWGIT_ENABLE_NEW_RELIC) {
    var newrelic = require('newrelic');
}

module.exports = function (req, res, next) {
    if (req.isCDN || !config.autoThrottle) {
        next();
        return;
    }

    var file        = stats.file(req.path),
        referrer    = stats.referrer(req.canonicalReferrer),
        naughtiness = Math.max(file.naughtiness, referrer.naughtiness);

    res.set('RawGit-Naughtiness', naughtiness);

    if (naughtiness >= 3) {
        evil(req, res);
        return;
    }

    if (naughtiness >= 1) {
        // Let this request stew a while (up to about 20 seconds) before we
        // respond with an error.
        delay(20000 * naughtiness, function () {
            blacklist(req, res);
        });

        return;
    }

    if (naughtiness >= 0.5) {
        // Let this request stew a while (up to about 20 seconds) before we
        // respond.
        res.set('RawGit-Message', "Please enhance your calm or this request will be blacklisted soon.");

        delay(20000 * naughtiness, next);
        return;
    }

    next();
};

// -- Private Functions --------------------------------------------------------

function blacklist(req, res) {
    res.set({
        'Cache-Control'     : 'max-age=86400', // one day
        'RawGit-Blacklisted': 'yup'
    });

    if (req.accepts('html')) {
        res.sendfile(path.join(config.publicDir, '/errors/blacklisted.html'));
        return;
    }

    res.type('txt').send('This request has been blacklisted. Stop abusing rawgit.com or worse things will happen soon.');
}

function delay(ms, callback) {
    if (typeof newrelic !== 'undefined') {
        newrelic.setIgnoreTransaction();
    }

    setTimeout(callback, ms);
}

function evil(req, res) {
    res.set({
        'Cache-Control'     : 'max-age=15778476', // 6 months
        'RawGit-Blacklisted': 'yup'
    });

    switch (path.extname(req.path).toLowerCase()) {
    case '.css':
        res.sendfile(path.join(config.publicDir, '/css/evil.css'));
        return;

    case '.html': // fallthrough
    case '.htm':
        res.sendfile(path.join(config.publicDir, '/evil.html'));
        return;

    case '.js':
        res.sendfile(path.join(config.publicDir, '/js/evil.js'));
        return;

    default:
        res.type('txt').send('This request has been blacklisted. Stop abusing rawgit.com.');
    }
}
<|endoftext|>


<commit_before>var assetTree = require('./asset_tree.js'),
    AssetNode = require('./asset_node.js'),
    preprocessors = require('./preprocessors.js'),
    path = require('path'),
    config = require('./config.js'),
    Promise = require('es6-promise').Promise,
    Q = require('q');

function build(filePath) {
    var deferred = Q.defer(),
        assetNode = new AssetNode({path: filePath});
    assetTree.makeTree(assetNode).then(function(assetNode) {
        var list = makeAssetList(assetNode);
        list.forEach(preprocessors.preprocess);
        deferred.resolve(list.map(function(node) {
            return {
                path: path.relative(config.assetPath, node.path),
                content: node.content,
                wrap: node.wrap
            };
        }));
    }).fail(function(err) {
        deferred.reject(err);
    });
    return deferred.promise;
}

/**
 * Gets flat list of {AssetNode}s
 * @param filePath {String}
 * @return {Promise} resolved with flattened asset tree
 */
function makeNodeList(filePath) {
    var assetNode = new AssetNode({path: filePath});
    return new Promise(function(resolve, reject) {
        assetTree.makeTree(assetNode).then(function(assetNode) {
            resolve(_flattenAssetTree(assetNode));
        }).fail(reject);
    });
}

/**
 * Fetch and compile single asset
 *
 * @param filePath {String}
 * @param wrap {Boolean} whether to wrap asset in module
 */
function makeSingleNode(filePath, wrap) {
    return new Promise(function(resolve, reject) {
        var assetNode = new AssetNode({
            path: filePath,
            wrap: wrap
        });
        assetNode.fetchContent().then(function(content) {
            assetNode.content = content;
            preprocessors.preprocess(assetNode);
            resolve(assetNode);
        }).catch(reject);
    });
}

/**
 * Flatten the node structure.
 * TODO: done this way because in future there will be directives like `exclude ./file/path.js`
 * and first, we'll need complete tree with files, their directives and content, and then
 * we'll cut off excluded branches.
 *
 * @param assetNode {AssetNode}
 * @param [_list] {Array} recursivelly pass and modify
 */
function _flattenAssetTree(assetNode, _list) {
    _list = (_list || []);
    _list.push(assetNode);
    assetNode.children.forEach(function(child) {
        _flattenAssetTree(child, _list);
    });
    return _list;
}

module.exports.makeNodeList = makeNodeList;
module.exports.makeSingleNode = makeSingleNode;
<commit_msg>Update build.js<commit_after>var assetTree = require('./asset_tree.js'),
    AssetNode = require('./asset_node.js'),
    preprocessors = require('./preprocessors.js'),
    path = require('path'),
    config = require('./config.js'),
    Promise = require('es6-promise').Promise,
    Q = require('q');

/**
 * Gets flat list of {AssetNode}s
 * @param filePath {String}
 * @return {Promise} resolved with flattened asset tree
 */
function makeNodeList(filePath) {
    var assetNode = new AssetNode({path: filePath});
    return new Promise(function(resolve, reject) {
        assetTree.makeTree(assetNode).then(function(assetNode) {
            resolve(_flattenAssetTree(assetNode));
        }).fail(reject);
    });
}

/**
 * Fetch and compile single asset
 *
 * @param filePath {String}
 * @param wrap {Boolean} whether to wrap asset in module
 */
function makeSingleNode(filePath, wrap) {
    return new Promise(function(resolve, reject) {
        var assetNode = new AssetNode({
            path: filePath,
            wrap: wrap
        });
        assetNode.fetchContent().then(function(content) {
            assetNode.content = content;
            preprocessors.preprocess(assetNode);
            resolve(assetNode);
        }).catch(reject);
    });
}

/**
 * Flatten the node structure.
 * TODO: done this way because in future there will be directives like `exclude ./file/path.js`
 * and first, we'll need complete tree with files, their directives and content, and then
 * we'll cut off excluded branches.
 *
 * @param assetNode {AssetNode}
 * @param [_list] {Array} recursivelly pass and modify
 */
function _flattenAssetTree(assetNode, _list) {
    _list = (_list || []);
    _list.push(assetNode);
    assetNode.children.forEach(function(child) {
        _flattenAssetTree(child, _list);
    });
    return _list;
}

module.exports.makeNodeList = makeNodeList;
module.exports.makeSingleNode = makeSingleNode;
<|endoftext|>


<commit_before>/**
 * ## this.js
 *
 * this contains methods to build the bite sized widget that do not need to be
 * outwardly facing
 */

import classes  from './classes.js';
import { http } from 'microbejs/dist/microbe.http.min';

/*
    exchanged for css in the gulp build
 */
const baseStyles        = `styla-widget-css-goes-here`;
const specificStyles    = `styla-build-specific-css-goes-here`;
const wrapperID         = `styla-widget`;
const _reportError      = function( e ){ console.log( `err`, e ) };

/*
    retrieved and parsed domain config.  this is declared here to keep it out
    of the global object, yet accessible.
 */
let domainConfig;

/*
    used in tracking ignored stories for the sake of getting the right amount later
 */
let ignored = 0;

class Build
{
    /**
     * ## buildHeadline
     *
     * builds the headline and headline wrapper and fills the wrapper with the
     * element and text
     *
     * @param {String} title story headline
     *
     * @return _DOMElement_ headlineWrapper
     */
    buildHeadline( title )
    {
        let create              = this.create;
        let headlineWrapper     = create( `div`, classes.HEADLINE_WRAPPER );
        let headline            = create( `h3`,  classes.HEADLINE );

        headline.textContent    = title;

        headlineWrapper.appendChild( headline );

        return headlineWrapper;
    }

    /**
     * ## buildImage
     *
     * builds the headline and headline wrapper and fills the wrapper with the
     * element and text
     *
     * @param {Array} images array of images from the product api
     * @param {String} title story headline
     * @param {Object} context sub for this.context - needed for testing
     *
     * @return _DOMElement_ imageWrapper
     */
    buildImage( images, title, context )
    {
        this.context           = this.context || context;
        let create              = this.create;
        let imageWrapper        = create( `div`, classes.IMAGE_WRAPPER );
        let imageSize           = this.context.imageSize;
        let id                  = images[0].id;
        let imgObj              = this.context.images[ id ];

        let url                 = this.getImageUrl( imgObj.fileName, imageSize );

        let image               = create( `img`, classes.IMAGE );
        image.src               = url;
        image.alt               = imgObj.caption || title;
        image.title             = title;

        imageWrapper.appendChild( image );

        return imageWrapper;
    }

    /**
     * ## buildStories
     *
     * after recieving the story data, this parses and build the individual
     * stories
     *
     * @param {String} domainConfig JSON response from the product api
     * @param {Object} parsedDomainConfig parsed JSON object for testing
     *
     * @return _Void_
     */
    buildStories = ( resDomainConfig, parsedDomainConfig ) =>
    {
        domainConfig = parsedDomainConfig || JSON.parse( resDomainConfig );

        if ( Object.keys( domainConfig ).length === 0 )
        {
            throw `Styla Widget error: Could not find magazine, please check if slug is configured correctly.`;
        }
        this.setDomain();
        this.includeBaseStyles();

        let images      = {};
        let context     = this.context;
        let stories     = context.stories;
        let resImages   = stories.images;

        if ( resImages )
        {
            context.title = this.buildTitle();

            resImages.forEach( function( _i ){ images[ _i.id ] = _i; });

            context.images = images;
            let _els    = stories.stories.map( this.buildStory );

            let styling = this.compileStyles();

            document.head.appendChild( styling );
            context.target.appendChild( context.refs.wrapper );
        }
    }

    /**
     * ## buildStory
     *
     * builds each story off the retrieved json.  skips a story if the id matches ignore.
     * no matter what it will always build the number of stories set in the limit
     *
     * @param {Object} json image data
     * @param {Number} i iterator
     *
     * @return _DOMElement_ outer story element
     */
    buildStory = ( { title, description, images, externalPermalink, id }, i ) =>
    {
        let context     = this.context;
        console.log( `${context.ignore}`, '!==', `${id}`, '&&', i, '-', ignored, '<', context.limit );
        if ( `${context.ignore}` !== `${id}` && i - ignored < context.limit )
        {
            let create              = this.create;

            let story               = create( `div`,    classes.STORY );
            let storyLink           = create( `a`,      classes.STORY_LINK );
            storyLink.href          = `//${context.domain}/story/${externalPermalink}/`;

            if ( context.newTab )
            {
                storyLink.setAttribute( `target`, `_blank` );
            }
            else if ( context.iframe )
            {
                storyLink.setAttribute( `target`, `_top` );
            }

            story.appendChild( storyLink );

            storyLink.appendChild( this.buildImage( images, title ) );
            storyLink.appendChild( this.buildStoryText( title, description ) );

            let container   = context.refs.container;
            let wrapper     = context.refs.wrapper;

            container.appendChild( story );
            wrapper.appendChild( container );

            return story;
        }
        else
        {
            ignored++;

            return false;
        }
    }

    /**
     * ## buildStoryText
     *
     * builds the story text (including headline and content), combines them
     * and returns the outer wrapper
     *
     * @param {String} title story headline
     * @param {String} description copy of the story to be inserted
     *
     * @return _DOMElement_ style element
     */
    buildStoryText( title, description )
    {
        let create          = this.create;
        let textWrapper     = create( `div`,    classes.TEXT_WRAPPER );

        let headlineWrapper = this.buildHeadline( title );
        textWrapper.appendChild( headlineWrapper );

        let paragraph       = create( `div`,    classes.PARAGRAPH );
        description         = this.getDescription( JSON.parse( description ) );

        if ( description )
        {
            paragraph.innerHTML = description;
            paragraph.innerHTML = paragraph.textContent;
        }

        textWrapper.appendChild( paragraph );

        let paragraphAfter  = create( `div`,    classes.PARAGRAPH_AFTER );
        textWrapper.appendChild( paragraphAfter );

        return textWrapper;
    }

    /**
     * ## buildStyleTag
     *
     * builds a style tag and appends it to the DOM
     *
     * @param {String} css styles to add to the created tag
     *
     * @return _DOMElement_ style element
     */
    buildStyleTag( css )
    {
        let el          = document.createElement( `style` );
        el.type         = `text/css`;
        el.className    = classes.STYLES;

        let t   = document.createTextNode( css );
        el.appendChild( t );

        return el;
    }

    /**
     * ## buildTitle
     *
     * builds the title element, fills it, and attaches it to the container
     *
     * @return _DOMElement_
     */
    buildTitle()
    {
        let context     = this.context;

        if ( context.title === true && domainConfig.title )
        {
            context.title = domainConfig.title;
        }

        if ( context.title )
        {
            let text        = context.title;
            let title       = context.title    = this.create( `DIV`, classes.TITLE );
            title.innerHTML = text;

            context.refs.container.appendChild( title );
        }

        return context.title;
    }

    /**
     * ## compileStyles
     *
     * compiles the styles and returns them added to the style tag
     *
     * @return _DOMElement_ style element
     */
    compileStyles()
    {
        let theme   = domainConfig.theme;
        let css     = ``;
        let now     = this.now;
        let context = this.context;

        if ( theme )
        {
            css =
                `.styla-widget-${now} .${classes.HEADLINE},
                .styla-widget-${now} .${classes.TITLE}
                {
                    font-family:        ${theme.hff};
                    font-weight:        ${theme.hfw};
                    font-style:         ${theme.hfs};
                    text-decoration:    ${theme.htd};
                    letter-spacing:     ${theme.hls};
                    color:              ${theme.htc};
                }
                .styla-widget-${now} .${classes.PARAGRAPH}, .styla-widget-${now} .${classes.PARAGRAPH_AFTER}
                {
                    font-family:        ${theme.sff};
                    font-weight:        ${theme.sfw};
                    color:              ${theme.stc};
                }
                .styla-widget-${now} .${classes.PARAGRAPH_AFTER}:after
                {
                    content:            '${theme.strm}';
                    font-weight:        ${theme.strmw};
                    text-decoration:    ${theme.strmd};
                }`;
        }

        let el          = this.buildStyleTag( css );
        el.className    = `${classes.THEME_STYLES}  styla-widget__${context.format}`;

        context.refs.themeStyle = el;

        return el;
    }

    /**
     * ## constructor
     *
     * builds build
     *
     * @param {Object} context context to be passed to this.context
     */
    constructor( context, stories )
    {
        this.context    = context;
        this.now        = Date.now();

        if ( !context.refs.wrapper )
        {
            context.stories = JSON.parse( stories );
            let format      = context.format.toLowerCase();

            let container   = context.refs.container = this.create( `DIV`, `${classes.CONTAINER}  styla-widget-${this.now}` );
            let wrapper     = context.refs.wrapper   = this.create( `DIV`, `${classes.WRAPPER}  ${format}` );
            wrapper.id      = wrapperID;

            let domainConfigAPI   = `https://live.styla.com/api/config/`;
            http.get( domainConfigAPI + context.slug ).then( this.buildStories ).catch( _reportError );

            return container;
        }

        return this;
    }

    /**
     * ## create
     *
     * creates an element with the supplied tagname and classname
     *
     * @param {String} tag tagname
     * @param {String} clss className to add to the created element
     *
     * @return _DOMElement_ newly created element
     */
    create( tag, clss )
    {
        let _el = document.createElement( tag.toUpperCase() );

        if ( clss )
        {
            _el.className = clss;
        }

        return _el;
    }

    /**
     * ## getDescription
     *
     * gets the first text description in the content and returns that
     *
     * @param {Array} arr array filled w/ content
     * @param {Number} i recursive index
     *
     * @return _String or Boolean_ text content or false
     */
    getDescription( arr, i = 0 )
    {
        let text        = arr[ i ];
        console.log( text );
        if ( !text )
        {
            return false;
        }

        let el          = this.create( `div` );
        el.innerHTML    = text.content;
        let actualText  = el.textContent;

        if ( text.type !== `text` || actualText === `` )
        {
            return this.getDescription( arr, i + 1 );
        }

        return text.content;
    }

    /**
     * ## getImageUrl
     *
     * uses the filename and size to create the full image url
     *
     * @param {String} filename from the image data object
     * @param {Number or String} imageSize width to grab from the server
     *
     * @return _String_ file name
     */
    getImageUrl( filename, imageSize = 400 )
    {
        return `//img.styla.com/resizer/sfh_${imageSize}x0/_${filename}?still`;
    }

    /**
     * ## includeBaseStyles
     *
     * creates the base styles DOM element and adds it to the head
     *
     * @return _Void_
     */
    includeBaseStyles( css )
    {
        let self        = this;
        let context     = this.context;
        let formatCaps  = context.format.toUpperCase();
        let head        = document.head;

        function _addBaseStyle( css, _class, _format )
        {
            let el          = self.buildStyleTag( css );
            el.className    = _class;

            context.refs[ `${_format}Style` ] = el;

            let baseStyle = head.querySelector( `.${_class}` );

            if ( !baseStyle )
            {
                head.appendChild( el );
            }

            return el;
        }

        _addBaseStyle( css || baseStyles, classes.BASE_STYLES, 'base' );
        _addBaseStyle( specificStyles, classes[ `${formatCaps}_STYLES` ], context.format );

        if ( domainConfig.embed.customFontUrl )
        {
            this.includeFonts( head );
        }
    }

    /**
     * ## includeFonts
     *
     * includes the webfonts link element
     *
     * @return _DOMElement_ link element
     */
    includeFonts()
    {
        let el      = document.createElement( `link` );
        el.type     = `text/css`;
        el.rel      = `stylesheet`;
        let fontUrl = domainConfig.embed.customFontUrl
        el.href     = fontUrl.indexOf( '//' ) !== -1 ? fontUrl : `//${fontUrl}`;

        document.head.appendChild( el );

        return el;
    }

    /**
     * ## setDomain
     *
     * takes pieces of the domainConfig and builds the domain
     *
     * @return _String_ domain address
     */
    setDomain()
    {
        let embed   = domainConfig.embed;
        let context = this.context;

        if ( context.domain )
        {
            return context.domain;
        }
        else if ( context.linkDomain )
        {
            return context.domain = context.linkDomain;
        }
        else if ( embed )
        {
            return context.domain = `${embed.magazineUrl}/${embed.rootPath}`;
        }
        else
        {
            throw `Styla Widget error: No domain defined or bad domain config`;
        }
    }
};

export default Build;
<commit_msg>removed extra story issue - ignored -> this.ignored<commit_after>/**
 * ## this.js
 *
 * this contains methods to build the bite sized widget that do not need to be
 * outwardly facing
 */

import classes  from './classes.js';
import { http } from 'microbejs/dist/microbe.http.min';

/*
    exchanged for css in the gulp build
 */
const baseStyles        = `styla-widget-css-goes-here`;
const specificStyles    = `styla-build-specific-css-goes-here`;
const wrapperID         = `styla-widget`;
const _reportError      = function( e ){ console.log( `err`, e ) };

/*
    retrieved and parsed domain config.  this is declared here to keep it out
    of the global object, yet accessible.
 */
let domainConfig;

class Build
{
    /**
     * ## buildHeadline
     *
     * builds the headline and headline wrapper and fills the wrapper with the
     * element and text
     *
     * @param {String} title story headline
     *
     * @return _DOMElement_ headlineWrapper
     */
    buildHeadline( title )
    {
        let create              = this.create;
        let headlineWrapper     = create( `div`, classes.HEADLINE_WRAPPER );
        let headline            = create( `h3`,  classes.HEADLINE );

        headline.textContent    = title;

        headlineWrapper.appendChild( headline );

        return headlineWrapper;
    }

    /**
     * ## buildImage
     *
     * builds the headline and headline wrapper and fills the wrapper with the
     * element and text
     *
     * @param {Array} images array of images from the product api
     * @param {String} title story headline
     * @param {Object} context sub for this.context - needed for testing
     *
     * @return _DOMElement_ imageWrapper
     */
    buildImage( images, title, context )
    {
        this.context           = this.context || context;
        let create              = this.create;
        let imageWrapper        = create( `div`, classes.IMAGE_WRAPPER );
        let imageSize           = this.context.imageSize;
        let id                  = images[0].id;
        let imgObj              = this.context.images[ id ];

        let url                 = this.getImageUrl( imgObj.fileName, imageSize );

        let image               = create( `img`, classes.IMAGE );
        image.src               = url;
        image.alt               = imgObj.caption || title;
        image.title             = title;

        imageWrapper.appendChild( image );

        return imageWrapper;
    }

    /**
     * ## buildStories
     *
     * after recieving the story data, this parses and build the individual
     * stories
     *
     * @param {String} domainConfig JSON response from the product api
     * @param {Object} parsedDomainConfig parsed JSON object for testing
     *
     * @return _Void_
     */
    buildStories = ( resDomainConfig, parsedDomainConfig ) =>
    {
        domainConfig = parsedDomainConfig || JSON.parse( resDomainConfig );

        if ( Object.keys( domainConfig ).length === 0 )
        {
            throw `Styla Widget error: Could not find magazine, please check if slug is configured correctly.`;
        }
        this.setDomain();
        this.includeBaseStyles();

        let images      = {};
        let context     = this.context;
        let stories     = context.stories;
        let resImages   = stories.images;

        if ( resImages )
        {
            context.title = this.buildTitle();

            resImages.forEach( function( _i ){ images[ _i.id ] = _i; });

            context.images = images;
            let _els    = stories.stories.map( this.buildStory );

            let styling = this.compileStyles();

            document.head.appendChild( styling );
            context.target.appendChild( context.refs.wrapper );
        }
    }

    /**
     * ## buildStory
     *
     * builds each story off the retrieved json.  skips a story if the id matches ignore.
     * no matter what it will always build the number of stories set in the limit
     *
     * @param {Object} json image data
     * @param {Number} i iterator
     *
     * @return _DOMElement_ outer story element
     */
    buildStory = ( { title, description, images, externalPermalink, id }, i ) =>
    {
        let context     = this.context;

        if ( `${context.ignore}` !== `${id}` && i < this.ignored + context.limit )
        {
            let create              = this.create;

            let story               = create( `div`,    classes.STORY );
            let storyLink           = create( `a`,      classes.STORY_LINK );
            storyLink.href          = `//${context.domain}/story/${externalPermalink}/`;

            if ( context.newTab )
            {
                storyLink.setAttribute( `target`, `_blank` );
            }
            else if ( context.iframe )
            {
                storyLink.setAttribute( `target`, `_top` );
            }

            story.appendChild( storyLink );

            storyLink.appendChild( this.buildImage( images, title ) );
            storyLink.appendChild( this.buildStoryText( title, description ) );

            let container   = context.refs.container;
            let wrapper     = context.refs.wrapper;

            container.appendChild( story );
            wrapper.appendChild( container );

            return story;
        }
        else
        {
            this.ignored++;

            return false;
        }
    }

    /**
     * ## buildStoryText
     *
     * builds the story text (including headline and content), combines them
     * and returns the outer wrapper
     *
     * @param {String} title story headline
     * @param {String} description copy of the story to be inserted
     *
     * @return _DOMElement_ style element
     */
    buildStoryText( title, description )
    {
        let create          = this.create;
        let textWrapper     = create( `div`,    classes.TEXT_WRAPPER );

        let headlineWrapper = this.buildHeadline( title );
        textWrapper.appendChild( headlineWrapper );

        let paragraph       = create( `div`,    classes.PARAGRAPH );
        description         = this.getDescription( JSON.parse( description ) );

        if ( description )
        {
            paragraph.innerHTML = description;
            paragraph.innerHTML = paragraph.textContent;
        }

        textWrapper.appendChild( paragraph );

        let paragraphAfter  = create( `div`,    classes.PARAGRAPH_AFTER );
        textWrapper.appendChild( paragraphAfter );

        return textWrapper;
    }

    /**
     * ## buildStyleTag
     *
     * builds a style tag and appends it to the DOM
     *
     * @param {String} css styles to add to the created tag
     *
     * @return _DOMElement_ style element
     */
    buildStyleTag( css )
    {
        let el          = document.createElement( `style` );
        el.type         = `text/css`;
        el.className    = classes.STYLES;

        let t   = document.createTextNode( css );
        el.appendChild( t );

        return el;
    }

    /**
     * ## buildTitle
     *
     * builds the title element, fills it, and attaches it to the container
     *
     * @return _DOMElement_
     */
    buildTitle()
    {
        let context     = this.context;

        if ( context.title === true && domainConfig.title )
        {
            context.title = domainConfig.title;
        }

        if ( context.title )
        {
            let text        = context.title;
            let title       = context.title    = this.create( `DIV`, classes.TITLE );
            title.innerHTML = text;

            context.refs.container.appendChild( title );
        }

        return context.title;
    }

    /**
     * ## compileStyles
     *
     * compiles the styles and returns them added to the style tag
     *
     * @return _DOMElement_ style element
     */
    compileStyles()
    {
        let theme   = domainConfig.theme;
        let css     = ``;
        let now     = this.now;
        let context = this.context;

        if ( theme )
        {
            css =
                `.styla-widget-${now} .${classes.HEADLINE},
                .styla-widget-${now} .${classes.TITLE}
                {
                    font-family:        ${theme.hff};
                    font-weight:        ${theme.hfw};
                    font-style:         ${theme.hfs};
                    text-decoration:    ${theme.htd};
                    letter-spacing:     ${theme.hls};
                    color:              ${theme.htc};
                }
                .styla-widget-${now} .${classes.PARAGRAPH}, .styla-widget-${now} .${classes.PARAGRAPH_AFTER}
                {
                    font-family:        ${theme.sff};
                    font-weight:        ${theme.sfw};
                    color:              ${theme.stc};
                }
                .styla-widget-${now} .${classes.PARAGRAPH_AFTER}:after
                {
                    content:            '${theme.strm}';
                    font-weight:        ${theme.strmw};
                    text-decoration:    ${theme.strmd};
                }`;
        }

        let el          = this.buildStyleTag( css );
        el.className    = `${classes.THEME_STYLES}  styla-widget__${context.format}`;

        context.refs.themeStyle = el;

        return el;
    }

    /**
     * ## constructor
     *
     * builds build
     *
     * @param {Object} context context to be passed to this.context
     */
    constructor( context, stories )
    {
        this.context    = context;
        this.now        = Date.now();
        this.ignored    = 0;

        if ( !context.refs.wrapper )
        {
            context.stories = JSON.parse( stories );
            let format      = context.format.toLowerCase();

            let container   = context.refs.container = this.create( `DIV`, `${classes.CONTAINER}  styla-widget-${this.now}` );
            let wrapper     = context.refs.wrapper   = this.create( `DIV`, `${classes.WRAPPER}  ${format}` );
            wrapper.id      = wrapperID;

            let domainConfigAPI   = `https://live.styla.com/api/config/`;
            http.get( domainConfigAPI + context.slug ).then( this.buildStories ).catch( _reportError );

            return container;
        }

        return this;
    }

    /**
     * ## create
     *
     * creates an element with the supplied tagname and classname
     *
     * @param {String} tag tagname
     * @param {String} clss className to add to the created element
     *
     * @return _DOMElement_ newly created element
     */
    create( tag, clss )
    {
        let _el = document.createElement( tag.toUpperCase() );

        if ( clss )
        {
            _el.className = clss;
        }

        return _el;
    }

    /**
     * ## getDescription
     *
     * gets the first text description in the content and returns that
     *
     * @param {Array} arr array filled w/ content
     * @param {Number} i recursive index
     *
     * @return _String or Boolean_ text content or false
     */
    getDescription( arr, i = 0 )
    {
        let text        = arr[ i ];

        if ( !text )
        {
            return false;
        }

        let el          = this.create( `div` );
        el.innerHTML    = text.content;
        let actualText  = el.textContent;

        if ( text.type !== `text` || actualText === `` )
        {
            return this.getDescription( arr, i + 1 );
        }

        return text.content;
    }

    /**
     * ## getImageUrl
     *
     * uses the filename and size to create the full image url
     *
     * @param {String} filename from the image data object
     * @param {Number or String} imageSize width to grab from the server
     *
     * @return _String_ file name
     */
    getImageUrl( filename, imageSize = 400 )
    {
        return `//img.styla.com/resizer/sfh_${imageSize}x0/_${filename}?still`;
    }

    /**
     * ## includeBaseStyles
     *
     * creates the base styles DOM element and adds it to the head
     *
     * @return _Void_
     */
    includeBaseStyles( css )
    {
        let self        = this;
        let context     = this.context;
        let formatCaps  = context.format.toUpperCase();
        let head        = document.head;

        function _addBaseStyle( css, _class, _format )
        {
            let el          = self.buildStyleTag( css );
            el.className    = _class;

            context.refs[ `${_format}Style` ] = el;

            let baseStyle = head.querySelector( `.${_class}` );

            if ( !baseStyle )
            {
                head.appendChild( el );
            }

            return el;
        }

        _addBaseStyle( css || baseStyles, classes.BASE_STYLES, 'base' );
        _addBaseStyle( specificStyles, classes[ `${formatCaps}_STYLES` ], context.format );

        if ( domainConfig.embed.customFontUrl )
        {
            this.includeFonts( head );
        }
    }

    /**
     * ## includeFonts
     *
     * includes the webfonts link element
     *
     * @return _DOMElement_ link element
     */
    includeFonts()
    {
        let el      = document.createElement( `link` );
        el.type     = `text/css`;
        el.rel      = `stylesheet`;
        let fontUrl = domainConfig.embed.customFontUrl
        el.href     = fontUrl.indexOf( '//' ) !== -1 ? fontUrl : `//${fontUrl}`;

        document.head.appendChild( el );

        return el;
    }

    /**
     * ## setDomain
     *
     * takes pieces of the domainConfig and builds the domain
     *
     * @return _String_ domain address
     */
    setDomain()
    {
        let embed   = domainConfig.embed;
        let context = this.context;

        if ( context.domain )
        {
            return context.domain;
        }
        else if ( context.linkDomain )
        {
            return context.domain = context.linkDomain;
        }
        else if ( embed )
        {
            return context.domain = `${embed.magazineUrl}/${embed.rootPath}`;
        }
        else
        {
            throw `Styla Widget error: No domain defined or bad domain config`;
        }
    }
};

export default Build;
<|endoftext|>


<commit_before>define(['lib/reload'], function(reload) {
    // XXX: move to toolbox
    var clone = function(o) {
        // http://www.andrewsellick.com/93/javascript-clone-object-function
        if(typeof(o) != 'object' || !o) {
            return o;
        }

        var newO = new Object();

        for(var i in o) {
            newO[i] = clone(o[i]);
        }

        return newO;
    };

    // output
    var consoleOutput = function(report) {
        console.log(report.text);
    };

    var HTMLOutput = function(target) {
        return function(report) {
            target.innerHTML += '
' + report.text + '
';
        }
    }

    // core logic
    var bunit = function(setName, newTests) {
        if(!('_tests' in bunit)) {
            bunit._tests = [];
        }

        if(setName && newTests) {
            bunit._tests.push({name: setName, tests: newTests});
        }
    };

    bunit.runner = function(interval) {
        var scope = this;
        scope.reloader = reload();

        return {
            defaultUI: function(parent) {
                parent = parent || document.body;

                var outputArea = document.createElement('div');

                scope.output = HTMLOutput(outputArea);
                scope.reloader.interval(2000);

                parent.appendChild(scope.reloader.ui());
                parent.appendChild(outputArea);
            },
            run: function(opts) {
                opts = opts || {};

                var passedTests = 0;
                var testTotal = 0;
                var out = [];

                scope.output = 'output' in opts? opts.output: scope.output;

                if(!scope.output) {
                    console.log('bunit.run is missing output sink!');

                    return;
                }

                var interval = 'interval' in opts? opts.interval: 0;

                if(interval) {
                    scope.reloader.interval(interval);
                }

                for(var i = 0; i < bunit._tests.length; i++) {
                    var model = bunit._tests[i];
                    var testSet = model.tests;

                    var setUp = 'setUp' in testSet? testSet.setUp: function() {};
                    delete testSet.setUp;

                    var tearDown = 'tearDown' in testSet? testSet.tearDown: function() {};
                    delete testSet.tearDown;

                    out.push({state: 'started', text: 'Running "' + model.name + '" tests'});

                    for(var testName in testSet) {
                        var test = testSet[testName];

                        try {
                            test.apply(testSet, setUp());

                            out.push({state: 'passed', text: 'PASSED: ' + testName});

                            passedTests++;
                        }
                        catch(e) {
                            out.push({state: 'failed', text: 'FAILED: ' + testName});
                            out.push({state: 'error', text: e});
                        }

                        tearDown();

                        testTotal++;
                    }
                }

                var finished = {state: 'finished', text: passedTests + '/' + testTotal + ' tests passed'};
                out.unshift(finished);
                out.push(finished);

                for(i = 0; i < out.length; i++) {
                    var line = out[i];

                    scope.output(line);
                }

                if(scope.reloader.interval()) {
                    scope.reloader.play();
                }
            }
        };
    };

    bunit.HTMLOutput = HTMLOutput;
    bunit.consoleOutput = consoleOutput;

    return bunit;
});
<commit_msg>Skip tests beginning with _<commit_after>define(['lib/reload'], function(reload) {
    // XXX: move to toolbox
    var clone = function(o) {
        // http://www.andrewsellick.com/93/javascript-clone-object-function
        if(typeof(o) != 'object' || !o) {
            return o;
        }

        var newO = new Object();

        for(var i in o) {
            newO[i] = clone(o[i]);
        }

        return newO;
    };

    // output
    var consoleOutput = function(report) {
        console.log(report.text);
    };

    var HTMLOutput = function(target) {
        return function(report) {
            target.innerHTML += '
' + report.text + '
';
        }
    }

    // core logic
    var bunit = function(setName, newTests) {
        if(!('_tests' in bunit)) {
            bunit._tests = [];
        }

        if(setName && newTests) {
            bunit._tests.push({name: setName, tests: newTests});
        }
    };

    bunit.runner = function(interval) {
        var scope = this;
        scope.reloader = reload();

        return {
            defaultUI: function(parent) {
                parent = parent || document.body;

                var outputArea = document.createElement('div');

                scope.output = HTMLOutput(outputArea);
                scope.reloader.interval(2000);

                parent.appendChild(scope.reloader.ui());
                parent.appendChild(outputArea);
            },
            run: function(opts) {
                opts = opts || {};

                var passedTests = 0;
                var testTotal = 0;
                var out = [];

                scope.output = 'output' in opts? opts.output: scope.output;

                if(!scope.output) {
                    console.log('bunit.run is missing output sink!');

                    return;
                }

                var interval = 'interval' in opts? opts.interval: 0;

                if(interval) {
                    scope.reloader.interval(interval);
                }

                for(var i = 0; i < bunit._tests.length; i++) {
                    var model = bunit._tests[i];
                    var testSet = model.tests;

                    var setUp = 'setUp' in testSet? testSet.setUp: function() {};
                    delete testSet.setUp;

                    var tearDown = 'tearDown' in testSet? testSet.tearDown: function() {};
                    delete testSet.tearDown;

                    out.push({state: 'started', text: 'Running "' + model.name + '" tests'});

                    for(var testName in testSet) {
                        var test = testSet[testName];

                        if(testName[0] == '_') {
                            continue;
                        }

                        try {
                            test.apply(testSet, setUp());

                            out.push({state: 'passed', text: 'PASSED: ' + testName});

                            passedTests++;
                        }
                        catch(e) {
                            out.push({state: 'failed', text: 'FAILED: ' + testName});
                            out.push({state: 'error', text: e});
                        }

                        tearDown();

                        testTotal++;
                    }
                }

                var finished = {state: 'finished', text: passedTests + '/' + testTotal + ' tests passed'};
                out.unshift(finished);
                out.push(finished);

                for(i = 0; i < out.length; i++) {
                    var line = out[i];

                    scope.output(line);
                }

                if(scope.reloader.interval()) {
                    scope.reloader.play();
                }
            }
        };
    };

    bunit.HTMLOutput = HTMLOutput;
    bunit.consoleOutput = consoleOutput;

    return bunit;
});
<|endoftext|>


<commit_before>'use strict';

import { default as extend } from 'extend';

const DEFAULT_OPTIONS = {
	'expire': 60 * 60, // 1hr
	'json': true,
	'rejectOnNull': false,
	'prefix': null
};

export class RedisCache {
	constructor(client, options = {}) {
		if(!client) throw new Error('redis client required');
		this._client = client;
		this._options = extend(DEFAULT_OPTIONS, options);
	}

	/**
	 * Try to parse a JSON value or return the original value
	**/
	_parseJSON(value) {
		try {
			value = JSON.parse(value);
		}
		catch(e) { }
		return value;
	}

	/**
	 * Try to stringify a JSON value or return the original value
	**/
	_stringifyJSON(value) {
		try {
			value = JSON.stringify(value);
		}
		catch(e) { }
		return value;
	}

	/**
	 * Prefixes the key
	**/
	_prefix(key, prefix = this._options.prefix) {
		if(prefix !== null)
			key = prefix + key;
		return key;
	}

	/**
	 * Fetch a key from the cache
	**/
	fetch(key, options = {}) {
		options = extend(this._options, options);
		key = this._prefix(key, options.prefix);
		return new Promise((resolve, reject) => {
			this._client.get(key, (err, reply) => {
				if(err) return reject(err);
				if(options.rejectOnNull && reply === null)
					return reject(new Error('reply is null'));
				if(options.json)
					reply = this._parseJSON(reply);
				return resolve(reply);
			});
		});
	}

	/**
	 * Set a key in the cache
	**/
	set(key, value, options = {}) {
		options = extend(this._options, options);
		key = this._prefix(key, options.prefix);
		return new Promise((resolve, reject) => {
			if(options.json) value = this._stringifyJSON(value);
			this._client.set(key, value, (err, reply) => {
				if(err) return reject(err);
				if(options.expire)
					this._client.expire(key, options.expire);
				return resolve((reply === 'OK') ? true : false);
			});
		});
	}

	/**
	 * Delete a key from the cache
	**/
	del(key) {
		key = this._prefix(key);
		return new Promise((resolve, reject) => {
			this._client.del(key, (err, reply) => {
				if(err) return reject(err);
				return resolve(reply);
			});
		});
	}

  /**
   * Get the Time-To-Live (TTL) for a key
  **/
  ttl(key) {
		key = this._prefix(key);
    return new Promise((resolve, reject) => {
      this._client.ttl(key, (err, reply) => {
        if(err) return reject(err);
        return resolve(reply);
      });
    });
  }

	/**
	 * Check if a key exists
	**/
	exists(key) {
		key = this._prefix(key);
		return new Promise((resolve, reject) => {
			this._client.exists(key, (err, reply) => {
				if(err) return reject(err);
				return resolve((reply === 1) ? true : false);
			});
		});
	}

	/**
	 * Set expiry time on a key
	**/
	expire(key, expire = this._options.expire) {
		key = this._prefix(key);
		return new Promise((resolve, reject) => {
			this._client.expire(key, expire, (err, reply) => {
				if(err) return reject(err);
				return resolve((reply === 1) ? true : false);
			});
		});
	}

	/**
	 * Remove expiry on a key
	**/
	persist(key) {
		key = this._prefix(key);
		return new Promise((resolve, reject) => {
			this._client.persist(key, (err, reply) => {
				if(err) return reject(err);
				return resolve((reply == 1) ? true : false);
			});
		});
	}

	/**
	 * Split the class into a new instance using the same Redis client
	**/
	split(options = {}, useDefaultOptions = false) {
		options = extend((useDefaultOptions) ? DEFAULT_OPTIONS : this._options, options);
		return new RedisCache(this._client, options);
	}
}
<commit_msg>Comment out split() for now<commit_after>'use strict';

import { default as extend } from 'extend';

const DEFAULT_OPTIONS = {
	'expire': 60 * 60, // 1hr
	'json': true,
	'rejectOnNull': false,
	'prefix': null
};

export class RedisCache {
	constructor(client, options = {}) {
		if(!client) throw new Error('redis client required');
		this._client = client;
		this._options = extend(DEFAULT_OPTIONS, options);
	}

	/**
	 * Try to parse a JSON value or return the original value
	**/
	_parseJSON(value) {
		try {
			value = JSON.parse(value);
		}
		catch(e) { }
		return value;
	}

	/**
	 * Try to stringify a JSON value or return the original value
	**/
	_stringifyJSON(value) {
		try {
			value = JSON.stringify(value);
		}
		catch(e) { }
		return value;
	}

	/**
	 * Prefixes the key
	**/
	_prefix(key, prefix = this._options.prefix) {
		if(prefix !== null)
			key = prefix + key;
		return key;
	}

	/**
	 * Fetch a key from the cache
	**/
	fetch(key, options = {}) {
		options = extend(this._options, options);
		key = this._prefix(key, options.prefix);
		return new Promise((resolve, reject) => {
			this._client.get(key, (err, reply) => {
				if(err) return reject(err);
				if(options.rejectOnNull && reply === null)
					return reject(new Error('reply is null'));
				if(options.json)
					reply = this._parseJSON(reply);
				return resolve(reply);
			});
		});
	}

	/**
	 * Set a key in the cache
	**/
	set(key, value, options = {}) {
		options = extend(this._options, options);
		key = this._prefix(key, options.prefix);
		return new Promise((resolve, reject) => {
			if(options.json) value = this._stringifyJSON(value);
			this._client.set(key, value, (err, reply) => {
				if(err) return reject(err);
				if(options.expire)
					this._client.expire(key, options.expire);
				return resolve((reply === 'OK') ? true : false);
			});
		});
	}

	/**
	 * Delete a key from the cache
	**/
	del(key) {
		key = this._prefix(key);
		return new Promise((resolve, reject) => {
			this._client.del(key, (err, reply) => {
				if(err) return reject(err);
				return resolve(reply);
			});
		});
	}

  /**
   * Get the Time-To-Live (TTL) for a key
  **/
  ttl(key) {
		key = this._prefix(key);
    return new Promise((resolve, reject) => {
      this._client.ttl(key, (err, reply) => {
        if(err) return reject(err);
        return resolve(reply);
      });
    });
  }

	/**
	 * Check if a key exists
	**/
	exists(key) {
		key = this._prefix(key);
		return new Promise((resolve, reject) => {
			this._client.exists(key, (err, reply) => {
				if(err) return reject(err);
				return resolve((reply === 1) ? true : false);
			});
		});
	}

	/**
	 * Set expiry time on a key
	**/
	expire(key, expire = this._options.expire) {
		key = this._prefix(key);
		return new Promise((resolve, reject) => {
			this._client.expire(key, expire, (err, reply) => {
				if(err) return reject(err);
				return resolve((reply === 1) ? true : false);
			});
		});
	}

	/**
	 * Remove expiry on a key
	**/
	persist(key) {
		key = this._prefix(key);
		return new Promise((resolve, reject) => {
			this._client.persist(key, (err, reply) => {
				if(err) return reject(err);
				return resolve((reply == 1) ? true : false);
			});
		});
	}

	/**
	 * Split the class into a new instance using the same Redis client
	**/
	// split(options = {}, useDefaultOptions = false) {
	// 	options = extend((useDefaultOptions) ? DEFAULT_OPTIONS : this._options, options);
	// 	return new RedisCache(this._client, options);
	// }
}
<|endoftext|>


<commit_before>function Chain (parent, k) {
  k = k || 0
  this.__parent = parent

  this.addresses = []
  this.k = k
  this.map = {}
}

Chain.prototype.find = function (address) {
  return this.map[address]
}

Chain.prototype.get = function () {
  if (this.addresses.length === 0) {
    var address = this.__parent.derive(this.k).getAddress().toString()
    this.map[address] = this.k
    this.addresses.push(address)

    return address
  }

  return this.addresses[this.addresses.length - 1]
}

Chain.prototype.getParent = function () {
  return this.__parent
}

Chain.prototype.next = function () {
  if (this.addresses.length === 0) return this.get()
  var address = this.__parent.derive(this.k + 1).getAddress().toString()

  this.k += 1
  this.map[address] = this.k
  this.addresses.push(address)

  return address
}

Chain.prototype.pop = function () {
  var address = this.addresses.pop()
  delete this.map[address]
  this.k -= 1

  return address
}

module.exports = Chain
<commit_msg>chain: next should skip first address if necessary<commit_after>function Chain (parent, k) {
  k = k || 0
  this.__parent = parent

  this.addresses = []
  this.k = k
  this.map = {}
}

Chain.prototype.__initialize = function () {
  var address = this.__parent.derive(this.k).getAddress().toString()
  this.map[address] = this.k
  this.addresses.push(address)
}

Chain.prototype.find = function (address) {
  return this.map[address]
}

Chain.prototype.get = function () {
  if (this.addresses.length === 0) this.__initialize()

  return this.addresses[this.addresses.length - 1]
}

Chain.prototype.getParent = function () {
  return this.__parent
}

Chain.prototype.next = function () {
  if (this.addresses.length === 0) this.__initialize()
  var address = this.__parent.derive(this.k + 1).getAddress().toString()

  this.k += 1
  this.map[address] = this.k
  this.addresses.push(address)

  return address
}

Chain.prototype.pop = function () {
  var address = this.addresses.pop()
  delete this.map[address]
  this.k -= 1

  return address
}

module.exports = Chain
<|endoftext|>


<commit_before>/** @babel */

let ParsedColor = null

// Essential: A simple color class returned from {Config::get} when the value
// at the key path is of type 'color'.
export default class Color {
  // Essential: Parse a {String} or {Object} into a {Color}.
  //
  // * `value` A {String} such as `'white'`, `#ff00ff`, or
  //   `'rgba(255, 15, 60, .75)'` or an {Object} with `red`, `green`, `blue`,
  //   and `alpha` properties.
  //
  // Returns a {Color} or `null` if it cannot be parsed.
  static parse (value) {
    switch (typeof value) {
      case 'string':
        break
      case 'object':
        if (Array.isArray(value)) { return null }
        break
      default:
        return null
    }

    if (!ParsedColor) {
      ParsedColor = require('color')
    }

    try {
      var parsedColor = new ParsedColor(value)
    } catch (error) {
      return null
    }

    return new Color(parsedColor.red(), parsedColor.green(), parsedColor.blue(), parsedColor.alpha())
  }

  constructor (red, green, blue, alpha) {
    this.red = red
    this.green = green
    this.blue = blue
    this.alpha = alpha
  }

  set red (red) {
    this._red = parseColor(red)
  }

  set green (green) {
    this._green = parseColor(green)
  }

  set blue (blue) {
    this._blue = parseColor(blue)
  }

  set alpha (alpha) {
    this._alpha = parseAlpha(alpha)
  }

  get red () {
    return this._red
  }

  get green () {
    return this._green
  }

  get blue () {
    return this._blue
  }

  get alpha () {
    return this._alpha
  }

  // Essential: Returns a {String} in the form `'#abcdef'`.
  toHexString () {
    return `#${numberToHexString(this.red)}${numberToHexString(this.green)}${numberToHexString(this.blue)}`
  }

  // Essential: Returns a {String} in the form `'rgba(25, 50, 75, .9)'`.
  toRGBAString () {
    return `rgba(${this.red}, ${this.green}, ${this.blue}, ${this.alpha})`
  }

  toJSON () {
    return this.alpha === 1 ? this.toHexString() : this.toRGBAString()
  }

  toString () {
    return this.toRGBAString()
  }

  isEqual (color) {
    if (this === color) {
      return true
    }

    if (!(color instanceof Color)) {
      color = Color.parse(color)
    }

    if (color == null) {
      return false
    }

    return color.red === this.red && color.blue === this.blue && color.green === this.green && color.alpha === this.alpha
  }

  clone () {
    return new Color(this.red, this.green, this.blue, this.alpha)
  }
}

function parseColor (colorString) {
  const color = parseInt(colorString, 10)
  return isNaN(color) ? 0 : Math.min(Math.max(color, 0), 255)
}

function parseAlpha (alphaString) {
  const alpha = parseFloat(alphaString)
  return isNaN(alpha) ? 1 : Math.min(Math.max(alpha, 0), 1)
}

function numberToHexString (number) {
  const hex = number.toString(16)
  return number < 16 ? `0${hex}` : hex
}
<commit_msg>:art:<commit_after>/** @babel */

let ParsedColor = null

// Essential: A simple color class returned from {Config::get} when the value
// at the key path is of type 'color'.
export default class Color {
  // Essential: Parse a {String} or {Object} into a {Color}.
  //
  // * `value` A {String} such as `'white'`, `#ff00ff`, or
  //   `'rgba(255, 15, 60, .75)'` or an {Object} with `red`, `green`, `blue`,
  //   and `alpha` properties.
  //
  // Returns a {Color} or `null` if it cannot be parsed.
  static parse (value) {
    switch (typeof value) {
      case 'string':
        break
      case 'object':
        if (Array.isArray(value)) { return null }
        break
      default:
        return null
    }

    if (!ParsedColor) {
      ParsedColor = require('color')
    }

    try {
      var parsedColor = new ParsedColor(value)
    } catch (error) {
      return null
    }

    return new Color(parsedColor.red(), parsedColor.green(), parsedColor.blue(), parsedColor.alpha())
  }

  constructor (red, green, blue, alpha) {
    this.red = red
    this.green = green
    this.blue = blue
    this.alpha = alpha
  }

  set red (red) {
    this._red = parseColor(red)
  }

  set green (green) {
    this._green = parseColor(green)
  }

  set blue (blue) {
    this._blue = parseColor(blue)
  }

  set alpha (alpha) {
    this._alpha = parseAlpha(alpha)
  }

  get red () {
    return this._red
  }

  get green () {
    return this._green
  }

  get blue () {
    return this._blue
  }

  get alpha () {
    return this._alpha
  }

  // Essential: Returns a {String} in the form `'#abcdef'`.
  toHexString () {
    return `#${numberToHexString(this.red)}${numberToHexString(this.green)}${numberToHexString(this.blue)}`
  }

  // Essential: Returns a {String} in the form `'rgba(25, 50, 75, .9)'`.
  toRGBAString () {
    return `rgba(${this.red}, ${this.green}, ${this.blue}, ${this.alpha})`
  }

  toJSON () {
    return this.alpha === 1 ? this.toHexString() : this.toRGBAString()
  }

  toString () {
    return this.toRGBAString()
  }

  isEqual (color) {
    if (this === color) {
      return true
    }

    if (!(color instanceof Color)) {
      color = Color.parse(color)
    }

    if (color == null) {
      return false
    }

    return color.red === this.red && color.blue === this.blue && color.green === this.green && color.alpha === this.alpha
  }

  clone () {
    return new Color(this.red, this.green, this.blue, this.alpha)
  }
}

function parseColor (colorString) {
  const color = parseInt(colorString, 10)
  return isNaN(color) ? 0 : Math.min(Math.max(color, 0), 255)
}

function parseAlpha (alphaString) {
  const alpha = parseFloat(alphaString)
  return isNaN(alpha) ? 1 : Math.min(Math.max(alpha, 0), 1)
}

function numberToHexString (number) {
  const hex = number.toString(16)
  return number < 16 ? `0${hex}` : hex
}
<|endoftext|>


<commit_before>export default class Color {
  constructor(space, components) {
    this.space      = space;
    this.components = new Map(components);
    this.components.forEach((value, key) => {
      let name = Symbol.keyFor(key);
      Object.defineProperty(this, name, {
        get: () => {
          return function(value = null) {
            if (value === null) {
              return this.get(key);
            }
            this.set(key, value);
            return this;
          }.bind(this);
        }
      });
    });
  }

  clone() {
  }

  isValid() {
    return false;
  }

  has(key) {
    return this.components.has(key);
  }

  get(key) {
    if (!this.has(key)) {
      throw new TypeError();
    }
    return this.components.get(key);
  }

  set(key, value) {
    if (!this.has(key)) {
      throw new TypeError();
    }
    this.components.set(key, value);
    return this;
  }

  keys() {
    return Array.from(this.components.keys());
  }

  values() {
    return Array.from(this.components.values());
  }

  entries() {
    return Array.from(this.components.entries());
  }

  cmy() {
  }

  cmyk() {
  }

  hsl() {
  }

  hsv() {
  }

  hwb() {
  }

  lab() {
  }

  rgb() {
  }

  xyz() {
  }

  yiq() {
  }

  yuv() {
  }

  yxy() {
  }

  static fromString(string) {
    return null;
  }

  static fromObject(object) {
    return null;
  }
}
<commit_msg>Added an abstract method that converts color space to CIE UVW<commit_after>export default class Color {
  constructor(space, components) {
    this.space      = space;
    this.components = new Map(components);
    this.components.forEach((value, key) => {
      let name = Symbol.keyFor(key);
      Object.defineProperty(this, name, {
        get: () => {
          return function(value = null) {
            if (value === null) {
              return this.get(key);
            }
            this.set(key, value);
            return this;
          }.bind(this);
        }
      });
    });
  }

  clone() {
  }

  isValid() {
    return false;
  }

  has(key) {
    return this.components.has(key);
  }

  get(key) {
    if (!this.has(key)) {
      throw new TypeError();
    }
    return this.components.get(key);
  }

  set(key, value) {
    if (!this.has(key)) {
      throw new TypeError();
    }
    this.components.set(key, value);
    return this;
  }

  keys() {
    return Array.from(this.components.keys());
  }

  values() {
    return Array.from(this.components.values());
  }

  entries() {
    return Array.from(this.components.entries());
  }

  cmy() {
  }

  cmyk() {
  }

  hsl() {
  }

  hsv() {
  }

  hwb() {
  }

  lab() {
  }

  rgb() {
  }

  xyz() {
  }

  uvw() {
  }

  yiq() {
  }

  yuv() {
  }

  yxy() {
  }

  static fromString(string) {
    return null;
  }

  static fromObject(object) {
    return null;
  }
}
<|endoftext|>


<commit_before>const Sequelize = require('sequelize');
// Create a database
const connection = new Sequelize('trip_raptor', 'root', '1234');

// example table name 'location'
const location = connection.define('location', {
  title: Sequelize.STRING,
  image: Sequelize.STRING,
});

connection.sync().then(() => {
  console.log('Connected to DB');
});

module.exports = connection;
<commit_msg>rebase<commit_after>const Sequelize = require('sequelize');
// Create a database
const connection = new Sequelize('trip_raptor', 'root', '1234');

// example table name 'location'
const location = connection.define('location', {
  title: Sequelize.STRING,
  image: Sequelize.STRING,
});

connection
  .sync({ force: true })
  .then((err) => {
    console.log('Connected to DB');
  }, (err) => {
    console.log('An error occurred while creating the table:', err);
  });

module.exports = connection;
<|endoftext|>