<commit_before>define(["js/html/HtmlElement", "underscore"], function (HtmlElement, _) {
    var radioNameCache = {},
        undefined;

    return HtmlElement.inherit("js.html.Input", {

        $classAttributes: ['updateOnEvent', 'checked'],

        defaults: {
            /***
             * the type of the input element
             * @type String
             */
            type: 'text',

            /***
             * the checked state for radio buttons and checkboxes
             * @type Boolean
             */
            checked: false,

            /***
             * the event on which the bound value will be updated
             * @string String
             */
            updateOnEvent: 'input'
        },

        _commitChangedAttributes: function (attributes) {
            if (this.$.type === 'radio') {

                if (attributes.name) {

                    if (this.$previousAttributes.name && radioNameCache[this.$previousAttributes.name]) {
                        delete radioNameCache[this.$previousAttributes.name][this.$cid];
                    }

                    radioNameCache[attributes.name] = radioNameCache[attributes.name] || {};
                    radioNameCache[attributes.name][this.$cid] = this;
                }

            }
            this.callBase();
        },

        _renderEnabled: function (enabled) {
            if (enabled) {
                this.$el.removeAttribute("disabled");
            } else {
                this.$el.setAttribute("disabled", "disabled");
            }
        },

        _supportsPlaceholder: function () {
            return "placeHolder" in this.$el || "placeholder" in this.$el;
        },

        _renderValue: function (value) {
            if (value === null || value === undefined) {
                value = "";
            }

            if (value == "" && !this._supportsPlaceholder() && this.$.placeholder && !this.$.focused) {
                value = this.$.placeholder;

            }

            if (String(value) !== this.$el.value) {
                if (this.$.type === "date") {
                    if (value instanceof Date) {
                        value = value.toLocaleString();
                    }
                }

                this.$el.value = value;
            }
        },

        _commitChecked: function (checked) {
            // sync shadow dom
            if (checked && this.$.type === "radio") {
                var cache = radioNameCache[this.$.name];
                for (var id in cache) {
                    if (cache.hasOwnProperty(id)) {
                        if (cache[id] !== this) {
                            cache[id].set('checked', false);
                        }
                    }
                }
            }
        },

        _renderChecked: function (checked) {
            this.$el.checked = checked ? "checked" : false;
        },

        _transformValue: function (value) {
            if (this.$.type === "number") {
                if (value === "") {
                    return null;
                }
                value = parseInt(value, 10);
                if (isNaN(value)) {
                    value = this.$.value;
                }
            } else if (this.$.type === "date") {
                try {
                    value = value !== "" ? new Date(value) : null;
                } catch (e) {
                    this.log("Invalid Date", "warn");
                    value = this.$.value;
                }
            }

            return value;
        },

        _bindDomEvents: function () {

            var self = this;
            if (_.include(["text", "password", "date", "number"], this.$.type)) {
                if (this.$.type === "date" || this.$.type === "number") {
                    this.$.updateOnEvent = "change";
                }
                // fix for IE
                if (this.$.updateOnEvent === "input" && "onpropertychange" in this.$el) {
                    this.bindDomEvent("keyup", function (e) {
                        self.set('value', self._transformValue(self.$el.value));
                    });
                } else {
                    this.bindDomEvent(this.$.updateOnEvent, function (e) {
                        self.set('value', self._transformValue(self.$el.value));
                    });
                }

            } else if (this.$.type === "checkbox" || this.$.type === "radio") {
                this.bindDomEvent('click', function (e) {
                    self.set('checked', self.$el.checked);
                });
            }

            this.callBase();
        },
        _renderPlaceholder: function (placeholder) {
            // shim for placeholder
            if (!this._supportsPlaceholder()) {
                var self = this;
                if (!this.__blurHandler) {
                    this.__blurHandler = function (e) {
                        self.set('focused', false);
                        if (self.$el.value != "") {
                            return;
                        }
                        self.$el.value = self.$.placeholder || "";
                        self.addClass('placeholder');
                    };
                    this.bindDomEvent('blur', this.__blurHandler);
                }
                if (!this.__focusHandler) {
                    this.__focusHandler = function () {
                        self.set('focused', true);
                        self.removeClass('placeholder');
                        if (!self.$.value) {
                            self.$el.value = '';
                        }

                    };
                    this.bindDomEvent("focus", this.__focusHandler);
                }
                if (placeholder) {
                    this.addClass('placeholder');
                }
            } else {
                this._setAttribute("placeHolder", placeholder);
            }
        }
    });
});<commit_msg>fixed date issue<commit_after>define(["js/html/HtmlElement", "underscore"], function (HtmlElement, _) {
    var radioNameCache = {},
        undefined;

    return HtmlElement.inherit("js.html.Input", {

        $classAttributes: ['updateOnEvent', 'checked'],

        defaults: {
            /***
             * the type of the input element
             * @type String
             */
            type: 'text',

            /***
             * the checked state for radio buttons and checkboxes
             * @type Boolean
             */
            checked: false,

            /***
             * the event on which the bound value will be updated
             * @string String
             */
            updateOnEvent: 'input'
        },

        _commitChangedAttributes: function (attributes) {
            if (this.$.type === 'radio') {

                if (attributes.name) {

                    if (this.$previousAttributes.name && radioNameCache[this.$previousAttributes.name]) {
                        delete radioNameCache[this.$previousAttributes.name][this.$cid];
                    }

                    radioNameCache[attributes.name] = radioNameCache[attributes.name] || {};
                    radioNameCache[attributes.name][this.$cid] = this;
                }

            }
            this.callBase();
        },

        _renderEnabled: function (enabled) {
            if (enabled) {
                this.$el.removeAttribute("disabled");
            } else {
                this.$el.setAttribute("disabled", "disabled");
            }
        },

        _supportsPlaceholder: function () {
            return "placeHolder" in this.$el || "placeholder" in this.$el;
        },

        _renderValue: function (value) {
            if (value === null || value === undefined) {
                value = "";
            }

            if (value == "" && !this._supportsPlaceholder() && this.$.placeholder && !this.$.focused) {
                value = this.$.placeholder;

            }

            if (String(value) !== this.$el.value) {
                if (this.$.type === "date") {
                    if (value instanceof Date) {
                        var m = value.getMonth() + 1;
                        m = m < 10 ? "0" + m : m;
                        var d = value.getDate();
                        d = d < 10 ? "0" + d : d;
                        value = [value.getFullYear(), m, d].join("-");
                    }
                }
                this.$el.value = value;
            }
        },

        _commitChecked: function (checked) {
            // sync shadow dom
            if (checked && this.$.type === "radio") {
                var cache = radioNameCache[this.$.name];
                for (var id in cache) {
                    if (cache.hasOwnProperty(id)) {
                        if (cache[id] !== this) {
                            cache[id].set('checked', false);
                        }
                    }
                }
            }
        },

        _renderChecked: function (checked) {
            this.$el.checked = checked ? "checked" : false;
        },

        _transformValue: function (value) {
            if (this.$.type === "number") {
                if (value === "") {
                    return null;
                }
                value = parseInt(value, 10);
                if (isNaN(value)) {
                    value = this.$.value;
                }
            } else if (this.$.type === "date") {
                try {
                    value = value !== "" ? new Date(value) : null;
                } catch (e) {
                    this.log("Invalid Date", "warn");
                    value = this.$.value;
                }
            }

            return value;
        },

        _bindDomEvents: function () {

            var self = this;
            if (_.include(["text", "password", "date", "number"], this.$.type)) {
                if (this.$.type === "date" || this.$.type === "number") {
                    this.$.updateOnEvent = "change";
                }
                // fix for IE
                if (this.$.updateOnEvent === "input" && "onpropertychange" in this.$el) {
                    this.bindDomEvent("keyup", function (e) {
                        self.set('value', self._transformValue(self.$el.value));
                    });
                } else {
                    this.bindDomEvent(this.$.updateOnEvent, function (e) {
                        self.set('value', self._transformValue(self.$el.value));
                    });
                }

            } else if (this.$.type === "checkbox" || this.$.type === "radio") {
                this.bindDomEvent('click', function (e) {
                    self.set('checked', self.$el.checked);
                });
            }

            this.callBase();
        },
        _renderPlaceholder: function (placeholder) {
            // shim for placeholder
            if (!this._supportsPlaceholder()) {
                var self = this;
                if (!this.__blurHandler) {
                    this.__blurHandler = function (e) {
                        self.set('focused', false);
                        if (self.$el.value != "") {
                            return;
                        }
                        self.$el.value = self.$.placeholder || "";
                        self.addClass('placeholder');
                    };
                    this.bindDomEvent('blur', this.__blurHandler);
                }
                if (!this.__focusHandler) {
                    this.__focusHandler = function () {
                        self.set('focused', true);
                        self.removeClass('placeholder');
                        if (!self.$.value) {
                            self.$el.value = '';
                        }

                    };
                    this.bindDomEvent("focus", this.__focusHandler);
                }
                if (placeholder) {
                    this.addClass('placeholder');
                }
            } else {
                this._setAttribute("placeHolder", placeholder);
            }
        }
    });
});<|endoftext|>


<commit_before>require("@babel/register")({ extensions: ['.js', '.jsx', '.ts', '.tsx'] });
require("jsdom-global")("", {
    url: "https://localhost:8081/index.html"
});
window.crypto = require("@trust/webcrypto");
window["msCrypto"] = require("@trust/webcrypto");
require("msal-common");
<commit_msg>removing mocha setup for mscrypto<commit_after>require("@babel/register")({ extensions: ['.js', '.jsx', '.ts', '.tsx'] });
require("jsdom-global")("", {
    url: "https://localhost:8081/index.html"
});
window.crypto = require("@trust/webcrypto");
require("msal-common");
<|endoftext|>


<commit_before>import prepareForProcess from '../query/lib/prepareForProcess.js';
import Base from './namedQuery.base';
import deepClone from 'lodash.clonedeep';
import MemoryResultCacher from './cache/MemoryResultCacher';
import intersectDeep from '../query/lib/intersectDeep';

export default class extends Base {
    /**
     * Retrieves the data.
     * @returns {*}
     */
    fetch(context) {
        this._performSecurityChecks(context, this.params);

        if (this.isResolver) {
            return this._fetchResolverData(context);
        } else {
            body = deepClone(this.body);
            if (this.params.$body) {
                body = intersectDeep(body, this.params.$body);
            }

            // we must apply emobdyment here
            this.doEmbodimentIfItApplies(body);

            const query = this.collection.createQuery(
                deepClone(body),
                {
                    params: deepClone(this.params)
                }
            );

            if (this.cacher) {
                const cacheId = this.cacher.generateQueryId(this.queryName, this.params);
                return this.cacher.fetch(cacheId, {query});
            }

            return query.fetch();
        }
    }

    /**
     * @param args
     * @returns {*}
     */
    fetchOne(...args) {
        return _.first(this.fetch(...args));
    }

    /**
     * Gets the count of matching elements.
     *
     * @returns {any}
     */
    getCount(context) {
        this._performSecurityChecks(context, this.params);

        const countCursor = this.getCursorForCounting();

        if (this.cacher) {
            const cacheId = 'count::' + this.cacher.generateQueryId(this.queryName, this.params);

            return this.cacher.fetch(cacheId, {countCursor});
        }

        return countCursor.count();
    }

    /**
     * Returns the cursor for counting
     * This is most likely used for counts cursor
     */
    getCursorForCounting() {
        let body = deepClone(this.body);
        this.doEmbodimentIfItApplies(body);
        body = prepareForProcess(body, this.params);

        return this.collection.find(body.$filters || {}, {fields: {_id: 1}});
    }

    /**
     * @param cacher
     */
    cacheResults(cacher) {
        if (!cacher) {
            cacher = new MemoryResultCacher();
        }

        this.cacher = cacher;
    }

    /**
     * Configure resolve. This doesn't actually call the resolver, it just sets it
     * @param fn
     */
    resolve(fn) {
        if (!this.isResolver) {
            throw new Meteor.Error('invalid-call', `You cannot use resolve() on a non resolver NamedQuery`);
        }

        this.resolver = fn;
    }

    /**
     * @returns {*}
     * @private
     */
    _fetchResolverData(context) {
        const resolver = this.resolver;
        const self = this;
        const query = {
            fetch() {
                return resolver.call(context, self.params);
            }
        };

        if (this.cacher) {
            const cacheId = this.cacher.generateQueryId(this.queryName, this.params);
            return this.cacher.fetch(cacheId, {query});
        }

        return query.fetch();
    }

    /**
     * @param context Meteor method/publish context
     * @param params
     *
     * @private
     */
    _performSecurityChecks(context, params) {
        if (context && this.exposeConfig) {
            this._callFirewall(context, context.userId, params);
        }

        this.doValidateParams(params);
    }
}<commit_msg>Update doEmbodimentIfItApplies usage<commit_after>import prepareForProcess from '../query/lib/prepareForProcess.js';
import Base from './namedQuery.base';
import deepClone from 'lodash.clonedeep';
import MemoryResultCacher from './cache/MemoryResultCacher';
import intersectDeep from '../query/lib/intersectDeep';

export default class extends Base {
    /**
     * Retrieves the data.
     * @returns {*}
     */
    fetch(context) {
        this._performSecurityChecks(context, this.params);

        if (this.isResolver) {
            return this._fetchResolverData(context);
        } else {
            body = deepClone(this.body);
            if (this.params.$body) {
                body = intersectDeep(body, this.params.$body);
            }

            // we must apply emobdyment here
            this.doEmbodimentIfItApplies(body, this.params);

            const query = this.collection.createQuery(
                deepClone(body),
                {
                    params: deepClone(this.params)
                }
            );

            if (this.cacher) {
                const cacheId = this.cacher.generateQueryId(this.queryName, this.params);
                return this.cacher.fetch(cacheId, {query});
            }

            return query.fetch();
        }
    }

    /**
     * @param args
     * @returns {*}
     */
    fetchOne(...args) {
        return _.first(this.fetch(...args));
    }

    /**
     * Gets the count of matching elements.
     *
     * @returns {any}
     */
    getCount(context) {
        this._performSecurityChecks(context, this.params);

        const countCursor = this.getCursorForCounting();

        if (this.cacher) {
            const cacheId = 'count::' + this.cacher.generateQueryId(this.queryName, this.params);

            return this.cacher.fetch(cacheId, {countCursor});
        }

        return countCursor.count();
    }

    /**
     * Returns the cursor for counting
     * This is most likely used for counts cursor
     */
    getCursorForCounting() {
        let body = deepClone(this.body);
        this.doEmbodimentIfItApplies(body, this.params);
        body = prepareForProcess(body, this.params);

        return this.collection.find(body.$filters || {}, {fields: {_id: 1}});
    }

    /**
     * @param cacher
     */
    cacheResults(cacher) {
        if (!cacher) {
            cacher = new MemoryResultCacher();
        }

        this.cacher = cacher;
    }

    /**
     * Configure resolve. This doesn't actually call the resolver, it just sets it
     * @param fn
     */
    resolve(fn) {
        if (!this.isResolver) {
            throw new Meteor.Error('invalid-call', `You cannot use resolve() on a non resolver NamedQuery`);
        }

        this.resolver = fn;
    }

    /**
     * @returns {*}
     * @private
     */
    _fetchResolverData(context) {
        const resolver = this.resolver;
        const self = this;
        const query = {
            fetch() {
                return resolver.call(context, self.params);
            }
        };

        if (this.cacher) {
            const cacheId = this.cacher.generateQueryId(this.queryName, this.params);
            return this.cacher.fetch(cacheId, {query});
        }

        return query.fetch();
    }

    /**
     * @param context Meteor method/publish context
     * @param params
     *
     * @private
     */
    _performSecurityChecks(context, params) {
        if (context && this.exposeConfig) {
            this._callFirewall(context, context.userId, params);
        }

        this.doValidateParams(params);
    }
}
<|endoftext|>


<commit_before>'use strict';

function draw(){
    buffer.clearRect(
      0,
      0,
      width,
      height
    );

    buffer.save();
    buffer.translate(
      x,
      y
    );

    // Draw corridor over grey background.
    buffer.fillStyle = '#000';
    buffer.fillRect(
      -x,
      -half_corridor_height,
      width,
      settings['corridor-height']
    );

    // Draw player body.
    buffer.fillStyle = settings['color'];
    buffer.fillRect(
      0,
      -player['y'] - 25,
      25,
      50
    );

    // Draw jetpack.
    buffer.fillStyle = '#aaa';
    buffer.fillRect(
      -25,
      -player['y'] - 15,
      25,
      20
    );

    // Draw activated jetpack fire.
    if(game_running
      && key_jetpack){
        buffer.fillStyle = '#f00';
        buffer.fillRect(
          -22,
          -player['y'] + 5,
          18,
          10
        );
    }

    buffer.font = '18pt sans-serif';
    // Draw obstacles.
    for(var obstacle in obstacles){
        buffer.fillStyle = '#555';
        buffer.fillRect(
          obstacles[obstacle]['x'],
          obstacles[obstacle]['y'],
          obstacles[obstacle]['width'] * 2,
          obstacles[obstacle]['height'] * 2
        );
        buffer.fillStyle = '#fff';
        buffer.fillText(
          obstacles[obstacle]['counter'],
          obstacles[obstacle]['x'],
          obstacles[obstacle]['y']
        );
    }

    // Draw smoke trails behind the player.
    buffer.fillStyle = '#777';
    for(var id in smoke){
        buffer.fillRect(
          smoke[id]['x'],
          -smoke[id]['y'],
          10,
          10
        );
    }

    buffer.restore();

    // Setup text display.
    buffer.fillStyle = '#fff';
    buffer.font = '23pt sans-serif';

    // If game is over, display game over messages.
    if(!game_running){
        if(!played_explosion_sound){
            if(settings['audio-volume'] > 0){
                // play_audio('explosion');
            }
            played_explosion_sound = true;
        }

        if(frame_counter > best){
            buffer.fillText(
              'NEW BEST SCORE!',
              5,
              height - 100
            );
        }
        buffer.fillText(
          'You crashed... ☹',
          5,
          height - 70
        );
        buffer.fillText(
          settings['restart-key'] + ' = Restart',
          5,
          height - 40
        );
        buffer.fillText(
          'ESC = Main Menu',
          5,
          height - 10
        );
    }

    // Top frame counter and best text displays.
    buffer.fillText(
      frame_counter,
      5,
      25
    );
    buffer.fillText(
      best,
      5,
      50
    );

    canvas.clearRect(
      0,
      0,
      width,
      height
    );
    canvas.drawImage(
      document.getElementById('buffer'),
      0,
      0
    );

    animationFrame = window.requestAnimationFrame(draw);
}

function logic(){
    if(!game_running){
        return;
    }

    // Check if player is outside of game boundaries.
    if(player['y'] + 25 > half_corridor_height
      || player['y'] - 25 < -half_corridor_height){
        game_running = false;
        update_best();
        return;
    }

    frame_counter += 1;

    // If new obstacle should be added this frame, add one.
    if(frame_counter % frames_per_obstacle === 0){
        var obstacle_width = Math.floor(Math.random() * 15) + 20;
        obstacles.push({
          'counter': obstacle_counter,
          'height': Math.floor(Math.random() * 15) + 20,
          'width': obstacle_width,
          'x': x + obstacle_width,
          'y': Math.floor(Math.random() * settings['corridor-height'])
            - half_corridor_height,
        });
        obstacle_counter += 1;
    }

    // If obstacle frequency increase should happen this frame, do it.
    if(settings['obstacle-frequency'] > 0
      && frames_per_obstacle > 1
      && frame_counter % settings['obstacle-increase'] === 0){
        // obstacle frequency increase
        frames_per_obstacle -= 1;
    }

    // If the player has activated jetpack, increase y speed and add smoke...
    if(key_jetpack){
        player['speed'] += settings['jetpack-power'];
        smoke.push({
          'x': -20,
          'y': player['y'] - 10,
        });

    // ...else apply gravity.
    }else{
        player['speed'] -= settings['gravity'];
    }

    player['y'] += player['speed'];

    for(var obstacle in obstacles){
        // Delete obstacles that are past left side of screen.
        if(obstacles[obstacle]['x'] < -x - 70){
            obstacles.splice(
              obstacle,
              1
            );
            continue;
        }

        // Move obstacles left at speed.
        obstacles[obstacle]['x'] -= settings['speed'];

        // Check for player collision with obstacle.
        if(obstacles[obstacle]['x'] <= -obstacles[obstacle]['width'] * 2
          || obstacles[obstacle]['x'] >= obstacles[obstacle]['width']
          || obstacles[obstacle]['y'] <= -player['y'] - 25 - obstacles[obstacle]['height'] * 2
          || obstacles[obstacle]['y'] >= -player['y'] + 25){
            continue;
        }

        game_running = false;
        update_best();
    }

    // Delete smoke trails past left side of screen.
    for(var id in smoke){
        smoke[id]['x'] -= settings['speed'];

        if(smoke[id]['x'] < -x){
            smoke.splice(
              id,
              1
            );
        }
    }
}

function play_audio(id){
    if(settings['audio-volume'] <= 0){
        return;
    }

    document.getElementById(id).currentTime = 0;
    document.getElementById(id).play();
}

function reset(){
    if(!window.confirm('Reset settings?')){
        return;
    }

    var ids = {
      'audio-volume': 1,
      'color': '#009900',
      'corridor-height': 500,
      'gravity': 1,
      'jetpack-key': 'W',
      'jetpack-power': 2,
      'ms-per-frame': 30,
      'obstacle-frequency': 23,
      'obstacle-increase': 115,
      'restart-key': 'H',
      'speed': 10,
    };
    for(var id in ids){
        document.getElementById(id).value = ids[id];
    }

    save();
}

function reset_best(){
    if(!window.confirm('Reset best?')){
        return;
    }

    best = 0;
    frame_counter = 0;
    update_best();
    setmode(
      0,
      true
    );
}

function resize(){
    if(mode <= 0){
        return;
    }

    height = window.innerHeight;
    document.getElementById('buffer').height = height;
    document.getElementById('canvas').height = height;
    y = height / 2;

    width = window.innerWidth;
    document.getElementById('buffer').width = width;
    document.getElementById('canvas').width = width;
    x = width / 2;
}

// Save settings into window.localStorage if they differ from default.
function save(){
    settings['audio-volume'] = parseFloat(document.getElementById('audio-volume').value);
    if(settings['audio-volume'] === 1){
        window.localStorage.removeItem('Jetpack-2D.htm-audio-volume');

    }else{
        window.localStorage.setItem(
          'Jetpack-2D.htm-audio-volume',
          settings['audio-volume']
        );
    }

    var ids = {
      'color': '#009900',
      'jetpack-key': 'W',
      'restart-key': 'H',
    };
    for(var id in ids){
        settings[id] = document.getElementById(id).value;

        if(settings[id] === ids[id]){
            window.localStorage.removeItem('Jetpack-2D.htm-' + id);

        }else{
            window.localStorage.setItem(
              'Jetpack-2D.htm-' + id,
              settings[id]
            );
        }
    }

    ids = {
      'corridor-height': 500,
      'gravity': 1,
      'jetpack-power': 2,
      'ms-per-frame': 30,
      'obstacle-frequency': 23,
      'obstacle-increase': 115,
      'speed': 10,
    };
    for(id in ids){
        settings[id] = parseInt(document.getElementById(id).value);

        if(settings[id] == ids[id]
          || isNaN(settings[id])){
            window.localStorage.removeItem('Jetpack-2D.htm-' + id);

        }else{
            window.localStorage.setItem(
              'Jetpack-2D.htm-' + id,
              settings[id]
            );
        }
    }
}

function setmode(newmode, newgame){
    window.cancelAnimationFrame(animationFrame);
    window.clearInterval(interval);

    mode = newmode;
    obstacle_counter = 0;
    obstacles = [];
    smoke = [];

    // Play game mode.
    if(mode > 0){
        if(newgame){
            save();
        }

        frame_counter = 0;
        frames_per_obstacle = settings['obstacle-frequency'];
        game_running = true;
        half_corridor_height = settings['corridor-height'] / 2;
        played_explosion_sound = false;
        player = {
          'speed': 0,
          'y': 0,
        };

        if(newgame){
            document.body.innerHTML =
              '<canvas id=canvas></canvas><canvas id=buffer></canvas>';

            buffer = document.getElementById('buffer').getContext('2d');
            canvas = document.getElementById('canvas').getContext('2d');

            resize();
        }

        animationFrame = window.requestAnimationFrame(draw);
        interval = window.setInterval(
          'logic()',
          settings['ms-per-frame']
        );

        return;
    }

    // Main menu mode.
    buffer = 0;
    canvas = 0;

    document.body.innerHTML = '

Cave Corridor

Best: '
      + best
      + '
Reset Best

Jetpack:

<input disabled value=Click>Activate
<input id=jetpack-key maxlength=1 value='
      + settings['jetpack-key'] + '>Activate
<input disabled value=ESC>Main Menu
<input id=restart-key maxlength=1 value='
      + settings['restart-key'] + '>Restart

<input id=audio-volume max=1 min=0 step=0.01 type=range value='
      + settings['audio-volume'] + '>Audio
<input id=color type=color value='
      + settings['color'] + '>Color
<input id=corridor-height value='
      + settings['corridor-height'] + '>Corridor Height
<input id=gravity value='
      + settings['gravity'] + '>Gravity
Jetpack:

<input id=jetpack-power value='
      + settings['jetpack-power'] + '>Power
<input id=speed value='
      + settings['speed'] + '>Speed
<input id=ms-per-frame value='
      + settings['ms-per-frame'] + '>ms/Frame
Obstacle:

<input id=obstacle-frequency value='
      + settings['obstacle-frequency'] + '>Frequency
<input id=obstacle-increase value='
      + settings['obstacle-increase'] + '>Increase
Reset Settings

';
}

function update_best(){
    if(frame_counter > best){
        best = frame_counter;
    }

    if(best > 0){
        window.localStorage.setItem(
          'Jetpack-2D.htm-best',
          best
        );

    }else{
        window.localStorage.removeItem('Jetpack-2D.htm-best');
    }
}

var animationFrame = 0;
var best = parseInt(window.localStorage.getItem('Jetpack-2D.htm-best')) || 0;
var buffer = 0;
var canvas = 0;
var frame_counter = 0;
var frames_per_obstacle = 0;
var game_running = false;
var half_corridor_height = 0;
var height = 0;
var interval = 0;
var key_jetpack = false;
var mode = 0;
var obstacle_counter = 0;
var obstacles = [];
var played_explosion_sound = false;
var player = {};
var settings = {
  'audio-volume': window.localStorage.getItem('Jetpack-2D.htm-audio-volume') !== null
    ? parseFloat(window.localStorage.getItem('Jetpack-2D.htm-audio-volume'))
    : 1,
  'color': window.localStorage.getItem('Jetpack-2D.htm-color') || '#009900',
  'corridor-height': window.localStorage.getItem('Jetpack-2D.htm-corridor-height') || 500,
  'gravity': window.localStorage.getItem('Jetpack-2D.htm-gravity') !== null
    ? parseFloat(window.localStorage.getItem('Jetpack-2D.htm-gravity'))
    : 1,
  'jetpack-key': window.localStorage.getItem('Jetpack-2D.htm-jetpack-key') || 'W',
  'jetpack-power': window.localStorage.getItem('Jetpack-2D.htm-jetpack-power') !== null
    ? parseFloat(window.localStorage.getItem('Jetpack-2D.htm-jetpack-power'))
    : 2,
  'ms-per-frame': parseInt(window.localStorage.getItem('Jetpack-2D.htm-ms-per-frame')) || 30,
  'obstacle-frequency': parseInt(window.localStorage.getItem('Jetpack-2D.htm-obstacle-frequency')) || 23,
  'obstacle-increase': parseInt(window.localStorage.getItem('Jetpack-2D.htm-obstacle-increase')) || 115,
  'restart-key': window.localStorage.getItem('Jetpack-2D.htm-restart-key') || 'H',
  'speed': parseFloat(window.localStorage.getItem('Jetpack-2D.htm-speed')) || 10,
};
var smoke = [];
var width = 0;
var x = 0;
var y = 0;

window.onkeydown = function(e){
    if(mode <= 0){
        return;
    }

    var key = e.keyCode || e.which;

    // ESC: update best and return to main menu.
    if(key === 27){
        update_best();
        setmode(
          0,
          true
        );
        return;
    }

    key = String.fromCharCode(key);

    if(key === settings['jetpack-key']){
        key_jetpack = true;

    }else if(key === settings['restart-key']){
        update_best();
        setmode(
          1,
          false
        );
    }
};

window.onkeyup = function(e){
    var key = String.fromCharCode(e.keyCode || e.which);

    if(key === settings['jetpack-key']){
        key_jetpack = false;
    }
};

window.onload = function(e){
    setmode(
      0,
      true
    );
};

window.onmousedown
  = window.ontouchstart = function(e){
    if(mode <= 0){
        return;
    }

    e.preventDefault();
    key_jetpack = true;
};

window.onmouseup
  = window.ontouchend = function(e){
    key_jetpack = false;
};

window.onresize = resize;
<commit_msg>fixed window.setInterval() usage<commit_after>'use strict';

function draw(){
    buffer.clearRect(
      0,
      0,
      width,
      height
    );

    buffer.save();
    buffer.translate(
      x,
      y
    );

    // Draw corridor over grey background.
    buffer.fillStyle = '#000';
    buffer.fillRect(
      -x,
      -half_corridor_height,
      width,
      settings['corridor-height']
    );

    // Draw player body.
    buffer.fillStyle = settings['color'];
    buffer.fillRect(
      0,
      -player['y'] - 25,
      25,
      50
    );

    // Draw jetpack.
    buffer.fillStyle = '#aaa';
    buffer.fillRect(
      -25,
      -player['y'] - 15,
      25,
      20
    );

    // Draw activated jetpack fire.
    if(game_running
      && key_jetpack){
        buffer.fillStyle = '#f00';
        buffer.fillRect(
          -22,
          -player['y'] + 5,
          18,
          10
        );
    }

    buffer.font = '18pt sans-serif';
    // Draw obstacles.
    for(var obstacle in obstacles){
        buffer.fillStyle = '#555';
        buffer.fillRect(
          obstacles[obstacle]['x'],
          obstacles[obstacle]['y'],
          obstacles[obstacle]['width'] * 2,
          obstacles[obstacle]['height'] * 2
        );
        buffer.fillStyle = '#fff';
        buffer.fillText(
          obstacles[obstacle]['counter'],
          obstacles[obstacle]['x'],
          obstacles[obstacle]['y']
        );
    }

    // Draw smoke trails behind the player.
    buffer.fillStyle = '#777';
    for(var id in smoke){
        buffer.fillRect(
          smoke[id]['x'],
          -smoke[id]['y'],
          10,
          10
        );
    }

    buffer.restore();

    // Setup text display.
    buffer.fillStyle = '#fff';
    buffer.font = '23pt sans-serif';

    // If game is over, display game over messages.
    if(!game_running){
        if(!played_explosion_sound){
            if(settings['audio-volume'] > 0){
                // play_audio('explosion');
            }
            played_explosion_sound = true;
        }

        if(frame_counter > best){
            buffer.fillText(
              'NEW BEST SCORE!',
              5,
              height - 100
            );
        }
        buffer.fillText(
          'You crashed... ☹',
          5,
          height - 70
        );
        buffer.fillText(
          settings['restart-key'] + ' = Restart',
          5,
          height - 40
        );
        buffer.fillText(
          'ESC = Main Menu',
          5,
          height - 10
        );
    }

    // Top frame counter and best text displays.
    buffer.fillText(
      frame_counter,
      5,
      25
    );
    buffer.fillText(
      best,
      5,
      50
    );

    canvas.clearRect(
      0,
      0,
      width,
      height
    );
    canvas.drawImage(
      document.getElementById('buffer'),
      0,
      0
    );

    animationFrame = window.requestAnimationFrame(draw);
}

function logic(){
    if(!game_running){
        return;
    }

    // Check if player is outside of game boundaries.
    if(player['y'] + 25 > half_corridor_height
      || player['y'] - 25 < -half_corridor_height){
        game_running = false;
        update_best();
        return;
    }

    frame_counter += 1;

    // If new obstacle should be added this frame, add one.
    if(frame_counter % frames_per_obstacle === 0){
        var obstacle_width = Math.floor(Math.random() * 15) + 20;
        obstacles.push({
          'counter': obstacle_counter,
          'height': Math.floor(Math.random() * 15) + 20,
          'width': obstacle_width,
          'x': x + obstacle_width,
          'y': Math.floor(Math.random() * settings['corridor-height'])
            - half_corridor_height,
        });
        obstacle_counter += 1;
    }

    // If obstacle frequency increase should happen this frame, do it.
    if(settings['obstacle-frequency'] > 0
      && frames_per_obstacle > 1
      && frame_counter % settings['obstacle-increase'] === 0){
        // obstacle frequency increase
        frames_per_obstacle -= 1;
    }

    // If the player has activated jetpack, increase y speed and add smoke...
    if(key_jetpack){
        player['speed'] += settings['jetpack-power'];
        smoke.push({
          'x': -20,
          'y': player['y'] - 10,
        });

    // ...else apply gravity.
    }else{
        player['speed'] -= settings['gravity'];
    }

    player['y'] += player['speed'];

    for(var obstacle in obstacles){
        // Delete obstacles that are past left side of screen.
        if(obstacles[obstacle]['x'] < -x - 70){
            obstacles.splice(
              obstacle,
              1
            );
            continue;
        }

        // Move obstacles left at speed.
        obstacles[obstacle]['x'] -= settings['speed'];

        // Check for player collision with obstacle.
        if(obstacles[obstacle]['x'] <= -obstacles[obstacle]['width'] * 2
          || obstacles[obstacle]['x'] >= obstacles[obstacle]['width']
          || obstacles[obstacle]['y'] <= -player['y'] - 25 - obstacles[obstacle]['height'] * 2
          || obstacles[obstacle]['y'] >= -player['y'] + 25){
            continue;
        }

        game_running = false;
        update_best();
    }

    // Delete smoke trails past left side of screen.
    for(var id in smoke){
        smoke[id]['x'] -= settings['speed'];

        if(smoke[id]['x'] < -x){
            smoke.splice(
              id,
              1
            );
        }
    }
}

function play_audio(id){
    if(settings['audio-volume'] <= 0){
        return;
    }

    document.getElementById(id).currentTime = 0;
    document.getElementById(id).play();
}

function reset(){
    if(!window.confirm('Reset settings?')){
        return;
    }

    var ids = {
      'audio-volume': 1,
      'color': '#009900',
      'corridor-height': 500,
      'gravity': 1,
      'jetpack-key': 'W',
      'jetpack-power': 2,
      'ms-per-frame': 30,
      'obstacle-frequency': 23,
      'obstacle-increase': 115,
      'restart-key': 'H',
      'speed': 10,
    };
    for(var id in ids){
        document.getElementById(id).value = ids[id];
    }

    save();
}

function reset_best(){
    if(!window.confirm('Reset best?')){
        return;
    }

    best = 0;
    frame_counter = 0;
    update_best();
    setmode(
      0,
      true
    );
}

function resize(){
    if(mode <= 0){
        return;
    }

    height = window.innerHeight;
    document.getElementById('buffer').height = height;
    document.getElementById('canvas').height = height;
    y = height / 2;

    width = window.innerWidth;
    document.getElementById('buffer').width = width;
    document.getElementById('canvas').width = width;
    x = width / 2;
}

// Save settings into window.localStorage if they differ from default.
function save(){
    settings['audio-volume'] = parseFloat(document.getElementById('audio-volume').value);
    if(settings['audio-volume'] === 1){
        window.localStorage.removeItem('Jetpack-2D.htm-audio-volume');

    }else{
        window.localStorage.setItem(
          'Jetpack-2D.htm-audio-volume',
          settings['audio-volume']
        );
    }

    var ids = {
      'color': '#009900',
      'jetpack-key': 'W',
      'restart-key': 'H',
    };
    for(var id in ids){
        settings[id] = document.getElementById(id).value;

        if(settings[id] === ids[id]){
            window.localStorage.removeItem('Jetpack-2D.htm-' + id);

        }else{
            window.localStorage.setItem(
              'Jetpack-2D.htm-' + id,
              settings[id]
            );
        }
    }

    ids = {
      'corridor-height': 500,
      'gravity': 1,
      'jetpack-power': 2,
      'ms-per-frame': 30,
      'obstacle-frequency': 23,
      'obstacle-increase': 115,
      'speed': 10,
    };
    for(id in ids){
        settings[id] = parseInt(document.getElementById(id).value);

        if(settings[id] == ids[id]
          || isNaN(settings[id])){
            window.localStorage.removeItem('Jetpack-2D.htm-' + id);

        }else{
            window.localStorage.setItem(
              'Jetpack-2D.htm-' + id,
              settings[id]
            );
        }
    }
}

function setmode(newmode, newgame){
    window.cancelAnimationFrame(animationFrame);
    window.clearInterval(interval);

    mode = newmode;
    obstacle_counter = 0;
    obstacles = [];
    smoke = [];

    // Play game mode.
    if(mode > 0){
        if(newgame){
            save();
        }

        frame_counter = 0;
        frames_per_obstacle = settings['obstacle-frequency'];
        game_running = true;
        half_corridor_height = settings['corridor-height'] / 2;
        played_explosion_sound = false;
        player = {
          'speed': 0,
          'y': 0,
        };

        if(newgame){
            document.body.innerHTML =
              '<canvas id=canvas></canvas><canvas id=buffer></canvas>';

            buffer = document.getElementById('buffer').getContext('2d');
            canvas = document.getElementById('canvas').getContext('2d');

            resize();
        }

        animationFrame = window.requestAnimationFrame(draw);
        interval = window.setInterval(
          logic,
          settings['ms-per-frame']
        );

        return;
    }

    // Main menu mode.
    buffer = 0;
    canvas = 0;

    document.body.innerHTML = '

Cave Corridor

Best: '
      + best
      + '
Reset Best

Jetpack:

<input disabled value=Click>Activate
<input id=jetpack-key maxlength=1 value='
      + settings['jetpack-key'] + '>Activate
<input disabled value=ESC>Main Menu
<input id=restart-key maxlength=1 value='
      + settings['restart-key'] + '>Restart

<input id=audio-volume max=1 min=0 step=0.01 type=range value='
      + settings['audio-volume'] + '>Audio
<input id=color type=color value='
      + settings['color'] + '>Color
<input id=corridor-height value='
      + settings['corridor-height'] + '>Corridor Height
<input id=gravity value='
      + settings['gravity'] + '>Gravity
Jetpack:

<input id=jetpack-power value='
      + settings['jetpack-power'] + '>Power
<input id=speed value='
      + settings['speed'] + '>Speed
<input id=ms-per-frame value='
      + settings['ms-per-frame'] + '>ms/Frame
Obstacle:

<input id=obstacle-frequency value='
      + settings['obstacle-frequency'] + '>Frequency
<input id=obstacle-increase value='
      + settings['obstacle-increase'] + '>Increase
Reset Settings

';
}

function update_best(){
    if(frame_counter > best){
        best = frame_counter;
    }

    if(best > 0){
        window.localStorage.setItem(
          'Jetpack-2D.htm-best',
          best
        );

    }else{
        window.localStorage.removeItem('Jetpack-2D.htm-best');
    }
}

var animationFrame = 0;
var best = parseInt(window.localStorage.getItem('Jetpack-2D.htm-best')) || 0;
var buffer = 0;
var canvas = 0;
var frame_counter = 0;
var frames_per_obstacle = 0;
var game_running = false;
var half_corridor_height = 0;
var height = 0;
var interval = 0;
var key_jetpack = false;
var mode = 0;
var obstacle_counter = 0;
var obstacles = [];
var played_explosion_sound = false;
var player = {};
var settings = {
  'audio-volume': window.localStorage.getItem('Jetpack-2D.htm-audio-volume') !== null
    ? parseFloat(window.localStorage.getItem('Jetpack-2D.htm-audio-volume'))
    : 1,
  'color': window.localStorage.getItem('Jetpack-2D.htm-color') || '#009900',
  'corridor-height': window.localStorage.getItem('Jetpack-2D.htm-corridor-height') || 500,
  'gravity': window.localStorage.getItem('Jetpack-2D.htm-gravity') !== null
    ? parseFloat(window.localStorage.getItem('Jetpack-2D.htm-gravity'))
    : 1,
  'jetpack-key': window.localStorage.getItem('Jetpack-2D.htm-jetpack-key') || 'W',
  'jetpack-power': window.localStorage.getItem('Jetpack-2D.htm-jetpack-power') !== null
    ? parseFloat(window.localStorage.getItem('Jetpack-2D.htm-jetpack-power'))
    : 2,
  'ms-per-frame': parseInt(window.localStorage.getItem('Jetpack-2D.htm-ms-per-frame')) || 30,
  'obstacle-frequency': parseInt(window.localStorage.getItem('Jetpack-2D.htm-obstacle-frequency')) || 23,
  'obstacle-increase': parseInt(window.localStorage.getItem('Jetpack-2D.htm-obstacle-increase')) || 115,
  'restart-key': window.localStorage.getItem('Jetpack-2D.htm-restart-key') || 'H',
  'speed': parseFloat(window.localStorage.getItem('Jetpack-2D.htm-speed')) || 10,
};
var smoke = [];
var width = 0;
var x = 0;
var y = 0;

window.onkeydown = function(e){
    if(mode <= 0){
        return;
    }

    var key = e.keyCode || e.which;

    // ESC: update best and return to main menu.
    if(key === 27){
        update_best();
        setmode(
          0,
          true
        );
        return;
    }

    key = String.fromCharCode(key);

    if(key === settings['jetpack-key']){
        key_jetpack = true;

    }else if(key === settings['restart-key']){
        update_best();
        setmode(
          1,
          false
        );
    }
};

window.onkeyup = function(e){
    var key = String.fromCharCode(e.keyCode || e.which);

    if(key === settings['jetpack-key']){
        key_jetpack = false;
    }
};

window.onload = function(e){
    setmode(
      0,
      true
    );
};

window.onmousedown
  = window.ontouchstart = function(e){
    if(mode <= 0){
        return;
    }

    e.preventDefault();
    key_jetpack = true;
};

window.onmouseup
  = window.ontouchend = function(e){
    key_jetpack = false;
};

window.onresize = resize;
<|endoftext|>


<commit_before>/*
* Copyright 2014 Your name <your e-mail>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
*    list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

(function(Nuvola)
{
"use strict";

var ADDRESS = "app.address";
var ADDRESS_DEFAULT = "http://localhost:32400/web";

// Create media player component
var player = Nuvola.$object(Nuvola.MediaPlayer);

// Handy aliases
var PlaybackState = Nuvola.PlaybackState;
var PlayerAction = Nuvola.PlayerAction;

// Create new WebApp prototype
var WebApp = Nuvola.$WebApp();

WebApp._onInitAppRunner = function(emitter)
{
    Nuvola.WebApp._onInitAppRunner.call(this, emitter);
    Nuvola.config.setDefault(ADDRESS, ADDRESS_DEFAULT);
    Nuvola.core.connect("InitializationForm", this);
    Nuvola.core.connect("PreferencesForm", this);
};

WebApp._onPreferencesForm = function(emitter, values, entries)
{
    this.appendPreferences(values, entries);
};

WebApp._onInitializationForm = function(emitter, values, entries)
{
    if (!Nuvola.config.hasKey(ADDRESS))
        this.appendPreferences(values, entries);
};

WebApp._onHomePageRequest = function(emitter, result)
{
    result.url = Nuvola.config.get(ADDRESS);
};

WebApp.appendPreferences = function(values, entries)
{
    values[ADDRESS] = Nuvola.config.get(ADDRESS);
    entries.push(["header", "Plex"]);
    entries.push(["label", "Address of your Plex Server"]);
    entries.push(["string", ADDRESS, "Address"]);
};

// Initialization routines
WebApp._onInitWebWorker = function(emitter)
{
    Nuvola.WebApp._onInitWebWorker.call(this, emitter);

    var state = document.readyState;
    if (state === "interactive" || state === "complete")
        this._onPageReady();
    else
        document.addEventListener("DOMContentLoaded", this._onPageReady.bind(this));
};

// Page is ready for magic
WebApp._onPageReady = function()
{
    // Connect handler for signal ActionActivated
    Nuvola.actions.connect("ActionActivated", this);

    // Start update routine
    this.update();
};

WebApp._isAvailable = function (el)
{
    return el && el.className && !/(:?\s|^)(:?disabled|hidden)(:?\s|$)/.test(el.className);
};

WebApp._getAttribute = function (el, attribute)
{
    if (el && el.attributes && el.attributes[attribute])
        return  el.attributes[attribute].value;
    return null;
};

// Extract data from the web page
WebApp.update = function()
{
    var playerElement = document.querySelector(".player.music");
    var playElement, pauseElement, previousElement, nextElement;
    if (playerElement)
    {
        playElement = playerElement.querySelector(".play-btn");
        pauseElement = playerElement.querySelector(".pause-btn");
        previousElement = playerElement.querySelector(".previous-btn");
        nextElement = playerElement.querySelector(".next-btn");
    }
    // Playback state
    var state = PlaybackState.UNKNOWN;
    if (playerElement)
    {
        if (playElement && !this._isAvailable(playElement))
            state = PlaybackState.PLAYING;
        else if (pauseElement && !this._isAvailable(pauseElement))
            state = PlaybackState.PAUSED;
    }
    player.setPlaybackState(state);
    // Track informations
    var posterElement = playerElement ? playerElement.querySelector('.media-poster') : null;
    player.setTrack({
        title:       this._getAttribute(posterElement, 'data-title'),
        artist:      this._getAttribute(posterElement, 'data-grandparent-title'),
        album:       this._getAttribute(posterElement, 'data-parent-title'),
        artLocation: this._getAttribute(posterElement, 'data-image-url')
    });
    // Player actions
    player.setCanPlay(this._isAvailable(playElement));
    player.setCanPause(this._isAvailable(pauseElement));
    player.setCanGoPrev(this._isAvailable(previousElement));
    player.setCanGoNext(this._isAvailable(nextElement));
    // Schedule the next update
    setTimeout(this.update.bind(this), 500);
};

// Handler of playback actions
WebApp._onActionActivated = function(emitter, name, param)
{
    var playerElement = document.querySelector(".player.music");
    var playElement, pauseElement, previousElement, nextElement;
    if (playerElement)
    {
        playElement = playerElement.querySelector(".play-btn");
        pauseElement = playerElement.querySelector(".pause-btn");
        previousElement = playerElement.querySelector(".previous-btn");
        nextElement = playerElement.querySelector(".next-btn");
    }

    switch (name)
    {
        case PlayerAction.TOGGLE_PLAY:
            if (playerElement)
                if (this._isAvailable(playElement))
                    Nuvola.clickOnElement(playElement);
                else
                    Nuvola.clickOnElement(pauseElement);
            break;
        case PlayerAction.PLAY:
            Nuvola.clickOnElement(playElement);
            break;
        case PlayerAction.PAUSE:
            Nuvola.clickOnElement(pauseElement);
            break;
        case PlayerAction.STOP:
            Nuvola.clickOnElement(playerElement.querySelector(".stop-btn"));
            break;
        case PlayerAction.PREV_SONG:
            Nuvola.clickOnElement(previousElement);
            break;
        case PlayerAction.NEXT_SONG:
            Nuvola.clickOnElement(nextElement);
            break;
    }
};

WebApp.start();

})(this);  // function(Nuvola)
<commit_msg>when no music is selected shuffle all music on play<commit_after>/*
* Copyright 2014 Your name <your e-mail>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
*    list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

(function(Nuvola)
{
"use strict";

var ADDRESS = "app.address";
var ADDRESS_DEFAULT = "http://localhost:32400/web";

// Create media player component
var player = Nuvola.$object(Nuvola.MediaPlayer);

// Handy aliases
var PlaybackState = Nuvola.PlaybackState;
var PlayerAction = Nuvola.PlayerAction;

// Create new WebApp prototype
var WebApp = Nuvola.$WebApp();

WebApp._onInitAppRunner = function(emitter)
{
    Nuvola.WebApp._onInitAppRunner.call(this, emitter);
    Nuvola.config.setDefault(ADDRESS, ADDRESS_DEFAULT);
    Nuvola.core.connect("InitializationForm", this);
    Nuvola.core.connect("PreferencesForm", this);
};

WebApp._onPreferencesForm = function(emitter, values, entries)
{
    this.appendPreferences(values, entries);
};

WebApp._onInitializationForm = function(emitter, values, entries)
{
    if (!Nuvola.config.hasKey(ADDRESS))
        this.appendPreferences(values, entries);
};

WebApp._onHomePageRequest = function(emitter, result)
{
    result.url = Nuvola.config.get(ADDRESS);
};

WebApp.appendPreferences = function(values, entries)
{
    values[ADDRESS] = Nuvola.config.get(ADDRESS);
    entries.push(["header", "Plex"]);
    entries.push(["label", "Address of your Plex Server"]);
    entries.push(["string", ADDRESS, "Address"]);
};

// Initialization routines
WebApp._onInitWebWorker = function(emitter)
{
    Nuvola.WebApp._onInitWebWorker.call(this, emitter);

    var state = document.readyState;
    if (state === "interactive" || state === "complete")
        this._onPageReady();
    else
        document.addEventListener("DOMContentLoaded", this._onPageReady.bind(this));
};

// Page is ready for magic
WebApp._onPageReady = function()
{
    // Connect handler for signal ActionActivated
    Nuvola.actions.connect("ActionActivated", this);

    // Start update routine
    this.update();
};

WebApp._isAvailable = function (el)
{
    return el && el.className && !/(:?\s|^)(:?disabled|hidden)(:?\s|$)/.test(el.className);
};

WebApp._getAttribute = function (el, attribute)
{
    if (el && el.attributes && el.attributes[attribute])
        return  el.attributes[attribute].value;
    return null;
};

// Extract data from the web page
WebApp.update = function()
{
    var playerElement = document.querySelector(".player.music");
    var playElement, pauseElement, previousElement, nextElement, shuffleElement;
    if (playerElement)
    {
        playElement = playerElement.querySelector(".play-btn");
        pauseElement = playerElement.querySelector(".pause-btn");
        previousElement = playerElement.querySelector(".previous-btn");
        nextElement = playerElement.querySelector(".next-btn");
    } else {
        shuffleElement = document.querySelector(".action-bar .play-shuffled-btn");
    }
    // Playback state
    var state = PlaybackState.UNKNOWN;
    if (playerElement)
    {
        if (playElement && !this._isAvailable(playElement))
            state = PlaybackState.PLAYING;
        else if (pauseElement && !this._isAvailable(pauseElement))
            state = PlaybackState.PAUSED;
    }
    player.setPlaybackState(state);
    // Track informations
    var posterElement = playerElement ? playerElement.querySelector('.media-poster') : null;
    player.setTrack({
        title:       this._getAttribute(posterElement, 'data-title'),
        artist:      this._getAttribute(posterElement, 'data-grandparent-title'),
        album:       this._getAttribute(posterElement, 'data-parent-title'),
        artLocation: this._getAttribute(posterElement, 'data-image-url')
    });
    // Player actions
    player.setCanPlay(this._isAvailable(playElement) || this._isAvailable(shuffleElement));
    player.setCanPause(this._isAvailable(pauseElement));
    player.setCanGoPrev(this._isAvailable(previousElement));
    player.setCanGoNext(this._isAvailable(nextElement));
    // Schedule the next update
    setTimeout(this.update.bind(this), 500);
};

// Handler of playback actions
WebApp._onActionActivated = function(emitter, name, param)
{
    var playerElement = document.querySelector(".player.music");
    var playElement, pauseElement, previousElement, nextElement;
    if (playerElement)
    {
        playElement = playerElement.querySelector(".play-btn");
        pauseElement = playerElement.querySelector(".pause-btn");
        previousElement = playerElement.querySelector(".previous-btn");
        nextElement = playerElement.querySelector(".next-btn");
    }

    switch (name)
    {
        case PlayerAction.TOGGLE_PLAY:
            if (playerElement) {
                if (this._isAvailable(playElement))
                    Nuvola.clickOnElement(playElement);
                else
                    Nuvola.clickOnElement(pauseElement);
            } else {
                var shuffleElement = document.querySelector(".action-bar .play-shuffled-btn");
                if (shuffleElement) {
                    Nuvola.clickOnElement(shuffleElement);
                }
            }
            break;
        case PlayerAction.PLAY:
            Nuvola.clickOnElement(playElement);
            break;
        case PlayerAction.PAUSE:
            Nuvola.clickOnElement(pauseElement);
            break;
        case PlayerAction.STOP:
            Nuvola.clickOnElement(playerElement.querySelector(".stop-btn"));
            break;
        case PlayerAction.PREV_SONG:
            Nuvola.clickOnElement(previousElement);
            break;
        case PlayerAction.NEXT_SONG:
            Nuvola.clickOnElement(nextElement);
            break;
    }
};

WebApp.start();

})(this);  // function(Nuvola)
<|endoftext|>


<commit_before>var canvas = new Canvas();
var graph;
var galleryShown = false;

function workCurrent(el) {
    el.siblings().not(el).toggleClass("grey");
    el.toggleClass("current");
}

function makeCurrent(el) {
    workCurrent(el);
    $(".edit")
        .appendTo(el).slideDown()
        .find("");
}

function finishCurrent(callback) {
    var el = $(".controls .function.current");
    workCurrent(el);
    $(".edit").slideUp(function(){
        $(this).appendTo(el.closest(".controls"));
        if(callback) callback();
    });
}

var spectrum_options = {
    showPaletteOnly: true,
    togglePaletteOnly: true,
    hideAfterPaletteSelect: true,
    showButtons: false,
    color: "#6FA8DC",
    togglePaletteMoreText: 'More',
    togglePaletteLessText: 'Less',
    replacerClassName: 'color-input',
    palette: [
    ["#000","#444","#666","#999","#ccc","#eee","#f3f3f3","#fff"],
    ["#f00","#f90","#ff0","#0f0","#0ff","#00f","#90f","#f0f"],
    ["#f4cccc","#fce5cd","#fff2cc","#d9ead3","#d0e0e3","#cfe2f3","#d9d2e9","#ead1dc"],
    ["#ea9999","#f9cb9c","#ffe599","#b6d7a8","#a2c4c9","#9fc5e8","#b4a7d6","#d5a6bd"],
    ["#e06666","#f6b26b","#ffd966","#93c47d","#76a5af","#6fa8dc","#8e7cc3","#c27ba0"],
    ["#c00","#e69138","#f1c232","#6aa84f","#45818e","#3d85c6","#674ea7","#a64d79"],
    ["#900","#b45f06","#bf9000","#38761d","#134f5c","#0b5394","#351c75","#741b47"],
    ["#600","#783f04","#7f6000","#274e13","#0c343d","#073763","#20124d","#4c1130"]
    ],
    change: function(color) {
        var ind = $(this).closest(".function").data("funcs-index");
        canvas.getFunction(ind).setColor(color);
        canvas.redraw();
    }
};

$(document).ready(function(){
    $(".controls .edit")
        .hide()
        .find(".gallery")
            .hide()
        .end()
        .find('input[type="color"]')
            .spectrum(spectrum_options)
        .end();

	graph = $("#graph");
	canvas.attachCanvas("graph");

	$(window).resize(function(){
        // Magic!
        // We shrink the canvas so that it doesn't affect its container size
        // Then calculate its size and the restore canvas size back
        graph
        .attr("width", 1)
        .attr("height", 1)
        .attr("width", graph.parent().width())
        .attr("height", graph.parent().height());

		canvas.resize();
	}).resize();
	graph
    .on("mousedown", function(event){ canvas.startScroll(event.originalEvent) })
    .on("mousemove", function(event){ canvas.scroll(event.originalEvent) })
    .on("mouseup", function(event){ canvas.endScroll() })
    .on("mouseover", function(event){ canvas.endScroll() })
    .on("dblclick", function(event){ canvas.center() })
    .on("wheel", function(event){ canvas.zoom(event.originalEvent) })
    .on("touchstart", function(event){ canvas.startTouchScroll(event.originalEvent) })
    .on("touchmove", function(event){ canvas.touchScroll(event.originalEvent) })
    .on("touchend", function(event){ canvas.endScroll() })
    .on("touchcansel", function(event){ canvas.endScroll() });

	$(".controls .add").click(function(){
		var fBody = '3*x+3';
		var newFunc = canvas.addFunction();
		newFunc.setExpression(fBody);
        var fHtml = $(this).closest(".controls").find("ul .template").clone();
		$(this).closest(".controls").find("ul").append(fHtml);
        fHtml
            .hide()
            .removeClass("template")
            .addClass("function")
            .slideDown()
            .data("funcs-index", canvas.functions.length)
            .find(".editor")
                .html(fBody)
            .end();
        /* var inputColor = fHtml.find('input[type="color"]');
        make_spectrum(inputColor);
        newFunc.setColor('#6FA8DC'); */
		canvas.redraw();
	});

    $('.controls').on("change", '.function .options input[type="checkbox"]', function(){
        var $this = $(this);
        var ind = $this.closest(".function").data("funcs-index");
        canvas.getFunction(ind).toggleEnabled($this.prop("checked"));
        canvas.redraw();
    });
    $('.controls').on("click", '.function .options .remove', function(){
        var $function = $(this).closest(".function");
        var ind = $function.data("funcs-index");
        canvas.deleteFunction(ind);
        canvas.redraw();
        var editPanel = $(this).closest(".controls").find(".edit");
        if(editPanel.filter(":visible").length > 0)
            editPanel.find(".button.go").click();
        $function.nextAll().find(".function").addBack().filter(".function").each(function(){
            $(this).data("funcs-index", $(this).data("funcs-index")-1);
        });
        $function.slideUp(function(){
            $function.remove();
        });
    });

	$(".controls").on("click", ".function:not(.current) p", function(){
		var curFunc = $(this).closest(".function");
        if(curFunc.hasClass("current"))
            return;
        function act() { makeCurrent(curFunc); }
        if(curFunc.hasClass("grey"))
            finishCurrent(act);
        else
            act();

	});

	$(".controls").on("input", ".function .editor", function(){
		var $this = $(this);
		var ind = $this.closest(".function").data("funcs-index");
		canvas.getFunction(ind).setExpression($this.text());
		canvas.redraw();
	});
	$(".controls .edit .button")
		.filter(".slide")
			.click(function(){
				$(this).closest(".edit").find(".gallery").slideToggle();
				galleryShown = !galleryShown;
				$(this).text((galleryShown?"Hide":"Show") + " functions");
			})
		.end()
		.filter(".go")
			.click(function(){finishCurrent(); })
		.end();
});
<commit_msg>Display the color and enabled-state of the current function in the apropriate controls Relies on not-really-public (aka completely private) API of core.js Or is it public? I'm not really sure<commit_after>var canvas = new Canvas();
var graph;
var galleryShown = false;

function workCurrent(el) {
    el.siblings().not(el).toggleClass("grey");
    el.toggleClass("current");
}

function makeCurrent(el) {
    workCurrent(el);
    var func = canvas.getFunction(el.data("funcs-index"));
    var color = func.color;
    var enabled = func.enabled;
    $(".edit")
        .appendTo(el).slideDown()
        .find("input")
            .filter('[type="color"]')
                .spectrum("set", color)
            .end()
            .filter('[type="checkbox"]')
                .prop("checked", enabled)
            .end();
}

function finishCurrent(callback) {
    var el = $(".controls .function.current");
    workCurrent(el);
    $(".edit").slideUp(function(){
        $(this).appendTo(el.closest(".controls"));
        if(callback) callback();
    });
}

var spectrum_options = {
    showPaletteOnly: true,
    togglePaletteOnly: true,
    hideAfterPaletteSelect: true,
    showButtons: false,
    color: "#6FA8DC",
    togglePaletteMoreText: 'More',
    togglePaletteLessText: 'Less',
    replacerClassName: 'color-input',
    palette: [
    ["#000","#444","#666","#999","#ccc","#eee","#f3f3f3","#fff"],
    ["#f00","#f90","#ff0","#0f0","#0ff","#00f","#90f","#f0f"],
    ["#f4cccc","#fce5cd","#fff2cc","#d9ead3","#d0e0e3","#cfe2f3","#d9d2e9","#ead1dc"],
    ["#ea9999","#f9cb9c","#ffe599","#b6d7a8","#a2c4c9","#9fc5e8","#b4a7d6","#d5a6bd"],
    ["#e06666","#f6b26b","#ffd966","#93c47d","#76a5af","#6fa8dc","#8e7cc3","#c27ba0"],
    ["#c00","#e69138","#f1c232","#6aa84f","#45818e","#3d85c6","#674ea7","#a64d79"],
    ["#900","#b45f06","#bf9000","#38761d","#134f5c","#0b5394","#351c75","#741b47"],
    ["#600","#783f04","#7f6000","#274e13","#0c343d","#073763","#20124d","#4c1130"]
    ],
    change: function(color) {
        var ind = $(this).closest(".function").data("funcs-index");
        canvas.getFunction(ind).setColor(color);
        canvas.redraw();
    }
};

$(document).ready(function(){
    $(".controls .edit")
        .hide()
        .find(".gallery")
            .hide()
        .end()
        .find('input[type="color"]')
            .spectrum(spectrum_options)
        .end();

	graph = $("#graph");
	canvas.attachCanvas("graph");

	$(window).resize(function(){
        // Magic!
        // We shrink the canvas so that it doesn't affect its container size
        // Then calculate its size and the restore canvas size back
        graph
        .attr("width", 1)
        .attr("height", 1)
        .attr("width", graph.parent().width())
        .attr("height", graph.parent().height());

		canvas.resize();
	}).resize();
	graph
    .on("mousedown", function(event){ canvas.startScroll(event.originalEvent) })
    .on("mousemove", function(event){ canvas.scroll(event.originalEvent) })
    .on("mouseup", function(event){ canvas.endScroll() })
    .on("mouseover", function(event){ canvas.endScroll() })
    .on("dblclick", function(event){ canvas.center() })
    .on("wheel", function(event){ canvas.zoom(event.originalEvent) })
    .on("touchstart", function(event){ canvas.startTouchScroll(event.originalEvent) })
    .on("touchmove", function(event){ canvas.touchScroll(event.originalEvent) })
    .on("touchend", function(event){ canvas.endScroll() })
    .on("touchcansel", function(event){ canvas.endScroll() });

	$(".controls .add").click(function(){
		var fBody = '3*x+3';
		var newFunc = canvas.addFunction();
		newFunc.setExpression(fBody);
        var fHtml = $(this).closest(".controls").find("ul .template").clone();
		$(this).closest(".controls").find("ul").append(fHtml);
        fHtml
            .hide()
            .removeClass("template")
            .addClass("function")
            .slideDown()
            .data("funcs-index", canvas.functions.length)
            .find(".editor")
                .html(fBody)
            .end();
		canvas.redraw();
	});

    $('.controls').on("change", '.function .options input[type="checkbox"]', function(){
        var $this = $(this);
        var ind = $this.closest(".function").data("funcs-index");
        canvas.getFunction(ind).toggleEnabled($this.prop("checked"));
        canvas.redraw();
    });
    $('.controls').on("click", '.function .options .remove', function(){
        var $function = $(this).closest(".function");
        var ind = $function.data("funcs-index");
        canvas.deleteFunction(ind);
        canvas.redraw();
        var editPanel = $(this).closest(".controls").find(".edit");
        if(editPanel.filter(":visible").length > 0)
            editPanel.find(".button.go").click();
        $function.nextAll().find(".function").addBack().filter(".function").each(function(){
            $(this).data("funcs-index", $(this).data("funcs-index")-1);
        });
        $function.slideUp(function(){
            $function.remove();
        });
    });

	$(".controls").on("click", ".function p", function(){
		var curFunc = $(this).closest(".function");
        if(curFunc.hasClass("current"))
            return;
        function act() { makeCurrent(curFunc); }
        if(curFunc.hasClass("grey"))
            finishCurrent(act);
        else
            act();
	});

	$(".controls").on("input", ".function .editor", function(){
		var $this = $(this);
		var ind = $this.closest(".function").data("funcs-index");
		canvas.getFunction(ind).setExpression($this.text());
		canvas.redraw();
	});
	$(".controls .edit .button")
		.filter(".slide")
			.click(function(){
				$(this).closest(".edit").find(".gallery").slideToggle();
				galleryShown = !galleryShown;
				$(this).text((galleryShown?"Hide":"Show") + " functions");
			})
		.end()
		.filter(".go")
			.click(function(){finishCurrent(); })
		.end();
});
<|endoftext|>


<commit_before>
/*
 * Copyright (C) 2015 ICOS Group, Newcastle University.  All rights reserved.
 * Contact:  James Alastair McLaughlin <j.a.mclaughlin@ncl.ac.uk>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

"use strict";

var xml = require('xml'),
    serializeIdentified = require('./serializeIdentified');

module.exports = function serializeModel(sbolDocument, xmlAttribs, model) {

    return serializeIdentified(sbolDocument, xmlAttribs, model, 'sbol:Model', {
        'sbol:source': { _attr: { 'rdf:resource': model.source }},
        'sbol:language': { _attr: { 'rdf:resource': model.language }},
        'sbol:framework': { _attr: { 'rdf:resource': model.framework }}
    });
}

<commit_msg>Added serializeModel<commit_after>
/*
 * Copyright (C) 2015 ICOS Group, Newcastle University.  All rights reserved.
 * Contact:  James Alastair McLaughlin <j.a.mclaughlin@ncl.ac.uk>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

"use strict";

var xml = require('xml'),
    serializeIdentified = require('./serializeIdentified');

module.exports = function serializeModel(sbolDocument, xmlAttribs, model) {

    return serializeIdentified(sbolDocument, xmlAttribs, model, 'sbol:Model', [
        {'sbol:source': { _attr: { 'rdf:resource': model.source }}},
        {'sbol:language': { _attr: { 'rdf:resource': model.language }}},
        {'sbol:framework': { _attr: { 'rdf:resource': model.framework }}}
    ]);
}

<|endoftext|>


<commit_before>"use strict";

var Class = require("nodeclass").Class,
    pathUtils = require("path"),
    paths = require("../../shared/helpers/pathHelpers.js"),
    _ = require("underscore");

var Request = new Class({

    "method" : "",
    "path" : "",
    "ids" : {},
    "data" : {},
    "type" : "",

    "__allowedMethods" : ["create", "read", "update", "delete"],

    "init" : function (method, path, data) {

        this.setMethod(method);
        this.setPath(path);
        this.data = data;
    },

    "setMethod" : function(method) {
        //one of the allowed methods
        method = method.toLowerCase();

        if(_.include(this.__allowedMethods, method)){
            this.method = method;
            return;
        }

        throw new Error("Unsupported Method: " + method);
    },

    "setPath" : function(path) {

        //reset ids
        this.ids = {};

        //normalize path to prevent ".." and "."
        path = pathUtils.normalize(path);

        //check traling at the beginning not end
        if(path.charAt(path.length-1) === "/"){
            path = path.substr(0, path.length-1);
        }

        //remove slash at the beginning
        if(path.charAt(0) === "/"){
            path = path.substr(1);
        }

        this.path = path;

        //check for IDs
        var pathParts = path.split("/");

        //determine request-types
        if (paths.filters.onlyServiceURL(path)) {
            this.type = "service";
        }
        else if(paths.filters.onlyValidatorURL(path)) {
            this.type = "validator";
        }
        else {
            throw new Error("(alamid) Cannot find resource '" + path + "': Unknown type '" + pathParts[0] + "'");
        }

        for(var i = 1; i < pathParts.length; i++) {
            if(i % 2 === 0) {
                this.ids[pathParts[i-1]] = pathParts[i];
            }
        }

        //TODO: create request url here - remove ids from url!
    }
});

module.exports = Request;

<commit_msg>- using pathHelpers now for path sanitizing on Request-Class<commit_after>"use strict";

var Class = require("nodeclass").Class,
    pathUtils = require("path"),
    pathHelpers = require("../../shared/helpers/pathHelpers.js"),
    _ = require("underscore");

var Request = new Class({

    "method" : "",
    "path" : "",
    "ids" : {},
    "data" : {},
    "type" : "",

    "__allowedMethods" : ["create", "read", "update", "delete"],

    "init" : function (method, path, data) {

        this.setMethod(method);
        this.setPath(path);
        this.data = data;
    },

    "setMethod" : function(method) {
        //one of the allowed methods
        method = method.toLowerCase();

        if(_.include(this.__allowedMethods, method)){
            this.method = method;
            return;
        }

        throw new Error("Unsupported Method: " + method);
    },

    "setPath" : function(path) {

        //reset ids
        this.ids = {};

        //sanitize the path
        path = pathHelpers.apply.modifier(
            pathHelpers.modifiers.normalize,
            pathHelpers.modifiers.noTrailingSlash,
            pathHelpers.modifiers.noLeadingSlash
        ).on(path);

        this.path = path;

        //check for IDs
        var pathParts = path.split("/");

        //determine request-types
        if (pathHelpers.filters.onlyServiceURL(path)) {
            this.type = "service";
        }
        else if(pathHelpers.filters.onlyValidatorURL(path)) {
            this.type = "validator";
        }
        else {
            throw new Error("(alamid) Cannot find resource '" + path + "': Unknown type '" + pathParts[0] + "'");
        }

        for(var i = 1; i < pathParts.length; i++) {
            if(i % 2 === 0) {
                this.ids[pathParts[i-1]] = pathParts[i];
            }
        }

        //TODO: create request url here - remove ids from url!
    }
});

module.exports = Request;

<|endoftext|>


<commit_before>'use strict';
// an app object, a single instance of which is created at launch, managing timer, events and screen fit
// copyright 2016 Samuel Baird MIT Licence

define(['letter.geometry', 'letter.dispatch', 'letter.display_list', 'letter.event_dispatch', 'letter.resources', 'letter.button'], function (geometry, dispatch, display_list, event_dispatch, resources, button) {

	var app = klass(function (app) {

		app.init = function (screen, timer) {
			this.screen = screen;
			this.timer = timer;
			this.resources = resources;

			this.dispatch = new dispatch.frame_dispatch();
			this.current_scene = null;
			this.last_time = null;

			var self = this;
			button.configure(function (action) { self.dispatch.delay(1, action); });
		}

		app.set_scene = function (scene) {
			if (this.current_scene != null) {
				this.current_scene.dispose();
				this.current_scene = null;
			}

			this.dispatch.clear();
			event_dispatch.reset_shared_instance();

			// if a string reference then load before continuing
			if (typeof scene == 'string') {
				var self = this;
				require([scene], function (loaded_scene_class) {
					self.set_scene(new loaded_scene_class());
				});
				return;
			}

			if (scene) {
				this.last_time = null;
				this.current_scene = scene
				this.current_scene.app = this
				this.current_scene.resources = resources
				this.current_scene.screen = this.screen

				this.current_scene.prepare();
				this.screen.root_view.add(scene.view);
				this.current_scene.begin();
			}
		}

		app.update = function () {
			var now = Date.now();
			this.screen.update();

			// update animation heirachy and fire off on-complete events once done
			var on_completes = [];
			this.screen.root_view.update_animated_clips(1.0/60.0, function (callback) { on_completes.push(callback); });
			on_completes.with_each(function (callback) {
				callback();
			});

			event_dispatch.shared_instance().dispatch_deferred();
			this.dispatch.update();

			if (this.current_scene) {
				var frames = 1;
				if (this.last_time != null) {
					var delta = (now - this.last_time);
					if (delta > 20) {
						frames = 2;
					}
				}
				for (var f = 0; f < frames; f++) {
					this.current_scene.update();
				}
				this.screen.render();
			}
			this.last_time = now;
		}

		app.pause = function () { this.timer.stop(); }
		app.resume = function () { var self = this; this.timer.start(function () { self.update(); }); }
	});

	var screen = klass(function (screen) {
		screen.init = function (canvas, nominal_width, nominal_height, fit) {
			this.canvas = canvas;
			this.ctx = canvas.getContext("2d");
			this.nominal_height = nominal_height;
			this.nominal_width = nominal_width;
			this.fit = fit;
			this.root_view = new display_list.display_list();

			this.update();

			var self = this;
			canvas.addEventListener("mousedown", function (evt) { self.touch_event('touch_begin', evt); }, false);
			canvas.addEventListener("mousemove", function (evt) { self.touch_event('touch_move', evt); }, false);
			canvas.addEventListener("mouseup", function (evt) { self.touch_event('touch_end', evt); }, false);

			canvas.addEventListener("touchstart", function (evt) { self.touch_event('touch_begin', evt); }, false);
			canvas.addEventListener("touchmove", function (evt) { self.touch_event('touch_move', evt); }, false);
			canvas.addEventListener("touchend", function (evt) { self.touch_event('touch_end', evt); }, false);
			canvas.addEventListener("touchcancel", function (evt) { self.touch_event('touch_cancel', evt); }, false);
		};

		screen.touch_event = function (event_name, evt) {
			evt.preventDefault();
			if (evt.changedTouches) {
				for (var i = 0; i < evt.changedTouches.length; i++) {
					var touch = evt.changedTouches[i];
					event_dispatch.shared_instance().defer(event_name, { id : touch.identifier, time : Date.now, x : touch.pageX - canvas.offsetLeft, y : touch.pageY - canvas.offsetTop });
				}
			} else {
				event_dispatch.shared_instance().defer(event_name, { id : 1, time : Date.now, x : evt.pageX - canvas.offsetLeft, y : evt.pageY - canvas.offsetTop });
			}
		};

		screen.update = function () {
			// update transform of root view to match sizing
		}

		screen.render = function () {
			// update scaling to fit nominal sizing to canvas size
			var scale_x = this.canvas.width / this.nominal_width;
			var scale_y = this.canvas.height / this.nominal_height;
			var scale = 1;

			if (this.fit == 'fit') {
				scale = (scale_x < scale_y) ? scale_x : scale_y;
			} else {
				// other screenfit strategies
			}

			this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
			this.root_view.scale_x = scale;
			this.root_view.scale_y = scale;
			this.root_view.render(this.ctx, geometry.default_transform());
		}

	});

	var timer = klass(function (timer) {
		// cross browser request animation frame
		var requestAnimFrame = (function() {
		    return window.requestAnimationFrame       ||
		        window.webkitRequestAnimationFrame ||
		        window.mozRequestAnimationFrame    ||
		        window.oRequestAnimationFrame      ||
		        window.msRequestAnimationFrame     ||
		        function(callback) {
		            window.setTimeout(callback, 1000 / 60);
		        };
		}) ();

		var get_time = function () { return Date.now(); }

		timer.init = function () {
			this.active = false;
			this.fps = 60;
			this.minimum_delay = (1000.0 / this.fps) - 3;
			this.last_frame = 0;
		}

		timer.start = function (callback) {
			this.active = true;

			var self = this;
			var next_frame = function () {
				if (!self.active) {
					return;
				}
				requestAnimFrame(next_frame);
				var now = get_time();
				if (now - self.last_frame < self.minimum_delay) {
					// skip it
				} else {
					self.last_frame = now;
					callback();
				}
			}

			requestAnimFrame(next_frame);
		}

		timer.stop = function () {
			this.active = false;
		}

		timer.set_frame_rate = function (fps) {
			this.fps = fps;
			this.minimum_delay = (1000.0 / fps) - 3;
		}
	});

	// exported module
	return {

		launch : function (canvas, scene, width, height, fit) {
			console.log('app launch');
			var _screen = new screen(canvas, width, height, fit);
			var _timer = new timer();

			var _app = new app(_screen, _timer);

			window.app = _app;
			window.resources = resources;

			_app.set_scene(scene);
			_app.resume();
			return _app;
		}

	}
})<commit_msg>FPS support in the app class<commit_after>'use strict';
// an app object, a single instance of which is created at launch, managing timer, events and screen fit
// copyright 2016 Samuel Baird MIT Licence

define(['letter.geometry', 'letter.dispatch', 'letter.display_list', 'letter.event_dispatch', 'letter.resources', 'letter.button'], function (geometry, dispatch, display_list, event_dispatch, resources, button) {

	var app = klass(function (app) {

		app.init = function (screen, timer) {
			this.screen = screen;
			this.timer = timer;
			this.fps = timer.fps;
			this.resources = resources;

			this.dispatch = new dispatch.frame_dispatch();
			this.current_scene = null;
			this.last_time = null;

			var self = this;
			button.configure(function (action) { self.dispatch.delay(1, action); });
		}

		app.set_scene = function (scene) {
			if (this.current_scene != null) {
				this.current_scene.dispose();
				this.current_scene = null;
			}

			this.dispatch.clear();
			event_dispatch.reset_shared_instance();

			// if a string reference then load before continuing
			if (typeof scene == 'string') {
				var self = this;
				require([scene], function (loaded_scene_class) {
					self.set_scene(new loaded_scene_class());
				});
				return;
			}

			if (scene) {
				this.last_time = null;
				this.current_scene = scene
				this.current_scene.app = this
				this.current_scene.resources = resources
				this.current_scene.screen = this.screen

				this.current_scene.prepare();
				this.screen.root_view.add(scene.view);
				this.current_scene.begin();
			}
		}

		app.update = function () {
			var now = Date.now();
			this.screen.update();

			// update animation heirachy and fire off on-complete events once done
			var on_completes = [];
			this.screen.root_view.update_animated_clips(1.0 / this.fps, function (callback) { on_completes.push(callback); });
			on_completes.with_each(function (callback) {
				callback();
			});

			event_dispatch.shared_instance().dispatch_deferred();
			this.dispatch.update();

			if (this.current_scene != null) {
				var frames = 1;
				if (this.last_time != null) {
					var delta = (now - this.last_time);
					if (delta > (1.0 / this.fps) * 1.25) {
						frames = 2;
					}
				}
				for (var f = 0; f < frames; f++) {
					if (this.current_scene != null) {
						this.current_scene.update();
					}
				}
				this.screen.render();
			}
			this.last_time = now;
		}

		app.set_frame_rate = function (fps) {
			this.timer.set_frame_rate(fps);
			this.fps = fps;
		}

		app.pause = function () { this.timer.stop(); }
		app.resume = function () { var self = this; this.timer.start(function () { self.update(); }); }
	});

	var screen = klass(function (screen) {
		screen.init = function (canvas, nominal_width, nominal_height, fit) {
			this.canvas = canvas;
			this.ctx = canvas.getContext("2d");
			this.nominal_height = nominal_height;
			this.nominal_width = nominal_width;
			this.fit = fit;
			this.root_view = new display_list.display_list();

			this.update();

			var self = this;
			canvas.addEventListener("mousedown", function (evt) { self.touch_event('touch_begin', evt); }, false);
			canvas.addEventListener("mousemove", function (evt) { self.touch_event('touch_move', evt); }, false);
			canvas.addEventListener("mouseup", function (evt) { self.touch_event('touch_end', evt); }, false);

			canvas.addEventListener("touchstart", function (evt) { self.touch_event('touch_begin', evt); }, false);
			canvas.addEventListener("touchmove", function (evt) { self.touch_event('touch_move', evt); }, false);
			canvas.addEventListener("touchend", function (evt) { self.touch_event('touch_end', evt); }, false);
			canvas.addEventListener("touchcancel", function (evt) { self.touch_event('touch_cancel', evt); }, false);
		};

		screen.touch_event = function (event_name, evt) {
			evt.preventDefault();
			if (evt.changedTouches) {
				for (var i = 0; i < evt.changedTouches.length; i++) {
					var touch = evt.changedTouches[i];
					event_dispatch.shared_instance().defer(event_name, { id : touch.identifier, time : Date.now, x : touch.pageX - canvas.offsetLeft, y : touch.pageY - canvas.offsetTop });
				}
			} else {
				event_dispatch.shared_instance().defer(event_name, { id : 1, time : Date.now, x : evt.pageX - canvas.offsetLeft, y : evt.pageY - canvas.offsetTop });
			}
		};

		screen.update = function () {
			// update transform of root view to match sizing
		}

		screen.render = function () {
			// update scaling to fit nominal sizing to canvas size
			var scale_x = this.canvas.width / this.nominal_width;
			var scale_y = this.canvas.height / this.nominal_height;
			var scale = 1;

			if (this.fit == 'fit') {
				scale = (scale_x < scale_y) ? scale_x : scale_y;
			} else {
				// other screenfit strategies
			}

			this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
			this.root_view.scale_x = scale;
			this.root_view.scale_y = scale;
			this.root_view.render(this.ctx, geometry.default_transform());
		}

	});

	var timer = klass(function (timer) {
		// cross browser request animation frame
		var requestAnimFrame = (function() {
		    return window.requestAnimationFrame       ||
		        window.webkitRequestAnimationFrame ||
		        window.mozRequestAnimationFrame    ||
		        window.oRequestAnimationFrame      ||
		        window.msRequestAnimationFrame     ||
		        function(callback) {
		            window.setTimeout(callback, 1000 / 60);
		        };
		}) ();

		var get_time = function () { return Date.now(); }

		timer.init = function () {
			this.active = false;
			this.fps = 60;
			this.minimum_delay = (1000.0 / this.fps) - 3;
			this.last_frame = 0;
		}

		timer.start = function (callback) {
			this.active = true;

			var self = this;
			var next_frame = function () {
				if (!self.active) {
					return;
				}
				requestAnimFrame(next_frame);
				var now = get_time();
				if (now - self.last_frame < self.minimum_delay) {
					// skip it
				} else {
					self.last_frame = now;
					callback();
				}
			}

			requestAnimFrame(next_frame);
		}

		timer.stop = function () {
			this.active = false;
		}

		timer.set_frame_rate = function (fps) {
			this.fps = fps;
			this.minimum_delay = (1000.0 / fps) - 3;
		}
	});

	// exported module
	return {

		launch : function (canvas, scene, width, height, fit) {
			console.log('app launch');
			var _screen = new screen(canvas, width, height, fit);
			var _timer = new timer();

			var _app = new app(_screen, _timer);

			window.app = _app;
			window.resources = resources;

			_app.set_scene(scene);
			_app.resume();
			return _app;
		}

	}
})<|endoftext|>


<commit_before>'use strict';

var async = require('async');
var debug = require('../util/debug')('analysis-time-logger');

function AnalysisTimeLogger(logger, batchClient) {
    this.logger = logger;
    this.batchClient = batchClient;
}

module.exports = AnalysisTimeLogger;

AnalysisTimeLogger.prototype.log = function (rows) {
    var self = this;
    var logElapsedTime = self._logNodeElapsedTime.bind(self);
    var nodesToLog = getNodesToLogFromRows(rows);

    async.map(nodesToLog, logElapsedTime, function (err) {
        if (err) {
            return self.logger.error(err);
        }
    });
};

function getNodesToLogFromRows(rows) {
    return rows
        .map(function (row) {
            if (row.last_modified_by) {
                return { nodeId: row.node_id, jobId: row.last_modified_by };
            }
        })
        .filter(function (toLog) {
            return !!toLog;
        });
}

AnalysisTimeLogger.prototype._logNodeElapsedTime = function (nodeToLog, callback) {
    var self = this;

    this._getNodeElapsedTime(nodeToLog.jobId, nodeToLog.nodeId, function (err, elapsedTimeMilliseconds) {
        if (err) {
            return callback(err);
        }

        if (Number.isFinite(elapsedTimeMilliseconds)) {
            self.logger.info({ node: nodeToLog.nodeId, elapsedTime: elapsedTimeMilliseconds});
        }

        callback();
    });
};

AnalysisTimeLogger.prototype._getNodeElapsedTime = function(jobId, nodeId, callback) {
    this.batchClient.getJob(jobId, function (err, job) {
        if (err) {
            return callback(err);
        }

        if (!isValidToGetElapsedTime(job)) {
            return callback();
        }

        var queryElapsedTime = getQueryElapsedTime(job.query.query, nodeId);

        if (!queryElapsedTime) {
            return callback();
        }

        callback(null, queryElapsedTime);
    });
};

function isValidToGetElapsedTime(job) {
    return job && job.status === 'done' && job.query && Array.isArray(job.query.query);
}

function getQueryElapsedTime (queries, nodeId) {
    for (var i = 0; i < queries.length; i++) {
        if (isQueryOfNodeId(queries[i].query, nodeId)) {
            var start = new Date(queries[i].started_at);
            var end = new Date(queries[i].ended_at);

            if (start && end) {
                var elapsedTimeMilliseconds = end.getTime() - start.getTime();

                debug('analysis time %j', { analysis: nodeId, time: elapsedTimeMilliseconds });
                return elapsedTimeMilliseconds;
            }
        }
    }
}

function isQueryOfNodeId(query, nodeId) {
    return query.indexOf('/* camshaft_node_id: ' + nodeId) !== -1;
}
<commit_msg>Apply early return pattern to improve readability<commit_after>'use strict';

var async = require('async');
var debug = require('../util/debug')('analysis-time-logger');

function AnalysisTimeLogger(logger, batchClient) {
    this.logger = logger;
    this.batchClient = batchClient;
}

module.exports = AnalysisTimeLogger;

AnalysisTimeLogger.prototype.log = function (rows) {
    var self = this;
    var logElapsedTime = self._logNodeElapsedTime.bind(self);
    var nodesToLog = getNodesToLogFromRows(rows);

    async.map(nodesToLog, logElapsedTime, function (err) {
        if (err) {
            return self.logger.error(err);
        }
    });
};

function getNodesToLogFromRows(rows) {
    return rows
        .map(function (row) {
            return row.last_modified_by ? { nodeId: row.node_id, jobId: row.last_modified_by } : undefined;
        })
        .filter(function (toLog) {
            return !!toLog;
        });
}

AnalysisTimeLogger.prototype._logNodeElapsedTime = function (nodeToLog, callback) {
    var self = this;

    this._getNodeElapsedTime(nodeToLog.jobId, nodeToLog.nodeId, function (err, elapsedTimeMilliseconds) {
        if (err) {
            return callback(err);
        }

        if (Number.isFinite(elapsedTimeMilliseconds)) {
            self.logger.info({ node: nodeToLog.nodeId, elapsedTime: elapsedTimeMilliseconds});
        }

        callback();
    });
};

AnalysisTimeLogger.prototype._getNodeElapsedTime = function(jobId, nodeId, callback) {
    this.batchClient.getJob(jobId, function (err, job) {
        if (err) {
            return callback(err);
        }

        if (!isValidToGetElapsedTime(job)) {
            return callback();
        }

        var queryElapsedTime = getQueryElapsedTime(job.query.query, nodeId);

        if (!queryElapsedTime) {
            return callback();
        }

        callback(null, queryElapsedTime);
    });
};

function isValidToGetElapsedTime(job) {
    return job && job.status === 'done' && job.query && Array.isArray(job.query.query);
}

function getQueryElapsedTime (queries, nodeId) {
    for (var i = 0; i < queries.length; i++) {
        if (!isQueryOfNodeId(queries[i].query, nodeId)) {
            continue;
        }

        var start = new Date(queries[i].started_at);
        var end = new Date(queries[i].ended_at);

        if (!start || !end) {
            continue;
        }

        var elapsedTimeMilliseconds = end.getTime() - start.getTime();

        debug('analysis time %j', { analysis: nodeId, time: elapsedTimeMilliseconds });
        return elapsedTimeMilliseconds;
    }
}

function isQueryOfNodeId(query, nodeId) {
    return query.indexOf('/* camshaft_node_id: ' + nodeId) !== -1;
}
<|endoftext|>