<commit_before>/**********************************************************\
|                                                          |
|                          hprose                          |
|                                                          |
| Official WebSite: http://www.hprose.com/                 |
|                   http://www.hprose.org/                 |
|                                                          |
\**********************************************************/

/**********************************************************\
 *                                                        *
 * hprose/common/Future.js                                *
 *                                                        *
 * Hprose Future for Node.js.                             *
 *                                                        *
 * LastModified: Jun 22, 2015                             *
 * Author: Ma Bingyao <andot@hprose.com>                  *
 *                                                        *
\**********************************************************/

/*jshint node:true, eqeqeq:true */
'use strict';

function Future() {}

function isFuture(obj) {
    return obj instanceof Future;
}

function isPromise(obj) {
    return (obj && (typeof obj.then === "function"));
}

var pending = 0;
var fulfilled = 1;
var rejected = 2;

function Completer() {
    var _status = pending;
    var _result;
    var _error;
    var _callbacks = [];
    var _future = new Future();

    function run(callback, value) {
        var completer = new Completer();
        global.setTimeout(function() {
            try {
                completer.complete(callback(value));
            }
            catch(e) {
                completer.completeError(e);
            }
        }, 0);
        return completer.future;
    }

    function runComplete(onComplete, onError, result) {
        if (isFuture(result)) {
            if (result === _future) {
                throw new TypeError('Self resolution');
            }
            return result.then(onComplete, onError);
        }
        else if (isPromise(result)) {
            var completer = new Completer();
            try {
                result.then(completer.complete, completer.completeError);
            }
            catch (e) {
                completer.completeError(e);
            }
            return completer.future;
        }
        else if (onComplete) {
            return run(onComplete, result);
        }
        return result;
    }

    // Calling complete must not be done more than once.
    function complete(result) {
        if (_status === pending) {
            _status = fulfilled;
            _result = result;
            while (_callbacks.length > 0) {
                var callback = _callbacks.shift();
                _result = runComplete(callback[0], callback[1], _result);
            }
            _result = result;
        }
    }

    // Calling complete must not be done more than once.
    function completeError(error) {
        if (_status === pending) {
            _status = rejected;
            _error = error;
            while (_callbacks.length > 0) {
                var callback = _callbacks.shift();
                if (callback[1]) {
                    _result = run(callback[1], _error);
                    break;
                }
            }
            if (_callbacks.length > 0) {
                while (_callbacks.length > 0) {
                    var callback = _callbacks.shift();
                    _result = runComplete(callback[0], callback[1], _result);
                }
            }
            _error = error;
        }
    }

    function then(onComplete, onError) {
        if (typeof onComplete !== "function") onComplete = null;
        if (typeof onError !== "function") onError = null;
        if (onComplete || onError) {
            if (onComplete && (_status === fulfilled)) {
                 return runComplete(onComplete, onError, _result);
            }
            if (onError && (_status === rejected)) {
                return run(onError, _error);
            }
            _callbacks.push([onComplete, onError]);
        }
        return _future;
    }

    function catchError(onError) {
        return then(null, onError);
    }

    Object.defineProperties(_future, {
        then: { value: then },
        catchError: { value: catchError },
    });

    Object.defineProperties(this, {
        future: { get: function() { return _future; } },
        complete: { value : complete },
        completeError: { value : completeError }
    });
}

Object.defineProperty(Completer, 'isFuture', { value: isFuture });
Object.defineProperty(Completer, 'isPromise', { value: isPromise });

global.hprose.Completer = Completer;
<commit_msg>Improved Future.<commit_after>/**********************************************************\
|                                                          |
|                          hprose                          |
|                                                          |
| Official WebSite: http://www.hprose.com/                 |
|                   http://www.hprose.org/                 |
|                                                          |
\**********************************************************/

/**********************************************************\
 *                                                        *
 * hprose/common/Future.js                                *
 *                                                        *
 * Hprose Future for Node.js.                             *
 *                                                        *
 * LastModified: Jun 22, 2015                             *
 * Author: Ma Bingyao <andot@hprose.com>                  *
 *                                                        *
\**********************************************************/

/*jshint node:true, eqeqeq:true */
'use strict';

function Future() {}

function isFuture(obj) {
    return obj instanceof Future;
}

function isPromise(obj) {
    return (obj && (typeof obj.then === "function"));
}

var pending = 0;
var fulfilled = 1;
var rejected = 2;

function Completer() {
    var _status = pending;
    var _result;
    var _error;
    var _callbacks = [];
    var _future = new Future();

    function run(callback, y) {
        var completer = new Completer();
        global.setTimeout(function() {
            try {
                completer.complete(callback(y));
            }
            catch(e) {
                completer.completeError(e);
            }
        }, 0);
        return completer.future;
    }

    function runComplete(onComplete, onError, x) {
        if (isFuture(x)) {
            if (x === _future) {
                throw new TypeError('Self resolution');
            }
            return x.then(onComplete, onError);
        }
        else if ((typeof obj === "object") || (typeof obj === "function")) {
            var completer = new Completer();
            var then;
            try {
                then = x.then;
            }
            catch (e) {
                completer.completeError(e);
                return completer.future;
            }
            if (typeof then === "function") {
                try {
                    then.call(x, completer.complete, completer.completeError);
                }
                catch (e) {
                    completer.completeError(e);
                }
                return completer.future;
            }
            else {
                return run(onComplete, x);
            }
        }
        else if (onComplete) {
            return run(onComplete, x);
        }
        return x;
    }

    // Calling complete must not be done more than once.
    function complete(result) {
        if (_status === pending) {
            _status = fulfilled;
            _result = result;
            while (_callbacks.length > 0) {
                var callback = _callbacks.shift();
                _result = runComplete(callback[0], callback[1], _result);
            }
            _result = result;
        }
    }

    // Calling complete must not be done more than once.
    function completeError(error) {
        if (_status === pending) {
            _status = rejected;
            _error = error;
            while (_callbacks.length > 0) {
                var callback = _callbacks.shift();
                if (callback[1]) {
                    _result = run(callback[1], _error);
                    break;
                }
            }
            if (_callbacks.length > 0) {
                while (_callbacks.length > 0) {
                    var callback = _callbacks.shift();
                    _result = runComplete(callback[0], callback[1], _result);
                }
            }
            _error = error;
        }
    }

    function then(onComplete, onError) {
        if (typeof onComplete !== "function") onComplete = null;
        if (typeof onError !== "function") onError = null;
        if (onComplete || onError) {
            if (onComplete && (_status === fulfilled)) {
                 return runComplete(onComplete, onError, _result);
            }
            if (onError && (_status === rejected)) {
                return run(onError, _error);
            }
            _callbacks.push([onComplete, onError]);
        }
        return _future;
    }

    function catchError(onError) {
        return then(null, onError);
    }

    Object.defineProperties(_future, {
        then: { value: then },
        catchError: { value: catchError },
    });

    Object.defineProperties(this, {
        future: { get: function() { return _future; } },
        complete: { value : complete },
        completeError: { value : completeError }
    });
}

Object.defineProperty(Completer, 'isFuture', { value: isFuture });
Object.defineProperty(Completer, 'isPromise', { value: isPromise });

global.hprose.Completer = Completer;
<|endoftext|>


<commit_before>window.computedStyle = function () {
  return null;
};<commit_msg>Basic property returns rgb x_x<commit_after>window.computedStyle = function (el, prop) {
  return el.style[prop];
};<|endoftext|>


<commit_before>import {List, Map} from 'immutable';
import {expect} from 'chai';
import {setEntries, next, vote} from '../src/core';

describe('application logic', () => {

    /* The application allows loading in a collection of entries to be voted on.
     * We should have a function that takes a previous state and produces a state
     * where the entries are included. The test is to check setEntries does that.
    * */
    describe('setEntries', () => {

        it('adds the entries to the state', () => {
            const state = Map();
            const entries = ['Trainspotting', '28 Days Later'];
            const nextState = setEntries(state, entries);
            expect(nextState).to.equal(Map({
                entries: List.of('Trainspotting', '28 Days Later')
            }));
        });

        /* For convenience we'll allow the input entries to be a regular JavaScript
         * array (or anything iterable). It should be an Immutable List by the time it
         * gets to the state tree.
         * */
        it('converts to immutable', () => {
            const state = Map();
            const entries = ['Trainspotting', '28 Days Later'];
            const nextState = setEntries(state, entries);
            expect(nextState).to.equal(Map({
                entries: List.of('Trainspotting', '28 Days Later')
            }));
        });
    });

    /* The voting can begin by calling next on a state that already has entries set.
     * The function takes no additional arguments.
     * It should create a vote map where the first two entries are included under the key 'pair'.
     * The entries under vote should no longer be in the vote list.
    * */
    describe('next', () => {

        it('takes the next two entries under vote', () => {
            const state = Map({
                entries: List.of('Trainspotting', '28 Days Later', 'Sunshine')
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of('Trainspotting', '28 Days Later')
                }),
                entries: List.of('Sunshine')
            }));
        });
        it('puts the winner of the current vote back to the entries', () => {
            const state = Map({
                vote: Map({
                   pair: List.of('Trainspotting', '28 Days Later'),
                   tally: Map({
                       'Trainspotting': 4,
                       '28 Days Later': 2
                   })
               }),
               entries: List.of('Sunshine', 'Millions', '127 Hours')
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of('Sunshine', 'Millions'),
                }),
                entries: List.of('127 Hours', 'Trainspotting')
            }));
        });
        it('puts both from tied entries', () => {
            const state = Map({
                vote: Map({
                    pair: List.of('Trainspotting', '28 Days Later'),
                    tally: Map({
                        'Trainspotting': 3,
                        '28 Days Later': 3
                    })
                }),
                entries: List.of('Sunshine', 'Millions', '127 Hours')
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of('Sunshine', 'Millions')
                }),
                entries: List.of('127 Hours', 'Trainspotting', '28 Days Later')
            }));
        });
        it('marks winner when just one entry left', () => {
            const state = Map({
                vote: Map({
                    pair: List.of('Trainspotting', '28 Days Later'),
                    tally: Map({
                        'Trainspotting': 4,
                        '28 Days Later': 2
                    })
                }),
                entries: List()
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                winner: 'Trainspotting'
            }));
        });

    });

    describe('vote', () => {

        it('creates a tally for the voted entry', () => {
            const state = Map({
                pair: List.of('Trainspotting', '28 Days Later')
            });
            const nextState = vote(state, 'Trainspotting');
            expect(nextState).to.equal(Map({
                pair: List.of('Trainspotting', '28 Days Later'),
                tally: Map({
                    'Trainspotting': 1
                })
            }));
        });
        it('adds to an existing tally for the voted entry', () => {
            const state = Map({
                pair: List.of('Trainspotting', '28 Days Later'),
                tally: Map({
                    'Trainspotting': 3,
                    '28 Days Later': 2
                })
            });
            const nextState = vote(state, 'Trainspotting');
            expect(nextState).to.equal(Map({
                pair: List.of('Trainspotting', '28 Days Later'),
                tally: Map({
                    'Trainspotting': 4,
                    '28 Days Later': 2
                })
            }));
        });
    });

});

<commit_msg>documentation for logic testing<commit_after>import {List, Map} from 'immutable';
import {expect} from 'chai';
import {setEntries, next, vote} from '../src/core';

describe('application logic', () => {

    /* The application allows loading in a collection of entries to be voted on.
     * We should have a function that takes a previous state and produces a state
     * where the entries are included. The test is to check setEntries does that.
    * */
    describe('setEntries', () => {

        it('adds the entries to the state', () => {
            const state = Map();
            const entries = ['Trainspotting', '28 Days Later'];
            const nextState = setEntries(state, entries);
            expect(nextState).to.equal(Map({
                entries: List.of('Trainspotting', '28 Days Later')
            }));
        });

        /* For convenience we'll allow the input entries to be a regular JavaScript
         * array (or anything iterable). It should be an Immutable List by the time it
         * gets to the state tree.
         * */
        it('converts to immutable', () => {
            const state = Map();
            const entries = ['Trainspotting', '28 Days Later'];
            const nextState = setEntries(state, entries);
            expect(nextState).to.equal(Map({
                entries: List.of('Trainspotting', '28 Days Later')
            }));
        });
    });

    /* The voting can begin by calling next on a state that already has entries set.
     * The function takes no additional arguments.
     * It should create a vote map where the first two entries are included under the key 'pair'.
     * The entries under vote should no longer be in the vote list.
    * */
    describe('next', () => {

        it('takes the next two entries under vote', () => {
            const state = Map({
                entries: List.of('Trainspotting', '28 Days Later', 'Sunshine')
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of('Trainspotting', '28 Days Later')
                }),
                entries: List.of('Sunshine')
            }));
        });
        it('puts the winner of the current vote back to the entries', () => {
            const state = Map({
                vote: Map({
                   pair: List.of('Trainspotting', '28 Days Later'),
                   tally: Map({
                       'Trainspotting': 4,
                       '28 Days Later': 2
                   })
               }),
               entries: List.of('Sunshine', 'Millions', '127 Hours')
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of('Sunshine', 'Millions'),
                }),
                entries: List.of('127 Hours', 'Trainspotting')
            }));
        });
        it('puts both from tied entries', () => {
            const state = Map({
                vote: Map({
                    pair: List.of('Trainspotting', '28 Days Later'),
                    tally: Map({
                        'Trainspotting': 3,
                        '28 Days Later': 3
                    })
                }),
                entries: List.of('Sunshine', 'Millions', '127 Hours')
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of('Sunshine', 'Millions')
                }),
                entries: List.of('127 Hours', 'Trainspotting', '28 Days Later')
            }));
        });
        it('marks winner when just one entry left', () => {
            const state = Map({
                vote: Map({
                    pair: List.of('Trainspotting', '28 Days Later'),
                    tally: Map({
                        'Trainspotting': 4,
                        '28 Days Later': 2
                    })
                }),
                entries: List()
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                winner: 'Trainspotting'
            }));
        });

    });

    /* When a vote is ongoing in should be possible for people to vote on entries.
     * When a new vote is cast for an entry, a 'tally' for it should appear in the vote.
     * If there is already a tally, it should be incremented.
    * */
    describe('vote', () => {

        it('creates a tally for the voted entry', () => {
            const state = Map({
                pair: List.of('Trainspotting', '28 Days Later')
            });
            const nextState = vote(state, 'Trainspotting');
            expect(nextState).to.equal(Map({
                pair: List.of('Trainspotting', '28 Days Later'),
                tally: Map({
                    'Trainspotting': 1
                })
            }));
        });
        it('adds to an existing tally for the voted entry', () => {
            const state = Map({
                pair: List.of('Trainspotting', '28 Days Later'),
                tally: Map({
                    'Trainspotting': 3,
                    '28 Days Later': 2
                })
            });
            const nextState = vote(state, 'Trainspotting');
            expect(nextState).to.equal(Map({
                pair: List.of('Trainspotting', '28 Days Later'),
                tally: Map({
                    'Trainspotting': 4,
                    '28 Days Later': 2
                })
            }));
        });
    });

});

<|endoftext|>


<commit_before>/*
 *   Copyright 2014-2015 Guy Bedford (http://guybedford.com)
 *
 *   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.
 */
var ConfigFileBase = require('./file-base');
var PackageName = require('../package-name');
var ui = require('../ui');
var registry = require('../registry');

/*
 * Loader configuration class
 *
 * Public Properties:
 * - baseMap
 * - depMap
 * - upgrade16
 *
 * Public Methods:
 * - ensureRegistry(registryName)
 * - getConfig
 * - prompt
 * - write
 */
module.exports = LoaderConfig;
function LoaderConfig(fileName) {
  this.file = new LoaderConfigFile(fileName, [
    'baseURL',
    'packageConfigPaths',
    'paths',
    'map',
    'packages'
  ]);

  var emptyConfig = this.file.properties.length == 0;

  var self = this;

  // the base install map is the global map config
  this.baseMap = {};
  var map = this.file.getObject(['map']);
  Object.keys(map).forEach(function(key) {
    self.baseMap[key] = new PackageName(map[key]);
  });

  // the dep map is the package contextual map
  this.depMap = {};
  (this.file.getProperties(['packages']) || []).forEach(function(prop) {
    if (!self.file.has(['packages', prop.key, 'map']))
      return;
    var curMap = self.depMap[prop.key] = self.file.getObject(['packages', prop.key, 'map']);
    Object.keys(curMap).forEach(function(key) {
      curMap[key] = new PackageName(curMap[key]);
    });
  });

  // downgrade back to jspm 0.16 then upgrade can mess packageConfigPaths
  this.upgrade16 = false;

  // packageConfigPaths is the indicator property in the config to know if the project is jspm 0.17-ready
  // if the config file doesn't exist, then we assume the project is jspm 0.17-ready
  var packageConfigPaths;
  try {
    packageConfigPaths = this.file.getProperties(['packageConfigPaths']);
  }
  catch(e) {}
  if (packageConfigPaths) {
    this.upgrade16 = !emptyConfig;
    this.file.setValue(['packageConfigPaths'], Object.keys(packageConfigPaths || {}).map(function(path) {
      return packageConfigPaths[path];
    }));
  }
}
LoaderConfig.prototype.ensureRegistry = function(registryName) {
  // ensure packageNameFormats are present as packageConfigPaths in the right order
  var packageConfigPaths = this.file.getValue(['packageConfigPaths'], 'array');

  var lastIndex;
  (registry.load(registryName).constructor.packageNameFormats || ['*'])
  .forEach(function(packageNameFormat) {
    var packageConfigPath = registryName + ':' + packageNameFormat + '.json';

    var curIndex = packageConfigPaths.indexOf(packageConfigPath);

    // add if not present
    if (curIndex == -1) {
      packageConfigPaths.push(packageConfigPath);
    }
    // reorder if not in order
    else {
      if (curIndex < lastIndex)
        packageConfigPaths.splice(curIndex, 1);

      lastIndex = curIndex;
    }
  });
};
LoaderConfig.prototype.removePackage = function(exactName) {
  delete this.depMap[exactName];
  this.file.remove(['packages', exactName]);
};
LoaderConfig.prototype.write = function() {
  this.syncFile();
  this.file.write();
};
LoaderConfig.prototype.toJSON = function() {
  this.syncFile();
  return this.file.toJSON();
};

// ensure baseMap and depMap are synced to file config
LoaderConfig.prototype.syncFile = function() {
  var self = this;

  var baseMap = {};
  Object.keys(this.baseMap).forEach(function(name) {
    baseMap[name] = self.baseMap[name].toString();
  });

  this.file.setObject(['map'], baseMap);

  Object.keys(this.depMap).forEach(function(parentName) {
    var depMap = {};
    Object.keys(self.depMap[parentName]).forEach(function(name) {
      depMap[name] = self.depMap[parentName][name].toString();
    });
    self.file.setObject(['packages', parentName, 'map'], depMap);
  });
};

LoaderConfig.prototype.getConfig = function() {
  this.syncFile();
  return this.file.getObject([], true);
};

/*
 * LoaderConfigFile
 * Extends ConfigFile, implementing specific jspm config serialization and deserialization
 */
function LoaderConfigFile(fileName, ordering) {
  ConfigFileBase.call(this, fileName, ordering);
}
LoaderConfigFile.prototype = Object.create(ConfigFileBase.prototype);
LoaderConfigFile.prototype.serialize = function(obj) {
  // base class serialize is JSON serialization of properties
  var serializedString = ConfigFileBase.prototype.serialize.call(this, obj);

  var tab = this.style.tab;
  var quote = this.style.quote;
  var newline = this.style.newline;
  var trailingNewline = this.style.trailingNewline;

  return ('System.config(' + serializedString.trim() + ');' + (trailingNewline ? newline : ''))
      // add a newline before "meta", "depCache", "map" blocks, removing quotes
      .replace(new RegExp('^' + tab + quote + '(meta|depCache|map|packages)' + quote, 'mg'), newline + tab + '$1')
      // remove quotes on first-level letter-based properties
      .replace(new RegExp('^' + tab + quote + '(\\w+)' + quote, 'mg'), tab + '$1');
};
LoaderConfigFile.prototype.deserialize = function(configString) {
  /*jshint unused:false */
  var cfg = {};
  var System = {
    config: function(_cfg) {
      for (var c in _cfg) {
        var v = _cfg[c];
        if (typeof v === 'object' && (!(v instanceof Array))) {
          cfg[c] = cfg[c] || {};
          for (var p in v)
            cfg[c][p] = v[p];
        }
        else {
          cfg[c] = v;
        }
      }
    },
    paths: {},
    map: {}
  };
  eval(configString.toString());
  return cfg;
};

// NB finish this
LoaderConfig.prototype.prompt = function() {
  var self = this;

  return ui.input('Enter the browser %baseURL% (absolute path) corresponding to the `directories.baseURL`, optional', self.baseURL, {
    edit: self.baseURL == '/'
  })
  .then(function(baseURL) {
    self.baseURL = baseURL;

    return ui.input('Enter the module %format% of your package - `ESM` (ES2015 module), `CJS` or `AMD`', self.format || 'esm', {
      completions: ['esm', 'cjs', 'amd', 'global', 'system', 'systemjs', 'register', 'ESM', 'CJS', 'AMD', 'Global', 'System', 'SystemJS', 'Register']
    })
    .then(function(format) {
      format = format.toLowerCase();
      if (format == 'system' || format == 'systemjs')
        format = 'register';
      if (['esm', 'cjs', 'amd', 'global', 'register'].indexOf(format) == -1) {
        ui.log('info', '%' + format + '% is not a vaild module format. Defaulting to `esm`.');
        return 'esm';
      }
      return format;
    })
    .then(function(format) {
      self.format = format;
      return ui.input('Enter the %main% entry point of your package within %' + (self.isDist ? self.dist : self.lib || self.dist) + '%', self.main || self.name + '.js');
    })
    .then(function(main) {
      self.main = main;
    });
  });

    // all package properties get their defaults from the package.json itself
    /* return ui.confirm('Would you like to configure package loader plugins for custom loading and transpilation?', true);
  })
  .then(function(loaderConfig) {
    if (!loaderConfig)
      return;

    ui.log('info', 'TODO!'); */

    /* return ui.confirm('Would you like to use a transpiler for the package?', true)
    .then(function(transpile) {
      // NB disable self.transpiler
      ui.log('info', 'TODO!');
    }); */
};
<commit_msg>make globalEvaluationScope: false the default<commit_after>/*
 *   Copyright 2014-2015 Guy Bedford (http://guybedford.com)
 *
 *   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.
 */
var ConfigFileBase = require('./file-base');
var PackageName = require('../package-name');
var ui = require('../ui');
var registry = require('../registry');

/*
 * Loader configuration class
 *
 * Public Properties:
 * - baseMap
 * - depMap
 * - upgrade16
 *
 * Public Methods:
 * - ensureRegistry(registryName)
 * - getConfig
 * - prompt
 * - write
 */
module.exports = LoaderConfig;
function LoaderConfig(fileName) {
  this.file = new LoaderConfigFile(fileName, [
    'baseURL',
    'packageConfigPaths',
    'globalEvaluationScope',
    'paths',
    'map',
    'packages'
  ]);

  var emptyConfig = this.file.properties.length == 0;

  var self = this;

  // the base install map is the global map config
  this.baseMap = {};
  var map = this.file.getObject(['map']);
  Object.keys(map).forEach(function(key) {
    self.baseMap[key] = new PackageName(map[key]);
  });

  // the dep map is the package contextual map
  this.depMap = {};
  (this.file.getProperties(['packages']) || []).forEach(function(prop) {
    if (!self.file.has(['packages', prop.key, 'map']))
      return;
    var curMap = self.depMap[prop.key] = self.file.getObject(['packages', prop.key, 'map']);
    Object.keys(curMap).forEach(function(key) {
      curMap[key] = new PackageName(curMap[key]);
    });
  });

  // downgrade back to jspm 0.16 then upgrade can mess packageConfigPaths
  this.upgrade16 = false;

  // packageConfigPaths is the indicator property in the config to know if the project is jspm 0.17-ready
  // if the config file doesn't exist, then we assume the project is jspm 0.17-ready
  var packageConfigPaths;
  try {
    packageConfigPaths = this.file.getProperties(['packageConfigPaths']);
  }
  catch(e) {}
  if (packageConfigPaths) {
    this.upgrade16 = !emptyConfig;
    this.file.setValue(['packageConfigPaths'], Object.keys(packageConfigPaths || {}).map(function(path) {
      return packageConfigPaths[path];
    }));
  }

  if (!this.file.has(['globalEvaluationScope']))
    this.file.setValue(['globalEvaluationScope'], false);
}
LoaderConfig.prototype.ensureRegistry = function(registryName) {
  // ensure packageNameFormats are present as packageConfigPaths in the right order
  var packageConfigPaths = this.file.getValue(['packageConfigPaths'], 'array');

  var lastIndex;
  (registry.load(registryName).constructor.packageNameFormats || ['*'])
  .forEach(function(packageNameFormat) {
    var packageConfigPath = registryName + ':' + packageNameFormat + '.json';

    var curIndex = packageConfigPaths.indexOf(packageConfigPath);

    // add if not present
    if (curIndex == -1) {
      packageConfigPaths.push(packageConfigPath);
    }
    // reorder if not in order
    else {
      if (curIndex < lastIndex)
        packageConfigPaths.splice(curIndex, 1);

      lastIndex = curIndex;
    }
  });
};
LoaderConfig.prototype.removePackage = function(exactName) {
  delete this.depMap[exactName];
  this.file.remove(['packages', exactName]);
};
LoaderConfig.prototype.write = function() {
  this.syncFile();
  this.file.write();
};
LoaderConfig.prototype.toJSON = function() {
  this.syncFile();
  return this.file.toJSON();
};

// ensure baseMap and depMap are synced to file config
LoaderConfig.prototype.syncFile = function() {
  var self = this;

  var baseMap = {};
  Object.keys(this.baseMap).forEach(function(name) {
    baseMap[name] = self.baseMap[name].toString();
  });

  this.file.setObject(['map'], baseMap);

  Object.keys(this.depMap).forEach(function(parentName) {
    var depMap = {};
    Object.keys(self.depMap[parentName]).forEach(function(name) {
      depMap[name] = self.depMap[parentName][name].toString();
    });
    self.file.setObject(['packages', parentName, 'map'], depMap);
  });
};

LoaderConfig.prototype.getConfig = function() {
  this.syncFile();
  return this.file.getObject([], true);
};

/*
 * LoaderConfigFile
 * Extends ConfigFile, implementing specific jspm config serialization and deserialization
 */
function LoaderConfigFile(fileName, ordering) {
  ConfigFileBase.call(this, fileName, ordering);
}
LoaderConfigFile.prototype = Object.create(ConfigFileBase.prototype);
LoaderConfigFile.prototype.serialize = function(obj) {
  // base class serialize is JSON serialization of properties
  var serializedString = ConfigFileBase.prototype.serialize.call(this, obj);

  var tab = this.style.tab;
  var quote = this.style.quote;
  var newline = this.style.newline;
  var trailingNewline = this.style.trailingNewline;

  return ('System.config(' + serializedString.trim() + ');' + (trailingNewline ? newline : ''))
      // add a newline before "meta", "depCache", "map" blocks, removing quotes
      .replace(new RegExp('^' + tab + quote + '(meta|depCache|map|packages)' + quote, 'mg'), newline + tab + '$1')
      // remove quotes on first-level letter-based properties
      .replace(new RegExp('^' + tab + quote + '(\\w+)' + quote, 'mg'), tab + '$1');
};
LoaderConfigFile.prototype.deserialize = function(configString) {
  /*jshint unused:false */
  var cfg = {};
  var System = {
    config: function(_cfg) {
      for (var c in _cfg) {
        var v = _cfg[c];
        if (typeof v === 'object' && (!(v instanceof Array))) {
          cfg[c] = cfg[c] || {};
          for (var p in v)
            cfg[c][p] = v[p];
        }
        else {
          cfg[c] = v;
        }
      }
    },
    paths: {},
    map: {}
  };
  eval(configString.toString());
  return cfg;
};

// NB finish this
LoaderConfig.prototype.prompt = function() {
  var self = this;

  return ui.input('Enter the browser %baseURL% (absolute path) corresponding to the `directories.baseURL`, optional', self.baseURL, {
    edit: self.baseURL == '/'
  })
  .then(function(baseURL) {
    self.baseURL = baseURL;

    return ui.input('Enter the module %format% of your package - `ESM` (ES2015 module), `CJS` or `AMD`', self.format || 'esm', {
      completions: ['esm', 'cjs', 'amd', 'global', 'system', 'systemjs', 'register', 'ESM', 'CJS', 'AMD', 'Global', 'System', 'SystemJS', 'Register']
    })
    .then(function(format) {
      format = format.toLowerCase();
      if (format == 'system' || format == 'systemjs')
        format = 'register';
      if (['esm', 'cjs', 'amd', 'global', 'register'].indexOf(format) == -1) {
        ui.log('info', '%' + format + '% is not a vaild module format. Defaulting to `esm`.');
        return 'esm';
      }
      return format;
    })
    .then(function(format) {
      self.format = format;
      return ui.input('Enter the %main% entry point of your package within %' + (self.isDist ? self.dist : self.lib || self.dist) + '%', self.main || self.name + '.js');
    })
    .then(function(main) {
      self.main = main;
    });
  });

    // all package properties get their defaults from the package.json itself
    /* return ui.confirm('Would you like to configure package loader plugins for custom loading and transpilation?', true);
  })
  .then(function(loaderConfig) {
    if (!loaderConfig)
      return;

    ui.log('info', 'TODO!'); */

    /* return ui.confirm('Would you like to use a transpiler for the package?', true)
    .then(function(transpile) {
      // NB disable self.transpiler
      ui.log('info', 'TODO!');
    }); */
};
<|endoftext|>


<commit_before>var µ=require("Morgas");
var gui=require("MorgasGui");
(function(µ,SMOD,GMOD,HMOD,SC){

	var SC=µ.shortcut({
		File:"File",
		Config:"Config"
	});

	/**
	 * @typedef {Object} configSetting
	 * @property {String} type - "string", "boolean", "number" or "select"
	 * @property {*} [value=null] - default value
	 * @property {*|*[]} [values=null] - possible values for select type
	 */

	/**
	 * @param {Object} configSettings.<String, String|configSetting> - dictionary of config attributes
	 * possible strings : "string","boolean","number","select"
	 */
	module.exports=function(config)
	{
		if(!(config instanceof SC.Config)) config=SC.Config.parse(config);
		try
		{
			config.setAll(require("../config/"+worker.name+".config"),true);
		}
		catch (e)
		{
			µ.logger.warn({error:e},"could not load config");
		}
		return function(param)
		{
			switch(param.method)
			{
				default:
				case "GET":
					return config.toJSON();
					break;
				case "POST":
					var key=param.data.key.split(/\]?\.|\[/);
					settings.set(param.key,param.data.value);
					//TODO save & notify
					break;
				case "OPTIONS":
					return {
						description:config.toDescription(),
						value:config.toJSON()
					};
			}
		}
	};

})(Morgas,Morgas.setModule,Morgas.getModule,Morgas.hasModule,Morgas.shortcut);
<commit_msg>load,set & save config<commit_after>var µ=require("Morgas");
var gui=require("MorgasGui");
(function(µ,SMOD,GMOD,HMOD,SC){

	var SC=µ.shortcut({
		File:"File",
		util:"File.util",
		Config:"Config"
	});
	/**
	 * @typedef {Object} configSetting
	 * @property {String} type - "string", "boolean", "number" or "select"
	 * @property {*} [value=null] - default value
	 * @property {*|*[]} [values=null] - possible values for select type
	 */

	/**
	 * @param {Object} configSettings.<String, String|configSetting> - dictionary of config attributes
	 * possible strings : "string","boolean","number","select"
	 */
	module.exports=function(config)
	{
		if(!(config instanceof SC.Config)) config=SC.Config.parse(config);
		var configFile=new SC.File(__dirname).changePath("../config/"+worker.name+".config");
		SC.util.getRotatedFile(configFile,JSON.parse)
		.then(result=>
		{
			if(result.others.length>0)
			{
				for(var other of result.others)
				{
					µ.logger.warn({error:other.error,file:other.file},"error loading config");
				}
				µ.logger.warn("load file "+result.file+" instead")
			}
			config.setAll(result.data,true)
		}, errors=>µ.logger.warn({errors:errors},"could not load config"));

		return function(param)
		{
			switch(param.method)
			{
				default:
				case "GET":
					return config.toJSON();
					break;
				case "POST":
					var key=param.data.key.split(/\]?\.|\[/);
					if(config.set(param.data.key,param.data.value))
					{
						//TODO save & notify
						return configFile.exists().then(()=>SC.util.rotateFile(configFile,3),()=>null)
						.then(()=>configFile.write(JSON.stringify(config.get())))
						.then(()=>({result:true}));
					}
					return {result:false};
					break;
				case "OPTIONS":
					return {
						description:config.toDescription(),
						value:config.toJSON()
					};
			}
		}
	};

})(Morgas,Morgas.setModule,Morgas.getModule,Morgas.hasModule,Morgas.shortcut);
<|endoftext|>


<commit_before>import React, { Component } from 'React';
import { Form, Button, Checkbox } from 'semantic-ui-react';

export default class AddActivity extends Component {
  constructor(props) {
    super(props);
    this.state = {
      firstname: '',
      nickname: '',
      lastname: '',
      address: '',
      city: '',
      state: '',
      zip: '',
      email: '',
      cellphone: '',
      homephone: '',
      birthday: '',
      handbook: false,
      orangeneckerchief: false,
      thunderbirdneckerchief: false,
      adult: false,
      active: true
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleCheckbox = this.handleCheckbox.bind(this);
  }

  handleChange(event) {
    console.log(event.target.name,event.target.value)
    const value = event.target.name;
    this.setState({ [value]: event.target.value})
  }

  handleSubmit(event) {
    console.log('handleSubmit: ', this.state);
    event.preventDefault();
  }
  render() {
    console.log('render-->', this.props);
    if (!this.props.view) {
      return

    }
    return (

        Update Profile
        <Form onSubmit={this.handleSubmit}>
          <Form.Group widths='equal'>
            <Form.Field>

              <input
                name='firstname'
                placeholder='First Name'
                value={this.state.firstname}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                name='nickname'
                placeholder='Nickname'
                value={this.state.nickname}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                name='lastname'
                placeholder='Last Name'
                value={this.state.lastname}
                onChange={this.handleChange}/>

            </Form.Field>
          </Form.Group>
          <Form.Group inline>
            <Form.Field>

              <input
                width={7}
                name='address'
                placeholder='Address'
                value={this.state.address}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                width={6}
                name='city'
                placeholder='City'
                value={this.state.city}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                width={1}
                name='state'
                placeholder='State'
                value={this.state.state}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                width={2}
                name='zip'
                placeholder='Zip'
                value={this.state.zip}
                onChange={this.handleChange}/>

            </Form.Field>
          </Form.Group>
          <Form.Group widths='equal'>
            <Form.Field>

              <input
                name='email'
                placeholder='Email'
                value={this.state.email}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                name='cellphone'
                placeholder='Cell Phone'
                value={this.state.cellphone}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                name='homephone'
                placeholder='Home Phone'
                value={this.state.homephone}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                name='birthday'
                placeholder='Birthday'
                value={this.state.birthday}
                onChange={this.handleChange}/>

            </Form.Field>
          </Form.Group>
          <Form.Group>
            <Checkbox
              toggle
              name='handbook'
              label='Read Handbook'
              value={this.state.handbook}
              onChange={this.handleCheckbox}
            />
            <Checkbox
              toggle
              name='orangeneckerchief'
              label='Orange Neckerchief'
              value={this.state.orangeneckerchief}
              onChange={this.handleCheckbox}
            />
            <Checkbox
              toggle
              name='thunderbirdneckerchief'
              label='T-bird Neckerchief'
              value={this.state.thunderbirdneckerchief}
              onChange={this.handleCheckbox}
            />
            <Checkbox
              toggle
              name='adult'
              label='Adult'
              value={this.state.adult}
              onChange={this.handleCheckbox}
            />
            <Checkbox
              toggle
              name='active'
              label='Active'
              value='active'
              onChange={this.handleCheckbox}
            />
          </Form.Group>
          <Button type='submit' value='Submit'>Submit</Button>
        </Form>

    )
  }
  handleCheckbox(event) {
    console.log('handleCheckbox: ', event.target.name)
    const T = this.state[event.target.name];
    console.log(event.target.name + ' value: ', this.state[event.target.name])
    // if (event.target.name = 'handbook') {
      T ? !T : T;
      this.setState({ [event.target.name]: T})
    // }
    console.log('End handleCheckbox: ',event.target.name, T);
  }
}
<commit_msg>retrieved data from checkboxes, ready to submit updated form to db<commit_after>import React, { Component } from 'React';
import { Form, Button, Checkbox } from 'semantic-ui-react';

export default class AddActivity extends Component {
  constructor(props) {
    super(props);
    this.state = {
      firstname: '',
      nickname: '',
      lastname: '',
      address: '',
      city: '',
      state: '',
      zip: '',
      email: '',
      cellphone: '',
      homephone: '',
      birthday: '',
      handbook: false,
      orangeneckerchief: false,
      thunderbirdneckerchief: false,
      adult: true,
      active: true
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleCheckbox = this.handleCheckbox.bind(this);
  }

  handleChange(event) {
    const value = event.target.name;
    this.setState({ [value]: event.target.value})
  }

  handleSubmit(event) {
    console.log('handleSubmit: ', this.state);
    event.preventDefault();
  }
  render() {
    // console.log('render-->', this.props);
    if (!this.props.view) {
      return

    }
    return (

        Update Profile
        <Form onSubmit={this.handleSubmit}>
          <Form.Group widths='equal'>
            <Form.Field>

              <input
                name='firstname'
                placeholder='First Name'
                value={this.state.firstname}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                name='nickname'
                placeholder='Nickname'
                value={this.state.nickname}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                name='lastname'
                placeholder='Last Name'
                value={this.state.lastname}
                onChange={this.handleChange}/>

            </Form.Field>
          </Form.Group>
          <Form.Group inline>
            <Form.Field>

              <input
                width={7}
                name='address'
                placeholder='Address'
                value={this.state.address}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                width={6}
                name='city'
                placeholder='City'
                value={this.state.city}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                width={1}
                name='state'
                placeholder='State'
                value={this.state.state}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                width={2}
                name='zip'
                placeholder='Zip'
                value={this.state.zip}
                onChange={this.handleChange}/>

            </Form.Field>
          </Form.Group>
          <Form.Group widths='equal'>
            <Form.Field>

              <input
                name='email'
                placeholder='Email'
                value={this.state.email}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                name='cellphone'
                placeholder='Cell Phone'
                value={this.state.cellphone}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                name='homephone'
                placeholder='Home Phone'
                value={this.state.homephone}
                onChange={this.handleChange}/>

            </Form.Field>
            <Form.Field>

              <input
                name='birthday'
                placeholder='Birthday'
                value={this.state.birthday}
                onChange={this.handleChange}/>

            </Form.Field>
          </Form.Group>
          <Form.Group widths='equal'>
            <Checkbox
              toggle
              type='checkbox'
              name='handbook'
              label='Read Handbook'
              checked={this.state.handbook}
              onChange={this.handleCheckbox}
            />

            <Checkbox
              toggle
              name='orangeneckerchief'
              label='Orange Neckerchief'
              checked={this.state.orangeneckerchief}
              onChange={this.handleCheckbox}
            />

            <Checkbox
              toggle
              type='checkbox'
              name='thunderbirdneckerchief'
              label='T-bird Neckerchief'
              checked={this.state.thunderbirdneckerchief}
              onChange={this.handleCheckbox}
            />

            <Checkbox
              toggle
              type='checkbox'
              name='adult'
              label='Adult'
              checked={this.state.adult}
              onChange={this.handleCheckbox}
            />

            <Checkbox
              toggle
              type='checkbox'
              name='active'
              label='Active'
              checked={this.state.active}
              onChange={this.handleCheckbox}
            />

          </Form.Group>
          <Button type='submit' value='Submit'>Submit</Button>
        </Form>

    )
  }
  handleCheckbox(event, data) {
    console.log('handleCheckbox: ', data)
    const key = data.name;
    const value = data.checked;
    console.log([key] + ' value: ', value)
      this.setState({ [key]: value})
  }
}
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015,2016 Telefónica Investigación y Desarrollo, S.A.U
 *
 * 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.
 */

'use strict';

var _ = require('lodash'),
    changeCase = require('change-case'),
    fs = require('fs'),
    yargs = require('yargs'),
    hjson = require('hjson'),
    yaml = require('js-yaml'),
    path = require('path'),
    therror = require('therror');

var errors = therror.register({
  FILE_INVALID: {
    message: 'Invalid configuration file: "{1}". {2}'
  }
});

/**
 * Configuration class to merge configuration from:
 *
 *  - file(path): configuration files (if path targets a configuration file) or configuration directories
 *    (if path targets a directory). With configuration directories, all the configuration files stored
 *    in the directory are merged in alphabetical order. Configuration files must be either JSON files
 *    (supporting comments with hjson) or YML files.
 *
 *  - env(whitelist): environment variables. An optional white list can be used to restrict which environment
 *    variables are to be merged.
 *
 *  - argv(whitelist): command-line arguments. An optional white list can be used to restrict which arguments
 *    are to be merged.
 *
 * NOTE: On contrast with nconf, this module supports multiple instances.
 *
 * @param {Object} opts
 *    Optional object with configuration options. Currently supported:
 *      - delimiter. Key delimiter (by default ':' to maintain compatibility with nconf).
 * @return {Object}
 *    Configuration instance.
 * @constructor
 */
function Configuration(opts) {

  var delimiter = opts && opts.delimiter || ':';

  var config = {};

  /**
   * Get the value identified by the array of keys in an object. For example, for an object:
   *     {key1: {key11: 'value'}}
   * with the keys: ['key1', 'key11']
   * it returns: 'value'.
   *
   * @param {Object} object
   * @param {String[]} keys
   * @return {Object}
   *    The value referenced by the keys.
   */
  function _getObject(object, keys) {
    var key = keys.shift();
    if (keys.length === 0) {
      return object[key];
    }
    if (typeof object[key] === 'object' && object[key] !== null) {
      return _getObject(object[key], keys);
    }
  }

  /**
   * Build an object with a hierarchy of keys array and assigning the value to the leaf element.
   *
   * The invocation:
   *    _buildObject({}, 'value', ['key1', 'key11'])
   * returns the object:
   *    {key1: {key11: 'value'}}
   *
   * @param {Object} object
   * @param {String[]} keys
   * @return {Object}
   *    The object enriched with the value at keys reference.
   */
  function _buildObject(object, value, keys) {
    var key = keys.shift();
    if (keys.length === 0) {
      object[key] = value;
    } else {
      object[key] = {};
      _buildObject(object[key], value, keys);
    }
    return object;
  }

  /**
   * Get the configuration object.
   *
   * @param {String} composedKey
   *    Optional path to the configuration object to be retrieved. By default, it retrieves an object
   *    with the whole configuration.
   * @return {Object}
   *    Configuration object resulting from merging files, directories and environment variables.
   */
  function get(composedKey) {
    if (!composedKey) {
      return config;
    }
    return _getObject(config, composedKey.split(delimiter));
  }

  /**
   * Set a single element in the configuration.
   *
   * @param {String} composedKey
   *    Path to the configuration object to be set. The delimiter (by default ':') is used to set
   *    a value in any of the levels of the configuration object hierarchy.
   * @param {String|Number|Array|Object} value
   *    Value to be assigned in the configuration.
   */
  function set(composedKey, value) {
    var configSet = _buildObject({}, value, composedKey.split(delimiter));
    _.merge(config, configSet);
  }

  /**
   * Merge one or several configuration objects.
   */
  function merge() {
    var args = Array.prototype.slice.call(arguments, 0);
    args.unshift(config);
    _.merge.apply(this, args);
  }

  /**
   * Merge the command-line arguments into the configuration.
   *
   * @param {String[]} whitelist
   *    Optional list of environment variables to avoid including all of them.
   */
  function argv(whitelist) {
    Object.keys(yargs.argv).forEach(function onArg(key) {
      if (!whitelist || whitelist.indexOf(key) >= 0) {
        set(key, yargs.argv[key]);
      }
    });
  }

  /**
   * Merge the environment variables into the configuration.
   * The keys from environment variables are transformed into camelCase to keep coherence with JSON format.
   *
   * @param {String[]} whitelist
   *    Optional list of environment variables to avoid including all of them.
   */
  function env(whitelist) {
    Object.keys(process.env).forEach(function onEnv(composedKey) {
      var keys = composedKey.split(delimiter);
      var formattedComposedKey = keys.map(changeCase.camelCase).join(delimiter);
      if (!whitelist || whitelist.indexOf(formattedComposedKey) >= 0) {
        set(formattedComposedKey, process.env[composedKey]);
      }
    });
  }

  /**
   * Merge a configuration file: either a json (with .json extension) or yaml (with either .yml or .yaml extension).
   *
   * @param {String} configFile
   *    Path to the configuration file.
   * @param {boolean} ignoreErrors
   *    Optional argument to throw an error if the file does not have a valid file extension.
   */
  function _loadFile(configFile, ignoreErrors) {
    var fileExtension = path.extname(configFile);
    if (fileExtension === '.json') {
      var jsonConfig = hjson.parse(fs.readFileSync(configFile, 'utf8'));
      _.merge(config, jsonConfig);
    } else if (fileExtension === '.yml' || fileExtension === '.yaml') {
      var ymlConfig = yaml.safeLoad(fs.readFileSync(configFile, 'utf8'));
      _.merge(config, ymlConfig);
    } else if (ignoreErrors !== true) {
      throw errors.FILE_INVALID(configFile, 'Configuration file has an invalid extension');
    }
  }

  /**
   * Merge a configuration directory by merging all the configuration files in the directory.
   *
   * @param {String} configDir
   *    Path to the configuration directory.
   */
  function _loadDir(configDir) {
    var files = fs.readdirSync(configDir);
    files = files.sort();
    for (var i = 0; i < files.length; i++) {
      var configFile = path.join(configDir, files[i]);
      if (fs.statSync(configFile).isFile()) {
        _loadFile(configFile, true);
      }
    }
  }

  /**
   * Merge the configuration from a configuration file, or from the configuration files inside a directory.
   * It supports either JSON files (with extension .json) with comments (via hjson module), or YML files.
   *
   * @param {String} filePath
   *    Path to the configuration file or configuration directory.
   */
  function file(filePath) {
    try {
      var stats = fs.statSync(filePath);
      if (stats.isDirectory()) {
        _loadDir(filePath);
      } else {
        _loadFile(filePath);
      }
    } catch (e) {
      throw errors.FILE_INVALID(filePath, e.message);
    }
  }

  return {
    get: get,
    set: set,
    merge: merge,
    argv: argv,
    env: env,
    file: file
  };
}

/**
 * Export Configuration class.
 */
module.exports = Configuration;
<commit_msg>Better readibility with explicit return<commit_after>/**
 * @license
 * Copyright 2015,2016 Telefónica Investigación y Desarrollo, S.A.U
 *
 * 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.
 */

'use strict';

var _ = require('lodash'),
    changeCase = require('change-case'),
    fs = require('fs'),
    yargs = require('yargs'),
    hjson = require('hjson'),
    yaml = require('js-yaml'),
    path = require('path'),
    therror = require('therror');

var errors = therror.register({
  FILE_INVALID: {
    message: 'Invalid configuration file: "{1}". {2}'
  }
});

/**
 * Configuration class to merge configuration from:
 *
 *  - file(path): configuration files (if path targets a configuration file) or configuration directories
 *    (if path targets a directory). With configuration directories, all the configuration files stored
 *    in the directory are merged in alphabetical order. Configuration files must be either JSON files
 *    (supporting comments with hjson) or YML files.
 *
 *  - env(whitelist): environment variables. An optional white list can be used to restrict which environment
 *    variables are to be merged.
 *
 *  - argv(whitelist): command-line arguments. An optional white list can be used to restrict which arguments
 *    are to be merged.
 *
 * NOTE: On contrast with nconf, this module supports multiple instances.
 *
 * @param {Object} opts
 *    Optional object with configuration options. Currently supported:
 *      - delimiter. Key delimiter (by default ':' to maintain compatibility with nconf).
 * @return {Object}
 *    Configuration instance.
 * @constructor
 */
function Configuration(opts) {

  var delimiter = opts && opts.delimiter || ':';

  var config = {};

  /**
   * Get the value identified by the array of keys in an object. For example, for an object:
   *     {key1: {key11: 'value'}}
   * with the keys: ['key1', 'key11']
   * it returns: 'value'.
   *
   * @param {Object} object
   * @param {String[]} keys
   * @return {Object}
   *    The value referenced by the keys.
   */
  function _getObject(object, keys) {
    var key = keys.shift();
    if (keys.length === 0) {
      return object[key];
    }
    if (typeof object[key] === 'object' && object[key] !== null) {
      return _getObject(object[key], keys);
    }
    return undefined;
  }

  /**
   * Build an object with a hierarchy of keys array and assigning the value to the leaf element.
   *
   * The invocation:
   *    _buildObject({}, 'value', ['key1', 'key11'])
   * returns the object:
   *    {key1: {key11: 'value'}}
   *
   * @param {Object} object
   * @param {String[]} keys
   * @return {Object}
   *    The object enriched with the value at keys reference.
   */
  function _buildObject(object, value, keys) {
    var key = keys.shift();
    if (keys.length === 0) {
      object[key] = value;
    } else {
      object[key] = {};
      _buildObject(object[key], value, keys);
    }
    return object;
  }

  /**
   * Get the configuration object.
   *
   * @param {String} composedKey
   *    Optional path to the configuration object to be retrieved. By default, it retrieves an object
   *    with the whole configuration.
   * @return {Object}
   *    Configuration object resulting from merging files, directories and environment variables.
   */
  function get(composedKey) {
    if (!composedKey) {
      return config;
    }
    return _getObject(config, composedKey.split(delimiter));
  }

  /**
   * Set a single element in the configuration.
   *
   * @param {String} composedKey
   *    Path to the configuration object to be set. The delimiter (by default ':') is used to set
   *    a value in any of the levels of the configuration object hierarchy.
   * @param {String|Number|Array|Object} value
   *    Value to be assigned in the configuration.
   */
  function set(composedKey, value) {
    var configSet = _buildObject({}, value, composedKey.split(delimiter));
    _.merge(config, configSet);
  }

  /**
   * Merge one or several configuration objects.
   */
  function merge() {
    var args = Array.prototype.slice.call(arguments, 0);
    args.unshift(config);
    _.merge.apply(this, args);
  }

  /**
   * Merge the command-line arguments into the configuration.
   *
   * @param {String[]} whitelist
   *    Optional list of environment variables to avoid including all of them.
   */
  function argv(whitelist) {
    Object.keys(yargs.argv).forEach(function onArg(key) {
      if (!whitelist || whitelist.indexOf(key) >= 0) {
        set(key, yargs.argv[key]);
      }
    });
  }

  /**
   * Merge the environment variables into the configuration.
   * The keys from environment variables are transformed into camelCase to keep coherence with JSON format.
   *
   * @param {String[]} whitelist
   *    Optional list of environment variables to avoid including all of them.
   */
  function env(whitelist) {
    Object.keys(process.env).forEach(function onEnv(composedKey) {
      var keys = composedKey.split(delimiter);
      var formattedComposedKey = keys.map(changeCase.camelCase).join(delimiter);
      if (!whitelist || whitelist.indexOf(formattedComposedKey) >= 0) {
        set(formattedComposedKey, process.env[composedKey]);
      }
    });
  }

  /**
   * Merge a configuration file: either a json (with .json extension) or yaml (with either .yml or .yaml extension).
   *
   * @param {String} configFile
   *    Path to the configuration file.
   * @param {boolean} ignoreErrors
   *    Optional argument to throw an error if the file does not have a valid file extension.
   */
  function _loadFile(configFile, ignoreErrors) {
    var fileExtension = path.extname(configFile);
    if (fileExtension === '.json') {
      var jsonConfig = hjson.parse(fs.readFileSync(configFile, 'utf8'));
      _.merge(config, jsonConfig);
    } else if (fileExtension === '.yml' || fileExtension === '.yaml') {
      var ymlConfig = yaml.safeLoad(fs.readFileSync(configFile, 'utf8'));
      _.merge(config, ymlConfig);
    } else if (ignoreErrors !== true) {
      throw errors.FILE_INVALID(configFile, 'Configuration file has an invalid extension');
    }
  }

  /**
   * Merge a configuration directory by merging all the configuration files in the directory.
   *
   * @param {String} configDir
   *    Path to the configuration directory.
   */
  function _loadDir(configDir) {
    var files = fs.readdirSync(configDir);
    files = files.sort();
    for (var i = 0; i < files.length; i++) {
      var configFile = path.join(configDir, files[i]);
      if (fs.statSync(configFile).isFile()) {
        _loadFile(configFile, true);
      }
    }
  }

  /**
   * Merge the configuration from a configuration file, or from the configuration files inside a directory.
   * It supports either JSON files (with extension .json) with comments (via hjson module), or YML files.
   *
   * @param {String} filePath
   *    Path to the configuration file or configuration directory.
   */
  function file(filePath) {
    try {
      var stats = fs.statSync(filePath);
      if (stats.isDirectory()) {
        _loadDir(filePath);
      } else {
        _loadFile(filePath);
      }
    } catch (e) {
      throw errors.FILE_INVALID(filePath, e.message);
    }
  }

  return {
    get: get,
    set: set,
    merge: merge,
    argv: argv,
    env: env,
    file: file
  };
}

/**
 * Export Configuration class.
 */
module.exports = Configuration;
<|endoftext|>


<commit_before>import React from 'react'
import {connect} from 'cerebral/react'
import {state, signal, props} from 'cerebral/tags'

import {
  Divider
 } from 'material-ui'
import List, {
  ListItem,
  ListItemText,
  ListItemSecondaryAction
} from 'material-ui/List'

import Switch from 'material-ui/Switch'
import styled from 'styled-components'
import filteredZoneIds from '../../computed/filteredZoneIds'

const ZoneListItem = connect({
  id: props`id`,
  name: state`zones.${props`id`}.name`,
  status: state`zones.${props`id`}.status`,
  bypass: state`zones.${props`id`}.bypass`,
  zonePressed: signal`zones.zonePressed`,
  bypassPressed: signal`zones.bypassPressed`
}, function NewZoneListItem({id, name, status, bypass, zonePressed, bypassPressed}) {
  return (
    <ListItem onClick={() => zonePressed({id:id})}>
      <ListItemText
        primary={`${id} - ${name}`}
        secondary={bypass ? `${status} (Bypassed)` : status}
      />
      <ListItemSecondaryAction>
        <Switch checked={bypass} onChange={() => bypassPressed({id: id})}/>
      </ListItemSecondaryAction>
    </ListItem>
  )
})

const ZoneListWrapper = styled.div`
  width: 100%;
  text-align: left;
`

export default connect({
  filtered: filteredZoneIds,
}, function ZoneList({filtered,classes}) {
  return (
    <ZoneListWrapper>
      <List>
        {
          filtered.map((id) => (

              <ZoneListItem id={id} />
              <Divider />

          ))
        }
      </List>
    </ZoneListWrapper>
  )
})<commit_msg>Added styled-component wrapper to list item to render different backgroud for zones states Ready, Open & Trouble<commit_after>import React from 'react'
import {connect} from 'cerebral/react'
import {state, signal, props} from 'cerebral/tags'

import {
  Divider
 } from 'material-ui'
import List, {
  ListItem,
  ListItemText,
  ListItemSecondaryAction
} from 'material-ui/List'

import Switch from 'material-ui/Switch'
import styled from 'styled-components'
import filteredZoneIds from '../../computed/filteredZoneIds'

const listItemColors = {
  Open: '#ffffcc',
  Trouble: '#ffd6cc'
}

const ListItemWrapper = styled.div`
  background-color: ${props => listItemColors[props.zoneStatus] || 'white'};
`

const ZoneListItem = connect({
  id: props`id`,
  name: state`zones.${props`id`}.name`,
  status: state`zones.${props`id`}.status`,
  bypass: state`zones.${props`id`}.bypass`,
  zonePressed: signal`zones.zonePressed`,
  bypassPressed: signal`zones.bypassPressed`
}, function NewZoneListItem({id, name, status, bypass, zonePressed, bypassPressed}) {
  return (
    <ListItemWrapper zoneStatus={status}>
      <ListItem onClick={() => zonePressed({id:id})}>
        <ListItemText
          primary={`${id} - ${name}`}
          secondary={bypass ? `${status} (Bypassed)` : status}
        />
        <ListItemSecondaryAction>
          <Switch checked={bypass} onChange={() => bypassPressed({id: id})}/>
        </ListItemSecondaryAction>
      </ListItem>
    </ListItemWrapper>
  )
})

const ZoneListWrapper = styled.div`
  width: 100%;
  text-align: left;
`

export default connect({
  filtered: filteredZoneIds,
}, function ZoneList({filtered,classes}) {
  return (
    <ZoneListWrapper>
      <List>
        {
          filtered.map((id) => (

              <ZoneListItem id={id} />
              <Divider />

          ))
        }
      </List>
    </ZoneListWrapper>
  )
})<|endoftext|>


<commit_before>import Contextualable from '~mixins/contextualable'
import Positionable from '~mixins/positionable'
import GenerateRouteLink from '~mixins/route-link'
import Themeable from '~mixins/themeable'
import Toggleable from '~mixins/toggleable'

export default {
  name: 'btn',

  mixins: [Contextualable, GenerateRouteLink, Positionable, Themeable, Toggleable],

  props: {
    activeClass: {
      type: String,
      default: 'btn--active'
    },
    block: Boolean,
    fab: Boolean,
    flat: Boolean,
    icon: Boolean,
    large: Boolean,
    loading: Boolean,
    outline: Boolean,
    ripple: {
      type: [Boolean, Object],
      default: true
    },
    round: Boolean,
    small: Boolean,
    tag: {
      type: String,
      default: 'button'
    },
    type: {
      type: String,
      default: 'button'
    }
  },

  computed: {
    classes () {
      return {
        'btn': true,
        'btn--absolute': this.absolute,
        'btn--active': this.isActive,
        'btn--block': this.block,
        'btn--bottom': this.bottom,
        'btn--flat': this.flat,
        'btn--floating': this.fab,
        'btn--fixed': this.fixed,
        'btn--hover': this.hover,
        'btn--icon': this.icon,
        'btn--large': this.large,
        'btn--left': this.left,
        'btn--loader': this.loading,
        'btn--outline': this.outline,
        'btn--raised': !this.flat,
        'btn--right': this.right,
        'btn--round': this.round,
        'btn--small': this.small,
        'btn--top': this.top,
        'theme--dark dark--bg': this.dark,
        'theme--light light--bg': this.light,
        'primary': this.primary && !this.outline,
        'secondary': this.secondary && !this.outline,
        'success': this.success && !this.outline,
        'info': this.info && !this.outline,
        'warning': this.warning && !this.outline,
        'error': this.error && !this.outline,
        'primary--text': this.primary && (this.outline || this.flat),
        'secondary--text': this.secondary && (this.outline || this.flat),
        'success--text': this.success && (this.outline || this.flat),
        'info--text': this.info && (this.outline || this.flat),
        'warning--text': this.warning && (this.outline || this.flat),
        'error--text': this.error && (this.outline || this.flat)
      }
    }
  },

  methods: {
    // Prevent focus to match md spec
    click (e) {
      !this.fab &&
        e.detail &&
        this.$el.blur()
    },
    genContent () {
      return this.$createElement('div', { 'class': 'btn__content' }, [this.$slots.default])
    },
    genLoader () {
      const children = []

      if (!this.$slots.loader) {
        children.push(this.$createElement('v-progress-circular', {
          props: {
            indeterminate: true,
            size: 26
          }
        }))
      } else {
        children.push(this.$slots.loader)
      }

      return this.$createElement('span', { 'class': 'btn__loading' }, children)
    }
  },

  render (h) {
    const { tag, data } = this.generateRouteLink()
    const children = [this.genContent()]

    tag === 'button' && (data.attrs.type = this.type)
    this.loading && children.push(this.genLoader())

    return h(tag, data, children)
  }
}
<commit_msg>added explicit click event emit<commit_after>import Contextualable from '~mixins/contextualable'
import Positionable from '~mixins/positionable'
import GenerateRouteLink from '~mixins/route-link'
import Themeable from '~mixins/themeable'
import Toggleable from '~mixins/toggleable'

export default {
  name: 'btn',

  mixins: [Contextualable, GenerateRouteLink, Positionable, Themeable, Toggleable],

  props: {
    activeClass: {
      type: String,
      default: 'btn--active'
    },
    block: Boolean,
    fab: Boolean,
    flat: Boolean,
    icon: Boolean,
    large: Boolean,
    loading: Boolean,
    outline: Boolean,
    ripple: {
      type: [Boolean, Object],
      default: true
    },
    round: Boolean,
    small: Boolean,
    tag: {
      type: String,
      default: 'button'
    },
    type: {
      type: String,
      default: 'button'
    }
  },

  computed: {
    classes () {
      return {
        'btn': true,
        'btn--absolute': this.absolute,
        'btn--active': this.isActive,
        'btn--block': this.block,
        'btn--bottom': this.bottom,
        'btn--flat': this.flat,
        'btn--floating': this.fab,
        'btn--fixed': this.fixed,
        'btn--hover': this.hover,
        'btn--icon': this.icon,
        'btn--large': this.large,
        'btn--left': this.left,
        'btn--loader': this.loading,
        'btn--outline': this.outline,
        'btn--raised': !this.flat,
        'btn--right': this.right,
        'btn--round': this.round,
        'btn--small': this.small,
        'btn--top': this.top,
        'theme--dark dark--bg': this.dark,
        'theme--light light--bg': this.light,
        'primary': this.primary && !this.outline,
        'secondary': this.secondary && !this.outline,
        'success': this.success && !this.outline,
        'info': this.info && !this.outline,
        'warning': this.warning && !this.outline,
        'error': this.error && !this.outline,
        'primary--text': this.primary && (this.outline || this.flat),
        'secondary--text': this.secondary && (this.outline || this.flat),
        'success--text': this.success && (this.outline || this.flat),
        'info--text': this.info && (this.outline || this.flat),
        'warning--text': this.warning && (this.outline || this.flat),
        'error--text': this.error && (this.outline || this.flat)
      }
    }
  },

  methods: {
    // Prevent focus to match md spec
    click (e) {
      !this.fab &&
        e.detail &&
        this.$el.blur()

      this.$emit('click', e)
    },
    genContent () {
      return this.$createElement('div', { 'class': 'btn__content' }, [this.$slots.default])
    },
    genLoader () {
      const children = []

      if (!this.$slots.loader) {
        children.push(this.$createElement('v-progress-circular', {
          props: {
            indeterminate: true,
            size: 26
          }
        }))
      } else {
        children.push(this.$slots.loader)
      }

      return this.$createElement('span', { 'class': 'btn__loading' }, children)
    }
  },

  render (h) {
    const { tag, data } = this.generateRouteLink()
    const children = [this.genContent()]

    tag === 'button' && (data.attrs.type = this.type)
    this.loading && children.push(this.genLoader())

    return h(tag, data, children)
  }
}
<|endoftext|>


<commit_before>var utils = require('connect').utils
  , http = require('http');

var storage = null
  , default_ttl = 3600000;

exports = module.exports = function (options) {
  options = options || {};
  if (!Array.isArray(options.rules)) {
    console.log('DEPRECATED : options.rules must be a set of regular expressions/ttl pairs');
    if (typeof options.regex !== "function") {
      throw new Error('you must define options.regex');
    }
    options.rules = [{regex: options.regex, ttl: options.ttl || default_ttl}];
  }
  if (options.rules.length < 1) {
    throw new Error('no rules');
  }
  if ("ttl" in options) {
    console.log('DEPRECATED : options.ttl usage');
  }
  if (!('storage' in options)) {
    storage = new (require('./storages/basic'));
  }
  else {
    storage = options.storage;
  }
  return function (req, res, next) {
    if (req.method !== 'GET'
        || req.headers['x-no-cache'] == "1") {
      return next();
    }
    var ttl = 0;
    var must_be_cached = false;
    options.rules.forEach(function (rule) {
      var match = rule.regex.test(req.url);
      if (match && ttl === 0) {
        ttl = Number(rule.ttl || default_ttl);
      }
      must_be_cached = must_be_cached || match;
    });
    if (!must_be_cached) {
      return next();
    }
    if (!('loopback' in options)) {
      if (!('host' in req.headers)) {
        throw new Error('host in HTTP headers must be defined');
      }
      options.loopback = req.headers.host;
    }
    var tmp = options.loopback.split(':')
      , loopback_host = tmp[0]
      , loopback_port = tmp.length > 1 ? tmp[1] : 80
      , key = utils.md5(req.url)
      , content_key = 'c' + key
      , metas_key = 'm' + key
      , onCachedContentRetrieved = function (cached_metas, cached_content, write_stream) {
        req.headers['x-no-cache'] = 1;
        var client = http.createClient(loopback_port, loopback_host)
          , request = client.request(req.method, req.url, req.headers);
        request.end();
        request.on('response', function (response) {
          if (cached_metas === false) {
            for (var key in response.headers) {
              res.setHeader(key, response.headers[key]);
            }
            res.statusCode = response.statusCode;
            var metas = {statusCode: response.statusCode,
                         headers: response.headers};
            storage.set(metas_key, JSON.stringify(metas));
            setTimeout(function () {
              storage.remove(metas_key);
            }, ttl);
          }
          if (cached_content !== false) {
            if ('readStream' in storage) {
              cached_content.pipe(res);
            }
            else {
              res.end(cached_content);
            }
            return;
          }
          response.on('end', function () {
            setTimeout(function () {
              storage.remove(content_key);
            }, options.ttl);
          });
          if ('writeStream' in storage) {
            response.pipe(write_stream);
          }
          else {
            var length = 0
              , chunks = [];
            response.on('data', function (chunk) {
              chunks.push(chunk);
              length += chunk.length;
            });
            response.on('end', function () {
              var content = new Buffer(length);
              var offset = 0;
              chunks.forEach(function (chunk) {
                chunk.copy(content, offset);
                offset += chunk.length;
              });
              storage.set(content_key, content);
            });
          }
          response.pipe(res);
        });
      };
    storage.get(metas_key, function (err, cached_metas) {
      if (err) throw err;
      if (cached_metas !== false) {
        var metas = JSON.parse(cached_metas);
        for (var key in metas.headers) {
          res.setHeader(key, metas.headers[key]);
        }
        res.statusCode = metas.statusCode;
      }
      if ('readStream' in storage) {
        storage.readStream(content_key, function (err, read_stream) {
          if (err) throw err;
          if (read_stream !== false && cached_metas !== false) {
            return read_stream.pipe(res);
          }
          if ('writeStream' in storage) {
            storage.writeStream(content_key, function(err, write_stream) {
              if (err) throw err;
              onCachedContentRetrieved(cached_metas, read_stream, write_stream);
            });
          }
          else {
            onCachedContentRetrieved(cached_metas, read_stream);
          }
        });
      }
      else {
        storage.get(content_key, function (err, cached_content) {
          if (err) throw err;
          if (cached_content !== false && cached_metas !== false) {
            return res.end(cached_content);
          }
          if ('writeStream' in storage) {
            storage.writeStream(content_key, function(err, write_stream) {
              if (err) throw err;
              onCachedContentRetrieved(cached_metas, cached_content, write_stream);
            });
          }
          else {
            onCachedContentRetrieved(cached_metas, cached_content);
          }
        });
      }
    });
  }
};
<commit_msg>add X-Forwarded-For HTTP header<commit_after>var utils = require('connect').utils
  , http = require('http');

var storage = null
  , default_ttl = 3600000;

exports = module.exports = function (options) {
  options = options || {};
  if (!Array.isArray(options.rules)) {
    console.log('DEPRECATED : options.rules must be a set of regular expressions/ttl pairs');
    if (typeof options.regex !== "function") {
      throw new Error('you must define options.regex');
    }
    options.rules = [{regex: options.regex, ttl: options.ttl || default_ttl}];
  }
  if (options.rules.length < 1) {
    throw new Error('no rules');
  }
  if ("ttl" in options) {
    console.log('DEPRECATED : options.ttl usage');
  }
  if (!('storage' in options)) {
    storage = new (require('./storages/basic'));
  }
  else {
    storage = options.storage;
  }
  return function (req, res, next) {
    if (req.method !== 'GET'
        || req.headers['x-no-cache'] == "1") {
      return next();
    }
    var ttl = 0;
    var must_be_cached = false;
    options.rules.forEach(function (rule) {
      var match = rule.regex.test(req.url);
      if (match && ttl === 0) {
        ttl = Number(rule.ttl || default_ttl);
      }
      must_be_cached = must_be_cached || match;
    });
    if (!must_be_cached) {
      return next();
    }
    if (!('loopback' in options)) {
      if (!('host' in req.headers)) {
        throw new Error('host in HTTP headers must be defined');
      }
      options.loopback = req.headers.host;
    }
    var tmp = options.loopback.split(':')
      , loopback_host = tmp[0]
      , loopback_port = tmp.length > 1 ? tmp[1] : 80
      , key = utils.md5(req.url)
      , content_key = 'c' + key
      , metas_key = 'm' + key
      , onCachedContentRetrieved = function (cached_metas, cached_content, write_stream) {
        req.headers['x-no-cache'] = 1;
        req.headers['x-forwarded-for'] = req.socket.remoteAddress;
        var client = http.createClient(loopback_port, loopback_host)
          , request = client.request(req.method, req.url, req.headers);
        request.end();
        request.on('response', function (response) {
          if (cached_metas === false) {
            for (var key in response.headers) {
              res.setHeader(key, response.headers[key]);
            }
            res.statusCode = response.statusCode;
            var metas = {statusCode: response.statusCode,
                         headers: response.headers};
            storage.set(metas_key, JSON.stringify(metas));
            setTimeout(function () {
              storage.remove(metas_key);
            }, ttl);
          }
          if (cached_content !== false) {
            if ('readStream' in storage) {
              cached_content.pipe(res);
            }
            else {
              res.end(cached_content);
            }
            return;
          }
          response.on('end', function () {
            setTimeout(function () {
              storage.remove(content_key);
            }, options.ttl);
          });
          if ('writeStream' in storage) {
            response.pipe(write_stream);
          }
          else {
            var length = 0
              , chunks = [];
            response.on('data', function (chunk) {
              chunks.push(chunk);
              length += chunk.length;
            });
            response.on('end', function () {
              var content = new Buffer(length);
              var offset = 0;
              chunks.forEach(function (chunk) {
                chunk.copy(content, offset);
                offset += chunk.length;
              });
              storage.set(content_key, content);
            });
          }
          response.pipe(res);
        });
      };
    storage.get(metas_key, function (err, cached_metas) {
      if (err) throw err;
      if (cached_metas !== false) {
        var metas = JSON.parse(cached_metas);
        for (var key in metas.headers) {
          res.setHeader(key, metas.headers[key]);
        }
        res.statusCode = metas.statusCode;
      }
      if ('readStream' in storage) {
        storage.readStream(content_key, function (err, read_stream) {
          if (err) throw err;
          if (read_stream !== false && cached_metas !== false) {
            return read_stream.pipe(res);
          }
          if ('writeStream' in storage) {
            storage.writeStream(content_key, function(err, write_stream) {
              if (err) throw err;
              onCachedContentRetrieved(cached_metas, read_stream, write_stream);
            });
          }
          else {
            onCachedContentRetrieved(cached_metas, read_stream);
          }
        });
      }
      else {
        storage.get(content_key, function (err, cached_content) {
          if (err) throw err;
          if (cached_content !== false && cached_metas !== false) {
            return res.end(cached_content);
          }
          if ('writeStream' in storage) {
            storage.writeStream(content_key, function(err, write_stream) {
              if (err) throw err;
              onCachedContentRetrieved(cached_metas, cached_content, write_stream);
            });
          }
          else {
            onCachedContentRetrieved(cached_metas, cached_content);
          }
        });
      }
    });
  }
};
<|endoftext|>


<commit_before>/* eslint-disable */
// TODO: Fix all eslint issues
import React, { Component, PropTypes } from 'react';
import connect from 'react-redux/lib/components/connect';
import _get from 'lodash/get';
import identity from 'lodash/identity';
import mapValues from 'lodash/mapValues';

import actions from '../actions';
import { validate, isValid } from '../utils';

class Form extends Component {
  handleSubmit(e) {
    e.preventDefault();

    const {
      model,
      validators,
      onSubmit,
      dispatch
    } = this.props;
    const modelValue = _get(this.props, model);

    const valid = isValid(mapValues(validators, (validator, field) => {
      const fieldModel = [model, field].join('.');
      const value = _get(this.props, fieldModel);
      const validity = validate(validator, value);

      dispatch(actions.setValidity(fieldModel, validate(validator, value)));

      return isValid(validity);
    }));

    if (onSubmit && !!valid) {
      onSubmit(modelValue);
    }
  }

  componentDidUpdate(prevProps) {
    const {
      validators,
      model,
      modelValue,
      dispatch,
      validateOn
    } = this.props;

    if (validateOn !== 'change') return;

    mapValues(validators, (validator, field) => {
      const fieldModel = [model, field].join('.');
      const value = _get(this.props, fieldModel);

      if (value === _get(prevProps, fieldModel)) return;

      const validity = validate(validator, value);

      dispatch(actions.setValidity(fieldModel, validate(validator, value)));
    });
  }

  render() {
    return (
      <form
        {...this.props}
        onSubmit={(e) => this.handleSubmit(e)}
      >
        { this.props.children }
      </form>
    );
  }
}

Form.PropTypes = {
  validators: PropTypes.object,
  validateOn: PropTypes.oneOf([
    'change',
  ]),
  model: PropTypes.string.isRequired
};

export default connect(identity)(Form);
<commit_msg>Linting<commit_after>
// TODO: Fix all eslint issues
import React, { Component, PropTypes } from 'react';
import connect from 'react-redux/lib/components/connect';
import _get from 'lodash/get';
import identity from 'lodash/identity';
import mapValues from 'lodash/mapValues';

import actions from '../actions';
import { validate, isValid } from '../utils';

class Form extends Component {
  constructor(props) {
    super(props);

    this.handleSubmit = this.handleSubmit.bind(this);
  }
  componentDidUpdate(prevProps) {
    /* eslint-disable react/prop-types */
    const {
      validators,
      model,
      dispatch,
      validateOn,
    } = this.props;
    /* eslint-enable react/prop-types */

    if (validateOn !== 'change') return;

    mapValues(validators, (validator, field) => {
      const fieldModel = [model, field].join('.');
      const value = _get(this.props, fieldModel);

      if (value === _get(prevProps, fieldModel)) return;

      const validity = validate(validator, value);

      dispatch(actions.setValidity(fieldModel, validity));
    });
  }

  handleSubmit(e) {
    e.preventDefault();

    /* eslint-disable react/prop-types */
    const {
      model,
      validators,
      onSubmit,
      dispatch,
    } = this.props;
    /* eslint-enable react/prop-types */

    const modelValue = _get(this.props, model);

    const valid = isValid(mapValues(validators, (validator, field) => {
      const fieldModel = [model, field].join('.');
      const value = _get(this.props, fieldModel);
      const validity = validate(validator, value);

      dispatch(actions.setValidity(fieldModel, validate(validator, value)));

      return isValid(validity);
    }));

    if (onSubmit && !!valid) {
      onSubmit(modelValue);
    }
  }

  render() {
    /* eslint-disable react/prop-types */
    return (
      <form
        {...this.props}
        onSubmit={this.handleSubmit}
      >
        { this.props.children }
      </form>
    );
    /* eslint-enable react/prop-types */
  }
}

Form.propTypes = {
  validators: PropTypes.object,
  validateOn: PropTypes.oneOf([
    'change',
  ]),
  model: PropTypes.string.isRequired,
  onSubmit: PropTypes.func,
};

export default connect(identity)(Form);
<|endoftext|>