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

var _self = {},
_ID = require("./manifest.json").namespace;

_self.start = function () {
	window.webworks.event.add(_ID, "community.joypad.eventCallback", eventHandler);
	return window.webworks.execSync(_ID, "start", null);
};

_self.stop = function () {
	return window.webworks.execSync(_ID, "stop", null);
};

// HTML5 spec http://www.w3.org/TR/2014/WD-gamepad-20140225/#widl-Navigator-getGamepads-Gamepad
_self.getGamepads = function() {
	return gamepads;
};

var gamepads = [];

eventHandler = function(event) {
	var gamepad = gamepads[event.ctrl];
	if (!gamepad) {
		gamepad = {};
		gamepads.push(gamepad);
	}
	gamepad.index = event.ctrl;
	gamepad.buttons = event.buttons;
	gamepad.axes = event.axes;
	gamepad.mapping = event.mapping;
	gamepad.id = event.id;
	gamepad.connected = true;
	switch (event.type) {
		case 0:
			break;
		case 1:
			// fire gamepadconnected event
			dispatchGamepadEvent("gamepadconnected", gamepad);
			break;
		case 2:
			// fire gamepaddisconnected event
			gamepad.connected = false;
			dispatchGamepadEvent("gamepaddisconnected", gamepad);
			break;
	}
};

dispatchGamepadEvent = function(type, gamepad) {
	var event = new CustomEvent(type);
	event.gamepad = gamepad;
	window.dispatchEvent(event);
};

if (!navigator.getGamepads) {
	// only start if the HTML5 API is not present
	var startup_messages = JSON.parse(_self.start());
	if (startup_messages.error) {
		console.log(startup_messages);
	}
}

// setup as a shim for the HTML5 spec
navigator.getGamepads = navigator.getGamepads || _self.getGamepads;

module.exports = _self;
<commit_msg>Adds increasing timestamp value on updates<commit_after>/*
* Copyright 2013-2014 BlackBerry Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

var _self = {},
_ID = require("./manifest.json").namespace;

_self.start = function () {
	window.webworks.event.add(_ID, "community.joypad.eventCallback", eventHandler);
	return window.webworks.execSync(_ID, "start", null);
};

_self.stop = function () {
	return window.webworks.execSync(_ID, "stop", null);
};

// HTML5 spec http://www.w3.org/TR/2014/WD-gamepad-20140225/#widl-Navigator-getGamepads-Gamepad
_self.getGamepads = function() {
	return gamepads;
};

var gamepads = [];

eventHandler = function(event) {
	var gamepad = gamepads[event.ctrl];
	if (!gamepad) {
		gamepad = {};
		gamepads.push(gamepad);
	}
	gamepad.index = event.ctrl;
	gamepad.buttons = event.buttons;
	gamepad.axes = event.axes;
	gamepad.mapping = event.mapping;
	gamepad.id = event.id;
	gamepad.connected = true;
	if (gamepad.timestamp >= 0) {
		gamepad.timestamp += 1;
	} else {
		gamepad.timestamp = 0;
	}
	switch (event.type) {
		case 0:
			break;
		case 1:
			// fire gamepadconnected event
			dispatchGamepadEvent("gamepadconnected", gamepad);
			break;
		case 2:
			// fire gamepaddisconnected event
			gamepad.connected = false;
			dispatchGamepadEvent("gamepaddisconnected", gamepad);
			break;
	}
};

dispatchGamepadEvent = function(type, gamepad) {
	var event = new CustomEvent(type);
	event.gamepad = gamepad;
	window.dispatchEvent(event);
};

if (!navigator.getGamepads) {
	// only start if the HTML5 API is not present
	var startup_messages = JSON.parse(_self.start());
	if (startup_messages.error) {
		console.log(startup_messages);
	}
}

// setup as a shim for the HTML5 spec
navigator.getGamepads = navigator.getGamepads || _self.getGamepads;

module.exports = _self;
<|endoftext|>


<commit_before>'use strict';

var util     = require('util');
var format   = util.format;
var inherits = util.inherits;

var objectAssign   = require('object-assign');
var uuidValidate   = require('uuid-validate');
var assert         = require('assert');
var tape           = require('tape-catch');
var SocketIOClient = require('socket.io-client');
var EventEmitter   = require('events').EventEmitter;

var asserts = require('./utils/asserts');
var Promise = require('./utils/Promise');

var testUtils     = require('./testUtils');
var serverAddress = require('../server-address');

var logger = require('./testLogger')('CoordinatedClient');

function CoordinatedClient(tests, uuid, platform, version, hasRequiredHardware) {
  asserts.isArray(tests);
  tests.forEach(function (test) {
    asserts.isString(test.name);
    asserts.isFunction(test.fun);
    asserts.isFunction(test.options.setup);
    asserts.isFunction(test.options.teardown);
    asserts.isNumber(test.options.setupTimeout);
    asserts.isNumber(test.options.testTimeout);
    asserts.isNumber(test.options.teardownTimeout);
    asserts.isNumber(test.options.emitRetryCount);
    asserts.isNumber(test.options.emitRetryTimeout);
  });
  assert(
    tests.length > 0,
    'we should have at least one test'
  );
  // We will use emit retry options from first test as default.
  this._defaults = {
    emitRetryCount:   tests[0].options.emitRetryCount,
    emitRetryTimeout: tests[0].options.emitRetryTimeout
  };

  this._tests = tests.slice();
  this._testNames = this._tests.map(function (test) {
    return test.name;
  });

  asserts.isString(uuid);
  this._uuid = uuid;

  asserts.isString(platform);
  this._platform = platform;

  asserts.exists(version);
  this._version = version;

  asserts.isBool(hasRequiredHardware);
  this._hasRequiredHardware = hasRequiredHardware;

  this._state = CoordinatedClient.states.created;

  this._io = SocketIOClient(
    'http://' + serverAddress + ':' + 3000 + '/',
    {
      reconnection: true,
      reconnectionAttempts: 15,
      reconnectionDelay: 200,
      reconnectionDelayMax: 1000,
      randomizationFactor: 0,

      transports: ['websocket']
    }
  );

  this._bind();
}

inherits(CoordinatedClient, EventEmitter);

CoordinatedClient.states = {
  created:   'created',
  connected: 'connected',
  completed: 'completed'
};

CoordinatedClient.prototype._bind = function () {
  this._io
  .on  ('connect',           this._connect.bind(this))
  .on  ('connect_timeout',   logger.debug.bind(logger))
  .on  ('connect_error',     logger.error.bind(logger))
  .on  ('reconnect',         this._reconnect.bind(this))
  .on  ('reconnect_error',   logger.error.bind(logger))
  .on  ('reconnect_failed',  this._error.bind(this))
  .once('schedule',          this._schedule.bind(this))
  .on  ('discard',           this._discard.bind(this))
  .on  ('disqualify',        this._disqualify.bind(this))
  .on  ('disconnect',        this._disconnect.bind(this))
  .on  ('error',             this._error.bind(this))
  .once('complete',          this._complete.bind(this));
}

// We are having similar logic in both connect reconnect
// events, because socket.io seems to behave so that sometimes
// we get the connect event even if we have been connected before
// (and sometimes the reconnect event).
CoordinatedClient.prototype._connect = function () {
  logger.debug('connected to the test server');
  this._newConnection();
}
CoordinatedClient.prototype._reconnect = function () {
  logger.debug('reconnected to the test server');
  this._newConnection();
}

CoordinatedClient.prototype._newConnection = function () {
  assert(
    this._state === CoordinatedClient.states.created ||
    this._state === CoordinatedClient.states.connected,
    'we should be in created or connected state'
  );
  this._state = CoordinatedClient.states.connected;

  this._emit('present', {
    name:    testUtils.getName(),
    uuid:    this._uuid,
    type:    'unittest',
    tests:   this._testNames,
    os:      this._platform,
    version: this._version,

    hasRequiredHardware: this._hasRequiredHardware,
  });
}

CoordinatedClient.prototype._schedule = function (data) {
  var self = this;

  var testNames = CoordinatedClient.getData(data);
  asserts.arrayEquals(testNames, this._testNames);

  this._emit('schedule_confirmed', data)
  .then(function () {
    var promises = self._tests.map(function (test) {
      return self._scheduleTest(test);
    });
    return Promise.all(promises);
  })
  .catch(function (error) {
    logger.error(
      'unexpected error: \'%s\', stack: \'%s\'',
      error.toString(), error.stack
    );
  });
}

CoordinatedClient.prototype._discard = function (data) {
  var self = this;

  this._emit('discard_confirmed', data)
  .then(function () {
    logger.debug('device discarded as surplus from the test server');
  });

  // We are waiting for 'disconnect' event.
  self._state = CoordinatedClient.states.completed;
}

CoordinatedClient.prototype._disqualify = function (data) {
  var self = this;

  this._emit('disqualify_confirmed', data)
  .then(function () {
    logger.debug('device disqualified from the test server');

    return testUtils.returnsValidNetworkStatus()
    .then(function (validStatus) {
      if (!validStatus) {
        self._failed(new Error(
          'test client failed, network status is not valid'
        ));
      }
    });
  });

  // We are waiting for 'disconnect' event.
  self._state = CoordinatedClient.states.completed;
}

CoordinatedClient.prototype._disconnect = function () {
  if (this._state === CoordinatedClient.states.completed) {
    logger.debug('test client disconnected');
    this._succeed();
  } else {
    // Just log the error since socket.io will try to reconnect.
    logger.debug('device disconnected from the test server');
  }
}

CoordinatedClient.prototype._error = function (error) {
  asserts.isString(error);
  this._failed(new Error(error));
}

CoordinatedClient.prototype._complete = function (data) {
  var self = this;

  this._emit('complete_confirmed', data)
  .then(function () {
    logger.debug('all tests completed');
  });

  // We are waiting for 'disconnect' event.
  self._state = CoordinatedClient.states.completed;
}

CoordinatedClient.prototype._succeed = function () {
  logger.debug('test client succeed');
  this._io.close();
  this.emit('finished');
}

CoordinatedClient.prototype._failed = function (error) {
  logger.debug('test client failed');
  this._io.close();
  this.emit('finished', error);
}

// Emitting message to 'connected' socket without confirmation.
// We will just check that socket is 'connected'.
CoordinatedClient.prototype._emit = function (event, data, externalOptions) {
  var self = this;

  var options = objectAssign({}, this._defaults, externalOptions);
  var timeout;
  var retryIndex = 0;
  data = data || '';

  return new Promise(function (resolve, reject) {
    function emit() {
      if (retryIndex >= options.emitRetryCount) {
        reject(new Error(
          'retry count exceed'
        ));
        return;
      }
      retryIndex ++;

      if (self._io.connected) {
        self._io.emit(event, data);
        resolve();
        return;
      }
      timeout = setTimeout(emit, options.emitRetryTimeout);
    }
    emit();
  })
  .catch(function (error) {
    logger.error(
      'unexpected error: \'%s\', stack: \'%s\'',
      error.toString(), error.stack
    );
    return Promise.reject(error);
  })
  .finally(function () {
    clearTimeout(timeout);
  });
}

CoordinatedClient.prototype._scheduleTest = function (test) {
  var self = this;

  function runEvent (event) {
    return new Promise(function (resolve, reject) {
      self._io.once(event, function (data) {
        self._emit(event + '_confirmed', data, test.options)
        .then(function () {
          resolve(CoordinatedClient.getData(data));
        })
        .catch(reject);
      });
    });
  }

  function skipEvent (tape, event, timeout) {
    return runEvent(event)
    .then(function () {
      return new Promise(function (resolve, reject) {
        tape.once('end', function () {
          self._emit(event + '_skipped', undefined, test.options)
          .then(resolve)
          .catch(reject);
        });
        tape.end();
      });
    })
    .timeout(
      timeout,
      format('timeout exceed while skipping test: \'%s\'', test.name)
    );
  }

  function processEvent(tape, event, fun, timeout) {
    return runEvent(event)
    .then(function (parsedData) {
      // Only for testing purposes.
      if (parsedData) {
        tape.participants = parsedData;
      }

      var resultHandler;
      var endHandler;

      return new Promise(function (resolve, reject) {
        // 'end' can be called without 'result', so success is true by default.
        // We can receive 'result' many times.
        // For example each 'tape.ok' will provide a 'result'.
        var success = true;
        resultHandler = function (result) {
          if (!result.ok) {
            success = false;
          }
        }
        tape.on('result', resultHandler);

        endHandler = function () {
          tape.removeListener('result', resultHandler);
          resultHandler = null;
          endHandler    = null;

          self._emit(
            event + '_finished',
            {
              success: success,
              data:    tape.data
            },
            test.options
          )
          .then(function () {
            if (success) {
              resolve(parsedData);
            } else {
              var error = format('test failed, name: \'%s\'', test.name);
              logger.error(error);
              reject(new Error(error));
            }
          })
          .catch(reject);
        }
        tape.once('end', endHandler);

        fun(tape);
      })
      .finally(function () {
        if (resultHandler) {
          tape.removeListener('result', resultHandler);
        }
        if (endHandler) {
          tape.removeListener('end', endHandler);
        }
      });
    })
    .timeout(
      timeout,
      format('timeout exceed while processing test: \'%s\'', test.name)
    );
  }

  function sync (tape, timeout) {
    // returns something like 'at file:lineNumber'.
    function getCaller (level) {
      var traces = (new Error()).stack.split('\n');
      assert(
        traces.length > level,
        format('stack should have a least %d lines', level + 1)
      );
      return traces[level].trim();
    }
    var callerId = getCaller(3);

    return self._emit('sync', callerId, test.options)
    .then(function () {
      return runEvent('syncFinished');
    })
    .timeout(
      timeout,
      format('timeout exceed while syncing test: \'%s\'', test.name)
    );
  }

  return new Promise(function (resolve, reject) {
    tape('setup', function (tape) {
      tape.sync = sync.bind(undefined, tape, test.options.setupTimeout);

      processEvent(tape, 'setup_' + test.name, test.options.setup, test.options.setupTimeout)
      .catch(reject);
    });

    tape(test.name, function (tape) {
      tape.sync = sync.bind(undefined, tape, test.options.testTimeout);

      Promise.try(function () {
        if (test.canBeSkipped) {
          return test.canBeSkipped();
        } else {
          return false;
        }
      })
      .then(function (canBeSkipped) {
        if (canBeSkipped) {
          logger.info('test was skipped, name: \'%s\'', test.name);
          return skipEvent(tape, 'run_' + test.name, test.options.testTimeout);
        } else {
          return processEvent(tape, 'run_' + test.name, test.fun, test.options.testTimeout);
        }
      })
      .catch(reject);
    });

    tape('teardown', function (tape) {
      tape.sync = sync.bind(undefined, tape, test.options.teardownTimeout);

      processEvent(tape, 'teardown_' + test.name, test.options.teardown, test.options.teardownTimeout)
      // We should exit after test teardown.
      .then(resolve)
      .catch(reject);
    });
  });
}

// We should remove prefix (uuid.v4) from data.
CoordinatedClient.getData = function (data) {
  assert(
    uuidValidate(data.uuid, 4),
    'we should have a valid uuid.v4'
  );
  return data.content;
}

module.exports = CoordinatedClient;
<commit_msg>fixed failed error<commit_after>'use strict';

var util     = require('util');
var format   = util.format;
var inherits = util.inherits;

var objectAssign   = require('object-assign');
var uuidValidate   = require('uuid-validate');
var assert         = require('assert');
var tape           = require('tape-catch');
var SocketIOClient = require('socket.io-client');
var EventEmitter   = require('events').EventEmitter;

var asserts = require('./utils/asserts');
var Promise = require('./utils/Promise');

var testUtils     = require('./testUtils');
var serverAddress = require('../server-address');

var logger = require('./testLogger')('CoordinatedClient');

function CoordinatedClient(tests, uuid, platform, version, hasRequiredHardware) {
  asserts.isArray(tests);
  tests.forEach(function (test) {
    asserts.isString(test.name);
    asserts.isFunction(test.fun);
    asserts.isFunction(test.options.setup);
    asserts.isFunction(test.options.teardown);
    asserts.isNumber(test.options.setupTimeout);
    asserts.isNumber(test.options.testTimeout);
    asserts.isNumber(test.options.teardownTimeout);
    asserts.isNumber(test.options.emitRetryCount);
    asserts.isNumber(test.options.emitRetryTimeout);
  });
  assert(
    tests.length > 0,
    'we should have at least one test'
  );
  // We will use emit retry options from first test as default.
  this._defaults = {
    emitRetryCount:   tests[0].options.emitRetryCount,
    emitRetryTimeout: tests[0].options.emitRetryTimeout
  };

  this._tests = tests.slice();
  this._testNames = this._tests.map(function (test) {
    return test.name;
  });

  asserts.isString(uuid);
  this._uuid = uuid;

  asserts.isString(platform);
  this._platform = platform;

  asserts.exists(version);
  this._version = version;

  asserts.isBool(hasRequiredHardware);
  this._hasRequiredHardware = hasRequiredHardware;

  this._state = CoordinatedClient.states.created;

  this._io = SocketIOClient(
    'http://' + serverAddress + ':' + 3000 + '/',
    {
      reconnection: true,
      reconnectionAttempts: 15,
      reconnectionDelay: 200,
      reconnectionDelayMax: 1000,
      randomizationFactor: 0,

      transports: ['websocket']
    }
  );

  this._bind();
}

inherits(CoordinatedClient, EventEmitter);

CoordinatedClient.states = {
  created:   'created',
  connected: 'connected',
  completed: 'completed'
};

CoordinatedClient.prototype._bind = function () {
  this._io
  .on  ('connect',           this._connect.bind(this))
  .on  ('connect_timeout',   logger.debug.bind(logger))
  .on  ('connect_error',     logger.error.bind(logger))
  .on  ('reconnect',         this._reconnect.bind(this))
  .on  ('reconnect_error',   logger.error.bind(logger))
  .on  ('reconnect_failed',  this._error.bind(this))
  .once('schedule',          this._schedule.bind(this))
  .on  ('discard',           this._discard.bind(this))
  .on  ('disqualify',        this._disqualify.bind(this))
  .on  ('disconnect',        this._disconnect.bind(this))
  .on  ('error',             this._error.bind(this))
  .once('complete',          this._complete.bind(this));
}

// We are having similar logic in both connect reconnect
// events, because socket.io seems to behave so that sometimes
// we get the connect event even if we have been connected before
// (and sometimes the reconnect event).
CoordinatedClient.prototype._connect = function () {
  logger.debug('connected to the test server');
  this._newConnection();
}
CoordinatedClient.prototype._reconnect = function () {
  logger.debug('reconnected to the test server');
  this._newConnection();
}

CoordinatedClient.prototype._newConnection = function () {
  assert(
    this._state === CoordinatedClient.states.created ||
    this._state === CoordinatedClient.states.connected,
    'we should be in created or connected state'
  );
  this._state = CoordinatedClient.states.connected;

  this._emit('present', {
    name:    testUtils.getName(),
    uuid:    this._uuid,
    type:    'unittest',
    tests:   this._testNames,
    os:      this._platform,
    version: this._version,

    hasRequiredHardware: this._hasRequiredHardware,
  });
}

CoordinatedClient.prototype._schedule = function (data) {
  var self = this;

  var testNames = CoordinatedClient.getData(data);
  asserts.arrayEquals(testNames, this._testNames);

  this._emit('schedule_confirmed', data)
  .then(function () {
    var promises = self._tests.map(function (test) {
      return self._scheduleTest(test);
    });
    return Promise.all(promises);
  })
  .catch(function (error) {
    logger.error(
      'unexpected error: \'%s\', stack: \'%s\'',
      error.toString(), error.stack
    );
    self._failed(error);
  });
}

CoordinatedClient.prototype._discard = function (data) {
  var self = this;

  this._emit('discard_confirmed', data)
  .then(function () {
    logger.debug('device discarded as surplus from the test server');
  });

  // We are waiting for 'disconnect' event.
  self._state = CoordinatedClient.states.completed;
}

CoordinatedClient.prototype._disqualify = function (data) {
  var self = this;

  this._emit('disqualify_confirmed', data)
  .then(function () {
    logger.debug('device disqualified from the test server');

    return testUtils.returnsValidNetworkStatus()
    .then(function (validStatus) {
      if (!validStatus) {
        self._failed(new Error(
          'test client failed, network status is not valid'
        ));
      }
    });
  });

  // We are waiting for 'disconnect' event.
  self._state = CoordinatedClient.states.completed;
}

CoordinatedClient.prototype._disconnect = function () {
  if (this._state === CoordinatedClient.states.completed) {
    logger.debug('test client disconnected');
    this._succeed();
  } else {
    // Just log the error since socket.io will try to reconnect.
    logger.debug('device disconnected from the test server');
  }
}

CoordinatedClient.prototype._error = function (error) {
  asserts.isString(error);
  this._failed(new Error(error));
}

CoordinatedClient.prototype._complete = function (data) {
  var self = this;

  this._emit('complete_confirmed', data)
  .then(function () {
    logger.debug('all tests completed');
  });

  // We are waiting for 'disconnect' event.
  self._state = CoordinatedClient.states.completed;
}

CoordinatedClient.prototype._succeed = function () {
  logger.debug('test client succeed');
  this._io.close();
  this.emit('finished');
}

CoordinatedClient.prototype._failed = function (error) {
  logger.debug('test client failed');
  this._io.close();
  this.emit('finished', error);
}

// Emitting message to 'connected' socket without confirmation.
// We will just check that socket is 'connected'.
CoordinatedClient.prototype._emit = function (event, data, externalOptions) {
  var self = this;

  var options = objectAssign({}, this._defaults, externalOptions);
  var timeout;
  var retryIndex = 0;
  data = data || '';

  return new Promise(function (resolve, reject) {
    function emit() {
      if (retryIndex >= options.emitRetryCount) {
        reject(new Error(
          'retry count exceed'
        ));
        return;
      }
      retryIndex ++;

      if (self._io.connected) {
        self._io.emit(event, data);
        resolve();
        return;
      }
      timeout = setTimeout(emit, options.emitRetryTimeout);
    }
    emit();
  })
  .catch(function (error) {
    logger.error(
      'unexpected error: \'%s\', stack: \'%s\'',
      error.toString(), error.stack
    );
    return Promise.reject(error);
  })
  .finally(function () {
    clearTimeout(timeout);
  });
}

CoordinatedClient.prototype._scheduleTest = function (test) {
  var self = this;

  function runEvent (event) {
    return new Promise(function (resolve, reject) {
      self._io.once(event, function (data) {
        self._emit(event + '_confirmed', data, test.options)
        .then(function () {
          resolve(CoordinatedClient.getData(data));
        })
        .catch(reject);
      });
    });
  }

  function skipEvent (tape, event, timeout) {
    return runEvent(event)
    .then(function () {
      return new Promise(function (resolve, reject) {
        tape.once('end', function () {
          self._emit(event + '_skipped', undefined, test.options)
          .then(resolve)
          .catch(reject);
        });
        tape.end();
      });
    })
    .timeout(
      timeout,
      format('timeout exceed while skipping test: \'%s\'', test.name)
    );
  }

  function processEvent(tape, event, fun, timeout) {
    return runEvent(event)
    .then(function (parsedData) {
      // Only for testing purposes.
      if (parsedData) {
        tape.participants = parsedData;
      }

      var resultHandler;
      var endHandler;

      return new Promise(function (resolve, reject) {
        // 'end' can be called without 'result', so success is true by default.
        // We can receive 'result' many times.
        // For example each 'tape.ok' will provide a 'result'.
        var success = true;
        resultHandler = function (result) {
          if (!result.ok) {
            success = false;
          }
        }
        tape.on('result', resultHandler);

        endHandler = function () {
          tape.removeListener('result', resultHandler);
          resultHandler = null;
          endHandler    = null;

          self._emit(
            event + '_finished',
            {
              success: success,
              data:    tape.data
            },
            test.options
          )
          .then(function () {
            if (success) {
              resolve(parsedData);
            } else {
              var error = format('test failed, name: \'%s\'', test.name);
              logger.error(error);
              reject(new Error(error));
            }
          })
          .catch(reject);
        }
        tape.once('end', endHandler);

        fun(tape);
      })
      .finally(function () {
        if (resultHandler) {
          tape.removeListener('result', resultHandler);
        }
        if (endHandler) {
          tape.removeListener('end', endHandler);
        }
      });
    })
    .timeout(
      timeout,
      format('timeout exceed while processing test: \'%s\'', test.name)
    );
  }

  function sync (tape, timeout) {
    // returns something like 'at file:lineNumber'.
    function getCaller (level) {
      var traces = (new Error()).stack.split('\n');
      assert(
        traces.length > level,
        format('stack should have a least %d lines', level + 1)
      );
      return traces[level].trim();
    }
    var callerId = getCaller(3);

    return self._emit('sync', callerId, test.options)
    .then(function () {
      return runEvent('syncFinished');
    })
    .timeout(
      timeout,
      format('timeout exceed while syncing test: \'%s\'', test.name)
    );
  }

  return new Promise(function (resolve, reject) {
    tape('setup', function (tape) {
      tape.sync = sync.bind(undefined, tape, test.options.setupTimeout);

      processEvent(tape, 'setup_' + test.name, test.options.setup, test.options.setupTimeout)
      .catch(reject);
    });

    tape(test.name, function (tape) {
      tape.sync = sync.bind(undefined, tape, test.options.testTimeout);

      Promise.try(function () {
        if (test.canBeSkipped) {
          return test.canBeSkipped();
        } else {
          return false;
        }
      })
      .then(function (canBeSkipped) {
        if (canBeSkipped) {
          logger.info('test was skipped, name: \'%s\'', test.name);
          return skipEvent(tape, 'run_' + test.name, test.options.testTimeout);
        } else {
          return processEvent(tape, 'run_' + test.name, test.fun, test.options.testTimeout);
        }
      })
      .catch(reject);
    });

    tape('teardown', function (tape) {
      tape.sync = sync.bind(undefined, tape, test.options.teardownTimeout);

      processEvent(tape, 'teardown_' + test.name, test.options.teardown, test.options.teardownTimeout)
      // We should exit after test teardown.
      .then(resolve)
      .catch(reject);
    });
  });
}

// We should remove prefix (uuid.v4) from data.
CoordinatedClient.getData = function (data) {
  assert(
    uuidValidate(data.uuid, 4),
    'we should have a valid uuid.v4'
  );
  return data.content;
}

module.exports = CoordinatedClient;
<|endoftext|>


<commit_before>/*
Copyright 2020 Modul 9 GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

// ALSAEQ

var exec = require('child_process').exec;
var execFile = require('child_process').execFile;
var version = require("./package.json").version;

var debug = beo.debug;

var settings = {
	"31": 66,
	"63": 66,
	"125": 66,
	"250": 66,
	"500": 66,
	"1000": 66,
	"2000": 66,
	"4000": 66,
	"8000": 66,
	"16000": 66,
};

var controls = {
	"31": '00. 31 Hz',
	"63": '01. 63 Hz',
	"125": '02. 125 Hz',
	"250": '03. 250 Hz',
	"500": '04. 500 Hz',
	"1000":	'05. 1 kHz',
	"2000":	'06. 2 kHz',
	"4000": '07. 4 kHz',
	"8000": '08. 8 kHz',
	"16000": '09. 16 kHz',
}

function read_settings() {
	var child;

	for (var hz in settings) {
		readALSAEq(hz);
	}

	beo.sendToUI("alsa-eq", {header: "eqSettings", content: {settings: settings}});
	checkEnabled();
}

function setALSAEq(hz, percent) {
	control = controls[hz.toString()];

	execFile("amixer", ["set", "-D", "equal", control, percent], function(error, stdout, stderr) {
		if (error) {
			console.error("Error adjusting ALSA mixer control '"+control+"':", error);
		} else {
			percent = parseFloat(stdout.match(/\[(.*?)\]/)[0].slice(1, -2));
			if (debug >= 2) console.log("ALSA mixer control '"+control+"' set to "+percent+" %.");
		}
	});
	settings[hz.toString()]=percent;
}

function readALSAEq(hz) {
	control = controls[hz.toString()];
	exec('amixer -D equal get "'+control+'"', function(error, stdout, stderr) {
		if (error) {
			console.log("error while reading eq for ",hz, error);
		} else {
			percent = parseFloat(stdout.match(/\[(.*?)\]/)[0].slice(1, -2));
			settings[hz.toString()]=percent;
			if (debug) console.log("caching ", hz, percent);
		}
	});
}

function checkEnabled() {
	exec('/opt/hifiberry/bin/alsa-mode', function(error, stdout, stderr) {
		if (error) {
			console.log("error checking ALSAEq status",error);
		} else {
			mode = stdout.trim();
			if (debug) console.log("ALSA mode", mode);
			if (mode == "EQUAL") {
				beo.sendToUI("alsa-eq", {header: "alsaEqEnabled", content: {eqEnabled: true}});
			} else {
				beo.sendToUI("alsa-eq", {header: "alsaEqEnabled", content: {eqEnabled: false}});
			}
		}
	});
}

function enableEq(enabled) {
	if (enabled) {
		mode = "EQUAL";
	} else {
		mode = "SOFTVOL";
	}

	exec('/opt/hifiberry/bin/alsa-mode '+mode, function(error, stdout, stderr) {
		if (error) {
			console.log("error enabling/disabling alsaeq",error);
			return false;
		}
	});
	return true
}

beo.bus.on('general', function(event) {

	if (event.header == "activatedExtension") {
		if (event.content.extension == "alsa-eq") {
			if (debug) console.log("Reading alsaeq settings...");
			read_settings();
		}
	}

});

beo.bus.on('alsa-eq', function(event) {

	if (event.header == "setEq") {
		try {
			hz = event.content.hz;
			percent = event.content.percent;
			setALSAEq(hz, percent)
		} catch (error) {
			console.error("Exception setting eq: ", error);
		}
	}

	if (event.header == "alsaEqEnable") {
		try {
			eqEnable = event.content.eqEnable;
			if (eqEnable) {
				console.log("enabling ALSAEq");
			} else {
				console.log("disabling ALSAEq");
			}
			enableEq(eqEnable);
			beo.sendToUI("alsa-eq", {header: "alsaEqEnabled", content: {eqEnabled: eqEnable}});
			if (debug) console.log("sent update to UI");
		} catch (error) {
			console.error("Exception enabling/disabling eq: ", error);
		}
	}

	if (event.header == "resetEq") {
		try {
			for (var hz in settings) {
				setALSAEq(hz, 66)
				if (debug) console.log("reseting",hz);
			}
			beo.sendToUI("alsa-eq", {header: "eqSettings", content: {settings: settings}});
		} catch (error) {
			console.error("Exception reseting eq: ", error);
		}
	}
});

module.exports = {
	version: version
};
<commit_msg>Added logging of usage<commit_after>/*
Copyright 2020 Modul 9 GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

// ALSAEQ

var exec = require('child_process').exec;
var execFile = require('child_process').execFile;
var version = require("./package.json").version;
var debug = beo.debug;
var lastUsed = Date.now();
var usagePrefix = "alsa-equalizer";

var settings = {
	"31": 66,
	"63": 66,
	"125": 66,
	"250": 66,
	"500": 66,
	"1000": 66,
	"2000": 66,
	"4000": 66,
	"8000": 66,
	"16000": 66,
};

var controls = {
	"31": '00. 31 Hz',
	"63": '01. 63 Hz',
	"125": '02. 125 Hz',
	"250": '03. 250 Hz',
	"500": '04. 500 Hz',
	"1000":	'05. 1 kHz',
	"2000":	'06. 2 kHz',
	"4000": '07. 4 kHz',
	"8000": '08. 8 kHz',
	"16000": '09. 16 kHz',
}

function read_settings() {
	var child;

	for (var hz in settings) {
		readALSAEq(hz);
	}

	beo.sendToUI("alsa-eq", {header: "eqSettings", content: {settings: settings}});
	checkEnabled();
}

function setALSAEq(hz, percent) {
	control = controls[hz.toString()];

	execFile("amixer", ["set", "-D", "equal", control, percent], function(error, stdout, stderr) {
		if (error) {
			console.error("Error adjusting ALSA mixer control '"+control+"':", error);
		} else {
			percent = parseFloat(stdout.match(/\[(.*?)\]/)[0].slice(1, -2));
			if (debug >= 2) console.log("ALSA mixer control '"+control+"' set to "+percent+" %.");
		}
	});
	settings[hz.toString()]=percent;
	timeLastUsed = Date.now() - lastUsed;
	if (timeLastUsed > 10000) {
		try {
			beo.extensions["hifiberry-debug"].reportUsage(usagePrefix,1);
		} catch (error) {
			console.error("Exception reporting usage: ", error);
		}
		lastUsed = Date.now();
	}
}

function readALSAEq(hz) {
	control = controls[hz.toString()];
	exec('amixer -D equal get "'+control+'"', function(error, stdout, stderr) {
		if (error) {
			console.log("error while reading eq for ",hz, error);
		} else {
			percent = parseFloat(stdout.match(/\[(.*?)\]/)[0].slice(1, -2));
			settings[hz.toString()]=percent;
			if (debug) console.log("caching ", hz, percent);
		}
	});
}

function checkEnabled() {
	exec('/opt/hifiberry/bin/alsa-mode', function(error, stdout, stderr) {
		if (error) {
			console.log("error checking ALSAEq status",error);
		} else {
			mode = stdout.trim();
			if (debug) console.log("ALSA mode", mode);
			if (mode == "EQUAL") {
				beo.sendToUI("alsa-eq", {header: "alsaEqEnabled", content: {eqEnabled: true}});
			} else {
				beo.sendToUI("alsa-eq", {header: "alsaEqEnabled", content: {eqEnabled: false}});
			}
		}
	});
}

function enableEq(enabled) {
	if (enabled) {
		mode = "EQUAL";
	} else {
		mode = "SOFTVOL";
	}

	exec('/opt/hifiberry/bin/alsa-mode '+mode, function(error, stdout, stderr) {
		if (error) {
			console.log("error enabling/disabling alsaeq",error);
			return false;
		}
	});
	try {
		beo.extensions["hifiberry-debug"].reportActivation(usagePrefix,enabled);
	} catch (error) {
		console.error("Exception reporting usage: ", error);
	}
	return true
}

beo.bus.on('general', function(event) {

	if (event.header == "activatedExtension") {
		if (event.content.extension == "alsa-eq") {
			if (debug) console.log("Reading alsaeq settings...");
			read_settings();
		}
	}

});

beo.bus.on('alsa-eq', function(event) {

	if (event.header == "setEq") {
		try {
			hz = event.content.hz;
			percent = event.content.percent;
			setALSAEq(hz, percent)
		} catch (error) {
			console.error("Exception setting eq: ", error);
		}
	}

	if (event.header == "alsaEqEnable") {
		try {
			eqEnable = event.content.eqEnable;
			if (eqEnable) {
				console.log("enabling ALSAEq");
			} else {
				console.log("disabling ALSAEq");
			}
			enableEq(eqEnable);
			beo.sendToUI("alsa-eq", {header: "alsaEqEnabled", content: {eqEnabled: eqEnable}});
			if (debug) console.log("sent update to UI");
		} catch (error) {
			console.error("Exception enabling/disabling eq: ", error);
		}
	}

	if (event.header == "resetEq") {
		try {
			for (var hz in settings) {
				setALSAEq(hz, 66)
				if (debug) console.log("reseting",hz);
			}
			beo.sendToUI("alsa-eq", {header: "eqSettings", content: {settings: settings}});
		} catch (error) {
			console.error("Exception reseting eq: ", error);
		}
	}
});

module.exports = {
	version: version
};
<|endoftext|>


<commit_before>var CONDITION = 0;
var STREAM = 1;
var SUCCESS = 2;
var FAIL = 3;
var PAYLOAD = 4;

var EOF = {};

Function.prototype.desc = function(d) {
  this.toString = function() { return d; };
  return this;
}

var StringPS = {
  create: function(str) {
    var o = Object.create(this);
    o.pos = 0;
    o.str_ = [str];
    o.tail_ = [];
    return o;
  },
  set str(str) { this.str_[0] = str; },
  get head() { return this.pos >= this.str_[0].length ? EOF : this.str_[0].charAt(this.pos); },
  // TODO(kgr): next line is slow because it can't bet JITed, fix.
  get tail() {
    if ( ! this.tail_[0] ) {
      var tail = Object.create(this.__proto__);
      tail.str_ = this.str_;
      tail.pos = this.pos+1;
      tail.tail_ = [];
      this.tail_[0] = tail;
    }
    return this.tail_[0];
  },
  toString: function() {
    return this.str_[0].substring(this.pos);
  }
};

function HEAD(state) {
  return state[STREAM].head;
}

function COPY_STATE(state, ps) {
  if ( state[CONDITION] === "END" ||
       state[CONDITION] === "END_FAIL" )
    return state;
  return [
    state[CONDITION],
    ps,
    state[SUCCESS],
    state[FAIL],
    state[PAYLOAD]
  ];
}

function TAIL(state) {
  return state[STREAM].tail;
}

function VALUE(state, value) {
  state[PAYLOAD] && state[PAYLOAD](value);
}

function COLLECT(state, f) {
  if ( state[PAYLOAD] ) {
    return f;
  }
}

function DO_SUCCESS(state, ps) {
//  if ( ! state[SUCCESS][STREAM] )
  //    state[SUCCESS][STREAM] = ps;
  if ( typeof state[SUCCESS] === "function" )
    return state[SUCCESS](ps);
  if ( ! state[SUCCESS][STREAM] ) state[SUCCESS][STREAM] = ps;
  return state[SUCCESS];
}

function DO_FAIL(state, ps) {
//  if ( ! state[FAIL][STREAM] )
//    state[FAIL][STREAM] = ps;
  if ( typeof state[FAIL] === "function" )
    return state[FAIL](ps);
  if ( ! state[FAIL][STREAM] ) state[FAIL][STREAM] = ps;
  return state[FAIL];
}

function char(c) {
  return function(state) {
    if ( HEAD(state) == c ) {
      VALUE(state, c);
      return DO_SUCCESS(state, TAIL(state));
    }
    return DO_FAIL(state, state[STREAM])
  }
}

function char_ic(c) {
  c = c.toLowerCase();
  return function(state) {
    if ( HEAD(state).toLowerCase() == c ) {
      VALUE(state, HEAD(state));
      return DO_SUCCESS(state, TAIL(state));
    }
    return DO_FAIL(state, state[STREAM]);
  }
}

function literal(str, opt_value) {
  var s = [];
  for ( var i = 0; i < str.length ; i++ ) {
    s.push(char(str[i]));
  }
  return seq.apply(null, s);
}

function literal_ic(str, opt_value) {
  var s = [];
  for ( var i = 0 ; i < str.length ; i++ ) {
    s.push(char_ic(str[i]));
  }
  return seq.apply(null, s);
}

function range(c1, c2) {
  return function(state) {
    if ( HEAD(state) >= c1 && HEAD(state) <= c2 ) {
      VALUE(state, HEAD(state));
      return DO_SUCCESS(state, TAIL(state));
    }
    return DO_FAIL(state, state[STREAM]);
  };
}

function anyChar(state) {
  if ( HEAD(state) == EOF )
    return DO_FAIL(state, state[STREAM]);

  VALUE(state, HEAD(state));
  return DO_SUCCESS(state, TAIL(state));
}

function notChars(str) {
  return function(state) {
    if ( HEAD(state) != EOF &&
         str.indexOf(HEAD(state)) == -1 ) {
      VALUE(state, HEAD(state));
      return DO_SUCCESS(state, TAIL(state));
    }
    return DO_FAIL(state, state[STREAM]);
  }
}

function notChar(c) {
  return notChars(c);
}

function pass(state) {
  VALUE(state);
  return DO_SUCCESS(state, state[STREAM]);
}

function fail(state) {
  return DO_FAIL(state, state[STREAM]);
}

function prep(a) {
  if ( typeof a == "string" ) return literal(a);
  return a;
}

function seq2(a, b) {
  a = prep(a);
  b = prep(b);
  return function(state) {
    var tmp;
    return [
      a,
      state[STREAM],
      [
        b,
        null, // Need STREAM after b is done with it
        state[SUCCESS],
        state[FAIL],
        function(v) {
          VALUE(state, [tmp, v]);
        }
      ],
      state[FAIL],
      COLLECT(state, function(v) {
        tmp = v;
      })
    ];
  }
}

function alt2(a, b) {
  a = prep(a);
  b = prep(b);
  return function(state) {
    return [
      a,
      state[STREAM],
      state[SUCCESS],
      [
        b,
        state[STREAM],
        state[SUCCESS],
        state[FAIL],
        state[PAYLOAD]
      ],
      state[PAYLOAD]
    ];
  };
}

function not(a, opt_else) {
  a = prep(a);
  opt_else = prep(opt_else);

  if ( ! opt_else ) {
    return function(state) {
      return [
        a,
        state[STREAM],
        COPY_STATE(state[FAIL], state[STREAM]),
        COPY_STATE(state[SUCCESS], state[STREAM])
      ];
    }
  }

  return function(state) {
    return [
      a,
      state[STREAM],
      COPY_STATE(state[FAIL], state[STREAM]),
      [
        opt_else,
        null,
        state[SUCCESS],
        state[FAIL],
        state[PAYLOAD]
      ]
    ]
  };
}

function compose_pairs(args, p) {
  for ( var i = 0 ; i < args.length ; i++ ) {
    args[i] = prep(args[i]);
  }

  if ( args.length == 0 ) return pass;
  if ( args.length == 1 ) return args[0];
  if ( args.length == 2 ) return p(args[0], args[1]);

  var v = p(args[args.length - 2], args[args.length - 1]);

  for ( var i = args.length - 3 ; i >= 0 ; i-- ) {
    v = p(args[i], v);
  }

  return v;
}

function alt() {
  return compose_pairs(arguments, alt2);
}

function seq() {
  return compose_pairs(arguments, seq2);
}

function optional(a) {
  a = prep(a);
  return function(state) {
    return [
      a,
      state[STREAM],
      state[SUCCESS],
      state[SUCCESS],
      state[PAYLOAD]
    ];
  }
}

function repeat(a, opt_delim, opt_min, opt_max) {
  if ( opt_delim === undefined ) {
    if ( opt_min === undefined ) {
      if ( opt_max === undefined ) {
        return repeat_basic(a);
      } else {
        return repeat_max(a, opt_max);
      }
    } else {
      if ( opt_max === undefined ) {
        return repeat_min(a, opt_min);
      } else {
        return repeat_min_max(a, opt_min, opt_max);
      }
    }
  } else {
    if ( opt_min === undefined ) {
      if ( opt_max === undefined ) {
        return repeat_basic_delim(a, opt_delim);
      } else {
        return repeat_max_delim(a, opt_delim, opt_max);
      }
    } else {
      if ( opt_max === undefined ) {
        return repeat_min_delim(a, opt_delim, opt_min);
      } else {
        return repeat_min_max_delim(a, opt_delim, opt_min, opt_max);
      }
    }
  }
}

function repeat_max(a, opt_max) {
  var s = [];
  for ( var i = 0 ; i < opt_max ; i++ ) {
    s.push([
      a
    ]);
  };
  var i = 0;
  return function(state) {
    var current = s[i];

  }
}

function repeat_basic(a) {
  return function(state) {
    // Collect results
    var res = [];

    var s2 = [
      a,
      state[STREAM],
      function(ps) {
        s2[STREAM] = ps;
        return s2;
      },
      [
        pass,
        null,
        state[SUCCESS],
        null,
        function(v) {
          VALUE(state, res);
        }
      ],
      COLLECT(state, function(v) {
        res.push(v);
      })
    ];

    // Repeat s2
//    s2[SUCCESS] = s2;

    return s2
  }
}

function repeat_delim(a, delim) {
  return function(state) {
    var res = [];

    var s2 = [
      delim,
      state[STREAM],
      // success
      [
        pass,
        // stream
        null,
        state[SUCCESS],
        // fail
        null,
        function(v) {
          VALUE(state, res);
        }
      ],
      // fail
      [
        a,
        // stream
        null,
        // success
        null,
        // fail
        state[SUCCESS],
        COLLECT(state, function(v) {
          res.push(v);
        })
      ]
    ];

    s2[FAIL][SUCCESS] = s2;

    return s2;
  };
}

function sym(name) {
  return function(state) {
    return this[name](state);
  }
}

var grammar = {
  END: ["END"],
  END_FAIL: ["END_FAIL"],
  parseString: function(str, opt_start) {
    opt_start = opt_start || this.START;

    var ps = StringPS.create(str);
    var res;
    this.state = [opt_start,
                  ps,
                  this.END,
                  this.END_FAIL,
                  function(v) {
                    res = v;
                  }];
    this.parse();
    return res;
  },
  // Pumps the state machine until termination or more data needed.
  parse: function() {
    while ( true ) {
      if ( ! this.state ) {
        throw "Parser returned undefined.";
      }

      if ( this.state === this.END ) {
        break;
      }

      if ( this.state === this.END_FAIL ) {
        break;
      }

      // Need more data.
      if ( this.state[STREAM].head === null ) {
        return;
      }

      this.state = this.state[CONDITION].call(this, this.state);
    }
  },

  addAction: function(sym, action) {
    var old = this[sym];
    this[sym] = function(state) {
      var self = this;
      var oldfn = state[PAYLOAD];
      function wrapper(v) {
        v = action.call(self, v);
        oldfn && oldfn.call(self, v);
      };
      state[PAYLOAD] = wrapper;
      return old.call(this, state);
    }
    return this;
  },

  addActions: function(map) {
    for ( var key in map ) {
      this.addAction(key, map[key]);
    }
    return this;
  }
};

var TestParser = {
  __proto__: grammar,
  //  START: sym('code tag'),
  START: sym('create child'),
//  'code tag': seq('<%', repeat(not('%>', anyChar)), '%>'),
//    test: alt2(seq2(char('a'), char('c')), seq2(char('a'), char('b')))
  //  test: alt2(char('a'), char('b'))
//  test: repeat(not('hello', anyChar))
  'create child': seq(
    '$$',
    repeat(notChars(' $\r\n<{,.'))),
}.addActions({
  START: function(v) {
    console.log("Result is: ", v);
  }
});

//TestParser.parseString("b");
//  TestParser.parseString("$$hellb");
//  TestParser.parseString("<% true; %>", TestParser["code tag"]);

//TestParser.parseString("c", TestParser.test);
//TestParser.parseString("vvvvz", TestParser.testRepeat);
//TestParser.parseString("vvvb", TestParser.test2);
//TestParser.parseString("b", TestParser.test2)
//TestParser.parseString("vvvvxvv", TestParser.test);

 // console.log("Test1", TemplateParser.parseString('<div id="<%= this.id %>"'));
<commit_msg>Add optimized literal to core/experimental/parse3.js<commit_after>var CONDITION = 0;
var STREAM = 1;
var SUCCESS = 2;
var FAIL = 3;
var PAYLOAD = 4;

var EOF = {};

Function.prototype.desc = function(d) {
  this.toString = function() { return d; };
  return this;
}

var StringPS = {
  create: function(str) {
    var o = Object.create(this);
    o.pos = 0;
    o.str_ = [str];
    o.tail_ = [];
    return o;
  },
  set str(str) { this.str_[0] = str; },
  get head() { return this.pos >= this.str_[0].length ? EOF : this.str_[0].charAt(this.pos); },
  // TODO(kgr): next line is slow because it can't bet JITed, fix.
  get tail() {
    if ( ! this.tail_[0] ) {
      var tail = Object.create(this.__proto__);
      tail.str_ = this.str_;
      tail.pos = this.pos+1;
      tail.tail_ = [];
      this.tail_[0] = tail;
    }
    return this.tail_[0];
  },
  toString: function() {
    return this.str_[0].substring(this.pos);
  }
};

function HEAD(state) {
  return state[STREAM].head;
}

function COPY_STATE(state, ps) {
  if ( state[CONDITION] === "END" ||
       state[CONDITION] === "END_FAIL" )
    return state;
  return [
    state[CONDITION],
    ps,
    state[SUCCESS],
    state[FAIL],
    state[PAYLOAD]
  ];
}

function TAIL(state) {
  return state[STREAM].tail;
}

function VALUE(state, value) {
  state[PAYLOAD] && state[PAYLOAD](value);
}

function COLLECT(state, f) {
  if ( state[PAYLOAD] ) {
    return f;
  }
}

function DO_SUCCESS(state, ps) {
//  if ( ! state[SUCCESS][STREAM] )
  //    state[SUCCESS][STREAM] = ps;
  if ( typeof state[SUCCESS] === "function" )
    return state[SUCCESS](ps);
  if ( ! state[SUCCESS][STREAM] ) state[SUCCESS][STREAM] = ps;
  return state[SUCCESS];
}

function DO_FAIL(state, ps) {
//  if ( ! state[FAIL][STREAM] )
//    state[FAIL][STREAM] = ps;
  if ( typeof state[FAIL] === "function" )
    return state[FAIL](ps);
  if ( ! state[FAIL][STREAM] ) state[FAIL][STREAM] = ps;
  return state[FAIL];
}

function char(c) {
  return function(state) {
    if ( HEAD(state) == c ) {
      VALUE(state, c);
      return DO_SUCCESS(state, TAIL(state));
    }
    return DO_FAIL(state, state[STREAM])
  }
}

function char_ic(c) {
  c = c.toLowerCase();
  return function(state) {
    if ( HEAD(state).toLowerCase() == c ) {
      VALUE(state, HEAD(state));
      return DO_SUCCESS(state, TAIL(state));
    }
    return DO_FAIL(state, state[STREAM]);
  }
}

function xxliteral(str, opt_value) {
  var s = [];
  for ( var i = 0; i < str.length ; i++ ) {
    s.push(char(str[i]));
  }
  return seq.apply(null, s);
}

function literal(str, opt_value) {
  return function(state) {
    var i = 0;
    var ps = state[STREAM];
    var c = ps.head;
    while ( c != null && i < str.length ) {
      if ( str.charAt(i) !== c) {
        return DO_FAIL(state, state[STREAM]);
      }
      ps = ps.tail;
      c = ps.head;
      i++;
    }
    if ( c == null ) {
      debugger;
      return [
        literal(str.subtring(i), opt_value || str),
        ps,
        state[SUCCESS],
        state[FAIL],
        state[PAYLOAD]
      ];
    }
    VALUE(state, opt_value || str);
    return DO_SUCCESS(state, ps);
  };
}

function literal_ic(str, opt_value) {
  var s = [];
  for ( var i = 0 ; i < str.length ; i++ ) {
    s.push(char_ic(str[i]));
  }
  return seq.apply(null, s);
}

function range(c1, c2) {
  return function(state) {
    if ( HEAD(state) >= c1 && HEAD(state) <= c2 ) {
      VALUE(state, HEAD(state));
      return DO_SUCCESS(state, TAIL(state));
    }
    return DO_FAIL(state, state[STREAM]);
  };
}

function anyChar(state) {
  if ( HEAD(state) == EOF )
    return DO_FAIL(state, state[STREAM]);

  VALUE(state, HEAD(state));
  return DO_SUCCESS(state, TAIL(state));
}

function notChars(str) {
  return function(state) {
    if ( HEAD(state) != EOF &&
         str.indexOf(HEAD(state)) == -1 ) {
      VALUE(state, HEAD(state));
      return DO_SUCCESS(state, TAIL(state));
    }
    return DO_FAIL(state, state[STREAM]);
  }
}

function notChar(c) {
  return notChars(c);
}

function pass(state) {
  VALUE(state);
  return DO_SUCCESS(state, state[STREAM]);
}

function fail(state) {
  return DO_FAIL(state, state[STREAM]);
}

function prep(a) {
  if ( typeof a == "string" ) return literal(a);
  return a;
}

function seq2(a, b) {
  a = prep(a);
  b = prep(b);
  return function(state) {
    var tmp;
    return [
      a,
      state[STREAM],
      [
        b,
        null, // Need STREAM after b is done with it
        state[SUCCESS],
        state[FAIL],
        function(v) {
          VALUE(state, [tmp, v]);
        }
      ],
      state[FAIL],
      COLLECT(state, function(v) {
        tmp = v;
      })
    ];
  }
}

function alt2(a, b) {
  a = prep(a);
  b = prep(b);
  return function(state) {
    return [
      a,
      state[STREAM],
      state[SUCCESS],
      [
        b,
        state[STREAM],
        state[SUCCESS],
        state[FAIL],
        state[PAYLOAD]
      ],
      state[PAYLOAD]
    ];
  };
}

function not(a, opt_else) {
  a = prep(a);
  opt_else = prep(opt_else);

  if ( ! opt_else ) {
    return function(state) {
      return [
        a,
        state[STREAM],
        COPY_STATE(state[FAIL], state[STREAM]),
        COPY_STATE(state[SUCCESS], state[STREAM])
      ];
    }
  }

  return function(state) {
    return [
      a,
      state[STREAM],
      COPY_STATE(state[FAIL], state[STREAM]),
      [
        opt_else,
        null,
        state[SUCCESS],
        state[FAIL],
        state[PAYLOAD]
      ]
    ]
  };
}

function compose_pairs(args, p) {
  for ( var i = 0 ; i < args.length ; i++ ) {
    args[i] = prep(args[i]);
  }

  if ( args.length == 0 ) return pass;
  if ( args.length == 1 ) return args[0];
  if ( args.length == 2 ) return p(args[0], args[1]);

  var v = p(args[args.length - 2], args[args.length - 1]);

  for ( var i = args.length - 3 ; i >= 0 ; i-- ) {
    v = p(args[i], v);
  }

  return v;
}

function alt() {
  return compose_pairs(arguments, alt2);
}

function seq() {
  return compose_pairs(arguments, seq2);
}

function optional(a) {
  a = prep(a);
  return function(state) {
    return [
      a,
      state[STREAM],
      state[SUCCESS],
      state[SUCCESS],
      state[PAYLOAD]
    ];
  }
}

function repeat(a, opt_delim, opt_min, opt_max) {
  if ( opt_delim === undefined ) {
    if ( opt_min === undefined ) {
      if ( opt_max === undefined ) {
        return repeat_basic(a);
      } else {
        return repeat_max(a, opt_max);
      }
    } else {
      if ( opt_max === undefined ) {
        return repeat_min(a, opt_min);
      } else {
        return repeat_min_max(a, opt_min, opt_max);
      }
    }
  } else {
    if ( opt_min === undefined ) {
      if ( opt_max === undefined ) {
        return repeat_basic_delim(a, opt_delim);
      } else {
        return repeat_max_delim(a, opt_delim, opt_max);
      }
    } else {
      if ( opt_max === undefined ) {
        return repeat_min_delim(a, opt_delim, opt_min);
      } else {
        return repeat_min_max_delim(a, opt_delim, opt_min, opt_max);
      }
    }
  }
}

function repeat_max(a, opt_max) {
  var s = [];
  for ( var i = 0 ; i < opt_max ; i++ ) {
    s.push([
      a
    ]);
  };
  var i = 0;
  return function(state) {
    var current = s[i];

  }
}

function repeat_basic(a) {
  return function(state) {
    // Collect results
    var res = [];

    var s2 = [
      a,
      state[STREAM],
      function(ps) {
        s2[STREAM] = ps;
        return s2;
      },
      [
        pass,
        null,
        state[SUCCESS],
        null,
        function(v) {
          VALUE(state, res);
        }
      ],
      COLLECT(state, function(v) {
        res.push(v);
      })
    ];

    // Repeat s2
//    s2[SUCCESS] = s2;

    return s2
  }
}

function repeat_delim(a, delim) {
  return function(state) {
    var res = [];

    var s2 = [
      delim,
      state[STREAM],
      // success
      [
        pass,
        // stream
        null,
        state[SUCCESS],
        // fail
        null,
        function(v) {
          VALUE(state, res);
        }
      ],
      // fail
      [
        a,
        // stream
        null,
        // success
        null,
        // fail
        state[SUCCESS],
        COLLECT(state, function(v) {
          res.push(v);
        })
      ]
    ];

    s2[FAIL][SUCCESS] = s2;

    return s2;
  };
}

function sym(name) {
  return function(state) {
    return this[name](state);
  }
}

var grammar = {
  END: ["END"],
  END_FAIL: ["END_FAIL"],
  parseString: function(str, opt_start) {
    opt_start = opt_start || this.START;

    var ps = StringPS.create(str);
    var res;
    this.state = [opt_start,
                  ps,
                  this.END,
                  this.END_FAIL,
                  function(v) {
                    res = v;
                  }];
    this.parse();
    return res;
  },
  // Pumps the state machine until termination or more data needed.
  parse: function() {
    while ( true ) {
      if ( ! this.state ) {
        throw "Parser returned undefined.";
      }

      if ( this.state === this.END ) {
        break;
      }

      if ( this.state === this.END_FAIL ) {
        break;
      }

      // Need more data.
      if ( this.state[STREAM].head === null ) {
        return;
      }

      this.state = this.state[CONDITION].call(this, this.state);
    }
  },

  addAction: function(sym, action) {
    var old = this[sym];
    this[sym] = function(state) {
      var self = this;
      var oldfn = state[PAYLOAD];
      function wrapper(v) {
        v = action.call(self, v);
        oldfn && oldfn.call(self, v);
      };
      state[PAYLOAD] = wrapper;
      return old.call(this, state);
    }
    return this;
  },

  addActions: function(map) {
    for ( var key in map ) {
      this.addAction(key, map[key]);
    }
    return this;
  }
};

var TestParser = {
  __proto__: grammar,
  //  START: sym('code tag'),
  START: sym('create child'),
//  'code tag': seq('<%', repeat(not('%>', anyChar)), '%>'),
//    test: alt2(seq2(char('a'), char('c')), seq2(char('a'), char('b')))
  //  test: alt2(char('a'), char('b'))
//  test: repeat(not('hello', anyChar))
  'create child': seq(
    '$$',
    repeat(notChars(' $\r\n<{,.'))),
}.addActions({
  START: function(v) {
    console.log("Result is: ", v);
  }
});

//TestParser.parseString("b");
//  TestParser.parseString("$$hellb");
//  TestParser.parseString("<% true; %>", TestParser["code tag"]);

//TestParser.parseString("c", TestParser.test);
//TestParser.parseString("vvvvz", TestParser.testRepeat);
//TestParser.parseString("vvvb", TestParser.test2);
//TestParser.parseString("b", TestParser.test2)
//TestParser.parseString("vvvvxvv", TestParser.test);

 // console.log("Test1", TemplateParser.parseString('<div id="<%= this.id %>"'));
<|endoftext|>


<commit_before>import Ember from 'ember'
const {
  Controller, inject
} = Ember

export default Controller.extend({
  notifications: inject.service('notification-messages'),
  error: true,

  actions: {
    // BEGIN-SNIPPET text-support-events
    support (type, value) {
      this.get('notifications').success(`${type}: ${value}`, {
        autoClear: true,
        clearDuration: 2000
      })
    },
    // END-SNIPPET text-support-events

    // BEGIN-SNIPPET text-dom-events
    event (event) {
      this.get('notifications').success(`${event.type}: ${event.target.value}`, {
        autoClear: true,
        clearDuration: 2000
      })
    }
    // END-SNIPPET text-dom-events
  }
})
<commit_msg>Address another PR comment<commit_after>import Ember from 'ember'
const {Controller, inject} = Ember

export default Controller.extend({
  notifications: inject.service('notification-messages'),
  error: true,

  actions: {
    // BEGIN-SNIPPET text-support-events
    support (type, value) {
      this.get('notifications').success(`${type}: ${value}`, {
        autoClear: true,
        clearDuration: 2000
      })
    },
    // END-SNIPPET text-support-events

    // BEGIN-SNIPPET text-dom-events
    event (event) {
      this.get('notifications').success(`${event.type}: ${event.target.value}`, {
        autoClear: true,
        clearDuration: 2000
      })
    }
    // END-SNIPPET text-dom-events
  }
})
<|endoftext|>


<commit_before>const includedSources = require('../plugins/included_source.js');

const version = process.argv[2];
if (!version) {;
    throw new Error("Missing version argument.");
}

console.info(`Updating sources in ${version} documentation`);
includedSources.updateVersionedSources({
  docsDir: `./versioned_docs/version-${version}`,
});
<commit_msg>raise an error if the docs do not exist yet<commit_after>const fs = require("fs");
const includedSources = require('../plugins/included_source.js');

const version = process.argv[2];
if (!version) {;
    throw new Error("Missing version argument.");
}

const docsDir = `./versioned_docs/version-${version}`;
if (!fs.existsSync(docsDir)) {
    throw new Error(`Documentation for version ${version} doesn't exist.`);
}

console.info(`Updating sources in ${version} documentation`);
includedSources.updateVersionedSources({ docsDir });
<|endoftext|>


<commit_before>import { Form, Select, Space, Table, Tag } from "antd";
import React from "react";
import { render } from "react-dom";
import { Provider, useDispatch, useSelector } from "react-redux";
import { useGetProjectsToShareToQuery } from "../../../apis/projects/projects";
import { useGetSampleIdsForProjectQuery } from "../../../apis/projects/samples";
import { setProject } from "./shareSlice";
import store from "./store";

/**
 * Base component for sharing samples between projects.
 *
 * @returns {JSX.Element}
 * @constructor
 */
function ShareSamples() {
  const dispatch = useDispatch();
  const [samples, setSamples] = React.useState([]);
  const { samples: originalSamples, currentProject, projectId } = useSelector(
    (state) => state.shareReducer
  );

  const {
    data: projects,
    isLoading: projectLoading,
  } = useGetProjectsToShareToQuery(currentProject, {
    skip: !currentProject,
  });

  const { data: sampleIds, isLoading } = useGetSampleIdsForProjectQuery(
    projectId,
    {
      skip: !projectId,
    }
  );

  React.useEffect(() => {
    setSamples(originalSamples);
  }, [originalSamples]);

  React.useEffect(() => {
    if (sampleIds) {
      setSamples(
        originalSamples.map((sample) => ({
          ...sample,
          exists: sampleIds.includes(sample.id),
        }))
      );
    }
  }, [originalSamples, sampleIds]);

  const updateCurrentSampleIds = (projectId) => dispatch(setProject(projectId));

  return (
    <Form layout="vertical">
      <Space direction="vertical" style={{ display: "block" }} size="large">
        <Form.Item label={i18n("ShareSamples.projects")}>
          <Select
            style={{ width: `100%` }}
            loading={projectLoading}
            options={projects?.map((project) => ({
              label: project.name,
              value: project.identifier,
            }))}
            onChange={updateCurrentSampleIds}
          />
        </Form.Item>
        <Table
          loading={!samples}
          dataSource={samples}
          rowKey={(sample) => `sample-${sample.id}`}
          columns={[
            {
              title: "Name",
              dataIndex: "name",
            },
            {
              title: "",
              dataIndex: "exists",
              render: (text, sample) =>
                sample.exists && (
                  <Tag color="red">
                    {i18n("ShareSamples.exists").toUpperCase()}
                  </Tag>
                ),
            },
          ]}
        />
      </Space>
    </Form>
  );
}

render(
  <Provider store={store}>
    <ShareSamples />
  </Provider>,
  document.querySelector("#root")
);
<commit_msg>Removed unused variable<commit_after>import { Form, Select, Space, Table, Tag } from "antd";
import React from "react";
import { render } from "react-dom";
import { Provider, useDispatch, useSelector } from "react-redux";
import { useGetProjectsToShareToQuery } from "../../../apis/projects/projects";
import { useGetSampleIdsForProjectQuery } from "../../../apis/projects/samples";
import { setProject } from "./shareSlice";
import store from "./store";

/**
 * Base component for sharing samples between projects.
 *
 * @returns {JSX.Element}
 * @constructor
 */
function ShareSamples() {
  const dispatch = useDispatch();
  const [samples, setSamples] = React.useState([]);
  const { samples: originalSamples, currentProject, projectId } = useSelector(
    (state) => state.shareReducer
  );

  const {
    data: projects,
    isLoading: projectLoading,
  } = useGetProjectsToShareToQuery(currentProject, {
    skip: !currentProject,
  });

  const { data: sampleIds } = useGetSampleIdsForProjectQuery(projectId, {
    skip: !projectId,
  });

  React.useEffect(() => {
    setSamples(originalSamples);
  }, [originalSamples]);

  React.useEffect(() => {
    if (sampleIds) {
      setSamples(
        originalSamples.map((sample) => ({
          ...sample,
          exists: sampleIds.includes(sample.id),
        }))
      );
    }
  }, [originalSamples, sampleIds]);

  const updateCurrentSampleIds = (projectId) => dispatch(setProject(projectId));

  return (
    <Form layout="vertical">
      <Space direction="vertical" style={{ display: "block" }} size="large">
        <Form.Item label={i18n("ShareSamples.projects")}>
          <Select
            style={{ width: `100%` }}
            loading={projectLoading}
            options={projects?.map((project) => ({
              label: project.name,
              value: project.identifier,
            }))}
            onChange={updateCurrentSampleIds}
          />
        </Form.Item>
        <Table
          loading={!samples}
          dataSource={samples}
          rowKey={(sample) => `sample-${sample.id}`}
          columns={[
            {
              title: "Name",
              dataIndex: "name",
            },
            {
              title: "",
              dataIndex: "exists",
              render: (text, sample) =>
                sample.exists && (
                  <Tag color="red">
                    {i18n("ShareSamples.exists").toUpperCase()}
                  </Tag>
                ),
            },
          ]}
        />
      </Space>
    </Form>
  );
}

render(
  <Provider store={store}>
    <ShareSamples />
  </Provider>,
  document.querySelector("#root")
);
<|endoftext|>


<commit_before>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2012 Google Inc.
 * https://developers.google.com/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 Log blocks for Gamefroot
 * @author ryanc1256@gmail.com (Ryan Clough)
 * @author benjamin.p.harding@gmail.com (Ben Harding)
 */
'use strict';

goog.provide('Blockly.Blocks.Kiwifroot.log');

goog.require('Blockly.Blocks');

Blockly.Blocks['kiwi_log'] = {
  init: function() {
    this.setHelpUrl( Blockly.Msg.KF_LOG_URL );
    this.setColour( Blockly.Variables.COLOUR.CONTROL );
    this.appendValueInput("LOG")
        .appendField(Blockly.Msg.KF_LOG_MSG);

    //this.setInputsInline(true);
    this.setPreviousStatement(true);
    this.setNextStatement(true);
    this.setTooltip( Blockly.Msg.KF_LOG_TOOLTIP );
  }
};

Blockly.Blocks['kiwi_set_debug_mode'] = {
  init: function() {
    this.setHelpUrl( Blockly.Msg.KF_SET_DEBUG_MODE_URL );
    this.setColour( Blockly.Variables.COLOUR.CONTROL );
    this.appendValueInput("SET_DEBUG")
        .setCheck('Boolean')
        .appendField( Blockly.Msg.KF_SET_DEBUG_MODE_MESSAGE );

    this.setInputsInline(true);
    this.setPreviousStatement(true);
    this.setNextStatement(true);
    this.setTooltip( Blockly.Msg.KF_SET_DEBUG_MODE_TOOLTIP );
  }
};

Blockly.Blocks['kiwi_get_debug_mode'] = {
  init: function() {
    this.setHelpUrl( Blockly.Msg.KF_GET_DEBUG_MODE_URL );
    this.setColour( Blockly.Variables.COLOUR.CONTROL );
    this.appendDummyInput()
        .appendField( Blockly.Msg.KF_GET_DEBUG_MODE_MESSAGE );

    this.setInputsInline(true);
    this.setOutput(true, "Boolean");
    this.setTooltip( Blockly.Msg.KF_GET_DEBUG_MODE_TOOLTIP );
  }
};

Blockly.Blocks['kiwi_block_category'] = {
  init: function( xmlBlock ) {

    Blockly.addClass_( ( this.svgGroup_ ), 'blocklyBlocksCategory' );

    this.setColour( "#f0f0f0" );
    this.setEditable( false );
    this.setMovable( false );
    this.moveBy( -10, 0 );

    if( xmlBlock ) {
        var category = xmlBlock.getAttribute('message') || 'Category';
    } else {
        var category = 'Category';
    }

    this.appendDummyInput()
        .appendField( category );

    this.setInputsInline(true);

    this.setDisabled( true );
  }
};

Blockly.Blocks['kiwi_device_cocoon'] = {
  init: function() {
    this.setHelpUrl( Blockly.Msg.KF_DEVICE_COCOON_URL );
    this.setColour( Blockly.Variables.COLOUR.CONTROL );
    this.appendDummyInput()
        .appendField( Blockly.Msg.KF_DEVICE_COCOON_MESSAGE );

    this.setInputsInline(true);
    this.setOutput(true, "Boolean");
    this.setTooltip( Blockly.Msg.KF_DEVICE_COCOON_TOOLTIP );
  }
};
<commit_msg>Category block background colour should now match background.<commit_after>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2012 Google Inc.
 * https://developers.google.com/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 Log blocks for Gamefroot
 * @author ryanc1256@gmail.com (Ryan Clough)
 * @author benjamin.p.harding@gmail.com (Ben Harding)
 */
'use strict';

goog.provide('Blockly.Blocks.Kiwifroot.log');

goog.require('Blockly.Blocks');

Blockly.Blocks['kiwi_log'] = {
  init: function() {
    this.setHelpUrl( Blockly.Msg.KF_LOG_URL );
    this.setColour( Blockly.Variables.COLOUR.CONTROL );
    this.appendValueInput("LOG")
        .appendField(Blockly.Msg.KF_LOG_MSG);

    //this.setInputsInline(true);
    this.setPreviousStatement(true);
    this.setNextStatement(true);
    this.setTooltip( Blockly.Msg.KF_LOG_TOOLTIP );
  }
};

Blockly.Blocks['kiwi_set_debug_mode'] = {
  init: function() {
    this.setHelpUrl( Blockly.Msg.KF_SET_DEBUG_MODE_URL );
    this.setColour( Blockly.Variables.COLOUR.CONTROL );
    this.appendValueInput("SET_DEBUG")
        .setCheck('Boolean')
        .appendField( Blockly.Msg.KF_SET_DEBUG_MODE_MESSAGE );

    this.setInputsInline(true);
    this.setPreviousStatement(true);
    this.setNextStatement(true);
    this.setTooltip( Blockly.Msg.KF_SET_DEBUG_MODE_TOOLTIP );
  }
};

Blockly.Blocks['kiwi_get_debug_mode'] = {
  init: function() {
    this.setHelpUrl( Blockly.Msg.KF_GET_DEBUG_MODE_URL );
    this.setColour( Blockly.Variables.COLOUR.CONTROL );
    this.appendDummyInput()
        .appendField( Blockly.Msg.KF_GET_DEBUG_MODE_MESSAGE );

    this.setInputsInline(true);
    this.setOutput(true, "Boolean");
    this.setTooltip( Blockly.Msg.KF_GET_DEBUG_MODE_TOOLTIP );
  }
};

Blockly.Blocks['kiwi_block_category'] = {
  init: function( xmlBlock ) {

    Blockly.addClass_( ( this.svgGroup_ ), 'blocklyBlocksCategory' );

    this.setColour( "#f0f0f0" );
    this.setEditable( false );
    this.setMovable( false );
    this.moveBy( -10, 0 );

    if( xmlBlock ) {
        var category = xmlBlock.getAttribute('message') || 'Category';
    } else {
        var category = 'Category';
    }

    this.appendDummyInput()
        .appendField( category );

    this.setInputsInline(true);

    this.setDisabled( true );

    //Colour the block
    //By default blockly won't colour disabled blocks

    //Override the update disabled function. Doesn't suit our needs.
    this.updateDisabled = function() {
      this.svgPath_.setAttribute('fill','#f0f0f0');
    };

  }
};

Blockly.Blocks['kiwi_device_cocoon'] = {
  init: function() {
    this.setHelpUrl( Blockly.Msg.KF_DEVICE_COCOON_URL );
    this.setColour( Blockly.Variables.COLOUR.CONTROL );
    this.appendDummyInput()
        .appendField( Blockly.Msg.KF_DEVICE_COCOON_MESSAGE );

    this.setInputsInline(true);
    this.setOutput(true, "Boolean");
    this.setTooltip( Blockly.Msg.KF_DEVICE_COCOON_TOOLTIP );
  }
};
<|endoftext|>


<commit_before>this.version = 1.0;
var cacheNames = {
  'static': 'static' + this.version,
  'core': 'core' + this.version
};

// Install process
this.oninstalled = function(event) {
  var staticCache = new Cache();
  var oldStaticCache;
  // TODO: how can we avoid downloading both PNGs?
  // https://github.com/slightlyoff/NavigationController/issues/60
  var staticUrls = [
    '//cdn.example.com/all-v1.css',
    '//cdn.example.com/all-v1.js',
    '//cdn.example.com/whatever-v1.png',
    '//cdn.example.com/whatever-large-v1.png',
    '//cdn.example.com/whatever-v1.woff'
  ];

  if (event.previousVersion) {
    oldStaticCache = caches.get('static' + event.previousVersion);
  }

  staticUrls.forEach(function(staticUrl) {
    // copy from previous cache, if it's there
    if (oldStaticCache && oldStaticCache.has(staticUrl)) {
      staticCache.set(staticUrl, oldStaticCache.get(staticUrl));
    }
    else {
      staticCache.add(staticUrl);
    }
  });

  caches.set(cacheNames['static'], staticCache);

  // core cache entried should be check on each controller update
  caches.set(cacheNames['core'], new Cache([
    '/'
  ]));

  event.waitUntil(Promise.every(
    caches.values().map(function(x) { return x.ready(); }
  )).then(function() {
    // if no previous version, we may as well take over now
    if (!event.previousVersion) {
      event.replace();
    }
  });
};

this.onactivate = function(event) {
  var expectedCaches = Object.keys(cacheNames).map(function(key) {
    return cacheNames[key];
  });

  // remove caches that shouldn't be there
  caches.keys.filter(function(cacheName) {
    return expectedCaches.indexOf(cacheName) == -1;
  }).forEach(caches.delete.bind(caches));
};

// Request handling
this.addEventListener('fetch', function(event) {
  if (event.request.url.host == "cdn.example.com") {
    event.respondWith(caches.match(cacheNames['static'], event.request.url).catch(function() {
      return networkFetch(event.request);
    }));
  }
  else {
    event.respondWith(caches.match(cacheNames['core'], event.request.url).catch(function() {
      return networkFetch(event.request);
    }));
  }
});<commit_msg>I wish I could code<commit_after>this.version = 1.0;
var cacheNames = {
  'static': 'static' + this.version,
  'core': 'core' + this.version
};

// Install process
this.oninstalled = function(event) {
  var staticCache = new Cache();
  var oldStaticCache;
  // TODO: how can we avoid downloading both PNGs?
  // https://github.com/slightlyoff/NavigationController/issues/60
  var staticUrls = [
    '//cdn.example.com/all-v1.css',
    '//cdn.example.com/all-v1.js',
    '//cdn.example.com/whatever-v1.png',
    '//cdn.example.com/whatever-large-v1.png',
    '//cdn.example.com/whatever-v1.woff'
  ];

  if (event.previousVersion) {
    oldStaticCache = caches.get('static' + event.previousVersion);
  }

  staticUrls.forEach(function(staticUrl) {
    // copy from previous cache, if it's there
    if (oldStaticCache && oldStaticCache.has(staticUrl)) {
      staticCache.set(staticUrl, oldStaticCache.get(staticUrl));
    }
    else {
      staticCache.add(staticUrl);
    }
  });

  caches.set(cacheNames['static'], staticCache);

  // core cache entried should be check on each controller update
  caches.set(cacheNames['core'], new Cache([
    '/'
  ]));

  event.waitUntil(Promise.every(
    caches.values().map(function(x) { return x.ready(); })
  )).then(function() {
    // if no previous version, we may as well take over now
    if (!event.previousVersion) {
      event.replace();
    }
  });
};

this.onactivate = function(event) {
  var expectedCaches = Object.keys(cacheNames).map(function(key) {
    return cacheNames[key];
  });

  // remove caches that shouldn't be there
  caches.keys.filter(function(cacheName) {
    return expectedCaches.indexOf(cacheName) == -1;
  }).forEach(caches.delete.bind(caches));
};

// Request handling
this.addEventListener('fetch', function(event) {
  if (event.request.url.host == "cdn.example.com") {
    event.respondWith(caches.match(cacheNames['static'], event.request.url).catch(function() {
      return networkFetch(event.request);
    }));
  }
  else {
    event.respondWith(caches.match(cacheNames['core'], event.request.url).catch(function() {
      return networkFetch(event.request);
    }));
  }
});<|endoftext|>


<commit_before>/**
 * Dependencies
 */

const _ = require('lodash');

// enable event listeners
require('./base/listeners');

/**
 * Expose all models
 */
exports = module.exports;

const models = [
    'action',
    'permission',
    'post',
    'role',
    'settings',
    'custom-theme-setting',
    'session',
    'tag',
    'tag-public',
    'user',
    'author',
    'invite',
    'webhook',
    'integration',
    'api-key',
    'mobiledoc-revision',
    'member',
    'offer',
    'offer-redemption',
    'product',
    'benefit',
    'stripe-product',
    'stripe-price',
    'member-subscribe-event',
    'member-paid-subscription-event',
    'member-login-event',
    'member-email-change-event',
    'member-payment-event',
    'member-status-event',
    'member-product-event',
    'member-analytic-event',
    'posts-meta',
    'member-stripe-customer',
    'stripe-customer-subscription',
    'email',
    'email-batch',
    'email-recipient',
    'label',
    'single-use-token',
    'snippet'
];

function init() {
    exports.Base = require('./base');

    models.forEach(function (name) {
        _.extend(exports, require('./' + name));
    });
}

/**
 * Expose `init`
 */

exports.init = init;
<commit_msg>Refactored model init to be implicit<commit_after>/**
 * Dependencies
 */

const _ = require('lodash');
const glob = require('glob');

// enable event listeners
require('./base/listeners');

/**
 * Expose all models
 */
exports = module.exports;

function init() {
    exports.Base = require('./base');

    let modelsFiles = glob.sync('!(index).js', {cwd: __dirname});
    modelsFiles.forEach((model) => {
        const name = model.replace(/.js$/, '');
        _.extend(exports, require('./' + name));
    });
}

/**
 * Expose `init`
 */

exports.init = init;
<|endoftext|>


<commit_before>'use strict';

angular.module('MLDS')
.factory('CommercialUsageService', ['$http', '$rootScope', '$log', '$q', 'Events', '$filter',
                                    function($http, $rootScope, $log, $q, Events, $filter){
		var lastId = 100;

		function fakeId() {
			lastId += 1;
			return lastId;
		}

		var fakeReports = [
			{
				commercialUsageId: fakeId(),
				startDate: new Date('2013-01-01'),
				endDate: new Date('2013-06-30'),
				submitted: new Date('2013-08-01'),
				created: new Date(),
				entries: [
				        {
				        	commercialUsageEntryId: fakeId(),
				        	name: 'Hospital 1',
				        	startDate: new Date(),
				        	country: {
				        		isoCode2: 'CA'
				        	}
				        }
				]

			}, {
				commercialUsageId: 21/*FIXMEfakeId()*/,
				startDate: new Date('2013-07-01'),
				endDate: new Date('2013-12-31'),
				submitted: new Date('2014-01-04'),
				created: new Date(),
				entries: [
				        {
			        	commercialUsageEntryId: fakeId(),
			        	name: 'Hospital 1',
			        	startDate: new Date(),
			        	endDate: new Date(),
			        	country: {
			        		isoCode2: 'CA'
			        	},
			        	created: new Date()
				        },
				        {
				        	commercialUsageEntryId: fakeId(),
				        	name: 'Hospital 2',
				        	startDate: new Date(),
				        	endDate: new Date(),
				        	country: {
				        		isoCode2: 'CA'
				        	},
				        	created: new Date()
				        },
				        {
				        	commercialUsageEntryId: fakeId(),
				        	name: 'Hospital 3',
				        	startDate: new Date(),
				        	endDate: new Date(),
				        	country: {
				        		isoCode2: 'US'
				        	},
				        	created: new Date()
					        }

				]
			}
		];

		function fakeFindUsageReport(reportId) {
			var found = fakeReports.filter(function(element) {
				return element.commercialUsageId === reportId;
			});
			return found ? found[0] : null;
		}

		function wrapData(data) {
			return {
				data: data
			};
		}

		function serializeDate(date) {
			if (date) {
				return $filter('date')(date, 'yyyy-MM-dd');
			} else {
				return null;
			}
		}

		function serializeCommercialEntry(entry) {
			return {
				commercialUsageEntryId: entry.commercialUsageEntryId,
				name: entry.name,
				startDate: serializeDate(entry.startDate),
				endDate: serializeDate(entry.endDate),
				country: entry.country,
				created: entry.created
			}
		}

		var service = {};

		var fakeService = {};

		service.getUsageReports = function(licenseeId) {
			return $http.get('/app/rest/licensees/'+8/*licenseeId*/+'/commercialUsages');
		};
		fakeService.getUsageReports = function(licenseeId) {
			//FIXME FAKE
			return $q.when(wrapData(fakeReports));
		};

		service.createUsageReport = function(licenseeId, startDate, endDate) {
			return $http.post('/app/rest/licensees/'+8/*licenseeId*/+'/commercialUsages',
					{
						startDate: serializeDate(startDate),
						endDate: serializeDate(endDate)
					});
		};
		fakeService.createUsageReport = function(licenseeId, startDate, endDate) {
			//FIXME does not duplicate last report
			var newReport = {
					commercialUsageId: fakeId(),
					//FIXME hack for 2nd Jan rather than 1st due to local/universal time...
					startDate: startDate,
					endDate: endDate,
					created: new Date(),
					usage: [
					]
			};
			fakeReports.push(newReport);
			return $q.when(wrapData(newReport));
		};

		service.getUsageReport = function(reportId) {
			return $http.get('/app/rest/commercialUsages/'+reportId);
		};
		fakeService.getUsageReport = function(reportId) {
			//FIXME FAKE
			return $q.when(wrapData(fakeFindUsageReport(parseInt(reportId, 10))));
		};

		service.addUsageEntry = function(usageReport, entry) {
			var httpPromise = $http.post('/app/rest/commercialUsages/'+usageReport.commercialUsageId,
					serializeCommercialEntry(entry));
			httpPromise.then(function() {
				$rootScope.$broadcast(Events.commercialUsageUpdated);
			});
			return httpPromise;
		};
		fakeService.addUsageEntry = function(usageReport, entry) {
			entry.commercialUsageEntryId = fakeId();
			usageReport.entries.push(entry);
			$rootScope.$broadcast(Events.commercialUsageUpdated);
			return $q.when(wrapData(entry));
		};

		service.updateUsageEntry = function(usageReport, entry) {
			var httpPromise = $http.put('/app/rest/commercialUsages/'+usageReport.commercialUsageId+'/entries/'+entry.commercialUsageEntryId,
					serializeCommercialEntry(entry)
				);
			httpPromise.then(function() {
				$rootScope.$broadcast(Events.commercialUsageUpdated);
			});
			return httpPromise;
		};
		fakeService.updateUsageEntry = function(usageReport, entry) {
			//FIXME FAKE
			$rootScope.$broadcast(Events.commercialUsageUpdated);
			return $q.when(wrapData(entry));
		};

		service.deleteUsageEntry = function(usageReport, entry) {
			var httpPromise = $http.delete('/app/rest/commercialUsages/'+usageReport.commercialUsageId+'/entries/'+entry.commercialUsageEntryId);
			httpPromise.then(function() {
				$rootScope.$broadcast(Events.commercialUsageUpdated);
			});
			return httpPromise;
		};
		fakeService.deleteUsageEntry = function(usageReport, entry) {
			//FIXME FAKE
			fakeReports.forEach(function(usageReport) {
				for (var i = 0; i < usageReport.entries.length; i++) {
				    if (usageReport.entries[i].commercialUsageEntryId === entry.commercialUsageEntryId) {
				    	usageReport.entries.splice(i--, 1);
				    }
				}
			});
			$rootScope.$broadcast(Events.commercialUsageUpdated);
			return $q.when(wrapData({}));
		};

		return service;
	}]);<commit_msg>Remove fake commercial usage data and api<commit_after>'use strict';

angular.module('MLDS')
.factory('CommercialUsageService', ['$http', '$rootScope', '$log', '$q', 'Events', '$filter',
                                    function($http, $rootScope, $log, $q, Events, $filter){
		function serializeDate(date) {
			if (date) {
				return $filter('date')(date, 'yyyy-MM-dd');
			} else {
				return null;
			}
		}

		function serializeCommercialEntry(entry) {
			return {
				commercialUsageEntryId: entry.commercialUsageEntryId,
				name: entry.name,
				startDate: serializeDate(entry.startDate),
				endDate: serializeDate(entry.endDate),
				country: entry.country,
				created: entry.created
			}
		}

		var service = {};

		service.getUsageReports = function(licenseeId) {
			return $http.get('/app/rest/licensees/'+8/*licenseeId*/+'/commercialUsages');
		};

		service.createUsageReport = function(licenseeId, startDate, endDate) {
			return $http.post('/app/rest/licensees/'+8/*licenseeId*/+'/commercialUsages',
					{
						startDate: serializeDate(startDate),
						endDate: serializeDate(endDate)
					});
		};

		service.getUsageReport = function(reportId) {
			return $http.get('/app/rest/commercialUsages/'+reportId);
		};

		service.addUsageEntry = function(usageReport, entry) {
			var httpPromise = $http.post('/app/rest/commercialUsages/'+usageReport.commercialUsageId,
					serializeCommercialEntry(entry));
			httpPromise.then(function() {
				$rootScope.$broadcast(Events.commercialUsageUpdated);
			});
			return httpPromise;
		};

		service.updateUsageEntry = function(usageReport, entry) {
			var httpPromise = $http.put('/app/rest/commercialUsages/'+usageReport.commercialUsageId+'/entries/'+entry.commercialUsageEntryId,
					serializeCommercialEntry(entry)
				);
			httpPromise.then(function() {
				$rootScope.$broadcast(Events.commercialUsageUpdated);
			});
			return httpPromise;
		};

		service.deleteUsageEntry = function(usageReport, entry) {
			var httpPromise = $http.delete('/app/rest/commercialUsages/'+usageReport.commercialUsageId+'/entries/'+entry.commercialUsageEntryId);
			httpPromise.then(function() {
				$rootScope.$broadcast(Events.commercialUsageUpdated);
			});
			return httpPromise;
		};

		return service;
	}]);<|endoftext|>


<commit_before>var RENDERERS = {
	// Inputs: pid
	add_player: (state, data) => {
		console.log('Players in the game: ', state.players.join(', '));
	},
	// Inputs: void
	start_mission: (state, data) => {
		console.log('Start mission!');
		var adjacentPidx = (state.players.indexOf(PLAYER_ID) + 1) % state.players.length;
		var possibleItfs = state.panels[adjacentPidx];
		var itf = randomItem(Object.keys(possibleItfs));
		dispatch({
			action: 'start_task',
			pid: adjacentPidx,
			itf: itf
		});
	},
	// Inputs: pid, itf
	start_task: (state, data) => {
		var pidx = getPlayerIndex(data.pid);
		var tid = lastItem(state.panels[pidx][data.itf].tasks);
		if(data.pid === PLAYER_ID){
			console.log('Activated interface: ', data.itf, ' with task: ', tid);
			/*dispatch({
				action: 'start_instructions',
				pid: sender,
				tid: tid
			});*/
		}
	},
	// Inputs: pid, tid
	start_instruction: (state, data) => {
		if(data.pid === PLAYER_ID){
			console.log('Displayed instructions for task: ', data.tid, 'Score: ', state.score.completed.length + '-' + state.score.failed.length);
		}
	},
	// Inputs: itf, tid
	complete_task: (state, data) => {
		console.log('Completed task: ', data.tid);
		//if(data.sender === )
		// TODO: Tell sender that they can load a new instruction
	},
	// Inputs: tid
	fail_task: (state, data) => {
		console.log('Failed task: ', data.tid, 'Score: ', state.score.completed.length + '-' + state.score.failed.length);
	},
	// Inputs: void
	finish_mission: (state, data) => {
		console.log('Mission finished.');
	}
}<commit_msg>Check score to dispatch mission finish when tasks are completed or failed<commit_after>var RENDERERS = {
	// Inputs: pid
	add_player: (state, data) => {
		console.log('Players in the game: ', state.players.join(', '));
	},
	// Inputs: void
	start_mission: (state, data) => {
		console.log('Start mission!');
		var adjacentPidx = (state.players.indexOf(PLAYER_ID) + 1) % state.players.length;
		var possibleItfs = state.panels[adjacentPidx];
		var itf = randomItem(Object.keys(possibleItfs));
		dispatch({
			action: 'start_task',
			pid: adjacentPidx,
			itf: itf
		});
	},
	// Inputs: pid, itf
	start_task: (state, data) => {
		var pidx = getPlayerIndex(data.pid);
		var tid = lastItem(state.panels[pidx][data.itf].tasks);
		if(data.pid === PLAYER_ID){
			console.log('Activated interface: ', data.itf, ' with task: ', tid);
			/*dispatch({
				action: 'start_instructions',
				pid: sender,
				tid: tid
			});*/
		}
	},
	// Inputs: pid, tid
	start_instruction: (state, data) => {
		if(data.pid === PLAYER_ID){
			console.log('Displayed instructions for task: ', data.tid);
		}
	},
	// Inputs: itf, tid
	complete_task: (state, data) => {
		console.log('Completed task: ', data.tid, 'Score: ', state.score.completed.length + '-' + state.score.failed.length);
		if(state.score.completed > GLOBAL.WIN){
			if(data.sender === PLAYER_ID){
				dispatch({
					action: 'finish_mission'
				});
			}
		}
		//if(data.sender === )
		// TODO: Tell sender that they can load a new instruction
	},
	// Inputs: tid
	fail_task: (state, data) => {
		console.log('Failed task: ', data.tid, 'Score: ', state.score.completed.length + '-' + state.score.failed.length);
		if(state.score.failed > GLOBAL.LOSE){
			if(data.sender === PLAYER_ID){
				dispatch({
					action: 'finish_mission'
				});
			}
		}
	},
	// Inputs: void
	finish_mission: (state, data) => {
		var result = (state.score.completed > GLOBAL.WIN) ? 'Success!' : 'Failure';
		console.log('Mission finished, result: ', result, state.score.completed.length + '-' + state.score.failed.length);
	}
}<|endoftext|>