<commit_before>'use strict';

const AWS = require('aws-sdk');
const cw = new AWS.CloudWatch({
    region: process.env.AWS_REGION || 'us-west-2'
});

module.exports = {
    overallMetrics: function (obj) {
        let promises = [];

        for (const minute in obj.stats) {
            const overall = obj.stats[minute]['_overall'];
            const data = [
                {
                    MetricName: 'nodes_created',
                    Value: overall.cnode || 0,
                    Timestamp: minute
                }, {
                    MetricName: 'nodes_modified',
                    Value: overall.mnode || 0,
                    Timestamp: minute
                }, {
                    MetricName: 'nodes_deleted',
                    Value: overall.dnode || 0,
                    Timestamp: minute
                }, {
                    MetricName: 'ways_created',
                    Value: overall.cway || 0,
                    Timestamp: minute
                }, {
                    MetricName: 'ways_modified',
                    Value: overall.mway || 0,
                    Timestamp: minute
                }, {
                    MetricName: 'ways_deleted',
                    Value: overall.dway || 0,
                    Timestamp: minute
                }, {
                    MetricName: 'relations_created',
                    Value: overall.crelation || 0,
                    Timestamp: minute
                }, {
                    MetricName: 'relations_modified',
                    Value: overall.mrelation || 0,
                    Timestamp: minute
                }, {
                    MetricName: 'relations_deleted',
                    Value: overall.drelation || 0,
                    Timestamp: minute
                }, {
                    MetricName: 'active_users',
                    Value: Object.keys(obj.stats[minute]).length - 1,
                    Timestamp: minute
                }
            ];

            const put = new Promise((resolve, reject) => {
                cw.putMetricData({
                    MetricData: data,
                    Namespace: ('osm-dash-' + process.env.Environment)
                }, (err) => {
                    if (err) return reject(err);
                    resolve();
                });
            });

            promises.push(put);
        }

        return new Promise((resolve, reject) => {
            Promise
                .all(promises)
                .then(() => {
                    resolve({
                        state: obj.state,
                        stats: obj.stats
                    });
                })
                .catch(reject);
        });
    }
};
<commit_msg>Update metric properties and timestamp<commit_after>'use strict';

const AWS = require('aws-sdk');
const cw = new AWS.CloudWatch({
    region: process.env.AWS_REGION || 'us-west-2'
});

module.exports = {
    overallMetrics: function (obj) {
        let promises = [];

        for (const minute in obj.stats) {
            const overall = obj.stats[minute]['_overall'];
            const timestamp = new Date(minute).toISOString();
            const data = [
                {
                    MetricName: 'nodes_created',
                    Value: overall.create_node || 0,
                    Timestamp: timestamp
                }, {
                    MetricName: 'nodes_modified',
                    Value: overall.modify_node || 0,
                    Timestamp: timestamp
                }, {
                    MetricName: 'nodes_deleted',
                    Value: overall.delete_node || 0,
                    Timestamp: timestamp
                }, {
                    MetricName: 'ways_created',
                    Value: overall.create_way || 0,
                    Timestamp: timestamp
                }, {
                    MetricName: 'ways_modified',
                    Value: overall.modify_way || 0,
                    Timestamp: timestamp
                }, {
                    MetricName: 'ways_deleted',
                    Value: overall.delete_way || 0,
                    Timestamp: timestamp
                }, {
                    MetricName: 'relations_created',
                    Value: overall.create_relation || 0,
                    Timestamp: timestamp
                }, {
                    MetricName: 'relations_modified',
                    Value: overall.modify_relation || 0,
                    Timestamp: timestamp
                }, {
                    MetricName: 'relations_deleted',
                    Value: overall.delete_relation || 0,
                    Timestamp: timestamp
                }, {
                    MetricName: 'active_users',
                    Value: Object.keys(obj.stats[minute]).length - 1,
                    Timestamp: timestamp
                }
            ];

            const put = new Promise((resolve, reject) => {
                cw.putMetricData({
                    MetricData: data,
                    Namespace: ('osm-dash-' + process.env.Environment)
                }, (err) => {
                    if (err) return reject(err);
                    resolve();
                });
            });

            promises.push(put);
        }

        return new Promise((resolve, reject) => {
            Promise
                .all(promises)
                .then(() => {
                    resolve({
                        state: obj.state,
                        stats: obj.stats
                    });
                })
                .catch(reject);
        });
    }
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

var homedir = (process.env.HOME) ? process.env.HOME : process.env.HOMEPATH;

var cmd = require('commander')
, _package = require('../package.json')
, tools = require('./tools')

var domains = require('./modules/domains')
var droplets = require('./modules/droplets')

var digio = {
  init: function () {

    var _config = tools.load_config()
    if (!_config) return

    cmd
      .version('Digio v' + _package.version)

    cmd
      .command('keys')
      .description('List all available API keys')
      .action(tools.list_keys)

    cmd
      .command('addkey <name> <key>')
      .description('Add a new API-key to the config file')
      .action(tools.add_key)

    cmd
      .command('usekey <name>')
      .description('Set key with <name> as active')
      .action(tools.use_key)

    cmd
      .command('deletekey <name>')
      .description('Delete key with <name>')
      .action(tools.delete_key)

    cmd
      .command('droplets')
      .description('List all droplets')
      .action(droplets.list_droplets)

    cmd
      .command('domains')
      .description('List all domains')
      .action(domains.list_all_domains)

    cmd
      .command('createdomain <domain> <ip>')
      .description('Create new domain record')
      .action(domains.create_domain_record)

    cmd.parse(process.argv)

    if (process.argv.length < 3) {
        console.log('Digio - DigitalOcean API v2.0 CLI')
        cmd.help()
    }
  }
}

module.exports = digio
<commit_msg>Add digio-api require<commit_after>var homedir = (process.env.HOME) ? process.env.HOME : process.env.HOMEPATH;

var api = require('digio-api')
, cmd = require('commander')
, _package = require('../package.json')
, tools = require('./tools')

var digio = {
  init: function () {

    var _config = tools.load_config()
    if (!_config) return

    cmd
      .version('Digio v' + _package.version)

    cmd
      .command('keys')
      .description('List all available API keys')
      .action(tools.list_keys)

    cmd
      .command('addkey <name> <key>')
      .description('Add a new API-key to the config file')
      .action(tools.add_key)

    cmd
      .command('usekey <name>')
      .description('Set key with <name> as active')
      .action(tools.use_key)

    cmd
      .command('deletekey <name>')
      .description('Delete key with <name>')
      .action(tools.delete_key)

    cmd
      .command('droplets')
      .description('List all droplets')
      .action(droplets.list_droplets)

    cmd
      .command('domains')
      .description('List all domains')
      .action(domains.list_all_domains)

    cmd
      .command('createdomain <domain> <ip>')
      .description('Create new domain record')
      .action(domains.create_domain_record)

    cmd.parse(process.argv)

    if (process.argv.length < 3) {
        console.log('Digio - DigitalOcean API v2.0 CLI')
        cmd.help()
    }
  }
}

module.exports = digio
<|endoftext|>


<commit_before>var
  dirty = exports,
  File = require('file').File;

dirty.uuid = function() {
  var uuid = '';
  for (i = 0; i < 32; i++) {
    uuid += Math.floor(Math.random() * 16).toString(16);
  }
  return uuid;
};

var Dirty = dirty.Dirty = function(file, options) {
  process.EventEmitter.call(this);
  options = process.mixin({
    flushInterval: 1000,
    flushLimit: 100,
  }, options);

  this.file = new File(file, 'a+', {encoding: 'utf8'});
  this.docs = [];
  this._keys = {};

  // Interval after which docs should be flushed to disk at latest
  this.flushInterval = options.flushInterval;

  // Listeners waiting for the next flush to finish
  this.flushCallbacks = [];

  // Wait for x docs to be in memory before flushing to disk
  this.flushLimit = options.flushLimit;

  // Candidates for being flushed to disk
  this.memoryQueueLength = 0;
  // Docs in the process of being flushed to disk
  this.flushQueueLength = 0;

  if (!this.flushInterval) {
    return;
  }

  var self = this;
  this.flushTimer = setInterval(function() {
    self.flush();
  }, this.flushInterval);
};
process.inherits(Dirty, process.EventEmitter);

Dirty.prototype.__defineGetter__('length', function() {
  return this.docs.length;
});

Dirty.prototype.load = function() {
  var
    self = this,
    promise = new process.Promise(),
    buffer = '',
    offset = 0,
    read = function() {
      self.file.read(16*1024).addCallback(function(chunk) {
        if (!chunk) {
          return promise.emitSuccess();
        }

        buffer += chunk;
        while ((offset = buffer.indexOf("\n")) !== -1) {
          var doc = JSON.parse(buffer.substr(0, offset));
          self._keys[doc._key] = (self.docs.push(doc)-1);
          buffer = buffer.substr(offset+1);
        }
        read();
      })
      .addErrback(function() {
        promise.emitError(new Error('could not read from '+self.file.filename));
      });
    }

  read();
  return promise;
};

Dirty.prototype.close = function() {
  clearInterval(this.flushTimer);
  return this.file.close();
};

Dirty.prototype.add = function(doc, cb) {
  var uuid = dirty.uuid();
  this.set(uuid, doc, cb);
  return uuid;
};

Dirty.prototype.set = function(key, doc, cb) {
  doc._key = key;

  this._keys[key] = (this.docs.push(doc)-1);
  this.memoryQueueLength++;

  if (this.memoryQueueLength === this.flushLimit) {
    this.flush().addCallback(function() {
      if (cb) {
        cb(doc);
      }
    });
  } else if (cb) {
    this.flushCallbacks.push(function() {
      cb(doc);
    });
  }

  // Start new flushTimer if needed
  if (!this.flushTimer && this.memoryQueueLength !== this.flushLimit) {
    var self = this;
    this.flushTimer = setInterval(function() {
      self.flush();
    }, this.flushInterval);
  }
};

Dirty.prototype.flush = function(cb) {
  if (this.memoryQueueLength === 0) {
    var promise = new process.Promise();
    setTimeout(function() {
      promise.emitSuccess();
    }, 0);
    return promise;
  }

  var
    self = this,
    chunk = '',
    length = this.docs.length;

  while (this.memoryQueueLength > 0) {
    this.memoryQueueLength--;
    chunk += JSON.stringify(this.docs[length-this.memoryQueueLength-1])+"\n";
  }

  this.flushQueueLength += this.flushLimit;
  return this.file.write(chunk).addCallback(function() {
    self.flushQueueLength -= self.flushLimit;
    // If memory === disk, emit the flush event
    if (self.flushQueueLength === 0) {
      // Clear flushTimer so the event loop can exit when idle
      clearInterval(self.flushTimer);
      self.flushTimer = null;

      self.emit('flush');
    }

    self.flushCallbacks.forEach(function(cb) {
      cb();
    });
    self.flushCallbacks = [];
  });
};

Dirty.prototype.get = function(key) {
  return this.docs[this._keys[key]];
};

Dirty.prototype.filter = function(fn) {
  return this.docs.filter(fn);
};<commit_msg>Don't set flushTimer when there is nothing to flush<commit_after>var
  dirty = exports,
  File = require('file').File;

dirty.uuid = function() {
  var uuid = '';
  for (i = 0; i < 32; i++) {
    uuid += Math.floor(Math.random() * 16).toString(16);
  }
  return uuid;
};

var Dirty = dirty.Dirty = function(file, options) {
  process.EventEmitter.call(this);
  options = process.mixin({
    flushInterval: 1000,
    flushLimit: 100,
  }, options);

  this.file = new File(file, 'a+', {encoding: 'utf8'});
  this.docs = [];
  this._keys = {};

  // Interval after which docs should be flushed to disk at latest
  this.flushInterval = options.flushInterval;

  // Listeners waiting for the next flush to finish
  this.flushCallbacks = [];

  // Wait for x docs to be in memory before flushing to disk
  this.flushLimit = options.flushLimit;

  // Candidates for being flushed to disk
  this.memoryQueueLength = 0;
  // Docs in the process of being flushed to disk
  this.flushQueueLength = 0;
};
process.inherits(Dirty, process.EventEmitter);

Dirty.prototype.__defineGetter__('length', function() {
  return this.docs.length;
});

Dirty.prototype.load = function() {
  var
    self = this,
    promise = new process.Promise(),
    buffer = '',
    offset = 0,
    read = function() {
      self.file.read(16*1024).addCallback(function(chunk) {
        if (!chunk) {
          return promise.emitSuccess();
        }

        buffer += chunk;
        while ((offset = buffer.indexOf("\n")) !== -1) {
          var doc = JSON.parse(buffer.substr(0, offset));
          self._keys[doc._key] = (self.docs.push(doc)-1);
          buffer = buffer.substr(offset+1);
        }
        read();
      })
      .addErrback(function() {
        promise.emitError(new Error('could not read from '+self.file.filename));
      });
    }

  read();
  return promise;
};

Dirty.prototype.close = function() {
  clearInterval(this.flushTimer);
  return this.file.close();
};

Dirty.prototype.add = function(doc, cb) {
  var uuid = dirty.uuid();
  this.set(uuid, doc, cb);
  return uuid;
};

Dirty.prototype.set = function(key, doc, cb) {
  doc._key = key;

  this._keys[key] = (this.docs.push(doc)-1);
  this.memoryQueueLength++;

  if (this.memoryQueueLength === this.flushLimit) {
    this.flush().addCallback(function() {
      if (cb) {
        cb(doc);
      }
    });
  } else if (cb) {
    this.flushCallbacks.push(function() {
      cb(doc);
    });
  }

  // Start new flushTimer if needed
  if (!this.flushTimer && this.memoryQueueLength !== this.flushLimit) {
    var self = this;
    this.flushTimer = setInterval(function() {
      self.flush();
    }, this.flushInterval);
  }
};

Dirty.prototype.flush = function(cb) {
  if (this.memoryQueueLength === 0) {
    var promise = new process.Promise();
    setTimeout(function() {
      promise.emitSuccess();
    }, 0);
    return promise;
  }

  var
    self = this,
    chunk = '',
    length = this.docs.length;

  while (this.memoryQueueLength > 0) {
    this.memoryQueueLength--;
    chunk += JSON.stringify(this.docs[length-this.memoryQueueLength-1])+"\n";
  }

  this.flushQueueLength += this.flushLimit;
  return this.file.write(chunk).addCallback(function() {
    self.flushQueueLength -= self.flushLimit;
    // If memory === disk, emit the flush event
    if (self.flushQueueLength === 0) {
      // Clear flushTimer so the event loop can exit when idle
      clearInterval(self.flushTimer);
      self.flushTimer = null;

      self.emit('flush');
    }

    self.flushCallbacks.forEach(function(cb) {
      cb();
    });
    self.flushCallbacks = [];
  });
};

Dirty.prototype.get = function(key) {
  return this.docs[this._keys[key]];
};

Dirty.prototype.filter = function(fn) {
  return this.docs.filter(fn);
};<|endoftext|>


<commit_before>/**
 ECMAScript5 implementation
 ----

    - methods native object implemented
    - methods native object extends

 codes from mootools, MDC or by Kael Zhang

 Indexes
 ----

 ### Array.prototype
     - indexOf
     - lastIndexOf
     - filter
     - forEach
     - every
     - map
     - some
     - reduce
     - reduceRight

 ### Object
     - keys
     - create: removed

 ### String.prototype
     - trim
     - trimLeft
     - trimRight

 Specification
 ----

 ### STANDALONE language enhancement

    - always has no dependencies on Neuron
    - always follow ECMA standard strictly, including logic, exception type
    - throw the same error hint as webkit on a certain exception

 */

function extend(host, methods){
    for(var name in methods){
        if(!host[name]){
            host[name] = methods[name];
        }
    }
}

function implement(host, methods){
    extend(host.prototype, methods);
}

var TYPE_ERROR = TypeError;

// ref: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array
implement(Array, {

// Accessor methods ------------------------

    indexOf: function (value, from) {
        var len = this.length >>> 0;

        from = Number(from) || 0;
        from = Math[from < 0 ? 'ceil' : 'floor'](from);

        if (from < 0) {
            from = Math.max(from + len, 0);
        }

        for (; from < len; from ++) {
            if (from in this && this[from] === value) {
                return from;
            }
        }

        return -1;
    },

    lastIndexOf: function (value, from) {
        var len = this.length >>> 0;

        from = Number(from) || len - 1;
        from = Math[from < 0 ? 'ceil' : 'floor'](from);

        if (from < 0) {
            from += len;
        }

        from = Math.min(from, len - 1);

        for (; from >= 0; from--) {
            if (from in this && this[from] === value) {
                return from;
            }
        }

        return -1;
    },

// Iteration methods -----------------------

    filter: function(fn, thisObject){
        var ret = [];
        for (var i = 0, len = this.length; i < len; i++){

            // Kael:
            // Some people might ask: "why we use a `i in this` here?".
            // ECMA:
            // > callback is invoked only for indexes of the array which have assigned values;
            // > it is not invoked for indexes which have been deleted or which have never been assigned values

            // Besides, `filter` method is not always used with real Arrays, invocations below might happen:

            //     var obj = {length: 4}; obj[3] = 1;
            //     Array.prototype.filter.call({length: 4});
            //     Array.prototype.filter.call($('body'));

            // as well as the lines below
            if ((i in this) && fn.call(thisObject, this[i], i, this)){
                ret.push(this[i]);
            }
        }

        return ret;
    },

    forEach: function(fn, thisObject){
        for (var i = 0, len = this.length; i < len; i++){
            if (i in this){

                // if fn is not callable, it will throw
                fn.call(thisObject, this[i], i, this);
            }
        }
    },

    every: function(fn, thisObject){
        for (var i = 0, len = this.length; i < len; i++){
            if ((i in this) && !fn.call(thisObject, this[i], i, this)){
                return false;
            }
        }
        return true;
    },

    map: function(fn, thisObject){
        var ret = [],
            i = 0,
            l = this.length;

        for (; i < l; i++){

            // if the subject of the index i is deleted, index i should not be contained in the result of array.map()
            if (i in this){
                ret[i] = fn.call(thisObject, this[i], i, this);
            }
        }
        return ret;
    },

    some: function(fn, thisObject){
        for (var i = 0, l = this.length; i < l; i++){
            if ((i in this) && fn.call(thisObject, this[i], i, this)){
                return true;
            }
        }
        return false;
    },

    reduce: function (fn) {
        if(typeof fn !== 'function') {
            throw new TYPE_ERROR(fn + ' is not an function');
        }

        var self = this,
            len = self.length >>> 0,
            i = 0,
            ret;

        if (arguments.length > 1) {
            ret = arguments[1];

        }else{
            do {
                if (i in self) {
                    ret = self[i++];
                    break;
                }

                // if array contains no values, no initial value to return
                if (++ i >= len) {
                    throw new TYPE_ERROR('Reduce of empty array with on initial value');
                }
            }while(true);
        }

        for (; i < len; i++) {
            if (i in self) {
                ret = fn.call(null, ret, self[i], i, self);
            }
        }

        return ret;
    },

    reduceRight: function (fn) {
        if(typeof fn !== 'function') {
            throw new TYPE_ERROR(fn + ' is not an function');
        }

        var self = this,
            len = self.length >>> 0,
            i = len - 1,
            ret;

        if (arguments.length > 1) {
            ret = arguments[1];

        }else {
            do {
                if (i in self) {
                    ret = self[i--];
                    break;
                }
                // if array contains no values, no initial value to return
                if (-- i < 0){
                    throw new TYPE_ERROR('Reduce of empty array with on initial value');
                }

            }while (true);
        }

        for (; i >= 0; i--) {
            if (i in self) {
                ret = fn.call(null, ret, self[i], i, self);
            }
        }

        return ret;
    }

});

extend(Object, {

    // ~ https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/create ~
    // create: function(o){
    //    if(o !== Object(o) && o !== null){
    //        throw new TYPE_ERROR('Object prototype may only be an Object or null');
    //    }

    //    function F() {}
    //    F.prototype = o;

    //    return new F();
    // },

    // refs:
    // http://ejohn.org/blog/ecmascript-5-objects-and-properties/
    // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys
    // https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute
    // http://msdn.microsoft.com/en-us/library/adebfyya(v=vs.94).aspx
    keys: (function () {
        var hasOwnProperty = Object.prototype.hasOwnProperty,
            has_dontEnumBug = !{toString:''}.propertyIsEnumerable('toString'),

            // In some old browsers, such as OLD IE, keys below might not be able to iterated with `for-in`,
            // even if each of them is one of current object's own properties
            NONT_ENUMS = [
                'toString',
                'toLocaleString',
                'valueOf',
                'hasOwnProperty',
                'isPrototypeOf',
                'propertyIsEnumerable',
                'constructor'
            ],

            NONT_ENUMS_LENGTH = NONT_ENUMS.length;

        return function (o) {
            if (o !== Object(o)) {
                throw new TYPE_ERROR('Object.keys called on non-object');
            }

            var ret = [],
                name;

            for (name in o) {
                if (hasOwnProperty.call(o, name)) {
                    ret.push(name);
                }
            }

            if (has_dontEnumBug) {
                for (var i = 0; i < NONT_ENUMS_LENGTH; i++) {
                    if (hasOwnProperty.call(o, NONT_ENUMS[i])) {
                        ret.push(NONT_ENUMS[i]);
                    }
                }
            }

            return ret;
        };

    })()

    // for our current OOP pattern, we don't reply on Object based inheritance
    // so Neuron has not implemented the methods of Object such as Object.defineProperty, etc.
});

implement(String, {
    trimLeft: function(){
        return this.replace(/^\s+/, '');
    },

    trimRight: function(){
        return this.replace(/\s+$/, '');
    },

    trim: function(){
        return this.trimLeft().trimRight();
    }
});

/**
 change log:

 2012-09-23  Kael:
 - remove implementation of Object.create, due to the failure of imitating ECMA standard with old JavaScript methods

 2012-09-22  Kael:
 TODO:
 X A. second argument of Object.create

 2012-09-21  Kael:
 - will no longer throw error if there're more than one parameters for Object.create, according to ECMA.

 2012-04-05  Kael:
 - use trimLeft and trimRight to do a entire trim

 2012-03-02  Kael:
 - Optimize the performance of String.trim method for IE who always do a bad work with regular expressions.
     It may even cause IE browsers(IE6-8) expectedly crash if use `/^\s+|\s+$/` to trim a big string which contains a lot of whitespaces.

 */<commit_msg>#66: ecma: adjust comments<commit_after>
// ## ECMAScript5 implementation

// - methods native object implemented
// - methods native object extends

// codes from mootools, MDC or by Kael Zhang

// ## Indexes

// ### Array.prototype
// - indexOf
// - lastIndexOf
// - filter
// - forEach
// - every
// - map
// - some
// - reduce
// - reduceRight

// ### Object
// - keys
// - create: removed

// ### String.prototype
// - trim
// - trimLeft
// - trimRight

// ## Specification

// ### STANDALONE language enhancement

// - always has no dependencies on Neuron
// - always follow ECMA standard strictly, including logic, exception type
// - throw the same error hint as webkit on a certain exception

function extend(host, methods){
    for(var name in methods){
        if(!host[name]){
            host[name] = methods[name];
        }
    }
}

function implement(host, methods){
    extend(host.prototype, methods);
}

var TYPE_ERROR = TypeError;

// ref: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array
implement(Array, {

// Accessor methods ------------------------

    indexOf: function (value, from) {
        var len = this.length >>> 0;

        from = Number(from) || 0;
        from = Math[from < 0 ? 'ceil' : 'floor'](from);

        if (from < 0) {
            from = Math.max(from + len, 0);
        }

        for (; from < len; from ++) {
            if (from in this && this[from] === value) {
                return from;
            }
        }

        return -1;
    },

    lastIndexOf: function (value, from) {
        var len = this.length >>> 0;

        from = Number(from) || len - 1;
        from = Math[from < 0 ? 'ceil' : 'floor'](from);

        if (from < 0) {
            from += len;
        }

        from = Math.min(from, len - 1);

        for (; from >= 0; from--) {
            if (from in this && this[from] === value) {
                return from;
            }
        }

        return -1;
    },

// Iteration methods -----------------------

    filter: function(fn, thisObject){
        var ret = [];
        for (var i = 0, len = this.length; i < len; i++){

            // Kael:
            // Some people might ask: "why we use a `i in this` here?".
            // ECMA:
            // > callback is invoked only for indexes of the array which have assigned values;
            // > it is not invoked for indexes which have been deleted or which have never been assigned values

            // Besides, `filter` method is not always used with real Arrays, invocations below might happen:

            //     var obj = {length: 4}; obj[3] = 1;
            //     Array.prototype.filter.call({length: 4});
            //     Array.prototype.filter.call($('body'));

            // as well as the lines below
            if ((i in this) && fn.call(thisObject, this[i], i, this)){
                ret.push(this[i]);
            }
        }

        return ret;
    },

    forEach: function(fn, thisObject){
        for (var i = 0, len = this.length; i < len; i++){
            if (i in this){

                // if fn is not callable, it will throw
                fn.call(thisObject, this[i], i, this);
            }
        }
    },

    every: function(fn, thisObject){
        for (var i = 0, len = this.length; i < len; i++){
            if ((i in this) && !fn.call(thisObject, this[i], i, this)){
                return false;
            }
        }
        return true;
    },

    map: function(fn, thisObject){
        var ret = [],
            i = 0,
            l = this.length;

        for (; i < l; i++){

            // if the subject of the index i is deleted, index i should not be contained in the result of array.map()
            if (i in this){
                ret[i] = fn.call(thisObject, this[i], i, this);
            }
        }
        return ret;
    },

    some: function(fn, thisObject){
        for (var i = 0, l = this.length; i < l; i++){
            if ((i in this) && fn.call(thisObject, this[i], i, this)){
                return true;
            }
        }
        return false;
    },

    reduce: function (fn) {
        if(typeof fn !== 'function') {
            throw new TYPE_ERROR(fn + ' is not an function');
        }

        var self = this,
            len = self.length >>> 0,
            i = 0,
            ret;

        if (arguments.length > 1) {
            ret = arguments[1];

        }else{
            do {
                if (i in self) {
                    ret = self[i++];
                    break;
                }

                // if array contains no values, no initial value to return
                if (++ i >= len) {
                    throw new TYPE_ERROR('Reduce of empty array with on initial value');
                }
            }while(true);
        }

        for (; i < len; i++) {
            if (i in self) {
                ret = fn.call(null, ret, self[i], i, self);
            }
        }

        return ret;
    },

    reduceRight: function (fn) {
        if(typeof fn !== 'function') {
            throw new TYPE_ERROR(fn + ' is not an function');
        }

        var self = this,
            len = self.length >>> 0,
            i = len - 1,
            ret;

        if (arguments.length > 1) {
            ret = arguments[1];

        }else {
            do {
                if (i in self) {
                    ret = self[i--];
                    break;
                }
                // if array contains no values, no initial value to return
                if (-- i < 0){
                    throw new TYPE_ERROR('Reduce of empty array with on initial value');
                }

            }while (true);
        }

        for (; i >= 0; i--) {
            if (i in self) {
                ret = fn.call(null, ret, self[i], i, self);
            }
        }

        return ret;
    }

});

extend(Object, {

    // ~ https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/create ~
    // create: function(o){
    //    if(o !== Object(o) && o !== null){
    //        throw new TYPE_ERROR('Object prototype may only be an Object or null');
    //    }

    //    function F() {}
    //    F.prototype = o;

    //    return new F();
    // },

    // refs:
    // http://ejohn.org/blog/ecmascript-5-objects-and-properties/
    // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys
    // https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute
    // http://msdn.microsoft.com/en-us/library/adebfyya(v=vs.94).aspx
    keys: (function () {
        var hasOwnProperty = Object.prototype.hasOwnProperty,
            has_dontEnumBug = !{toString:''}.propertyIsEnumerable('toString'),

            // In some old browsers, such as OLD IE, keys below might not be able to iterated with `for-in`,
            // even if each of them is one of current object's own properties
            NONT_ENUMS = [
                'toString',
                'toLocaleString',
                'valueOf',
                'hasOwnProperty',
                'isPrototypeOf',
                'propertyIsEnumerable',
                'constructor'
            ],

            NONT_ENUMS_LENGTH = NONT_ENUMS.length;

        return function (o) {
            if (o !== Object(o)) {
                throw new TYPE_ERROR('Object.keys called on non-object');
            }

            var ret = [],
                name;

            for (name in o) {
                if (hasOwnProperty.call(o, name)) {
                    ret.push(name);
                }
            }

            if (has_dontEnumBug) {
                for (var i = 0; i < NONT_ENUMS_LENGTH; i++) {
                    if (hasOwnProperty.call(o, NONT_ENUMS[i])) {
                        ret.push(NONT_ENUMS[i]);
                    }
                }
            }

            return ret;
        };

    })()

    // for our current OOP pattern, we don't reply on Object based inheritance
    // so Neuron has not implemented the methods of Object such as Object.defineProperty, etc.
});

implement(String, {
    trimLeft: function(){
        return this.replace(/^\s+/, '');
    },

    trimRight: function(){
        return this.replace(/\s+$/, '');
    },

    trim: function(){
        return this.trimLeft().trimRight();
    }
});

/**
 change log:

 2012-09-23  Kael:
 - remove implementation of Object.create, due to the failure of imitating ECMA standard with old JavaScript methods

 2012-09-22  Kael:
 TODO:
 X A. second argument of Object.create

 2012-09-21  Kael:
 - will no longer throw error if there're more than one parameters for Object.create, according to ECMA.

 2012-04-05  Kael:
 - use trimLeft and trimRight to do a entire trim

 2012-03-02  Kael:
 - Optimize the performance of String.trim method for IE who always do a bad work with regular expressions.
     It may even cause IE browsers(IE6-8) expectedly crash if use `/^\s+|\s+$/` to trim a big string which contains a lot of whitespaces.

 */<|endoftext|>


<commit_before>const HtmlWebpackPlugin = require("html-webpack-plugin");

const entrypoints = require("./entrypoints");

module.exports = Object.keys(entrypoints).map(entry =>
  new HtmlWebpackPlugin({
    filename: `entrypoints/${entry}.html`,
    // use a jinja tag so the static url can be resolved at runtime:
    publicPath: "{{ STATIC_URL_WEBPACK }}",
    chunks: [entry],
    inject: false,
    scriptLoading: "defer",
    templateContent: ({htmlWebpackPlugin}) => {
      if (entry == "screen") {
        return `<link href="${htmlWebpackPlugin.files.css[0]}" rel="stylesheet">`;
      }
      // inject nonce in the script for django-csp to populate
      htmlWebpackPlugin.tags.headTags.forEach(element => {
        element.attributes.nonce = "{{ request.csp_nonce }}";
      });

      return htmlWebpackPlugin.tags.headTags.join("");
    }
  }),
);
<commit_msg>Trigger build after GH saml.<commit_after>const HtmlWebpackPlugin = require("html-webpack-plugin");

const entrypoints = require("./entrypoints");

module.exports = Object.keys(entrypoints).map(entry =>
  new HtmlWebpackPlugin({
    filename: `entrypoints/${entry}.html`,
    // use a jinja tag so the static url can be resolved at runtime:
    publicPath: "{{ STATIC_URL_WEBPACK }}",
    chunks: [entry],
    inject: false,
    scriptLoading: "defer",
    templateContent: ({htmlWebpackPlugin}) => {
      if (entry == "screen") {
        return `<link href="${htmlWebpackPlugin.files.css[0]}" rel="stylesheet">`;
      }
      // inject nonce in the script for django-csp to populate
      htmlWebpackPlugin.tags.headTags.forEach(element => {
        element.attributes.nonce = "{{ request.csp_nonce }}";
      });
      return htmlWebpackPlugin.tags.headTags.join("");
    }
  }),
);
<|endoftext|>


<commit_before>"use strict";

var getLocal = require("./local.js").get;
var UNKNOWN_VALUE = Object.create(null);
var emptySetPool = [];
var entryPool = [];

// Since this package might be used browsers, we should avoid using the
// Node built-in assert module.
function assert(condition, optionalMessage) {
  if (! condition) {
    throw new Error(optionalMessage || "assertion failure");
  }
}

function Entry(fn, key, args) {
  this.parents = new Set;
  this.childValues = new Map;

  // When this Entry has children that are dirty, this property becomes
  // a Set containing other Entry objects, borrowed from emptySetPool.
  // When the set becomes empty, it gets recycled back to emptySetPool.
  this.dirtyChildren = null;

  reset(this, fn, key, args);

  ++Entry.count;
}

Entry.count = 0;

function reset(entry, fn, key, args) {
  entry.fn = fn;
  entry.key = key;
  entry.args = args;
  entry.value = UNKNOWN_VALUE;
  entry.dirty = true;
  entry.subscribe = null;
  entry.unsubscribe = null;
  entry.recomputing = false;
  // Optional callback that will be invoked when entry.parents becomes
  // empty. The Entry object is given as the first parameter. If the
  // callback returns true, then this entry can be removed from the graph
  // and safely recycled into the entryPool.
  entry.reportOrphan = null;
}

Entry.acquire = function (fn, key, args) {
  var entry = entryPool.pop();
  if (entry) {
    reset(entry, fn, key, args);
    return entry;
  }
  return new Entry(fn, key, args);
};

function release(entry) {
  assert(entry.parents.size === 0);
  forgetChildren(entry);
  entryPool.push(entry);
}

exports.Entry = Entry;

var Ep = Entry.prototype;

// The public API of Entry objects consists of the Entry constructor,
// along with the recompute, setDirty, and dispose methods.

Ep.recompute = function recompute() {
  if (! rememberParent(this) &&
      maybeReportOrphan(this)) {
    // The recipient of the entry.reportOrphan callback decided to dispose
    // of this orphan entry by calling entry.dispos(), which recycles it
    // into the entryPool, so we don't need to (and should not) proceed
    // with the recomputation.
    return;
  }

  return recomputeIfDirty(this);
};

// If the given entry has a reportOrphan method, and no remaining parents,
// call entry.reportOrphan and return true iff it returns true. The
// reportOrphan function should return true to indicate entry.dispose()
// has been called, and the entry has been removed from any other caches
// (see index.js for the only current example).
function maybeReportOrphan(entry) {
  var report = entry.reportOrphan;
  return typeof report === "function" &&
    entry.parents.size === 0 &&
    report(entry) === true;
}

Ep.setDirty = function setDirty() {
  if (this.dirty) return;
  this.dirty = true;
  this.value = UNKNOWN_VALUE;
  // Since we're explicitly setting this.dirty = true, we won't need to
  // examine any of our children in recomputeIfDirty, so we can go ahead
  // and forget them.
  forgetChildren(this);
  reportDirty(this);
  // We can also go ahead and unsubscribe, since any further dirty
  // notifications we receive will be redundant, and unsubscribing may
  // free up some resources, e.g. file watchers.
  unsubscribe(this);
};

Ep.dispose = function dispose() {
  var entry = this;
  forgetChildren(entry);
  unsubscribe(entry);

  // Because this entry has been kicked out of the cache (in index.js),
  // we've lost the ability to find out if/when this entry becomes dirty,
  // whether that happens through a subscription, because of a direct call
  // to entry.setDirty(), or because one of its children becomes dirty.
  // Because of this loss of future information, we have to assume the
  // worst (that this entry might have become dirty very soon), so we must
  // immediately mark this entry's parents as dirty. Normally we could
  // just call entry.setDirty() rather than calling parent.setDirty() for
  // each parent, but that would leave this entry in parent.childValues
  // and parent.dirtyChildren, which would prevent the child from being
  // truly forgotten.
  entry.parents.forEach(function (parent) {
    // Causes parent to forget all of its children, including entry.
    parent.setDirty();
  });

  // Since this entry has no parents and no children anymore, and the
  // caller of Entry#dispose has indicated that entry.value no longer
  // matters, we can safely recycle this Entry object for later use.
  release(entry);
};

function setClean(entry) {
  entry.dirty = false;

  if (mightBeDirty(entry)) {
    // This Entry may still have dirty children, in which case we can't
    // let our parents know we're clean just yet.
    return;
  }

  reportClean(entry);
}

function reportDirty(entry) {
  entry.parents.forEach(function (parent) {
    reportDirtyChild(parent, entry);
  });
}

function reportClean(entry) {
  entry.parents.forEach(function (parent) {
    reportCleanChild(parent, entry);
  });
}

function mightBeDirty(entry) {
  return entry.dirty ||
    (entry.dirtyChildren &&
     entry.dirtyChildren.size);
}

// Let a parent Entry know that one of its children may be dirty.
function reportDirtyChild(entry, child) {
  // Must have called rememberParent(child) before calling
  // reportDirtyChild(parent, child).
  assert(entry.childValues.has(child));
  assert(mightBeDirty(child));

  if (! entry.dirtyChildren) {
    entry.dirtyChildren = emptySetPool.pop() || new Set;

  } else if (entry.dirtyChildren.has(child)) {
    // If we already know this child is dirty, then we must have already
    // informed our own parents that we are dirty, so we can terminate
    // the recursion early.
    return;
  }

  entry.dirtyChildren.add(child);
  reportDirty(entry);
}

// Let a parent Entry know that one of its children is no longer dirty.
function reportCleanChild(entry, child) {
  // Must have called rememberChild(child) before calling
  // reportCleanChild(parent, child).
  assert(entry.childValues.has(child));
  assert(! mightBeDirty(child));

  if (entry.childValues.get(child) !== child.value) {
    entry.setDirty();
  }

  removeDirtyChild(entry, child);

  if (mightBeDirty(entry)) {
    return;
  }

  reportClean(entry);
}

function removeDirtyChild(entry, child) {
  var dc = entry.dirtyChildren;
  if (dc) {
    dc.delete(child);
    if (dc.size === 0) {
      emptySetPool.push(dc);
      entry.dirtyChildren = null;
    }
  }
}

function rememberParent(entry) {
  var local = getLocal();
  var parent = local.currentParentEntry;
  if (parent) {
    entry.parents.add(parent);

    if (! parent.childValues.has(entry)) {
      parent.childValues.set(entry, UNKNOWN_VALUE);
    }

    if (mightBeDirty(entry)) {
      reportDirtyChild(parent, entry);
    } else {
      reportCleanChild(parent, entry);
    }

    return parent;
  }
}

// This is the most important method of the Entry API, because it
// determines whether the cached entry.value can be returned immediately,
// or must be recomputed. The overall performance of the caching system
// depends on the truth of the following observations: (1) this.dirty is
// usually false, (2) this.dirtyChildren is usually null/empty, and thus
// (3) this.value is usally returned very quickly, without recomputation.
function recomputeIfDirty(entry) {
  if (entry.dirty) {
    // If this Entry is explicitly dirty because someone called
    // entry.setDirty(), recompute.
    return reallyRecompute(entry);
  }

  if (mightBeDirty(entry)) {
    // Get fresh values for any dirty children, and if those values
    // disagree with this.childValues, mark this Entry explicitly dirty.
    entry.dirtyChildren.forEach(function (child) {
      assert(entry.childValues.has(child));
      try {
        recomputeIfDirty(child);
      } catch (e) {
        entry.setDirty();
      }
    });

    if (entry.dirty) {
      // If this Entry has become explicitly dirty after comparing the fresh
      // values of its dirty children against this.childValues, recompute.
      return reallyRecompute(entry);
    }
  }

  assert(entry.value !== UNKNOWN_VALUE);

  return entry.value;
}

function reallyRecompute(entry) {
  assert(! entry.recomputing, "already recomputing");
  entry.recomputing = true;

  forgetChildren(entry);

  var local = getLocal();
  var parent = local.currentParentEntry;
  local.currentParentEntry = entry;

  var threw = true;
  try {
    entry.value = entry.fn.apply(null, entry.args);
    threw = false;

  } finally {
    entry.recomputing = false;

    assert(local.currentParentEntry === entry);
    local.currentParentEntry = parent;

    if (threw || ! subscribe(entry)) {
      // Mark this Entry dirty if entry.fn threw or we failed to
      // resubscribe. This is important because, if we have a subscribe
      // function and it failed, then we're going to miss important
      // notifications about the potential dirtiness of entry.value.
      entry.setDirty();
    } else {
      // If we successfully recomputed entry.value and did not fail to
      // (re)subscribe, then this Entry is no longer explicitly dirty.
      setClean(entry);
    }
  }

  return entry.value;
}

function forgetChildren(entry) {
  entry.childValues.forEach(function (value, child) {
    forgetChild(entry, child);
  });

  // After we forget all our children, this.dirtyChildren must be empty
  // and therefor must have been reset to null.
  assert(entry.dirtyChildren === null);
}

function forgetChild(entry, child) {
  child.parents.delete(entry);
  entry.childValues.delete(child);
  removeDirtyChild(entry, child);
  maybeReportOrphan(child);
}

function subscribe(entry) {
  if (typeof entry.subscribe === "function") {
    try {
      unsubscribe(entry); // Prevent double subscriptions.
      entry.unsubscribe = entry.subscribe.apply(null, entry.args);
    } catch (e) {
      // If this Entry has a subscribe function and it threw an exception
      // (or an unsubscribe function it previously returned now throws),
      // return false to indicate that we were not able to subscribe (or
      // unsubscribe), and this Entry should remain dirty.
      entry.setDirty();
      return false;
    }
  }

  // Returning true indicates either that there was no entry.subscribe
  // function or that it succeeded.
  return true;
}

function unsubscribe(entry) {
  var unsub = entry.unsubscribe;
  if (typeof unsub === "function") {
    entry.unsubscribe = null;
    unsub();
  }
}
<commit_msg>Don't set parent dirty in reportCleanChild if child value unknown.<commit_after>"use strict";

var getLocal = require("./local.js").get;
var UNKNOWN_VALUE = Object.create(null);
var emptySetPool = [];
var entryPool = [];

// Since this package might be used browsers, we should avoid using the
// Node built-in assert module.
function assert(condition, optionalMessage) {
  if (! condition) {
    throw new Error(optionalMessage || "assertion failure");
  }
}

function Entry(fn, key, args) {
  this.parents = new Set;
  this.childValues = new Map;

  // When this Entry has children that are dirty, this property becomes
  // a Set containing other Entry objects, borrowed from emptySetPool.
  // When the set becomes empty, it gets recycled back to emptySetPool.
  this.dirtyChildren = null;

  reset(this, fn, key, args);

  ++Entry.count;
}

Entry.count = 0;

function reset(entry, fn, key, args) {
  entry.fn = fn;
  entry.key = key;
  entry.args = args;
  entry.value = UNKNOWN_VALUE;
  entry.dirty = true;
  entry.subscribe = null;
  entry.unsubscribe = null;
  entry.recomputing = false;
  // Optional callback that will be invoked when entry.parents becomes
  // empty. The Entry object is given as the first parameter. If the
  // callback returns true, then this entry can be removed from the graph
  // and safely recycled into the entryPool.
  entry.reportOrphan = null;
}

Entry.acquire = function (fn, key, args) {
  var entry = entryPool.pop();
  if (entry) {
    reset(entry, fn, key, args);
    return entry;
  }
  return new Entry(fn, key, args);
};

function release(entry) {
  assert(entry.parents.size === 0);
  forgetChildren(entry);
  entryPool.push(entry);
}

exports.Entry = Entry;

var Ep = Entry.prototype;

// The public API of Entry objects consists of the Entry constructor,
// along with the recompute, setDirty, and dispose methods.

Ep.recompute = function recompute() {
  if (! rememberParent(this) &&
      maybeReportOrphan(this)) {
    // The recipient of the entry.reportOrphan callback decided to dispose
    // of this orphan entry by calling entry.dispos(), which recycles it
    // into the entryPool, so we don't need to (and should not) proceed
    // with the recomputation.
    return;
  }

  return recomputeIfDirty(this);
};

// If the given entry has a reportOrphan method, and no remaining parents,
// call entry.reportOrphan and return true iff it returns true. The
// reportOrphan function should return true to indicate entry.dispose()
// has been called, and the entry has been removed from any other caches
// (see index.js for the only current example).
function maybeReportOrphan(entry) {
  var report = entry.reportOrphan;
  return typeof report === "function" &&
    entry.parents.size === 0 &&
    report(entry) === true;
}

Ep.setDirty = function setDirty() {
  if (this.dirty) return;
  this.dirty = true;
  this.value = UNKNOWN_VALUE;
  // Since we're explicitly setting this.dirty = true, we won't need to
  // examine any of our children in recomputeIfDirty, so we can go ahead
  // and forget them.
  forgetChildren(this);
  reportDirty(this);
  // We can also go ahead and unsubscribe, since any further dirty
  // notifications we receive will be redundant, and unsubscribing may
  // free up some resources, e.g. file watchers.
  unsubscribe(this);
};

Ep.dispose = function dispose() {
  var entry = this;
  forgetChildren(entry);
  unsubscribe(entry);

  // Because this entry has been kicked out of the cache (in index.js),
  // we've lost the ability to find out if/when this entry becomes dirty,
  // whether that happens through a subscription, because of a direct call
  // to entry.setDirty(), or because one of its children becomes dirty.
  // Because of this loss of future information, we have to assume the
  // worst (that this entry might have become dirty very soon), so we must
  // immediately mark this entry's parents as dirty. Normally we could
  // just call entry.setDirty() rather than calling parent.setDirty() for
  // each parent, but that would leave this entry in parent.childValues
  // and parent.dirtyChildren, which would prevent the child from being
  // truly forgotten.
  entry.parents.forEach(function (parent) {
    // Causes parent to forget all of its children, including entry.
    parent.setDirty();
  });

  // Since this entry has no parents and no children anymore, and the
  // caller of Entry#dispose has indicated that entry.value no longer
  // matters, we can safely recycle this Entry object for later use.
  release(entry);
};

function setClean(entry) {
  entry.dirty = false;

  if (mightBeDirty(entry)) {
    // This Entry may still have dirty children, in which case we can't
    // let our parents know we're clean just yet.
    return;
  }

  reportClean(entry);
}

function reportDirty(entry) {
  entry.parents.forEach(function (parent) {
    reportDirtyChild(parent, entry);
  });
}

function reportClean(entry) {
  entry.parents.forEach(function (parent) {
    reportCleanChild(parent, entry);
  });
}

function mightBeDirty(entry) {
  return entry.dirty ||
    (entry.dirtyChildren &&
     entry.dirtyChildren.size);
}

// Let a parent Entry know that one of its children may be dirty.
function reportDirtyChild(entry, child) {
  // Must have called rememberParent(child) before calling
  // reportDirtyChild(parent, child).
  assert(entry.childValues.has(child));
  assert(mightBeDirty(child));

  if (! entry.dirtyChildren) {
    entry.dirtyChildren = emptySetPool.pop() || new Set;

  } else if (entry.dirtyChildren.has(child)) {
    // If we already know this child is dirty, then we must have already
    // informed our own parents that we are dirty, so we can terminate
    // the recursion early.
    return;
  }

  entry.dirtyChildren.add(child);
  reportDirty(entry);
}

// Let a parent Entry know that one of its children is no longer dirty.
function reportCleanChild(entry, child) {
  var cv = entry.childValues;

  // Must have called rememberChild(child) before calling
  // reportCleanChild(parent, child).
  assert(cv.has(child));
  assert(! mightBeDirty(child));

  var childValue = cv.get(child);
  if (childValue === UNKNOWN_VALUE) {
    cv.set(child, child.value);
  } else if (childValue !== child.value) {
    entry.setDirty();
  }

  removeDirtyChild(entry, child);

  if (mightBeDirty(entry)) {
    return;
  }

  reportClean(entry);
}

function removeDirtyChild(entry, child) {
  var dc = entry.dirtyChildren;
  if (dc) {
    dc.delete(child);
    if (dc.size === 0) {
      emptySetPool.push(dc);
      entry.dirtyChildren = null;
    }
  }
}

function rememberParent(entry) {
  var local = getLocal();
  var parent = local.currentParentEntry;
  if (parent) {
    entry.parents.add(parent);

    if (! parent.childValues.has(entry)) {
      parent.childValues.set(entry, UNKNOWN_VALUE);
    }

    if (mightBeDirty(entry)) {
      reportDirtyChild(parent, entry);
    } else {
      reportCleanChild(parent, entry);
    }

    return parent;
  }
}

// This is the most important method of the Entry API, because it
// determines whether the cached entry.value can be returned immediately,
// or must be recomputed. The overall performance of the caching system
// depends on the truth of the following observations: (1) this.dirty is
// usually false, (2) this.dirtyChildren is usually null/empty, and thus
// (3) this.value is usally returned very quickly, without recomputation.
function recomputeIfDirty(entry) {
  if (entry.dirty) {
    // If this Entry is explicitly dirty because someone called
    // entry.setDirty(), recompute.
    return reallyRecompute(entry);
  }

  if (mightBeDirty(entry)) {
    // Get fresh values for any dirty children, and if those values
    // disagree with this.childValues, mark this Entry explicitly dirty.
    entry.dirtyChildren.forEach(function (child) {
      assert(entry.childValues.has(child));
      try {
        recomputeIfDirty(child);
      } catch (e) {
        entry.setDirty();
      }
    });

    if (entry.dirty) {
      // If this Entry has become explicitly dirty after comparing the fresh
      // values of its dirty children against this.childValues, recompute.
      return reallyRecompute(entry);
    }
  }

  assert(entry.value !== UNKNOWN_VALUE);

  return entry.value;
}

function reallyRecompute(entry) {
  assert(! entry.recomputing, "already recomputing");
  entry.recomputing = true;

  forgetChildren(entry);

  var local = getLocal();
  var parent = local.currentParentEntry;
  local.currentParentEntry = entry;

  var threw = true;
  try {
    entry.value = entry.fn.apply(null, entry.args);
    threw = false;

  } finally {
    entry.recomputing = false;

    assert(local.currentParentEntry === entry);
    local.currentParentEntry = parent;

    if (threw || ! subscribe(entry)) {
      // Mark this Entry dirty if entry.fn threw or we failed to
      // resubscribe. This is important because, if we have a subscribe
      // function and it failed, then we're going to miss important
      // notifications about the potential dirtiness of entry.value.
      entry.setDirty();
    } else {
      // If we successfully recomputed entry.value and did not fail to
      // (re)subscribe, then this Entry is no longer explicitly dirty.
      setClean(entry);
    }
  }

  return entry.value;
}

function forgetChildren(entry) {
  entry.childValues.forEach(function (value, child) {
    forgetChild(entry, child);
  });

  // After we forget all our children, this.dirtyChildren must be empty
  // and therefor must have been reset to null.
  assert(entry.dirtyChildren === null);
}

function forgetChild(entry, child) {
  child.parents.delete(entry);
  entry.childValues.delete(child);
  removeDirtyChild(entry, child);
  maybeReportOrphan(child);
}

function subscribe(entry) {
  if (typeof entry.subscribe === "function") {
    try {
      unsubscribe(entry); // Prevent double subscriptions.
      entry.unsubscribe = entry.subscribe.apply(null, entry.args);
    } catch (e) {
      // If this Entry has a subscribe function and it threw an exception
      // (or an unsubscribe function it previously returned now throws),
      // return false to indicate that we were not able to subscribe (or
      // unsubscribe), and this Entry should remain dirty.
      entry.setDirty();
      return false;
    }
  }

  // Returning true indicates either that there was no entry.subscribe
  // function or that it succeeded.
  return true;
}

function unsubscribe(entry) {
  var unsub = entry.unsubscribe;
  if (typeof unsub === "function") {
    entry.unsubscribe = null;
    unsub();
  }
}
<|endoftext|>


<commit_before>'use strict';

var noble = require('noble');
var debug = require('debug');

var Drone = function(uuid) {
  this.uuid = uuid;
  this.connected = false;
  this.ble = noble;
  this.steps = {
    fa0a: 0,
    fa0b: 0,
    fa0c: 0
  };
};

// create client helper function to match ar-drone
Drone.createClient = function (options) {
  return new Drone(options);
};

Drone.prototype.connect = function(callback) {
  this.ble.on('discover', function(peripheral) {

    var onConnected = function(error) {
      if (error) {
        console.error(error);
      }
      debug('Connected to: '+peripheral.advertisement.localName);
      this.connected = true;
      this.ble.stopScanning();
      callback();
    }.bind(this);

    if (peripheral.uuid === this.uuid) {
      this.peripheral = peripheral;
      this.peripheral.connect(onConnected);
    } else if ((typeof this.uuid) === 'undefined' &&
      peripheral.advertisement.localName &&
      peripheral.advertisement.localName.indexOf('RS_') === 0) {
      console.log('Found a rolling spider');
      this.peripheral = peripheral;
      this.peripheral.connect(onConnected);
    }
  }.bind(this));

  this.ble.startScanning();
};

Drone.prototype.setup = function(callback) {
  this.peripheral.discoverAllServicesAndCharacteristics(function(error, services, characteristics) {
    this.services = services;
    this.characteristics = characteristics;

    this.handshake(callback);
  }.bind(this));
};

Drone.prototype.handshake = function(callback) {
  this.getCharacteristic('fb0f').notify(true);
  this.getCharacteristic('fb0e').notify(true);
  this.getCharacteristic('fb1b').notify(true);
  this.getCharacteristic('fb1c').notify(true);
  this.getCharacteristic('fd22').notify(true);
  this.getCharacteristic('fd23').notify(true);
  this.getCharacteristic('fd24').notify(true);
  this.getCharacteristic('fd52').notify(true);
  this.getCharacteristic('fd53').notify(true);
  this.getCharacteristic('fd54').notify(true);

  setTimeout(function() {
    this.steps['fa0b']++;

    this.getCharacteristic('fa0b').write(
      new Buffer([0x04,this.steps['fa0b'],0x00,0x04,0x01,0x00,0x32,0x30,0x31,0x34,0x2D,0x31,0x30,0x2D,0x32,0x38,0x00]),
      true,
      function(error) {
        setTimeout(function() {
          callback();
        }, 100);
      }
    );
  }.bind(this), 100);
};

Drone.prototype.getCharacteristic = function(unique_uuid_segment) {
  var filtered = this.characteristics.filter(function(c) {
    return c.uuid.search(new RegExp(unique_uuid_segment)) !== -1;
  });

  return filtered[0];
};

Drone.prototype.writeTo = function(unique_uuid_segment, buffer) {
  this.getCharacteristic(unique_uuid_segment).write(buffer, true);
};

Drone.prototype.startPing = function() {
  setInterval(function() {
    this.steps['fa0a']++;

    this.writeTo(
      'fa0a',
      new Buffer([0x02,this.steps['fa0a'],0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])
    );
  }.bind(this), 50);
};

//
// tilt [-100:100]
// forward [-100:100]
// turn [-100:100]
// up [-100:100]
//
Drone.prototype.drive = function(tilt, forward, turn, up, steps) {
  for (var i=0; i < steps; i++) {
    this.steps['fa0a']++;

    var buffer = new Buffer([
      0x02,
      this.steps['fa0a'],
      0x02,
      0x00,
      0x02,
      0x00,
      tilt === 0 && forward === 0 ? 0x00 : 0x01,
      tilt,
      forward,
      turn,
      up
    ]);

    this.writeTo('fa0a', buffer);
  }
};

// Operational Functions
// Multiple use cases provided to support initial build API as well as
// NodeCopter API and parity with the ar-drone library.

function takeOff() {
  this.steps['fa0b']++;
  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x00,0x01,0x00])
  );
}

function land(){
  this.steps['fa0b']++;
  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x00,0x03,0x00])
  );
}

function cutOff()  {
  this.steps['fa0c']++;
  this.writeTo(
    'fa0c',
    new Buffer([0x02,this.steps['fa0c'],0x02,0x00,0x04,0x00])
  );
}

function flatTrim () {
  this.steps['fa0b']++;
  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x00,0x00,0x00])
  );
}

function frontFlip() {
  this.steps['fa0b']++;
  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00])
  );
}

function backFlip() {
  this.steps['fa0b']++;
  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x04,0x00,0x00,0x01,0x00,0x00,0x00])
  );
}

function rightFlip() {
  this.steps['fa0b']++;

  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x04,0x00,0x00,0x02,0x00,0x00,0x00])
  );
}

function leftFlip() {
  this.steps['fa0b']++;

  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x04,0x00,0x00,0x03,0x00,0x00,0x00])
  );
}

function up(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(0, 0, 0, speed, steps);
}

function down(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(0, 0, 0, speed * -1, steps);
}
function forward(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(0, speed, 0, 0, steps);
}

function backward(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(0, speed * -1, 0, 0, steps);
}
function turnRight(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(0, 0, speed, 0, steps);
}

function turnLeft(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(0, 0, speed * -1, 0, steps);
}

function tiltRight(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(speed, 0, 0, 0, steps);
}

function tiltLeft(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(speed * -1, 0, 0, 0, steps);
}

// provide options for use case
Drone.prototype.takeoff = takeOff;
Drone.prototype.takeOff = takeOff;
Drone.prototype.land = land;
Drone.prototype.emergency = cutOff;
Drone.prototype.emergancy = cutOff;
Drone.prototype.flatTrim = flatTrim;
Drone.prototype.calibrate = flatTrim;
Drone.prototype.up = up;
Drone.prototype.down = down;
// animation
Drone.prototype.frontFlip = frontFlip;
Drone.prototype.backFlip = backFlip;
Drone.prototype.rightFlip = rightFlip;
Drone.prototype.leftFlip = leftFlip;

// rotational
Drone.prototype.turnRight = turnRight;
Drone.prototype.clockwise = turnRight;
Drone.prototype.turnLeft = turnLeft;
Drone.prototype.counterClockwise = turnLeft;

// directional
Drone.prototype.forward = forward;
Drone.prototype.backward = backward;
Drone.prototype.tiltRight = tiltRight;
Drone.prototype.tiltLeft = tiltLeft;
Drone.prototype.right = tiltRight;
Drone.prototype.left = tiltLeft;

module.exports = Drone;
<commit_msg>fill buffer with 0x00<commit_after>'use strict';

var noble = require('noble');
var debug = require('debug');

var Drone = function(uuid) {
  this.uuid = uuid;
  this.connected = false;
  this.ble = noble;
  this.steps = {
    fa0a: 0,
    fa0b: 0,
    fa0c: 0
  };
};

// create client helper function to match ar-drone
Drone.createClient = function (options) {
  return new Drone(options);
};

Drone.prototype.connect = function(callback) {
  this.ble.on('discover', function(peripheral) {

    var onConnected = function(error) {
      if (error) {
        console.error(error);
      }
      debug('Connected to: '+peripheral.advertisement.localName);
      this.connected = true;
      this.ble.stopScanning();
      callback();
    }.bind(this);

    if (peripheral.uuid === this.uuid) {
      this.peripheral = peripheral;
      this.peripheral.connect(onConnected);
    } else if ((typeof this.uuid) === 'undefined' &&
      peripheral.advertisement.localName &&
      peripheral.advertisement.localName.indexOf('RS_') === 0) {
      console.log('Found a rolling spider');
      this.peripheral = peripheral;
      this.peripheral.connect(onConnected);
    }
  }.bind(this));

  this.ble.startScanning();
};

Drone.prototype.setup = function(callback) {
  this.peripheral.discoverAllServicesAndCharacteristics(function(error, services, characteristics) {
    this.services = services;
    this.characteristics = characteristics;

    this.handshake(callback);
  }.bind(this));
};

Drone.prototype.handshake = function(callback) {
  this.getCharacteristic('fb0f').notify(true);
  this.getCharacteristic('fb0e').notify(true);
  this.getCharacteristic('fb1b').notify(true);
  this.getCharacteristic('fb1c').notify(true);
  this.getCharacteristic('fd22').notify(true);
  this.getCharacteristic('fd23').notify(true);
  this.getCharacteristic('fd24').notify(true);
  this.getCharacteristic('fd52').notify(true);
  this.getCharacteristic('fd53').notify(true);
  this.getCharacteristic('fd54').notify(true);

  setTimeout(function() {
    this.steps['fa0b']++;

    this.getCharacteristic('fa0b').write(
      new Buffer([0x04,this.steps['fa0b'],0x00,0x04,0x01,0x00,0x32,0x30,0x31,0x34,0x2D,0x31,0x30,0x2D,0x32,0x38,0x00]),
      true,
      function(error) {
        setTimeout(function() {
          callback();
        }, 100);
      }
    );
  }.bind(this), 100);
};

Drone.prototype.getCharacteristic = function(unique_uuid_segment) {
  var filtered = this.characteristics.filter(function(c) {
    return c.uuid.search(new RegExp(unique_uuid_segment)) !== -1;
  });

  return filtered[0];
};

Drone.prototype.writeTo = function(unique_uuid_segment, buffer) {
  this.getCharacteristic(unique_uuid_segment).write(buffer, true);
};

Drone.prototype.startPing = function() {
  setInterval(function() {
    this.steps['fa0a']++;

    this.writeTo(
      'fa0a',
      new Buffer([0x02,this.steps['fa0a'],0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])
    );
  }.bind(this), 50);
};

//
// tilt [-100:100]
// forward [-100:100]
// turn [-100:100]
// up [-100:100]
//
Drone.prototype.drive = function(tilt, forward, turn, up, steps) {
  for (var i=0; i < steps; i++) {
    this.steps['fa0a']++;

    var buffer = new Buffer([
      0x02,
      this.steps['fa0a'],
      0x02,
      0x00,
      0x02,
      0x00,
      tilt === 0 && forward === 0 ? 0x00 : 0x01,
      tilt,
      forward,
      turn,
      up,
      0x00,
      0x00,
      0x00,
      0x00
    ]);

    this.writeTo('fa0a', buffer);
  }
};

// Operational Functions
// Multiple use cases provided to support initial build API as well as
// NodeCopter API and parity with the ar-drone library.

function takeOff() {
  this.steps['fa0b']++;
  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x00,0x01,0x00])
  );
}

function land(){
  this.steps['fa0b']++;
  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x00,0x03,0x00])
  );
}

function cutOff()  {
  this.steps['fa0c']++;
  this.writeTo(
    'fa0c',
    new Buffer([0x02,this.steps['fa0c'],0x02,0x00,0x04,0x00])
  );
}

function flatTrim () {
  this.steps['fa0b']++;
  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x00,0x00,0x00])
  );
}

function frontFlip() {
  this.steps['fa0b']++;
  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00])
  );
}

function backFlip() {
  this.steps['fa0b']++;
  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x04,0x00,0x00,0x01,0x00,0x00,0x00])
  );
}

function rightFlip() {
  this.steps['fa0b']++;

  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x04,0x00,0x00,0x02,0x00,0x00,0x00])
  );
}

function leftFlip() {
  this.steps['fa0b']++;

  this.writeTo(
    'fa0b',
    new Buffer([0x02,this.steps['fa0b'],0x02,0x04,0x00,0x00,0x03,0x00,0x00,0x00])
  );
}

function up(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(0, 0, 0, speed, steps);
}

function down(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(0, 0, 0, speed * -1, steps);
}
function forward(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(0, speed, 0, 0, steps);
}

function backward(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(0, speed * -1, 0, 0, steps);
}
function turnRight(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(0, 0, speed, 0, steps);
}

function turnLeft(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(0, 0, speed * -1, 0, steps);
}

function tiltRight(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(speed, 0, 0, 0, steps);
}

function tiltLeft(options) {
  options = options || {};
  var speed = options.speed || 50;
  var steps = options.steps || 50;

  this.drive(speed * -1, 0, 0, 0, steps);
}

// provide options for use case
Drone.prototype.takeoff = takeOff;
Drone.prototype.takeOff = takeOff;
Drone.prototype.land = land;
Drone.prototype.emergency = cutOff;
Drone.prototype.emergancy = cutOff;
Drone.prototype.flatTrim = flatTrim;
Drone.prototype.calibrate = flatTrim;
Drone.prototype.up = up;
Drone.prototype.down = down;
// animation
Drone.prototype.frontFlip = frontFlip;
Drone.prototype.backFlip = backFlip;
Drone.prototype.rightFlip = rightFlip;
Drone.prototype.leftFlip = leftFlip;

// rotational
Drone.prototype.turnRight = turnRight;
Drone.prototype.clockwise = turnRight;
Drone.prototype.turnLeft = turnLeft;
Drone.prototype.counterClockwise = turnLeft;

// directional
Drone.prototype.forward = forward;
Drone.prototype.backward = backward;
Drone.prototype.tiltRight = tiltRight;
Drone.prototype.tiltLeft = tiltLeft;
Drone.prototype.right = tiltRight;
Drone.prototype.left = tiltLeft;

module.exports = Drone;
<|endoftext|>


<commit_before>import React, {Component} from "react";
import PropTypes from 'prop-types';

import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import IconButton from '@material-ui/core/IconButton';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import MoreVertIcon from '@material-ui/icons/MoreVert';
import AddIcon from '@material-ui/icons/AddCircleOutline';
import RemoveIcon from '@material-ui/icons/DeleteOutline';
import RemoveAllIcon from '@material-ui/icons/DeleteSweep';
import ArrowUpIcon from '@material-ui/icons/ArrowUpward';
import ArrowDownIcon from '@material-ui/icons/ArrowDownward';
import CopyIcon from '@material-ui/icons/FileCopy';
import CloudDownloadIcon from '@material-ui/icons/CloudDownload';
import FileDownloadIcon from '@material-ui/icons/ArrowDropDownCircle';
import IconSettings from '@material-ui/icons/Settings';
import IconSettingsCancel from '@material-ui/icons/HighlightOff';
import IconSettingsDone from '@material-ui/icons/Done';

import withStyles from '../Header/toolbar';
import {export_handlers} from '../plugin';

const cmpType = PropTypes.oneOfType([PropTypes.object, PropTypes.array]);

class TabularSectionToolbar extends Component {

  static propTypes = {

    handleAdd: PropTypes.func.isRequired,     // обработчик добавления объекта
    handleRemove: PropTypes.func.isRequired,  // обработчик удаления строки
    handleClear: PropTypes.func.isRequired,   // обработчик очистки табчасти
    handleUp: PropTypes.func.isRequired,      // обработчик перемещения строки вверх
    handleDown: PropTypes.func.isRequired,    // обработчик перемещения строки вниз

    denyAddDel: PropTypes.bool,               // Запрет добавления и удаления строк (скрывает кнопки в панели, отключает обработчики)
    denyReorder: PropTypes.bool,              // Запрет изменения порядка строк

    btns: cmpType,                            // дополнительные кнопки
    menu_items: cmpType,                      // дополнительные пункты меню

  }

  constructor(props, context) {

    super(props, context);

    this.state = {
      anchorEl: undefined,
      menuOpen: false,
    };

    export_handlers.call(this);
  }

  render() {

    const {props, state} = this;
    const {handleUp, handleDown, denyAddDel, denyReorder, classes, width, settings_open, btns, menu_items} = props;

    return (
      <Toolbar disableGutters className={classes.toolbar} style={{width: width || '100%'}}>
        {[
          !denyAddDel && <IconButton key="btn_add" title="Добавить строку" onClick={props.handleAdd}><AddIcon /></IconButton>,
          !denyAddDel && <IconButton key="btn_del" title="Удалить строку" onClick={props.handleRemove}><RemoveIcon /></IconButton>,
          !denyAddDel && <IconButton key="btn_del" title="Удалить все строки" onClick={props.handleClear}><RemoveAllIcon /></IconButton>,
          !denyAddDel && !denyReorder && <IconButton key="sep1" disabled>|</IconButton>,
          !denyReorder && <IconButton key="btn_up" title="Переместить вверх" onClick={handleUp}><ArrowUpIcon/></IconButton>,
          !denyReorder && <IconButton key="btn_down"  title="Переместить вниз" onClick={handleDown}><ArrowDownIcon/></IconButton>,

          // дополнительные кнопки
          btns,

          <Typography key="space" variant="title" color="inherit" className={classes.flex}> </Typography>,

          !settings_open && <IconButton key="more" onClick={this.handleMenuOpen} title="Дополнительно">
            <MoreVertIcon/>
          </IconButton>,

          !settings_open && <Menu key="menu" anchorEl={state.anchorEl} open={state.menuOpen} onClose={this.handleMenuClose}>
            <MenuItem onClick={this.handleExportCSV}><CopyIcon/>  Копировать CSV</MenuItem>
            <MenuItem onClick={this.handleExportJSON}><CloudDownloadIcon/>  Копировать JSON</MenuItem>
            <MenuItem onClick={this.handleExportXLS}><FileDownloadIcon/>  Экспорт в XLS</MenuItem>
            {
              // дополнительные пункты меню
              menu_items
            }
            <MenuItem onClick={() => {
              this.handleMenuClose();
              props.handleSettingsOpen();
            }}><IconSettings/>  Настройка списка</MenuItem>

          </Menu>,

          settings_open && <IconButton key="ss4" title="Применить настройки" onClick={props.handleSettingsClose}><IconSettingsDone/></IconButton>,
          settings_open && <IconButton key="ss5" title="Скрыть настройки" onClick={props.handleSettingsClose}><IconSettingsCancel/></IconButton>

        ]}
      </Toolbar>
    )
  }
}

export default withStyles(TabularSectionToolbar);
<commit_msg>(#378) унификация формы объекта и табчасти<commit_after>import React, {Component} from "react";
import PropTypes from 'prop-types';

import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import IconButton from '@material-ui/core/IconButton';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import MoreVertIcon from '@material-ui/icons/MoreVert';
import AddIcon from '@material-ui/icons/AddCircleOutline';
import RemoveIcon from '@material-ui/icons/DeleteOutline';
import RemoveAllIcon from '@material-ui/icons/DeleteSweep';
import ArrowUpIcon from '@material-ui/icons/ArrowUpward';
import ArrowDownIcon from '@material-ui/icons/ArrowDownward';
import CopyIcon from '@material-ui/icons/FileCopy';
import CloudDownloadIcon from '@material-ui/icons/CloudDownload';
import FileDownloadIcon from '@material-ui/icons/ArrowDropDownCircle';
import IconSettings from '@material-ui/icons/Settings';
import IconSettingsCancel from '@material-ui/icons/HighlightOff';
import IconSettingsDone from '@material-ui/icons/Done';

import withStyles from '../Header/toolbar';
import {export_handlers} from '../plugin';

const cmpType = PropTypes.oneOfType([PropTypes.object, PropTypes.array]);

class TabularSectionToolbar extends Component {

  static propTypes = {

    handleAdd: PropTypes.func.isRequired,     // обработчик добавления объекта
    handleRemove: PropTypes.func.isRequired,  // обработчик удаления строки
    handleClear: PropTypes.func.isRequired,   // обработчик очистки табчасти
    handleUp: PropTypes.func.isRequired,      // обработчик перемещения строки вверх
    handleDown: PropTypes.func.isRequired,    // обработчик перемещения строки вниз

    denyAddDel: PropTypes.bool,               // Запрет добавления и удаления строк (скрывает кнопки в панели, отключает обработчики)
    denyReorder: PropTypes.bool,              // Запрет изменения порядка строк

    btns: cmpType,                            // дополнительные кнопки
    menu_items: cmpType,                      // дополнительные пункты меню

  }

  constructor(props, context) {

    super(props, context);

    this.state = {
      anchorEl: undefined,
      menuOpen: false,
    };

    export_handlers.call(this);
  }

  render() {

    const {props, state} = this;
    const {handleUp, handleDown, denyAddDel, denyReorder, classes, width, settings_open, btns, menu_items} = props;

    return (
      <Toolbar disableGutters className={classes.toolbar} style={{width: width || '100%'}}>
        {[
          !denyAddDel && <IconButton key="btn_add" title="Добавить строку" onClick={props.handleAdd}><AddIcon /></IconButton>,
          !denyAddDel && <IconButton key="btn_del" title="Удалить строку" onClick={props.handleRemove}><RemoveIcon /></IconButton>,
          !denyAddDel && <IconButton key="btn_clear" title="Удалить все строки" onClick={props.handleClear}><RemoveAllIcon /></IconButton>,
          !denyAddDel && !denyReorder && <IconButton key="sep1" disabled>|</IconButton>,
          !denyReorder && <IconButton key="btn_up" title="Переместить вверх" onClick={handleUp}><ArrowUpIcon/></IconButton>,
          !denyReorder && <IconButton key="btn_down"  title="Переместить вниз" onClick={handleDown}><ArrowDownIcon/></IconButton>,

          // дополнительные кнопки
          btns,

          <Typography key="space" variant="title" color="inherit" className={classes.flex}> </Typography>,

          !settings_open && <IconButton key="more" onClick={this.handleMenuOpen} title="Дополнительно">
            <MoreVertIcon/>
          </IconButton>,

          !settings_open && <Menu key="menu" anchorEl={state.anchorEl} open={state.menuOpen} onClose={this.handleMenuClose}>
            <MenuItem onClick={this.handleExportCSV}><CopyIcon/>  Копировать CSV</MenuItem>
            <MenuItem onClick={this.handleExportJSON}><CloudDownloadIcon/>  Копировать JSON</MenuItem>
            <MenuItem onClick={this.handleExportXLS}><FileDownloadIcon/>  Экспорт в XLS</MenuItem>
            {
              // дополнительные пункты меню
              menu_items
            }
            <MenuItem onClick={() => {
              this.handleMenuClose();
              props.handleSettingsOpen();
            }}><IconSettings/>  Настройка списка</MenuItem>

          </Menu>,

          settings_open && <IconButton key="ss4" title="Применить настройки" onClick={props.handleSettingsClose}><IconSettingsDone/></IconButton>,
          settings_open && <IconButton key="ss5" title="Скрыть настройки" onClick={props.handleSettingsClose}><IconSettingsCancel/></IconButton>

        ]}
      </Toolbar>
    )
  }
}

export default withStyles(TabularSectionToolbar);
<|endoftext|>


<commit_before>/**
 * Visual Blocks Editor
 *
 * Copyright 2011 Google Inc.
 * http://code.google.com/p/google-blockly/
 *
 * 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.
 */

/**
 * @fileoverview Functions for injecting Blockly into a web page.
 * @author fraser@google.com (Neil Fraser)
 */

/**
 * Initialise the SVG document with various handlers.
 * @param {!Element} doc The document object.
 * @param {Object} opt_options Optional dictionary of options.
 */
Blockly.inject = function(doc, opt_options) {
  if (opt_options) {
    Blockly.parseOptions_(opt_options);
  }
  Blockly.createDom_(doc);
  Blockly.init_();
};

/**
 * Configure Blockly to behave according to a set of options.
 * @param {!Object} options Dictionary of options.
 * @private
 */
Blockly.parseOptions_ = function(options) {
  Blockly.RTL = !!options['rtl'];
  Blockly.editable = !options['readOnly'];
};

/**
 * Create the SVG image.
 * @param {!Element} doc The document object.
 * @private
 */
Blockly.createDom_ = function(container) {
  // Find the document for the container.
  var doc = container;
  while (doc.parentNode) {
    doc = doc.parentNode;
  }
  Blockly.svgDoc = doc;

  // Load CSS.
  //<link href="blockly.css" rel="stylesheet" type="text/css" />
  var link = doc.createElement('link');
  link.setAttribute('href', 'blockly.css');
  link.setAttribute('rel', 'stylesheet');
  link.setAttribute('type', 'text/css');
  var head = doc.head || doc.getElementsByTagName('head')[0];
  if (!head) {
    throw 'No head in document.';
  }
  head.appendChild(link);

  // Build the SVG DOM.
  /*
  <svg
    xmlns="http://www.w3.org/2000/svg"
    xmlns:html="http://www.w3.org/1999/xhtml"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    version="1.1"
    class="blocklySvg">
    ...
  </svg>
  */
  var svg = Blockly.createSvgElement('svg', {
    'xmlns': 'http://www.w3.org/2000/svg',
    'xmlns:html': 'http://www.w3.org/1999/xhtml',
    'xmlns:xlink': 'http://www.w3.org/1999/xlink',
    'version': '1.1',
    'class': 'blocklySvg'
  }, null);
  /*
  <defs>
    ... filters go here ...
  </defs>
  */
  var defs = Blockly.createSvgElement('defs', {}, svg);
  var filter, feSpecularLighting, feMerge;
  /*
    <!--
      Blocks are highlighted from a light source at the top-left.
      In RTL languages we wish to keep this top-left light source.
    -->
    <filter id="blocklyEmboss">
      <feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"/>
      <feSpecularLighting in="blur" surfaceScale="1" specularConstant="0.5"
                          specularExponent="10" lighting-color="white"
                          result="specOut">
        <fePointLight x="-5000" y="-10000" z="20000"/>
      </feSpecularLighting>
      <feComposite in="specOut" in2="SourceAlpha" operator="in"
                   result="specOut"/>
      <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic"
                   k1="0" k2="1" k3="1" k4="0"/>
    </filter>
  */
  filter = Blockly.createSvgElement('filter', {id: 'blocklyEmboss'}, defs);
  Blockly.createSvgElement('feGaussianBlur',
                {in: 'SourceAlpha', stdDeviation: 1, result: 'blur'}, filter);
  feSpecularLighting = Blockly.createSvgElement('feSpecularLighting',
                {in: 'blur', surfaceScale: 1, specularConstant: 0.5,
                specularExponent: 10, 'lighting-color': 'white',
                result: 'specOut'}, filter);
  Blockly.createSvgElement('fePointLight',
                {x: -5000, y: -10000, z: 20000}, feSpecularLighting);
  Blockly.createSvgElement('feComposite', {in: 'specOut', in2: 'SourceAlpha',
                operator: 'in', result: 'specOut'}, filter);
  Blockly.createSvgElement('feComposite', {in: 'SourceGraphic', in2: 'specOut',
                operator: 'arithmetic', k1: 0, k2: 1, k3: 1, k4: 0}, filter);
  /*
    <filter id="blocklyTrashcanShadowFilter">
      <feGaussianBlur in="SourceAlpha" stdDeviation="2" result="blur"/>
      <feOffset in="blur" dx="1" dy="1" result="offsetBlur"/>
      <feMerge>
        <feMergeNode in="offsetBlur"/>
        <feMergeNode in="SourceGraphic"/>
      </feMerge>
    </filter>
  */
  filter = Blockly.createSvgElement('filter',
      {id: 'blocklyTrashcanShadowFilter'}, defs);
  Blockly.createSvgElement('feGaussianBlur',
      {in: 'SourceAlpha', stdDeviation: 2, result: 'blur'}, filter);
  Blockly.createSvgElement('feOffset',
      {in: 'blur', dx: 1, dy: 1, result: 'offsetBlur'}, filter);
  feMerge = Blockly.createSvgElement('feMerge', {}, filter);
  Blockly.createSvgElement('feMergeNode', {in: 'offsetBlur'}, feMerge);
  Blockly.createSvgElement('feMergeNode', {in: 'SourceGraphic'}, feMerge);
  /*
    <filter id="blocklyShadowFilter">
      <feGaussianBlur stdDeviation="2"/>
    </filter>
  */
  filter = Blockly.createSvgElement('filter',
      {id: 'blocklyShadowFilter'}, defs);
  Blockly.createSvgElement('feGaussianBlur', {stdDeviation: 2}, filter);

  Blockly.mainWorkspace = new Blockly.Workspace(Blockly.editable);
  svg.appendChild(Blockly.mainWorkspace.createDom());
  svg.appendChild(Blockly.FieldTextInput.createDom());
  Blockly.commentCanvas = Blockly.createSvgElement('g', {}, svg);
  if (Blockly.Toolbox && Blockly.editable) {
    svg.appendChild(Blockly.Toolbox.createDom());
  }
  if (Blockly.Mutator && Blockly.editable) {
    svg.appendChild(Blockly.Mutator.createDom());
  }
  Blockly.Tooltip && svg.appendChild(Blockly.Tooltip.createDom());
  if (Blockly.editable) {
    svg.appendChild(Blockly.FieldDropdown.createDom());
  }
  if (Blockly.ContextMenu) {
    svg.appendChild(Blockly.ContextMenu.createDom());
  }

  // The SVG is now fuly assembled.  Add it to the container.
  container.appendChild(svg);
  Blockly.svg = svg;
  Blockly.svgResize();
};

/**
 * Initialise Blockly with various handlers.
 * @private
 */
Blockly.init_ = function() {
  var doc = Blockly.svgDoc;

  Blockly.bindEvent_(window, 'resize', doc, Blockly.svgResize);
  // Bind events for scrolling the workspace.
  // Most of these events should be bound to the SVG's surface.
  // However, 'mouseup' has to be on the whole document so that a block dragged
  // out of bounds and released will know that it has been released.
  // Also, 'keydown' has to be on the whole document since the browser doesn't
  // understand a concept of focus on the SVG image.
  Blockly.bindEvent_(Blockly.svg, 'mousedown', null, Blockly.onMouseDown_);
  Blockly.bindEvent_(doc, 'mouseup', null, Blockly.onMouseUp_);
  Blockly.bindEvent_(Blockly.svg, 'mousemove', null, Blockly.onMouseMove_);
  Blockly.bindEvent_(Blockly.svg, 'contextmenu', null, Blockly.onContextMenu_);
  Blockly.bindEvent_(doc, 'keydown', null, Blockly.onKeyDown_);
  if (Blockly.editable) {
    Blockly.Toolbox && Blockly.Toolbox.init();
    Blockly.Mutator && Blockly.Mutator.init();
  }

  Blockly.mainWorkspace.addTrashcan(Blockly.getMainWorkspaceMetrics);
  Blockly.mainWorkspace.addScrollbar(new Blockly.ScrollbarPair(
      Blockly.mainWorkspace.svgBlockCanvas_,
      Blockly.getMainWorkspaceMetrics, this.setMainWorkspaceMetrics));

  // Load the sounds.
  Blockly.loadAudio_('click');
  Blockly.loadAudio_('delete');
};
<commit_msg>Fixed 'in' reserved word<commit_after>/**
 * Visual Blocks Editor
 *
 * Copyright 2011 Google Inc.
 * http://code.google.com/p/google-blockly/
 *
 * 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.
 */

/**
 * @fileoverview Functions for injecting Blockly into a web page.
 * @author fraser@google.com (Neil Fraser)
 */

/**
 * Initialise the SVG document with various handlers.
 * @param {!Element} doc The document object.
 * @param {Object} opt_options Optional dictionary of options.
 */
Blockly.inject = function(doc, opt_options) {
  if (opt_options) {
    Blockly.parseOptions_(opt_options);
  }
  Blockly.createDom_(doc);
  Blockly.init_();
};

/**
 * Configure Blockly to behave according to a set of options.
 * @param {!Object} options Dictionary of options.
 * @private
 */
Blockly.parseOptions_ = function(options) {
  Blockly.RTL = !!options['rtl'];
  Blockly.editable = !options['readOnly'];
};

/**
 * Create the SVG image.
 * @param {!Element} doc The document object.
 * @private
 */
Blockly.createDom_ = function(container) {
  // Find the document for the container.
  var doc = container;
  while (doc.parentNode) {
    doc = doc.parentNode;
  }
  Blockly.svgDoc = doc;

  // Load CSS.
  //<link href="blockly.css" rel="stylesheet" type="text/css" />
  var link = doc.createElement('link');
  link.setAttribute('href', 'blockly.css');
  link.setAttribute('rel', 'stylesheet');
  link.setAttribute('type', 'text/css');
  var head = doc.head || doc.getElementsByTagName('head')[0];
  if (!head) {
    throw 'No head in document.';
  }
  head.appendChild(link);

  // Build the SVG DOM.
  /*
  <svg
    xmlns="http://www.w3.org/2000/svg"
    xmlns:html="http://www.w3.org/1999/xhtml"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    version="1.1"
    class="blocklySvg">
    ...
  </svg>
  */
  var svg = Blockly.createSvgElement('svg', {
    'xmlns': 'http://www.w3.org/2000/svg',
    'xmlns:html': 'http://www.w3.org/1999/xhtml',
    'xmlns:xlink': 'http://www.w3.org/1999/xlink',
    'version': '1.1',
    'class': 'blocklySvg'
  }, null);
  /*
  <defs>
    ... filters go here ...
  </defs>
  */
  var defs = Blockly.createSvgElement('defs', {}, svg);
  var filter, feSpecularLighting, feMerge;
  /*
    <!--
      Blocks are highlighted from a light source at the top-left.
      In RTL languages we wish to keep this top-left light source.
    -->
    <filter id="blocklyEmboss">
      <feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"/>
      <feSpecularLighting in="blur" surfaceScale="1" specularConstant="0.5"
                          specularExponent="10" lighting-color="white"
                          result="specOut">
        <fePointLight x="-5000" y="-10000" z="20000"/>
      </feSpecularLighting>
      <feComposite in="specOut" in2="SourceAlpha" operator="in"
                   result="specOut"/>
      <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic"
                   k1="0" k2="1" k3="1" k4="0"/>
    </filter>
  */
  filter = Blockly.createSvgElement('filter', {id: 'blocklyEmboss'}, defs);
  Blockly.createSvgElement('feGaussianBlur',
                {'in': 'SourceAlpha', stdDeviation: 1, result: 'blur'}, filter);
  feSpecularLighting = Blockly.createSvgElement('feSpecularLighting',
                {'in': 'blur', surfaceScale: 1, specularConstant: 0.5,
                specularExponent: 10, 'lighting-color': 'white',
                result: 'specOut'}, filter);
  Blockly.createSvgElement('fePointLight',
                {x: -5000, y: -10000, z: 20000}, feSpecularLighting);
  Blockly.createSvgElement('feComposite', {'in': 'specOut', in2: 'SourceAlpha',
                operator: 'in', result: 'specOut'}, filter);
  Blockly.createSvgElement('feComposite', {'in': 'SourceGraphic', in2: 'specOut',
                operator: 'arithmetic', k1: 0, k2: 1, k3: 1, k4: 0}, filter);
  /*
    <filter id="blocklyTrashcanShadowFilter">
      <feGaussianBlur in="SourceAlpha" stdDeviation="2" result="blur"/>
      <feOffset in="blur" dx="1" dy="1" result="offsetBlur"/>
      <feMerge>
        <feMergeNode in="offsetBlur"/>
        <feMergeNode in="SourceGraphic"/>
      </feMerge>
    </filter>
  */
  filter = Blockly.createSvgElement('filter',
      {id: 'blocklyTrashcanShadowFilter'}, defs);
  Blockly.createSvgElement('feGaussianBlur',
      {'in': 'SourceAlpha', stdDeviation: 2, result: 'blur'}, filter);
  Blockly.createSvgElement('feOffset',
      {'in': 'blur', dx: 1, dy: 1, result: 'offsetBlur'}, filter);
  feMerge = Blockly.createSvgElement('feMerge', {}, filter);
  Blockly.createSvgElement('feMergeNode', {'in': 'offsetBlur'}, feMerge);
  Blockly.createSvgElement('feMergeNode', {'in': 'SourceGraphic'}, feMerge);
  /*
    <filter id="blocklyShadowFilter">
      <feGaussianBlur stdDeviation="2"/>
    </filter>
  */
  filter = Blockly.createSvgElement('filter',
      {id: 'blocklyShadowFilter'}, defs);
  Blockly.createSvgElement('feGaussianBlur', {stdDeviation: 2}, filter);

  Blockly.mainWorkspace = new Blockly.Workspace(Blockly.editable);
  svg.appendChild(Blockly.mainWorkspace.createDom());
  svg.appendChild(Blockly.FieldTextInput.createDom());
  Blockly.commentCanvas = Blockly.createSvgElement('g', {}, svg);
  if (Blockly.Toolbox && Blockly.editable) {
    svg.appendChild(Blockly.Toolbox.createDom());
  }
  if (Blockly.Mutator && Blockly.editable) {
    svg.appendChild(Blockly.Mutator.createDom());
  }
  Blockly.Tooltip && svg.appendChild(Blockly.Tooltip.createDom());
  if (Blockly.editable) {
    svg.appendChild(Blockly.FieldDropdown.createDom());
  }
  if (Blockly.ContextMenu) {
    svg.appendChild(Blockly.ContextMenu.createDom());
  }

  // The SVG is now fuly assembled.  Add it to the container.
  container.appendChild(svg);
  Blockly.svg = svg;
  Blockly.svgResize();
};

/**
 * Initialise Blockly with various handlers.
 * @private
 */
Blockly.init_ = function() {
  var doc = Blockly.svgDoc;

  Blockly.bindEvent_(window, 'resize', doc, Blockly.svgResize);
  // Bind events for scrolling the workspace.
  // Most of these events should be bound to the SVG's surface.
  // However, 'mouseup' has to be on the whole document so that a block dragged
  // out of bounds and released will know that it has been released.
  // Also, 'keydown' has to be on the whole document since the browser doesn't
  // understand a concept of focus on the SVG image.
  Blockly.bindEvent_(Blockly.svg, 'mousedown', null, Blockly.onMouseDown_);
  Blockly.bindEvent_(doc, 'mouseup', null, Blockly.onMouseUp_);
  Blockly.bindEvent_(Blockly.svg, 'mousemove', null, Blockly.onMouseMove_);
  Blockly.bindEvent_(Blockly.svg, 'contextmenu', null, Blockly.onContextMenu_);
  Blockly.bindEvent_(doc, 'keydown', null, Blockly.onKeyDown_);
  if (Blockly.editable) {
    Blockly.Toolbox && Blockly.Toolbox.init();
    Blockly.Mutator && Blockly.Mutator.init();
  }

  Blockly.mainWorkspace.addTrashcan(Blockly.getMainWorkspaceMetrics);
  Blockly.mainWorkspace.addScrollbar(new Blockly.ScrollbarPair(
      Blockly.mainWorkspace.svgBlockCanvas_,
      Blockly.getMainWorkspaceMetrics, this.setMainWorkspaceMetrics));

  // Load the sounds.
  Blockly.loadAudio_('click');
  Blockly.loadAudio_('delete');
};
<|endoftext|>


<commit_before>'use strict';

var formEl = document.getElementById('credit-form');
console.log(formEl);

formEl.addEventListener('submit', sendToNextPage);

function sendToNextPage(event) {
  event.stopPropagation();
  event.preventDefault();
  alert('Congrats ' + userName + ' you did it. On to the next level. Good luck!');
  location.href = 'about-us.html';
  // location.href = 'about.html';
}
<commit_msg>linked all the pages for deployment<commit_after>'use strict';

var formEl = document.getElementById('credit-form');
console.log(formEl);

formEl.addEventListener('submit', sendToNextPage);

function sendToNextPage(event) {
  event.stopPropagation();
  event.preventDefault();
  alert('Congrats ' + userName + ' you did it. On to the next level. Good luck!');
  location.href = 'debugger.html';
  // location.href = 'about.html';
}
<|endoftext|>