<commit_before>'use strict';

/* global Plotly:false */

var Fuse = require('fuse.js');
var mocks = require('../../build/test_dashboard_mocks.json');
var credentials = require('../../build/credentials.json');
var Lib = require('@src/lib');
var d3 = Plotly.d3;

// Our gracious testing object
var Tabs = {

    // Set plot config options
    setPlotConfig: function() {
        Plotly.setPlotConfig({

            // use local topojson files
            topojsonURL: '../../dist/topojson/',

            // register mapbox access token
            // run `npm run preset` if you haven't yet
            mapboxAccessToken: credentials.MAPBOX_ACCESS_TOKEN,

            // show all logs in console
            logging: 2
        });
    },

    // Return the specified plot container (or default one)
    getGraph: function(id) {
        id = id || 'graph';
        return document.getElementById(id);
    },

    // Create a new plot container
    fresh: function(id) {
        id = id || 'graph';

        var graphDiv = Tabs.getGraph(id);

        if(graphDiv) {
            graphDiv.parentNode.removeChild(graphDiv);
        }

        graphDiv = document.createElement('div');
        graphDiv.className = 'dashboard-plot';
        graphDiv.id = id;

        var plotArea = document.getElementById('plots');
        plotArea.appendChild(graphDiv);

        return graphDiv;
    },

    // Plot a mock by name (without .json) to the default or specified container
    plotMock: function(mockName, id) {
        var mockURL = '/test/image/mocks/' + mockName + '.json';

        d3.json(mockURL, function(err, fig) {
            Plotly.plot(Tabs.fresh(id), fig.data, fig.layout);

            console.warn('Plotting:', mockURL);
        });
    },

    getMock: function(mockName, callback) {
        var mockURL = '/test/image/mocks/' + mockName + '.json';

        d3.json(mockURL, function(err, fig) {
            if(typeof callback !== 'function') {
                window.mock = fig;
            } else {
                callback(err, fig);
            }
        });
    },

    // Save a png snapshot and display it below the plot
    snapshot: function(id) {
        var gd = Tabs.getGraph(id);

        if(!gd._fullLayout || !gd._fullData) {
            console.error('no graph with id ' + id + ' found.');
            return;
        }

        var image = new Image();

        Plotly.Snapshot.toImage(gd, { format: 'png' }).on('success', function(img) {
            image.src = img;

            var imageDiv = document.getElementById('snapshot');
            imageDiv.appendChild(image);

            console.warn('Snapshot complete!');
        });
    },

    // Remove all plots and snapshots from the page
    purge: function() {
        var plots = document.getElementsByClassName('dashboard-plot');
        var images = document.getElementById('snapshot');

        while(images.firstChild) {
            images.removeChild(images.firstChild);
        }

        for(var i = 0; i < plots.length; i++) {
            Plotly.purge(plots[i]);
        }
    },

    // Specify what to do after each plotly.js script reload
    onReload: function() {
        return;
    },

    // Refreshes the plotly.js source without needing to refresh the page
    reload: function() {
        var source = document.getElementById('source');
        var reloaded = document.getElementById('reload-time');

        source.remove();

        window.Plotly = null;

        source = document.createElement('script');
        source.id = 'source';
        source.src = '../../build/plotly.js';

        document.body.appendChild(source);

        var reloadTime = new Date().toLocaleTimeString();
        console.warn('plotly.js reloaded at ' + reloadTime);
        reloaded.textContent = 'last reload at ' + reloadTime;

        var interval = setInterval(function() {
            if(window.Plotly) {
                clearInterval(interval);
                handleOnLoad();
                Tabs.onReload();
            }
        }, 100);
    }
};

// Bind things to the window
window.Tabs = Tabs;
window.Lib = Lib;
window.d3 = d3;
window.onload = handleOnLoad;
setInterval(function() {
    window.gd = Tabs.getGraph() || Tabs.fresh();
    window.fullLayout = window.gd._fullLayout;
    window.fullData = window.gd._fullData;
}, 1000);

// Mocks search and plotting
var f = new Fuse(mocks, {
    keys: [{
        name: 'name',
        weight: 0.7
    }, {
        name: 'keywords',
        weight: 0.3
    }]
});

var searchBar = document.getElementById('mocks-search');
var mocksList = document.getElementById('mocks-list');
var plotArea = document.getElementById('plots');

searchBar.addEventListener('keyup', debounce(searchMocks, 250));

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if(!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if(callNow) func.apply(context, args);
    };
}

function searchMocks(e) {

    // Clear results.
    while(mocksList.firstChild) {
        mocksList.removeChild(mocksList.firstChild);
    }

    var results = f.search(e.target.value);

    results.forEach(function(r) {
        var result = document.createElement('span');
        result.className = 'search-result';
        result.innerText = r.name;

        result.addEventListener('click', function() {
            var mockName = r.file.slice(0, -5);
            window.location.hash = mockName;

            // Clear plots and plot selected.
            Tabs.purge();
            Tabs.plotMock(mockName);
        });

        mocksList.appendChild(result);

        var listWidth = mocksList.getBoundingClientRect().width;
        var plotAreaWidth = Math.floor(window.innerWidth - listWidth);
        plotArea.setAttribute('style', 'width: ' + plotAreaWidth + 'px;');
    });
}

function plotFromHash() {
    var initialMock = window.location.hash.replace(/^#/, '');

    if(initialMock.length > 0) {
        Tabs.plotMock(initialMock);
    }
}

function handleOnLoad() {
    Tabs.setPlotConfig();
    plotFromHash();
}
<commit_msg>load frames in test dashboard<commit_after>'use strict';

/* global Plotly:false */

var Fuse = require('fuse.js');
var mocks = require('../../build/test_dashboard_mocks.json');
var credentials = require('../../build/credentials.json');
var Lib = require('@src/lib');
var d3 = Plotly.d3;

// Our gracious testing object
var Tabs = {

    // Set plot config options
    setPlotConfig: function() {
        Plotly.setPlotConfig({

            // use local topojson files
            topojsonURL: '../../dist/topojson/',

            // register mapbox access token
            // run `npm run preset` if you haven't yet
            mapboxAccessToken: credentials.MAPBOX_ACCESS_TOKEN,

            // show all logs in console
            logging: 2
        });
    },

    // Return the specified plot container (or default one)
    getGraph: function(id) {
        id = id || 'graph';
        return document.getElementById(id);
    },

    // Create a new plot container
    fresh: function(id) {
        id = id || 'graph';

        var graphDiv = Tabs.getGraph(id);

        if(graphDiv) {
            graphDiv.parentNode.removeChild(graphDiv);
        }

        graphDiv = document.createElement('div');
        graphDiv.className = 'dashboard-plot';
        graphDiv.id = id;

        var plotArea = document.getElementById('plots');
        plotArea.appendChild(graphDiv);

        return graphDiv;
    },

    // Plot a mock by name (without .json) to the default or specified container
    plotMock: function(mockName, id) {
        var mockURL = '/test/image/mocks/' + mockName + '.json';

        d3.json(mockURL, function(err, fig) {
            Plotly.plot(Tabs.fresh(id), fig);

            console.warn('Plotting:', mockURL);
        });
    },

    getMock: function(mockName, callback) {
        var mockURL = '/test/image/mocks/' + mockName + '.json';

        d3.json(mockURL, function(err, fig) {
            if(typeof callback !== 'function') {
                window.mock = fig;
            } else {
                callback(err, fig);
            }
        });
    },

    // Save a png snapshot and display it below the plot
    snapshot: function(id) {
        var gd = Tabs.getGraph(id);

        if(!gd._fullLayout || !gd._fullData) {
            console.error('no graph with id ' + id + ' found.');
            return;
        }

        var image = new Image();

        Plotly.Snapshot.toImage(gd, { format: 'png' }).on('success', function(img) {
            image.src = img;

            var imageDiv = document.getElementById('snapshot');
            imageDiv.appendChild(image);

            console.warn('Snapshot complete!');
        });
    },

    // Remove all plots and snapshots from the page
    purge: function() {
        var plots = document.getElementsByClassName('dashboard-plot');
        var images = document.getElementById('snapshot');

        while(images.firstChild) {
            images.removeChild(images.firstChild);
        }

        for(var i = 0; i < plots.length; i++) {
            Plotly.purge(plots[i]);
        }
    },

    // Specify what to do after each plotly.js script reload
    onReload: function() {
        return;
    },

    // Refreshes the plotly.js source without needing to refresh the page
    reload: function() {
        var source = document.getElementById('source');
        var reloaded = document.getElementById('reload-time');

        source.remove();

        window.Plotly = null;

        source = document.createElement('script');
        source.id = 'source';
        source.src = '../../build/plotly.js';

        document.body.appendChild(source);

        var reloadTime = new Date().toLocaleTimeString();
        console.warn('plotly.js reloaded at ' + reloadTime);
        reloaded.textContent = 'last reload at ' + reloadTime;

        var interval = setInterval(function() {
            if(window.Plotly) {
                clearInterval(interval);
                handleOnLoad();
                Tabs.onReload();
            }
        }, 100);
    }
};

// Bind things to the window
window.Tabs = Tabs;
window.Lib = Lib;
window.d3 = d3;
window.onload = handleOnLoad;
setInterval(function() {
    window.gd = Tabs.getGraph() || Tabs.fresh();
    window.fullLayout = window.gd._fullLayout;
    window.fullData = window.gd._fullData;
}, 1000);

// Mocks search and plotting
var f = new Fuse(mocks, {
    keys: [{
        name: 'name',
        weight: 0.7
    }, {
        name: 'keywords',
        weight: 0.3
    }]
});

var searchBar = document.getElementById('mocks-search');
var mocksList = document.getElementById('mocks-list');
var plotArea = document.getElementById('plots');

searchBar.addEventListener('keyup', debounce(searchMocks, 250));

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if(!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if(callNow) func.apply(context, args);
    };
}

function searchMocks(e) {

    // Clear results.
    while(mocksList.firstChild) {
        mocksList.removeChild(mocksList.firstChild);
    }

    var results = f.search(e.target.value);

    results.forEach(function(r) {
        var result = document.createElement('span');
        result.className = 'search-result';
        result.innerText = r.name;

        result.addEventListener('click', function() {
            var mockName = r.file.slice(0, -5);
            window.location.hash = mockName;

            // Clear plots and plot selected.
            Tabs.purge();
            Tabs.plotMock(mockName);
        });

        mocksList.appendChild(result);

        var listWidth = mocksList.getBoundingClientRect().width;
        var plotAreaWidth = Math.floor(window.innerWidth - listWidth);
        plotArea.setAttribute('style', 'width: ' + plotAreaWidth + 'px;');
    });
}

function plotFromHash() {
    var initialMock = window.location.hash.replace(/^#/, '');

    if(initialMock.length > 0) {
        Tabs.plotMock(initialMock);
    }
}

function handleOnLoad() {
    Tabs.setPlotConfig();
    plotFromHash();
}
<|endoftext|>


<commit_before>var wpi = require('wiring-pi');

wpi.setup('wpi');
wpi.pinMode(7, wpi.INPUT);
wpi.pullUpDnControl(7, wpi.PUD_UP);
wpi.wiringPiISR(7, wpi.INT_EDGE_FALLING, function(delta){
	console.log('Pin 7 changed to Low (', delta, ')');
});<commit_msg>changed buttons working<commit_after>var wpi = require('wiring-pi');

wpi.setup('wpi');
wpi.pinMode(7, wpi.INPUT);
wpi.pullUpDnControl(7, wpi.PUD_UP);
wpi.wiringPiISR(7, wpi.INT_EDGE_FALLING, function(){
	handleButton(7);
});

function handleButton(pin) {
	if(wpi.digitalRead(pin)) {
		console.log('Pressed ' + pin)
	}
}<|endoftext|>


<commit_before>/* vim:ts=4:sts=4:sw=4:
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Ajax.org Code Editor (ACE).
 *
 * The Initial Developer of the Original Code is
 * Ajax.org B.V.
 * Portions created by the Initial Developer are Copyright (C) 2010
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *      Fabian Jakobs <fabian AT ajax DOT org>
 *      Julian Viereck <julian.viereck@gmail.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {

var Range = require("ace/range").Range;
var dom = require("pilot/dom");

var Marker = function(parentEl) {
    this.element = dom.createElement("div");
    this.element.className = "ace_layer ace_marker-layer";
    parentEl.appendChild(this.element);
};

(function() {

    this.$padding = 0;

    this.setPadding = function(padding) {
        this.$padding = padding;
    };
    this.setSession = function(session) {
        this.session = session;
    };

    this.setMarkers = function(markers) {
        this.markers = markers;
    };

    this.update = function(config) {
        var config = config || this.config;
        if (!config)
            return;

        this.config = config;

        var html = [];
        for ( var key in this.markers) {
            var marker = this.markers[key];

            var range = marker.range.clipRows(config.firstRow, config.lastRow);
            if (range.isEmpty()) continue;

            range = range.toScreenRange(this.session);

            if (marker.renderer) {
                var top = this.$getTop(range.start.row, config);
                var left = Math.round(this.$padding +
                                      range.start.column *
                                      config.characterWidth);
                marker.renderer(html, range, left, top, config);
            }
            else if (range.isMultiLine()) {
                if (marker.type == "text") {
                    this.drawTextMarker(html, range, marker.clazz, config);
                } else {
                    this.drawMultiLineMarker(html, range, marker.clazz, config);
                }
            }
            else {
                this.drawSingleLineMarker(html, range, marker.clazz, config);
            }
        }
        this.element = dom.setInnerHtml(this.element, html.join(""));
    };

    this.$getTop = function(row, layerConfig) {
        return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight;
    };

    this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) {
        // selection start
        var row = range.start.row;

        var lineRange = new Range(row, range.start.column,
                                  row, this.session.getScreenLastRowColumn(row));
        this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1);

        // selection end
        var row = range.end.row;
        var lineRange = new Range(row, 0, row, range.end.column);
        this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig);

        for (var row = range.start.row + 1; row < range.end.row; row++) {
            lineRange.start.row = row;
            lineRange.end.row = row;
            lineRange.end.column = this.session.getScreenLastRowColumn(row);
            this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1);
        }
    };

    this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) {
        // from selection start to the end of the line
        var height = layerConfig.lineHeight;
        var width = Math.round(layerConfig.width - (range.start.column * layerConfig.characterWidth));
        var top = this.$getTop(range.start.row, layerConfig);
        var left = Math.round(this.$padding +
                              range.start.column * layerConfig.characterWidth);

        stringBuilder.push(
            "

"
        );

        // from start of the last line to the selection end
        top = this.$getTop(range.end.row, layerConfig);
        width = Math.round(range.end.column * layerConfig.characterWidth);

        stringBuilder.push(
            "

"
        );

        // all the complete lines
        height = (range.end.row - range.start.row - 1) * layerConfig.lineHeight;
        if (height < 0)
            return;
        top = this.$getTop(range.start.row + 1, layerConfig);
        width = layerConfig.width;

        stringBuilder.push(
            "

"
        );
    };

    this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig, extraLength) {
        var height = layerConfig.lineHeight;
        var width = Math.round((range.end.column + (extraLength || 0) - range.start.column) * layerConfig.characterWidth);
        var top = this.$getTop(range.start.row, layerConfig);
        var left = Math.round(this.$padding +
                              range.start.column * layerConfig.characterWidth);

        stringBuilder.push(
            "

"
        );
    };

}).call(Marker.prototype);

exports.Marker = Marker;

});
<commit_msg>Fixing issue with multiline selection where selection does not start from the begining of line.<commit_after>/* vim:ts=4:sts=4:sw=4:
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Ajax.org Code Editor (ACE).
 *
 * The Initial Developer of the Original Code is
 * Ajax.org B.V.
 * Portions created by the Initial Developer are Copyright (C) 2010
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *      Fabian Jakobs <fabian AT ajax DOT org>
 *      Julian Viereck <julian.viereck@gmail.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {

var Range = require("ace/range").Range;
var dom = require("pilot/dom");

var Marker = function(parentEl) {
    this.element = dom.createElement("div");
    this.element.className = "ace_layer ace_marker-layer";
    parentEl.appendChild(this.element);
};

(function() {

    this.$padding = 0;

    this.setPadding = function(padding) {
        this.$padding = padding;
    };
    this.setSession = function(session) {
        this.session = session;
    };

    this.setMarkers = function(markers) {
        this.markers = markers;
    };

    this.update = function(config) {
        var config = config || this.config;
        if (!config)
            return;

        this.config = config;

        var html = [];
        for ( var key in this.markers) {
            var marker = this.markers[key];

            var range = marker.range.clipRows(config.firstRow, config.lastRow);
            if (range.isEmpty()) continue;

            range = range.toScreenRange(this.session);

            if (marker.renderer) {
                var top = this.$getTop(range.start.row, config);
                var left = Math.round(this.$padding +
                                      range.start.column *
                                      config.characterWidth);
                marker.renderer(html, range, left, top, config);
            }
            else if (range.isMultiLine()) {
                if (marker.type == "text") {
                    this.drawTextMarker(html, range, marker.clazz, config);
                } else {
                    this.drawMultiLineMarker(html, range, marker.clazz, config);
                }
            }
            else {
                this.drawSingleLineMarker(html, range, marker.clazz, config);
            }
        }
        this.element = dom.setInnerHtml(this.element, html.join(""));
    };

    this.$getTop = function(row, layerConfig) {
        return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight;
    };

    this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) {
        // selection start
        var row = range.start.row;

        var lineRange = new Range(row, range.start.column,
                                  row, this.session.getScreenLastRowColumn(row));
        this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1);

        // selection end
        var row = range.end.row;
        var lineRange = new Range(row, 0, row, range.end.column);
        this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig);

        for (var row = range.start.row + 1; row < range.end.row; row++) {
            lineRange.start.row = row;
            lineRange.end.row = row;
            lineRange.end.column = this.session.getScreenLastRowColumn(row);
            this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1);
        }
    };

    this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) {
        // from selection start to the end of the line
        var height = layerConfig.lineHeight;
        var width = Math.round(layerConfig.width - (range.start.column * layerConfig.characterWidth));
        var top = this.$getTop(range.start.row, layerConfig);
        var left = Math.round(this.$padding +
                              range.start.column * layerConfig.characterWidth);

        stringBuilder.push(
            "

"
        );

        // from start of the last line to the selection end
        top = this.$getTop(range.end.row, layerConfig);
        width = Math.round(range.end.column * layerConfig.characterWidth);

        stringBuilder.push(
            "

"
        );

        // all the complete lines
        height = (range.end.row - range.start.row - 1) * layerConfig.lineHeight;
        if (height < 0)
            return;
        top = this.$getTop(range.start.row + 1, layerConfig);
        width = layerConfig.width;

        stringBuilder.push(
            "

"
        );
    };

    this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig, extraLength) {
        var height = layerConfig.lineHeight;
        var width = Math.round((range.end.column + (extraLength || 0) - range.start.column) * layerConfig.characterWidth);
        var top = this.$getTop(range.start.row, layerConfig);
        var left = Math.round(this.$padding +
                              range.start.column * layerConfig.characterWidth);

        stringBuilder.push(
            "

"
        );
    };

}).call(Marker.prototype);

exports.Marker = Marker;

});
<|endoftext|>


<commit_before>import Ember from 'ember';
import flatten from './utils/flatten';

function isRelationshipManaged(relationship){
    return relationship.relationshipMeta.options.managed;
}

export default Ember.Mixin.create({
    /* Public API changes */
    isDirty: Ember.computed('hasDirtyAttributes', '_hasDirtyRelationships', function(){
        return this.get('hasDirtyAttributes') || this.get('_hasDirtyRelationships');
    }),

    rollback(){
        if (this.get('hasDirtyAttributes')){
            this.rollbackAttributes();
        }
        if (this.get('_hasDirtyRelationships')){
            this._rollbackRelationships();
        }
    },

    save(...args){
        return this._super(...args).then( savedModel => {
            savedModel._commitModelAndManagedRelationships();
            return savedModel;
        })
    },

    /* private API */

    _commitModelAndManagedRelationships(commitThisModel = false){
        if (commitThisModel){
        	this._internalModel.adapterWillCommit();
            this._internalModel.adapterDidCommit();
            this._internalModel.flushChangedAttributes();
        }

        this.eachRelationship((name, relationship) => {
            if (relationship.options.managed){
                if (relationship.kind == 'hasMany'){
                    this._commitManagedHasMany(name);
                } else if (relationship.kind =='belongsTo'){
                    this._commitManagedBelongsTo(name);

                } else {
                    throw new Error(`this relationship type is not supported ${relationship.kind}`);
                }
            }
        });
    },

    _commitManagedBelongsTo(name){
        let currentValue = this.get(name).content;
        if (currentValue && currentValue._commitModelAndManagedRelationships){
            currentValue._commitModelAndManagedRelationships(true);
        }
    },

    _commitManagedHasMany(name){
        let currentValue = this.get(name).content;
        if (currentValue){
            currentValue.toArray().forEach((model) => {
                if (model && model._commitModelAndManagedRelationships){
                    model._commitModelAndManagedRelationships(true)
                }
            });
        }

    },

    _rollbackRelationships(){
        this.eachRelationship((name, relationship) => {
            if (relationship.options.referenced  || relationship.options.managed){
                if (relationship.kind == 'hasMany'){
                    this._rollbackHasManyRelation(name);
                } else if (relationship.kind =='belongsTo'){
                    this._rollbackBelongsToRelation(name);

                } else {
                    throw new Error(`this relationship type is not supported ${relationship.kind}`);
                }
            }
        });
    },

    _rollbackBelongsToRelation(name){
        let relationship = this.belongsTo(name).belongsToRelationship;
        if (relationship.hasLoaded && this._isBelongsToDirty(relationship)){
            let originalValue = null;
            if (relationship.canonicalState){
                originalValue = this.store.peekRecord(relationship.canonicalState.modelName, relationship.canonicalState.id);
            }

            let currentValue = this.get(name).content;
            this.set(name, originalValue);

            if (originalValue && isRelationshipManaged(relationship) && originalValue.get('isDirty')){
                originalValue.rollback();
            }
        }
    },

    _rollbackHasManyRelation(name){
        let relationship = this.hasMany(name).hasManyRelationship;

        let currentValue = Ember.A(this.get(relationship.key).content);

        currentValue.clear();

        if (relationship.isPolymorphic){
            let originalValueIdsAndTypes = Ember.A(relationship.canonicalState.map(m => {
                return { id: m.id, type:m.modelName }
            }));
            originalValueIdsAndTypes.forEach((e) => {
                currentValue.addObject(this.store.peekRecord(e.type, e.id));
            })
        } else {
            let originalValueIds = Ember.A(relationship.canonicalState.map(m => m.id));

            currentValue.addObjects(this.store.peekAll(relationship.belongsToType).filter(model => {
                return originalValueIds.contains(model.id)
            }));
        }

        if (isRelationshipManaged(relationship)){
            currentValue.forEach( model => {
                if (model.get('isDirty')){
                    model.rollback();
                }
            })
        }
    },

    _defineRelationshipComputedProperty: Ember.on('init', function(){
        const related = Ember.A();

        this.eachRelationship((name, relationship) => {
            if (relationship.options.referenced || relationship.options.managed){
                if (!relationship.options.async){
                    throw new Error('Managed relationships mixin works only with async relationships');
                }

                let relationshipData = {
                    name: name,
                    kind: relationship.kind,
                    managed: Boolean(relationship.options.managed)
                }

                if (relationship.kind == 'hasMany'){
                    relationshipData.keys = [`${name}.[]`];

                    if (relationshipData.managed){
                        relationshipData.keys.push(`${name}.@each.isDirty`);
                    }

                } else if (relationship.kind =='belongsTo'){
                    relationshipData.keys = [name];

                    if (relationshipData.managed){
                        relationshipData.keys.push(`${name}.isDirty`);
                    }

                } else {
                    throw new Error(`this relationship type is not supported ${relationship.kind}`);
                }
                related.addObject(relationshipData);
            }
        });

        if (!Ember.isEmpty(related)){
            Ember.defineProperty(this, '_hasDirtyRelationships', Ember.computed.apply(null, [...flatten(related.mapBy('keys')), function(){
                return this._isAtLeastOneBelongsToDirty(related) || this._isAtLeastOneHasManyDirty(related);
            }]));
        }
    }),

    _isAtLeastOneBelongsToDirty(relationships){
        let belongsTos = relationships.filterBy('kind', 'belongsTo');
        let belongsToRelations = belongsTos.map((r) => this.belongsTo(r.name).belongsToRelationship);

        //We filter out the ones which are not loaded yet, because there cannot be a change from the user side
        let belongsToLoadedRelations = Ember.A(belongsToRelations).filterBy('hasLoaded', true);

        return Ember.A(belongsToLoadedRelations).any((relation) => this._isBelongsToDirty(relation));
    },

    _isAtLeastOneHasManyDirty(relationships){
        let hasManys = relationships.filterBy('kind', 'hasMany');
        let hasManyRelations = hasManys.map((r) => this.hasMany(r.name).hasManyRelationship);

        //We filter out the ones which are not loaded yet, because there cannot be a change from the user side
        let hasManyLoadedRelations = Ember.A(hasManyRelations).filterBy('hasLoaded', true);

        return Ember.A(hasManyLoadedRelations).any((relation) => this._isHasManyDirty(relation));

    },

    _isBelongsToDirty(belongsToRelationship){
        //Working just on async relations
        let currentValue = this.get(belongsToRelationship.key).content;

        function isReferenceChanged(){
            if (belongsToRelationship.canonicalState){
                return !currentValue || belongsToRelationship.canonicalState.id !== currentValue.get('id') ;
            } else {
                return Boolean(currentValue);
            }
        }

        function isTheManegedEntityDirty(){
            if (!currentValue){
                return false;
            }
            return currentValue.get('isDirty');
        }

        return isRelationshipManaged(belongsToRelationship) ? isReferenceChanged() || isTheManegedEntityDirty() : isReferenceChanged();
    },

    _isHasManyDirty(hasManyRelationship){
        //Working just on async relations
        let currentValue = this.get(hasManyRelationship.key).content;

        function isReferenceChanged(){
            return hasManyRelationship.canonicalState.length !== currentValue.length || Ember.A(hasManyRelationship.canonicalState).any((e, i) => e === currentValue[i]);
        }

        function isTheManegedEntityDirty(){
            return currentValue.any(model => model.get('isDirty') );
        }
        return isRelationshipManaged(hasManyRelationship) ? isReferenceChanged() || isTheManegedEntityDirty() : isReferenceChanged();

    },
});
<commit_msg>making sure that changed attrs are flushed after the changes are commited<commit_after>import Ember from 'ember';
import flatten from './utils/flatten';

function isRelationshipManaged(relationship){
    return relationship.relationshipMeta.options.managed;
}

export default Ember.Mixin.create({
    /* Public API changes */
    isDirty: Ember.computed('hasDirtyAttributes', '_hasDirtyRelationships', function(){
        return this.get('hasDirtyAttributes') || this.get('_hasDirtyRelationships');
    }),

    rollback(){
        if (this.get('hasDirtyAttributes')){
            this.rollbackAttributes();
        }
        if (this.get('_hasDirtyRelationships')){
            this._rollbackRelationships();
        }
    },

    save(...args){
        return this._super(...args).then( savedModel => {
            savedModel._commitModelAndManagedRelationships();
            return savedModel;
        })
    },

    /* private API */

    _commitModelAndManagedRelationships(commitThisModel = false){
        if (commitThisModel){
        	this._internalModel.adapterWillCommit();
            this._internalModel.updateChangedAttributes();
            this._internalModel.adapterDidCommit();
        }

        this.eachRelationship((name, relationship) => {
            if (relationship.options.managed){
                if (relationship.kind == 'hasMany'){
                    this._commitManagedHasMany(name);
                } else if (relationship.kind =='belongsTo'){
                    this._commitManagedBelongsTo(name);

                } else {
                    throw new Error(`this relationship type is not supported ${relationship.kind}`);
                }
            }
        });
    },

    _commitManagedBelongsTo(name){
        let currentValue = this.get(name).content;
        if (currentValue && currentValue._commitModelAndManagedRelationships){
            currentValue._commitModelAndManagedRelationships(true);
        }
    },

    _commitManagedHasMany(name){
        let currentValue = this.get(name).content;
        if (currentValue){
            currentValue.toArray().forEach((model) => {
                if (model && model._commitModelAndManagedRelationships){
                    model._commitModelAndManagedRelationships(true)
                }
            });
        }

    },

    _rollbackRelationships(){
        this.eachRelationship((name, relationship) => {
            if (relationship.options.referenced  || relationship.options.managed){
                if (relationship.kind == 'hasMany'){
                    this._rollbackHasManyRelation(name);
                } else if (relationship.kind =='belongsTo'){
                    this._rollbackBelongsToRelation(name);

                } else {
                    throw new Error(`this relationship type is not supported ${relationship.kind}`);
                }
            }
        });
    },

    _rollbackBelongsToRelation(name){
        let relationship = this.belongsTo(name).belongsToRelationship;
        if (relationship.hasLoaded && this._isBelongsToDirty(relationship)){
            let originalValue = null;
            if (relationship.canonicalState){
                originalValue = this.store.peekRecord(relationship.canonicalState.modelName, relationship.canonicalState.id);
            }

            let currentValue = this.get(name).content;
            this.set(name, originalValue);

            if (originalValue && isRelationshipManaged(relationship) && originalValue.get('isDirty')){
                originalValue.rollback();
            }
        }
    },

    _rollbackHasManyRelation(name){
        let relationship = this.hasMany(name).hasManyRelationship;

        let currentValue = Ember.A(this.get(relationship.key).content);

        currentValue.clear();

        if (relationship.isPolymorphic){
            let originalValueIdsAndTypes = Ember.A(relationship.canonicalState.map(m => {
                return { id: m.id, type:m.modelName }
            }));
            originalValueIdsAndTypes.forEach((e) => {
                currentValue.addObject(this.store.peekRecord(e.type, e.id));
            })
        } else {
            let originalValueIds = Ember.A(relationship.canonicalState.map(m => m.id));

            currentValue.addObjects(this.store.peekAll(relationship.belongsToType).filter(model => {
                return originalValueIds.contains(model.id)
            }));
        }

        if (isRelationshipManaged(relationship)){
            currentValue.forEach( model => {
                if (model.get('isDirty')){
                    model.rollback();
                }
            })
        }
    },

    _defineRelationshipComputedProperty: Ember.on('init', function(){
        const related = Ember.A();

        this.eachRelationship((name, relationship) => {
            if (relationship.options.referenced || relationship.options.managed){
                if (!relationship.options.async){
                    throw new Error('Managed relationships mixin works only with async relationships');
                }

                let relationshipData = {
                    name: name,
                    kind: relationship.kind,
                    managed: Boolean(relationship.options.managed)
                }

                if (relationship.kind == 'hasMany'){
                    relationshipData.keys = [`${name}.[]`];

                    if (relationshipData.managed){
                        relationshipData.keys.push(`${name}.@each.isDirty`);
                    }

                } else if (relationship.kind =='belongsTo'){
                    relationshipData.keys = [name];

                    if (relationshipData.managed){
                        relationshipData.keys.push(`${name}.isDirty`);
                    }

                } else {
                    throw new Error(`this relationship type is not supported ${relationship.kind}`);
                }
                related.addObject(relationshipData);
            }
        });

        if (!Ember.isEmpty(related)){
            Ember.defineProperty(this, '_hasDirtyRelationships', Ember.computed.apply(null, [...flatten(related.mapBy('keys')), function(){
                return this._isAtLeastOneBelongsToDirty(related) || this._isAtLeastOneHasManyDirty(related);
            }]));
        }
    }),

    _isAtLeastOneBelongsToDirty(relationships){
        let belongsTos = relationships.filterBy('kind', 'belongsTo');
        let belongsToRelations = belongsTos.map((r) => this.belongsTo(r.name).belongsToRelationship);

        //We filter out the ones which are not loaded yet, because there cannot be a change from the user side
        let belongsToLoadedRelations = Ember.A(belongsToRelations).filterBy('hasLoaded', true);

        return Ember.A(belongsToLoadedRelations).any((relation) => this._isBelongsToDirty(relation));
    },

    _isAtLeastOneHasManyDirty(relationships){
        let hasManys = relationships.filterBy('kind', 'hasMany');
        let hasManyRelations = hasManys.map((r) => this.hasMany(r.name).hasManyRelationship);

        //We filter out the ones which are not loaded yet, because there cannot be a change from the user side
        let hasManyLoadedRelations = Ember.A(hasManyRelations).filterBy('hasLoaded', true);

        return Ember.A(hasManyLoadedRelations).any((relation) => this._isHasManyDirty(relation));

    },

    _isBelongsToDirty(belongsToRelationship){
        //Working just on async relations
        let currentValue = this.get(belongsToRelationship.key).content;

        function isReferenceChanged(){
            if (belongsToRelationship.canonicalState){
                return !currentValue || belongsToRelationship.canonicalState.id !== currentValue.get('id') ;
            } else {
                return Boolean(currentValue);
            }
        }

        function isTheManegedEntityDirty(){
            if (!currentValue){
                return false;
            }
            return currentValue.get('isDirty');
        }

        return isRelationshipManaged(belongsToRelationship) ? isReferenceChanged() || isTheManegedEntityDirty() : isReferenceChanged();
    },

    _isHasManyDirty(hasManyRelationship){
        //Working just on async relations
        let currentValue = this.get(hasManyRelationship.key).content;

        function isReferenceChanged(){
            return hasManyRelationship.canonicalState.length !== currentValue.length || Ember.A(hasManyRelationship.canonicalState).any((e, i) => e === currentValue[i]);
        }

        function isTheManegedEntityDirty(){
            return currentValue.any(model => model.get('isDirty') );
        }
        return isRelationshipManaged(hasManyRelationship) ? isReferenceChanged() || isTheManegedEntityDirty() : isReferenceChanged();

    },
});
<|endoftext|>


<commit_before>import React from 'react';
import {NavigationLink} from 'navigation-react';
import Banner from './Banner';
import Tweets from './Tweets';

export default ({timeline: {id, name, username, logo, bio,
  followers, following, tweets}, stateNavigator}) => {
  var container;
  return (

 container = el}>
      <Banner title={name} stateNavigator={stateNavigator} />

{name}

{username}

{bio}

{following.toLocaleString()}

Following

{followers.toLocaleString()}

Followers

      <Tweets
        tweets={tweets}
        onTimeline={(e, accountId) => {
          if (accountId === id) {
            e.preventDefault();
            container.closest('.scene').scrollTop = 0;
          }
          return accountId !== id;
        }}
        stateNavigator={stateNavigator} />

  );
};

<commit_msg>Replaced ref with event target<commit_after>import React from 'react';
import {NavigationLink} from 'navigation-react';
import Banner from './Banner';
import Tweets from './Tweets';

export default ({timeline: {id, name, username, logo, bio,
  followers, following, tweets}, stateNavigator}) => (

    <Banner title={name} stateNavigator={stateNavigator} />

{name}

{username}

{bio}

{following.toLocaleString()}

Following

{followers.toLocaleString()}

Followers

    <Tweets
      tweets={tweets}
      onTimeline={(e, accountId) => {
        if (accountId === id) {
          e.preventDefault();
          e.target.closest('.scene').scrollTop = 0;
        }
        return accountId !== id;
      }}
      stateNavigator={stateNavigator} />

);

<|endoftext|>


<commit_before>'use strict';

$(function() {
    $('body').on('new_message', function() {
        var unread_page = false;
        if (hm_page_name() == 'message_list' && hm_list_path() == 'unread') {
            unread_page = true;
        }
        if (!document.hidden && unread_page) {
            return;
        }
        var current = $('.total_unread_count').text()*1;
        var past = Hm_Message_List.past_total;
        if (current == past || current < past) {
            return;
        }
        var content;
        if (unread) {
            content = Hm_Message_List.just_inserted.reverse().join("\n");
        }
        else {
            content = globals.Hm_Background_Unread.just_inserted.reverse().join("\n");
        }
        Push.create("New Message", {
            body: content,
            timeout: 10000,
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAIBJREFUWIXtlkEOgCAMBEdfpj/Hl+FB8GBiWoqEg7sJt7YzTXoAlL9nAfJMgXUmXAJVYAeOCeyjsO9sQOI6ypEvFdZrRomY4FEiJtgqiIp45zY3fAWu9d0Devu6N4mCTYHw9TrBboFWES+4WcASaQWHBZ4iUXAGsv4DEpCABBTlBOkR5VdJRFCfAAAAAElFTkSuQmCC',
            onClick: function () { window.focus(); this.close(); }
        });
    });
});
<commit_msg>typo fix in desktop notification module set<commit_after>'use strict';

$(function() {
    $('body').on('new_message', function() {
        var unread_page = false;
        if (hm_page_name() == 'message_list' && hm_list_path() == 'unread') {
            unread_page = true;
        }
        if (!document.hidden && unread_page) {
            return;
        }
        var current = $('.total_unread_count').text()*1;
        var past = Hm_Message_List.past_total;
        if (current == past || current < past) {
            return;
        }
        var content;
        if (unread_page) {
            content = Hm_Message_List.just_inserted.reverse().join("\n");
        }
        else {
            content = globals.Hm_Background_Unread.just_inserted.reverse().join("\n");
        }
        Push.create("New Message", {
            body: content,
            timeout: 10000,
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAIBJREFUWIXtlkEOgCAMBEdfpj/Hl+FB8GBiWoqEg7sJt7YzTXoAlL9nAfJMgXUmXAJVYAeOCeyjsO9sQOI6ypEvFdZrRomY4FEiJtgqiIp45zY3fAWu9d0Devu6N4mCTYHw9TrBboFWES+4WcASaQWHBZ4iUXAGsv4DEpCABBTlBOkR5VdJRFCfAAAAAElFTkSuQmCC',
            onClick: function () { window.focus(); this.close(); }
        });
    });
});
<|endoftext|>


<commit_before>// Modules to paths
module.exports = {
  constants: {
    EventTypes: 'EventTypes',
    FrameworkConstants: 'FrameworkConstants',
    HTTPStatusCodes: 'HTTPStatusCodes'
  },
  events: {
    SidebarActions: 'SidebarActions'
  },
  stores: {
    AuthStore: 'AuthStore',
    BaseStore: 'BaseStore',
    ConfigStore: 'ConfigStore',
    MetadataStore: 'MetadataStore',
    NotificationStore: 'NotificationStore',
    UsersStore: 'UsersStore',
    UserStore: 'UserStore',
    VisibilityStore: 'VisibilityStore'
  },
  structs: {
    CompositeState: 'CompositeState',
    Item: 'Item',
    List: 'List',
    Tree: 'Tree'
  },
  utils: {
    CookieUtils: 'CookieUtils',
    DateUtil: 'DateUtil',
    DOMUtils: 'DOMUtils',
    LocalStorageUtil: 'LocalStorageUtil',
    Maths: 'Maths',
    ResourceTableUtil: 'ResourceTableUtil',
    StoreMixinConfig: 'StoreMixinConfig',
    StringUtil: 'StringUtil',
    TableUtil: 'TableUtil',
    TabsUtil: 'TabsUtil',
    Units: 'Units',
    Util: 'Util'
  },
  mixins: {
    InternalStorageMixin: 'InternalStorageMixin',
    TabsMixin: 'TabsMixin'
  },
  components: {
    AccessDeniedPage: 'AccessDeniedPage',
    ActionsModal: 'modals/ActionsModal',
    AlertPanel: 'AlertPanel',
    Authenticated: 'Authenticated',
    Breadcrumbs: 'Breadcrumbs',
    Chart: 'charts/Chart',
    CheckboxTable: 'CheckboxTable',
    ClipboardTrigger: 'ClipboardTrigger',
    ClusterHeader: 'ClusterHeader',
    ClusterName: 'ClusterName',
    DCOSLogo: 'DCOSLogo',
    DescriptionList: 'DescriptionList',
    FilterBar: 'FilterBar',
    FilterButtons: 'FilterButtons',
    FilterHeadline: 'FilterHeadline',
    FilterInputText: 'FilterInputText',
    FormModal: 'FormModal',
    IconInfo: 'icons/IconInfo',
    MesosphereLogo: 'icons/MesosphereLogo',
    NestedServiceLinks: 'NestedServiceLinks',
    Page: 'Page',
    PageHeader: 'PageHeader',
    RequestErrorMsg: 'RequestErrorMsg',
    SidePanelContents: 'SidePanelContents',
    ToggleButton: 'ToggleButton'
  },
  config: {
    Config: 'Config'
  }
};
<commit_msg>Expose progressbar<commit_after>// Modules to paths
module.exports = {
  constants: {
    EventTypes: 'EventTypes',
    FrameworkConstants: 'FrameworkConstants',
    HTTPStatusCodes: 'HTTPStatusCodes'
  },
  events: {
    SidebarActions: 'SidebarActions'
  },
  stores: {
    AuthStore: 'AuthStore',
    BaseStore: 'BaseStore',
    ConfigStore: 'ConfigStore',
    MetadataStore: 'MetadataStore',
    NotificationStore: 'NotificationStore',
    UsersStore: 'UsersStore',
    UserStore: 'UserStore',
    VisibilityStore: 'VisibilityStore'
  },
  structs: {
    CompositeState: 'CompositeState',
    Item: 'Item',
    List: 'List',
    Tree: 'Tree'
  },
  utils: {
    CookieUtils: 'CookieUtils',
    DateUtil: 'DateUtil',
    DOMUtils: 'DOMUtils',
    LocalStorageUtil: 'LocalStorageUtil',
    Maths: 'Maths',
    ResourceTableUtil: 'ResourceTableUtil',
    StoreMixinConfig: 'StoreMixinConfig',
    StringUtil: 'StringUtil',
    TableUtil: 'TableUtil',
    TabsUtil: 'TabsUtil',
    Units: 'Units',
    Util: 'Util'
  },
  mixins: {
    InternalStorageMixin: 'InternalStorageMixin',
    TabsMixin: 'TabsMixin'
  },
  components: {
    AccessDeniedPage: 'AccessDeniedPage',
    ActionsModal: 'modals/ActionsModal',
    AlertPanel: 'AlertPanel',
    Authenticated: 'Authenticated',
    Breadcrumbs: 'Breadcrumbs',
    Chart: 'charts/Chart',
    CheckboxTable: 'CheckboxTable',
    ClipboardTrigger: 'ClipboardTrigger',
    ClusterHeader: 'ClusterHeader',
    ClusterName: 'ClusterName',
    DCOSLogo: 'DCOSLogo',
    DescriptionList: 'DescriptionList',
    FilterBar: 'FilterBar',
    FilterButtons: 'FilterButtons',
    FilterHeadline: 'FilterHeadline',
    FilterInputText: 'FilterInputText',
    FormModal: 'FormModal',
    IconInfo: 'icons/IconInfo',
    MesosphereLogo: 'icons/MesosphereLogo',
    NestedServiceLinks: 'NestedServiceLinks',
    Page: 'Page',
    PageHeader: 'PageHeader',
    ProgressBar: 'charts/ProgressBar',
    RequestErrorMsg: 'RequestErrorMsg',
    SidePanelContents: 'SidePanelContents',
    ToggleButton: 'ToggleButton'
  },
  config: {
    Config: 'Config'
  }
};
<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs');
var _ = require('underscore');

var rjsConf = require('./src/main/webapp/require-conf');

var commentLineExp = /^[\s]*<!-- (\/|#) (CE|EE)/;

function productionFileProcessing(content, srcpath) {
  // removes the template comments
  content = content
            .split('\n').filter(function(line) {
              // console.info(line.slice(0, 10), !commentLineExp.test(line));
              return !commentLineExp.test(line);
            }).join('\n');

  return content;
}

function developmentFileProcessing(content, srcpath) {
  console.log(this, grunt);

  // Unfortunately, this might (in some cases) make angular complaining about template having no single root element (when the "replace" option is set to "true").

  // if (/\.html$/.test(srcpath)) {
  //   content = '<!-- # CE - auto-comment - '+ srcpath +' -->\n'+
  //             content +
  //             '\n<!-- / CE - auto-comment - '+ srcpath +' -->';
  // }

  if (/require-conf.js$/.test(srcpath)) {
    content = content
              .replace(/\/\* live-reload/, '/* live-reload */')
              .replace(/LIVERELOAD_PORT/g, "<%= app.liveReloadPort %>");
  }
  return content;
}

module.exports = function(grunt) {

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  var packageJSON = grunt.file.readJSON('package.json');

  // Project configuration.
  grunt.initConfig({
    pkg: packageJSON,

    app: {
      port: parseInt(process.env.APP_PORT || 8080, 10),
      liveReloadPort: parseInt(process.env.LIVERELOAD_PORT || 8081, 10)
    },

    clean: {
      target: [
        'target/webapp'
      ],
      assets: [
        'target/webapp/assets'
      ]
    },

    copy: {
      development: {
        files: [
          {
            expand: true,
            cwd: 'src/main/webapp/WEB-INF',
            src: ['*'],
            dest: 'target/webapp/WEB-INF'
          },
          {
            expand: true,
            cwd: 'src/main/webapp/',
            src: [
              'require-conf.js',
              'index.html'
            ],
            dest: 'target/webapp/'
          },
          {
            expand: true,
            cwd: 'src/main/webapp/',
            src: [
              '{app,plugin,develop,common}/{,**/}*.{js,html}'
            ],
            dest: 'target/webapp/'
          }
        ],
        options: {
          process: function(content, srcpath) {

            var liveReloadPort = grunt.config('app.liveReloadPort');

            return content
              .replace(/\/\* live-reload/, '/* live-reload */')
              .replace(/LIVERELOAD_PORT/g, liveReloadPort);
          }
        }
      },
      production: {
        files: [
          {
            expand: true,
            cwd: 'src/main/webapp/WEB-INF',
            src: ['*'],
            dest: 'target/webapp/WEB-INF'
          },
          {
            expand: true,
            cwd: 'src/main/webapp/',
            src: [
              'require-conf.js',
              'index.html'
            ],
            dest: 'target/webapp/'
          },
          {
            expand: true,
            cwd: 'src/main/webapp/',
            src: [
              '{app,plugin,develop,common}/{,**/}*.{js,html}'
            ],
            dest: 'target/webapp/'
          }
        ],
        options: {
          process: productionFileProcessing
        }
      },

      // for now, copy as development, but leave the livereload comment
      production: {
        files: [
          {
            expand: true,
            cwd: 'src/main/webapp/WEB-INF',
            src: ['*'],
            dest: 'target/webapp/WEB-INF'
          },
          {
            expand: true,
            cwd: 'src/main/webapp/',
            src: [
              'require-conf.js',
              'index.html'
            ],
            dest: 'target/webapp/'
          },
          {
            expand: true,
            cwd: 'src/main/webapp/',
            src: [
              '{app,plugin,develop,common}/{,**/}*.{js,html}'
            ],
            dest: 'target/webapp/'
          }
        ]
      },

      assets: {
        files: [
          // requirejs
          {
            src: 'src/main/webapp/assets/vendor/requirejs/index.js',
            dest: 'target/webapp/assets/vendor/requirejs/require.js'
          },
          // others
          {
            expand: true,
            cwd: 'src/main/webapp/assets',
            src: [
              '!vendor/requirejs/**/*',
              'css/**/*',
              'img/**/*',
              'vendor/**/*.{js,css,jpg,png,gif,html,eot,ttf,svg,woff}'
            ],
            dest: 'target/webapp/assets'
          }
        ]
      },

      // TODO: remove that when using less
      css: {
        files: [
          {
            expand: true,
            cwd: 'src/main/webapp/assets',
            src: [
              'css/**/*'
            ],
            dest: 'target/webapp/assets'
          }
        ]
      }
    },

    watch: {
      options: {
        livereload: false
      },

      // watch for source script changes
      scripts: {
        files: [
          'src/main/webapp/require-conf.js',
          'src/main/webapp/{app,develop,plugin,common}/**/*.{js,html}'
        ],
        tasks: [
          // 'jshint:scripts',
          'newer:copy:development'
          // 'copy:development'
        ]
      },

      // watch for source script and test changes
      // QUESTION:
      // Does that entry make sense?
      // We can use `karma:unit` and `karma:e2e` instead of watching
      // tests: {
      //   files: [
      //     'src/main/webapp/require-conf.js',
      //     'src/main/webapp/{app,develop,plugin,common}/**/*.{js,html}',
      //     'src/test/js/{config,e2e,test,unit}/{,**/}*.js'
      //   ],
      //   tasks: [
      //     // 'jshint:test',
      //     // we use the CI versions (who are runned only once)
      //     // 'karma:testOnce',
      //     'karma:unitOnce',
      //     'karma:e2eOnce'
      //   ]
      // },

      // TODO: add that when using less
      // styles: {
      //   files: [
      //     'src/main/webapp/styles/{**/,}*.less'
      //   ],
      //   tasks: [
      //     'newer:less:development'
      //   ]
      // },

      // TODO: remove that when using less
      css: {
        files: [
          'src/main/webapp/assets/css/**/*.css'
        ],
        tasks: [
          'newer:copy:css'
          // 'copy:css'
        ]
      },

      servedAssets: {
        options: {
          livereload: '<%= app.liveReloadPort %>'
        },
        files: [
          'target/webapp/assets/{css,img}/**/*.{css,jpg,png,html}',
          'target/webapp/{app,plugin,develop}/**/*.{css,js,html,jpg,png}'
        ],
        tasks: []
      }
    },

    // jshint: {
    //   options: {
    //     browser: true,
    //     globals: {
    //       angular: true,
    //       jQuery: true
    //     }
    //   },
    //   test: {
    //     files: {
    //       src: [
    //         'test/js/{config,e2e,unit}/{,**/}*.js'
    //       ]
    //     }
    //   },
    //   scripts: {
    //     files: {
    //       src: [
    //         'Gruntfile.js',
    //         'src/main/webapp/{app,assets,develop,plugin}/{,**/}*.js'
    //       ]
    //     }
    //   }
    // },

    // karma: {
    //   options: {
    //     browsers: ['Chrome', 'Firefox']//, 'IE']
    //   },

    //   // to test the testing environment
    //   test: {
    //     configFile: 'src/test/js/config/karma.test.js'
    //   },

    //   unit: {
    //     configFile: 'src/test/js/config/karma.unit.js'
    //   },
    //   e2e: {
    //     configFile: 'src/test/js/config/karma.e2e.js'
    //   },

    //   //continuous integration mode: run tests once in PhantomJS browser.
    //   unitOnce: {
    //     singleRun: true,
    //     autoWatch: false,
    //     configFile: 'src/test/js/config/karma.unit.js',
    //     browsers: ['PhantomJS']
    //   },
    //   e2eOnce: {
    //     singleRun: true,
    //     autoWatch: false,
    //     configFile: 'src/test/js/config/karma.e2e.js',
    //     browsers: ['PhantomJS']
    //   }
    // },

    jsdoc : {
      dist : {
        src: [
          'src/main/webapp/require-conf.js',
          'src/main/webapp/app',
          'src/main/webapp/develop',
          'src/main/webapp/plugin'
        ],
        options: {
          configure: './jsdoc-conf.json',
          destination: 'doc'
        }
      }
    },

    bower: {
      install: {}
    },

    requirejs: {
    // ngr: {
      // see https://github.com/jrburke/r.js/blob/master/build/example.build.js
      options: {
        baseUrl: 'src/main/webapp',

        dir: 'target/webapp',

        // Inlines the text for any text! dependencies, to avoid the separate
        // async XMLHttpRequest calls to load those dependencies.
        inlineText: true,

        optimize: 'none',

        paths: rjsConf.paths,
        shim: rjsConf.shim,

        // CommonJS packages support
        // http://requirejs.org/docs/api.html#packages
        packages: rjsConf.packages,

        //
        optimizeCss: 'none'
      },

      app: {
        modules: [{
          name: 'src/main/webapp/app/app',
          out: 'app/app.js',
          override: {},
          exclude: [
            'ngDefine'
          ]
        }]
      },

      admin: {
        modules: [{
          name: 'app/admin/admin',
          out: 'app/admin.min.js',
          override: {},
          exclude: []
        }]
      },

      cockpit: {
        modules: [
          {
            name: 'app/cockpit/cockpit',
            out: 'app/cockpit.min.js',
            override: {},
            exclude: []
          }
        ]
      },

      tasklist: {
        modules: [{
          name: 'src/main/webapp/app/tasklist/tasklist',
          out: 'app/tasklist.js',
          override: {},
          exclude: []
        }]
      }
    },

    open: {
      server: {
        url: 'http://localhost:<%= app.port %>/camunda'
      }
    },

    // less: {
    //   options: {
    //     // paths: []
    //   },

    //   production: {
    //     options: {
    //       cleancss: true
    //     },
    //     files: {
    //       'target/webapp/assets/css/common.css': 'src/main/webapp/styles/common.less',
    //       'target/webapp/assets/css/cockpit/loader.css': 'src/main/webapp/styles/cockpit/loader.less',
    //       'target/webapp/assets/css/admin/loader.css': 'src/main/webapp/styles/admin/loader.less',
    //       'target/webapp/assets/css/tasklist/loader.css': 'src/main/webapp/styles/tasklist/loader.less'
    //     }
    //   },

    //   development: {
    //     files: {
    //       'target/webapp/assets/css/common.css': 'src/main/webapp/styles/common.less',
    //       'target/webapp/assets/css/cockpit/loader.css': 'src/main/webapp/styles/cockpit/loader.less',
    //       'target/webapp/assets/css/admin/loader.css': 'src/main/webapp/styles/admin/loader.less',
    //       'target/webapp/assets/css/tasklist/loader.css': 'src/main/webapp/styles/tasklist/loader.less'
    //     }
    //   }
    // }
  });

  // custom task for ngDefine minification
  grunt.registerMultiTask('ngr', 'Minifies the angular related scripts', function() {
    var done = this.async();
    var ngr = require('requirejs-angular-define/src/ngr');

    var setup = _.extend({}, this.options(), this.data);
    // console.info('ngr options', setup);

    ngr.optimize(setup, function() {
      console.info('optimized', arguments.length);
      done();
    }, function(e) {
      console.log('Error during minify: ', e);
      done(new Error('With failures: ' + e));
    });
  });

  // automatically (re-)build web assets
  grunt.registerTask('auto-build', 'Continuously (re-)build front-end assets', function (target) {

    if (target === 'dist') {
      throw new Error('dist target not yet supported');
    }

    grunt.task.run([
      'build',
      'open',
      'watch'
    ]);
  });

  // Aimed to hold more complex build processes
  grunt.registerTask('build', 'Build the frontend assets', function(target) {
    var defaultTasks = [
      'clean',
      'bower'
    ];

    if (target === 'dist') {
      // TODO: minification using ngr:
      // - Minifaction: https://app.camunda.com/jira/browse/CAM-1667
      // - Bug in ngDefine: https://app.camunda.com/jira/browse/CAM-1713

      return grunt.task.run(defaultTasks.concat([
        'copy:assets',
        'copy:production'
      ]));
    }

    // tasks.push('newer:less:'+ this.target);
    // tasks.push('less:'+ this.target);

    return grunt.task.run(defaultTasks.concat([
      'newer:copy:assets',
      'newer:copy:development'
      // 'copy:assets',
      // 'copy:development'
    ]));
  });

  grunt.registerTask('test', []);

  // Default task(s).
  grunt.registerTask('default', ['build:dist']);
};
<commit_msg>improve(grunt): rewording "production" into "dist"<commit_after>var path = require('path');
var fs = require('fs');
var _ = require('underscore');

var rjsConf = require('./src/main/webapp/require-conf');

var commentLineExp = /^[\s]*<!-- (\/|#) (CE|EE)/;

function distFileProcessing(content, srcpath) {
  // removes the template comments
  content = content
            .split('\n').filter(function(line) {
              // console.info(line.slice(0, 10), !commentLineExp.test(line));
              return !commentLineExp.test(line);
            }).join('\n');

  return content;
}

function developmentFileProcessing(content, srcpath) {
  // Unfortunately, this might (in some cases) make angular complaining
  // about template having no single root element
  // (when the "replace" option is set to "true").

  // if (/\.html$/.test(srcpath)) {
  //   content = '<!-- # CE - auto-comment - '+ srcpath +' -->\n'+
  //             content +
  //             '\n<!-- / CE - auto-comment - '+ srcpath +' -->';
  // }

  if (/require-conf.js$/.test(srcpath)) {
    content = content
              .replace(/\/\* live-reload/, '/* live-reload */')
              .replace(/LIVERELOAD_PORT/g, "<%= app.liveReloadPort %>");
  }
  return content;
}

module.exports = function(grunt) {

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  var packageJSON = grunt.file.readJSON('package.json');

  // Project configuration.
  grunt.initConfig({
    pkg: packageJSON,

    app: {
      port: parseInt(process.env.APP_PORT || 8080, 10),
      liveReloadPort: parseInt(process.env.LIVERELOAD_PORT || 8081, 10)
    },

    clean: {
      target: [
        'target/webapp'
      ],
      assets: [
        'target/webapp/assets'
      ]
    },

    copy: {
      development: {
        files: [
          {
            expand: true,
            cwd: 'src/main/webapp/WEB-INF',
            src: ['*'],
            dest: 'target/webapp/WEB-INF'
          },
          {
            expand: true,
            cwd: 'src/main/webapp/',
            src: [
              'require-conf.js',
              'index.html'
            ],
            dest: 'target/webapp/'
          },
          {
            expand: true,
            cwd: 'src/main/webapp/',
            src: [
              '{app,plugin,develop,common}/{,**/}*.{js,html}'
            ],
            dest: 'target/webapp/'
          }
        ],
        options: {
          process: function(content, srcpath) {

            var liveReloadPort = grunt.config('app.liveReloadPort');

            return content
              .replace(/\/\* live-reload/, '/* live-reload */')
              .replace(/LIVERELOAD_PORT/g, liveReloadPort);
          }
        }
      },
      dist: {
        files: [
          {
            expand: true,
            cwd: 'src/main/webapp/WEB-INF',
            src: ['*'],
            dest: 'target/webapp/WEB-INF'
          },
          {
            expand: true,
            cwd: 'src/main/webapp/',
            src: [
              'require-conf.js',
              'index.html'
            ],
            dest: 'target/webapp/'
          },
          {
            expand: true,
            cwd: 'src/main/webapp/',
            src: [
              '{app,plugin,develop,common}/{,**/}*.{js,html}'
            ],
            dest: 'target/webapp/'
          }
        ],
        options: {
          process: distFileProcessing
        }
      },

      // for now, copy as development, but leave the livereload comment
      dist: {
        files: [
          {
            expand: true,
            cwd: 'src/main/webapp/WEB-INF',
            src: ['*'],
            dest: 'target/webapp/WEB-INF'
          },
          {
            expand: true,
            cwd: 'src/main/webapp/',
            src: [
              'require-conf.js',
              'index.html'
            ],
            dest: 'target/webapp/'
          },
          {
            expand: true,
            cwd: 'src/main/webapp/',
            src: [
              '{app,plugin,develop,common}/{,**/}*.{js,html}'
            ],
            dest: 'target/webapp/'
          }
        ]
      },

      assets: {
        files: [
          // requirejs
          {
            src: 'src/main/webapp/assets/vendor/requirejs/index.js',
            dest: 'target/webapp/assets/vendor/requirejs/require.js'
          },
          // others
          {
            expand: true,
            cwd: 'src/main/webapp/assets',
            src: [
              '!vendor/requirejs/**/*',
              'css/**/*',
              'img/**/*',
              'vendor/**/*.{js,css,jpg,png,gif,html,eot,ttf,svg,woff}'
            ],
            dest: 'target/webapp/assets'
          }
        ]
      },

      // TODO: remove that when using less
      css: {
        files: [
          {
            expand: true,
            cwd: 'src/main/webapp/assets',
            src: [
              'css/**/*'
            ],
            dest: 'target/webapp/assets'
          }
        ]
      }
    },

    watch: {
      options: {
        livereload: false
      },

      // watch for source script changes
      scripts: {
        files: [
          'src/main/webapp/require-conf.js',
          'src/main/webapp/{app,develop,plugin,common}/**/*.{js,html}'
        ],
        tasks: [
          // 'jshint:scripts',
          'newer:copy:development'
          // 'copy:development'
        ]
      },

      // watch for source script and test changes
      // QUESTION:
      // Does that entry make sense?
      // We can use `karma:unit` and `karma:e2e` instead of watching
      // tests: {
      //   files: [
      //     'src/main/webapp/require-conf.js',
      //     'src/main/webapp/{app,develop,plugin,common}/**/*.{js,html}',
      //     'src/test/js/{config,e2e,test,unit}/{,**/}*.js'
      //   ],
      //   tasks: [
      //     // 'jshint:test',
      //     // we use the CI versions (who are runned only once)
      //     // 'karma:testOnce',
      //     'karma:unitOnce',
      //     'karma:e2eOnce'
      //   ]
      // },

      // TODO: add that when using less
      // styles: {
      //   files: [
      //     'src/main/webapp/styles/{**/,}*.less'
      //   ],
      //   tasks: [
      //     'newer:less:development'
      //   ]
      // },

      // TODO: remove that when using less
      css: {
        files: [
          'src/main/webapp/assets/css/**/*.css'
        ],
        tasks: [
          'newer:copy:css'
          // 'copy:css'
        ]
      },

      servedAssets: {
        options: {
          livereload: '<%= app.liveReloadPort %>'
        },
        files: [
          'target/webapp/assets/{css,img}/**/*.{css,jpg,png,html}',
          'target/webapp/{app,plugin,develop}/**/*.{css,js,html,jpg,png}'
        ],
        tasks: []
      }
    },

    // jshint: {
    //   options: {
    //     browser: true,
    //     globals: {
    //       angular: true,
    //       jQuery: true
    //     }
    //   },
    //   test: {
    //     files: {
    //       src: [
    //         'test/js/{config,e2e,unit}/{,**/}*.js'
    //       ]
    //     }
    //   },
    //   scripts: {
    //     files: {
    //       src: [
    //         'Gruntfile.js',
    //         'src/main/webapp/{app,assets,develop,plugin}/{,**/}*.js'
    //       ]
    //     }
    //   }
    // },

    // karma: {
    //   options: {
    //     browsers: ['Chrome', 'Firefox']//, 'IE']
    //   },

    //   // to test the testing environment
    //   test: {
    //     configFile: 'src/test/js/config/karma.test.js'
    //   },

    //   unit: {
    //     configFile: 'src/test/js/config/karma.unit.js'
    //   },
    //   e2e: {
    //     configFile: 'src/test/js/config/karma.e2e.js'
    //   },

    //   //continuous integration mode: run tests once in PhantomJS browser.
    //   unitOnce: {
    //     singleRun: true,
    //     autoWatch: false,
    //     configFile: 'src/test/js/config/karma.unit.js',
    //     browsers: ['PhantomJS']
    //   },
    //   e2eOnce: {
    //     singleRun: true,
    //     autoWatch: false,
    //     configFile: 'src/test/js/config/karma.e2e.js',
    //     browsers: ['PhantomJS']
    //   }
    // },

    jsdoc : {
      dist : {
        src: [
          'src/main/webapp/require-conf.js',
          'src/main/webapp/app',
          'src/main/webapp/develop',
          'src/main/webapp/plugin'
        ],
        options: {
          configure: './jsdoc-conf.json',
          destination: 'doc'
        }
      }
    },

    bower: {
      install: {}
    },

    requirejs: {
    // ngr: {
      // see https://github.com/jrburke/r.js/blob/master/build/example.build.js
      options: {
        baseUrl: 'src/main/webapp',

        dir: 'target/webapp',

        // Inlines the text for any text! dependencies, to avoid the separate
        // async XMLHttpRequest calls to load those dependencies.
        inlineText: true,

        optimize: 'none',

        paths: rjsConf.paths,
        shim: rjsConf.shim,

        // CommonJS packages support
        // http://requirejs.org/docs/api.html#packages
        packages: rjsConf.packages,

        //
        optimizeCss: 'none'
      },

      app: {
        modules: [{
          name: 'src/main/webapp/app/app',
          out: 'app/app.js',
          override: {},
          exclude: [
            'ngDefine'
          ]
        }]
      },

      admin: {
        modules: [{
          name: 'app/admin/admin',
          out: 'app/admin.min.js',
          override: {},
          exclude: []
        }]
      },

      cockpit: {
        modules: [
          {
            name: 'app/cockpit/cockpit',
            out: 'app/cockpit.min.js',
            override: {},
            exclude: []
          }
        ]
      },

      tasklist: {
        modules: [{
          name: 'src/main/webapp/app/tasklist/tasklist',
          out: 'app/tasklist.js',
          override: {},
          exclude: []
        }]
      }
    },

    open: {
      server: {
        url: 'http://localhost:<%= app.port %>/camunda'
      }
    },

    // less: {
    //   options: {
    //     // paths: []
    //   },

    //   dist: {
    //     options: {
    //       cleancss: true
    //     },
    //     files: {
    //       'target/webapp/assets/css/common.css': 'src/main/webapp/styles/common.less',
    //       'target/webapp/assets/css/cockpit/loader.css': 'src/main/webapp/styles/cockpit/loader.less',
    //       'target/webapp/assets/css/admin/loader.css': 'src/main/webapp/styles/admin/loader.less',
    //       'target/webapp/assets/css/tasklist/loader.css': 'src/main/webapp/styles/tasklist/loader.less'
    //     }
    //   },

    //   development: {
    //     files: {
    //       'target/webapp/assets/css/common.css': 'src/main/webapp/styles/common.less',
    //       'target/webapp/assets/css/cockpit/loader.css': 'src/main/webapp/styles/cockpit/loader.less',
    //       'target/webapp/assets/css/admin/loader.css': 'src/main/webapp/styles/admin/loader.less',
    //       'target/webapp/assets/css/tasklist/loader.css': 'src/main/webapp/styles/tasklist/loader.less'
    //     }
    //   }
    // }
  });

  // custom task for ngDefine minification
  grunt.registerMultiTask('ngr', 'Minifies the angular related scripts', function() {
    var done = this.async();
    var ngr = require('requirejs-angular-define/src/ngr');

    var setup = _.extend({}, this.options(), this.data);
    // console.info('ngr options', setup);

    ngr.optimize(setup, function() {
      console.info('optimized', arguments.length);
      done();
    }, function(e) {
      console.log('Error during minify: ', e);
      done(new Error('With failures: ' + e));
    });
  });

  // automatically (re-)build web assets
  grunt.registerTask('auto-build', 'Continuously (re-)build front-end assets', function (target) {

    if (target === 'dist') {
      throw new Error('dist target not yet supported');
    }

    grunt.task.run([
      'build',
      'open',
      'watch'
    ]);
  });

  // Aimed to hold more complex build processes
  grunt.registerTask('build', 'Build the frontend assets', function(target) {
    var defaultTasks = [
      'clean',
      'bower'
    ];

    if (target === 'dist') {
      // TODO: minification using ngr:
      // - Minifaction: https://app.camunda.com/jira/browse/CAM-1667
      // - Bug in ngDefine: https://app.camunda.com/jira/browse/CAM-1713

      return grunt.task.run(defaultTasks.concat([
        'copy:assets',
        'copy:dist'
      ]));
    }

    // tasks.push('newer:less:'+ this.target);
    // tasks.push('less:'+ this.target);

    return grunt.task.run(defaultTasks.concat([
      'newer:copy:assets',
      'newer:copy:development'
      // 'copy:assets',
      // 'copy:development'
    ]));
  });

  grunt.registerTask('test', []);

  // Default task(s).
  grunt.registerTask('default', ['build:dist']);
};
<|endoftext|>


<commit_before>"use strict";

var buffer = require("./buffer");

function Animation() {
	this.frames = [];
	this.frame = 0;
	this.elapsedMillis = 0;
	this.repeatAt = 0;
	this.width = 0;
	this.height = 0;
}
Animation.prototype.add = function(img, time) {
	this.frames.push({img: img, time: time});
	if (this.frames.length === 1) {
		this.width = img.width;
		this.height = img.height;
	}
};
Animation.prototype.step = function() {
	this.frame++;
	if (this.frame >= this.frames.length) {
		this.frame = this.repeatAt;
	}
};
Animation.prototype.move = function(elapsedMillis) {
	this.elapsedMillis += elapsedMillis;
	while (this.elapsedMillis > this.frames[this.frame].time) {
		this.elapsedMillis -= this.frames[this.frame].time;
		this.step();
	}
};
Animation.prototype.draw = function(context, x, y) {
	var img = this.frames[this.frame].img;
	context.drawImage(img, x, y);
};
Animation.prototype.reset = function() {
	this.frame = 0;
	this.elapsedMillis = 0;
};
Animation.prototype.flipHorizontally = function() {
	for (var i = 0; i < this.frames.length; i++) {
		this.frames[i].img = buffer.flipBufferHorizontally(this.frames[i].img);
	}
};
Animation.prototype.flipVertically = function() {
	for (var i = 0; i < this.frames.length; i++) {
		this.frames[i].img = buffer.flipBufferVertically(this.frames[i].img);
	}
};

module.exports = Animation;
<commit_msg>Add Animation docs.<commit_after>"use strict";

var buffer = require("./buffer");

/**
 * An animated picture made of multiple images.
 * @constructor
 */
function Animation() {
	/**
	 * The individual frames making up the animation.
	 * @member {Array}
	 * @private
	 */
	this.frames = [];
	/**
	 * The currently displayed frame of the animation.
	 * @member {number}
	 */
	this.frame = 0;
	/**
	 * How long, in milliseconds, the current frame has been displayed for.
	 * @member {number}
	 * @private
	 */
	this.elapsedMillis = 0;
	/**
	 * The frame at which to restart the animation after the last frame plays. It defaults to 0, so animations loop. If you want to disable looping, set this to the last frame. Otherwise, you can set it to one of the middle frames to have non-repeating introductory frames, while having looping later frames.
	 * @member {number}
	 */
	this.repeatAt = 0;
	/**
	 * The width of the first frame of the animation.
	 * @member {number}
	 * @readonly
	 */
	this.width = 0;
	/**
	 * The height of the first frame of the animation.
	 * @member {number}
	 * @readonly
	 */
	this.height = 0;
}
/**
 * Add a frame to the animation.
 * @param {external:canvas|external:image} img The image to draw for the frame being added.
 * @param {number} time How long, in milliseconds this frame should be displayed in the animation.
 */
Animation.prototype.add = function(img, time) {
	this.frames.push({img: img, time: time});
	if (this.frames.length === 1) {
		this.width = img.width;
		this.height = img.height;
	}
};
/**
 * Advance the animation by a single frame.
 */
Animation.prototype.step = function() {
	this.frame++;
	if (this.frame >= this.frames.length) {
		this.frame = this.repeatAt;
	}
};
/**
 * Advance the animation by a number of milliseconds.
 * @param {number} elapsedMillis How many milliseconds to advance the animation by.
 */
Animation.prototype.move = function(elapsedMillis) {
	this.elapsedMillis += elapsedMillis;
	while (this.elapsedMillis > this.frames[this.frame].time) {
		this.elapsedMillis -= this.frames[this.frame].time;
		this.step();
	}
};
/**
 * Draw the current frame of the animation.
 * @param {external:CanvasRenderingContext2D} context The drawing context.
 * @param {number} x The x coordinate to draw the animation at.
 * @param {number} y The y coordinate to draw the animation at.
 */
Animation.prototype.draw = function(context, x, y) {
	var img = this.frames[this.frame].img;
	context.drawImage(img, x, y);
};
/**
 * Reset the animation to the first frame. This can be useful when you have one piece of code calling {@link Animation#move} each frame, but you want the animation to appear stopped.
 */
Animation.prototype.reset = function() {
	this.frame = 0;
	this.elapsedMillis = 0;
};
/**
 * Flip all frames in the animation horizontally. Useful when you want to use a single set of images for left and right animations.
 */
Animation.prototype.flipHorizontally = function() {
	for (var i = 0; i < this.frames.length; i++) {
		this.frames[i].img = buffer.flipBufferHorizontally(this.frames[i].img);
	}
};
/**
 * Flip all frames in the animation vertically. Useful when you want to use a single set of images for up and down animations.
 */
Animation.prototype.flipVertically = function() {
	for (var i = 0; i < this.frames.length; i++) {
		this.frames[i].img = buffer.flipBufferVertically(this.frames[i].img);
	}
};

module.exports = Animation;
<|endoftext|>


<commit_before>var url = require('url');
var path = require('path');
var request = require('request');
var http = require('http');
var URLValidator = require('valid-url');
var cheerio = require('cheerio');
var Iconv = require('iconv').Iconv;
var characterDetector = require('jschardet');
var base64 = require('js-base64').Base64;

var HTMLConverter = require('./HTMLConverter.js');

var server = http.createServer();

server.on('request', function (req, res) {
    var proxyHost = req.headers.host;
    var proxyURL = req.url;
	var forwardURL = getForwardURL(proxyURL, req.headers.referer);

    if (forwardURL) {
        bypass(req, res, proxyHost, forwardURL);
    } else {
        res.writeHead(404);
        res.end('114514');
    }

});

function getForwardURL(proxyURL, referer) {
    if (typeof proxyURL != 'string') return null;

    var forwardURL = (function () {
        var forwardURL = proxyURL.substr(1);
        if (forwardURL.match(/\./g)) return forwardURL;

        var exclamationIndex = forwardURL.indexOf('?');
        if (exclamationIndex == -1) return base64.decode(forwardURL);

        return base64.decode(forwardURL.substr(0, exclamationIndex)) + forwardURL.substr(exclamationIndex);
    })();

    if (referer) {
        if (forwardURL.substr(0, 4) != 'http') {
            var refererObject = url.parse(referer);
            var refererURL = base64.decode(refererObject.path.substr(1));
            refererObject = url.parse(refererURL);
            forwardURL = url.resolve(refererObject.protocol + '//' + refererObject.host, forwardURL);
        }
    }

    if (URLValidator.isWebUri(forwardURL)) return forwardURL;

    return null;
}

function bypass(req, res, proxyHost, forwardURL) {

    var forward = request({ uri: forwardURL, gzip: true}, function (err, respo, body) {
        console.log(respo.body);
    });

    forward.on('response', function (response) {
        if (res.headersSent) {
            forwardResponse.pipe(res);
            return;
        }

        for (var name in response.headers) {
            res.setHeader(name, response.headers[name]);
        }
        res.setHeader('Access-Control-Allow-Origin', '*');
        res.setHeader('Content-Security-Policy', 'connect-src *');
        res.setHeader('Content-Encoding', 'utf-8');

        var contentType = response.headers['content-type'] || '';
        var htmlConverter = HTMLConverter(proxyHost, forwardURL);
        if (contentType.match('text/html')) {
            response.pipe(htmlConverter).pipe(res);
        }
        else response.pipe(res);
    });

    forward.on('error', function (err) {
        console.log(err);
    });

    req.pipe(forward);
}

var clientCodes = require('./clientCodeFactory');

server.listen(3015);
<commit_msg>これがバイパスですか…<commit_after>var url = require('url');
var path = require('path');
var request = require('request');
var http = require('http');
var URLValidator = require('valid-url');
var cheerio = require('cheerio');
var Iconv = require('iconv').Iconv;
var characterDetector = require('jschardet');
var base64 = require('js-base64').Base64;

var HTMLConverter = require('./HTMLConverter.js');

var server = http.createServer();

server.on('request', function (req, res) {
    var proxyHost = req.headers.host;
    var proxyURL = req.url;
	var forwardURL = getForwardURL(proxyURL, req.headers.referer);

    if (forwardURL) {
        bypass(req, res, proxyHost, forwardURL);
    } else {
        res.writeHead(404);
        res.end('114514');
    }

});

function getForwardURL(proxyURL, referer) {
    if (typeof proxyURL != 'string') return null;

    var forwardURL = (function () {
        var forwardURL = proxyURL.substr(1);
        if (forwardURL.match(/\./g)) return forwardURL;

        var exclamationIndex = forwardURL.indexOf('?');
        if (exclamationIndex == -1) return base64.decode(forwardURL);

        return base64.decode(forwardURL.substr(0, exclamationIndex)) + forwardURL.substr(exclamationIndex);
    })();

    if (referer) {
        if (forwardURL.substr(0, 4) != 'http') {
            var refererObject = url.parse(referer);
            var refererURL = base64.decode(refererObject.path.substr(1));
            refererObject = url.parse(refererURL);
            forwardURL = url.resolve(refererObject.protocol + '//' + refererObject.host, forwardURL);
        }
    }

    if (URLValidator.isWebUri(forwardURL)) return forwardURL;

    return null;
}

function bypass(req, res, proxyHost, forwardURL) {

    var forward = request({ uri: forwardURL, gzip: true});

    forward.on('response', function (response) {
        if (res.headersSent) {
            forwardResponse.pipe(res);
            return;
        }

        for (var name in response.headers) {
            res.setHeader(name, response.headers[name]);
        }
        res.setHeader('Access-Control-Allow-Origin', '*');
        res.setHeader('Content-Security-Policy', 'connect-src *');
        res.setHeader('Content-Encoding', 'utf-8');

        var contentType = response.headers['content-type'] || '';
        var htmlConverter = HTMLConverter(proxyHost, forwardURL);
        if (contentType.match('text/html')) {
            forward.pipe(htmlConverter).pipe(res);
        }
        else response.pipe(res);
    });

    forward.on('error', function (err) {
        console.log(err);
    });

    req.pipe(forward);
}

var clientCodes = require('./clientCodeFactory');

server.listen(3015);
<|endoftext|>


<commit_before>import Ember from 'ember';
export default Ember.Mixin.create({
	_condition : false,
	_conditionFn : null,
	_conditionProps :null,

	init:function() {
		this._super();
		if(typeof this._conditionFn==='function') {
			// Do not schedule this, causes all kinds of syncing issues
			this.reopen({
				_condition:Ember.computed(this._conditionProps+',_form.for',this._conditionFn)
			});

			// Initialize the condition so observers get notified and our condition will observe its condition properties
			this.get('hasPrerequisites');
		}
	},

	hasPrerequisites : Ember.computed.alias('_condition'),

	conditionProperties: Ember.computed('_conditionProps',function() {
		if(!this._conditionProps)
			return null;
		return Ember.A(this._conditionProps.split(','));
	}).readOnly().volatile(),
});<commit_msg>Fixed race issue with condition initializing<commit_after>import Ember from 'ember';
export default Ember.Mixin.create({
	_condition : false,
	_conditionFn : null,
	_conditionProps :null,

	init:function() {
		this._super();
		if(typeof this._conditionFn==='function') {
			// Do not schedule this, causes all kinds of syncing issues
			this.reopen({
				_condition:Ember.computed(this._conditionProps+',_form.for',this._conditionFn)
			});

		}
	},

	// Initialize the condition so observers get notified and our condition will observe its condition properties
	_initCondition : Ember.on('init',function() {
		this.get('hasPrerequisites');
	}),

	hasPrerequisites : Ember.computed.alias('_condition'),

	conditionProperties: Ember.computed('_conditionProps',function() {
		if(!this._conditionProps)
			return null;
		return Ember.A(this._conditionProps.split(','));
	}).readOnly().volatile(),
});<|endoftext|>


<commit_before>'use strict';

var tools = require('../tools.js');

function addDevice(ip, device, options, callback) {

  var instance = tools.findInstance(options, 'lupusec', function(obj) {
    return (obj.native.alarm_host === ip || obj.native.alarm_host === device._name);
  });

  if (!instance) {

    var id = tools.getNextInstanceID('lupusec', options);
    var name = device._name ? device._name : '';

    tools.words['alarm_user'] = {
      "de": "Lupusec Benutzer eingeben",
      "en": "Lupusec username"
    };

    tools.words['alarm_password'] = {
      "de": "Lupusec Passwort für Benutzer eingeben",
      "en": "Lupusec password for username"
    };

    instance = {
      _id: id,
      common: {
        name: 'lupusec',
        title: 'Lupusec (' + ip + (name ? (' - ' + name) : '') + ')'
      },
      native: {
        alarm_host: ip,
        alarm_port: 80,
        alarm_https: false
      },
      comment: {
        add: 'Lupusec (' + [name, ip] + ')',
        inputs: [{
            name: 'native.alarm_user',
            def: '',
            type: 'text', // text, checkbox, number, select, password. Select requires
            title: 'Lupusec Username' // tools.translate(options.language, 'alarm_user') // see translation in words.js
          },
          {
            name: 'native.alarm_password',
            def: '',
            type: 'password', // text, checkbox, number, select, password. Select requires
            title: 'Lupusec Password' // tools.translate(options.language, 'alarm_password') // see translation in words.js
          },
          {
            name: 'native.alarm_password_confirm',
            def: '',
            type: 'password', // text, checkbox, number, select, password. Select requires
            title: 'Confirm Lupusec Password' // tools.translate(options.language, 'alarm_password') // see translation in words.js
          }
        ]
      }
    };
    options.newInstances.push(instance);
    return callback(true);
  } else {
    callback(null, false, ip);
  }
}

// just check if IP exists
function detect(ip, device, options, callback) {

  tools.httpGet('http://' + ip + '/action/logout', function(err, data) {
    if (err) {
      if (callback) {
        callback(null, false, ip);
        callback = null;
      }
    } else {
      var testData;
      try {
        testData = JSON.parse(data);
      } catch (e) {
        testData = null;
      }

      if (testData && testData.result == 1 && testData.message == "{WEB_MSG_SUBMIT_SUCCESS}") {
        addDevice(ip, device, options, callback);
      } else if (callback) {
        callback(null, false, ip);
        callback = null;
      }
    }
  });
}

exports.detect = detect;
exports.type = ['ip']; // make type=serial for USB sticks
<commit_msg>changed password query<commit_after>'use strict';

var tools = require('../tools.js');

function addDevice(ip, device, options, callback) {

  var instance = tools.findInstance(options, 'lupusec', function(obj) {
    return (obj.native.alarm_host === ip || obj.native.alarm_host === device._name);
  });

  if (!instance) {

    var id = tools.getNextInstanceID('lupusec', options);
    var name = device._name ? device._name : '';

    tools.words['alarm_user'] = {
      "de": "Lupusec Benutzer eingeben",
      "en": "Lupusec username"
    };

    tools.words['alarm_password'] = {
      "de": "Lupusec Passwort für Benutzer eingeben",
      "en": "Lupusec password for username"
    };

    instance = {
      _id: id,
      common: {
        name: 'lupusec',
        title: 'Lupusec (' + ip + (name ? (' - ' + name) : '') + ')'
      },
      native: {
        alarm_host: ip,
        alarm_port: 80,
        alarm_https: false
      },
      comment: {
        add: [name, ip],
        inputs: [{
            name: 'native.alarm_user',
            def: '',
            type: 'text', // text, checkbox, number, select, password. Select requires
            title: 'username' // tools.translate(options.language, 'alarm_user') // see translation in words.js
          },
          {
            name: 'native.alarm_password',
            def: '',
            type: 'password', // text, checkbox, number, select, password. Select requires
            title: 'password' // tools.translate(options.language, 'alarm_password') // see translation in words.js
          }
        ]
      }
    };
    options.newInstances.push(instance);
    return callback(true);
  } else {
    callback(null, false, ip);
  }
}

// just check if IP exists
function detect(ip, device, options, callback) {

  tools.httpGet('http://' + ip + '/action/logout', function(err, data) {
    if (err) {
      if (callback) {
        callback(null, false, ip);
        callback = null;
      }
    } else {
      var testData;
      try {
        testData = JSON.parse(data);
      } catch (e) {
        testData = null;
      }

      if (testData && testData.result == 1 && testData.message == "{WEB_MSG_SUBMIT_SUCCESS}") {
        addDevice(ip, device, options, callback);
      } else if (callback) {
        callback(null, false, ip);
        callback = null;
      }
    }
  });
}

exports.detect = detect;
exports.type = ['ip']; // make type=serial for USB sticks
<|endoftext|>


<commit_before>import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

let files = require.context('~/store', true, /^\.\/.*\.(js|ts)$/)
let filenames = files.keys()

function getModule (filename) {
  let file = files(filename)
  return file.default
    ? file.default
    : file
}

function getModuleNamespace (storeData, namePath) {
  if (namePath.length === 1) {
    return storeData.modules
  }
  let namespace = namePath.shift()
  storeData.modules[namespace] = storeData.modules[namespace] || {}
  storeData.modules[namespace].namespaced = true
  storeData.modules[namespace].modules = storeData.modules[namespace].modules || {}
  return getModuleNamespace(storeData.modules[namespace], namePath)
}

let store
let storeData = {}

// Check if store/index.js returns a vuex store
if (filenames.indexOf('./index.js') !== -1) {
  let mainModule = getModule('./index.js')
  if (mainModule.commit) {
    console.error('[nuxt.js] store/index should export raw store options instead of an instance.')
  } else {
    if (mainModule.state && typeof mainModule.state !== 'function') {
      console.error('[nuxt.js] store state should be a function.')
    }
    storeData = mainModule
  }
}

// Generate the store if there is no store yet
if (store == null) {
  storeData.modules = storeData.modules || {}
  for (let filename of filenames) {
    let name = filename.replace(/^\.\//, '').replace(/\.(js|ts)$/, '')
    if (name === 'index') continue

    let namePath = name.split(/\//)
    let module = getModuleNamespace(storeData, namePath)

    name = namePath.pop()
    module[name] = getModule(filename)
    module[name].namespaced = true

    if (typeof module[name].state !== 'function') {
      console.error('[nuxt.js] store module state should be a function.')
    }
  }
}

export function createStore () {
  return new Vuex.Store(storeData)
}
<commit_msg>[Store] Fix createStore bug<commit_after>import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// Recursive find files in ~/store
const files = require.context('~/store', true, /^\.\/.*\.(js|ts)$/)
const filenames = files.keys()

// Store
let storeData = {}

// Check if store/index.js exists
if (filenames.indexOf('./index.js') !== -1) {
  storeData = getModule('./index.js')
  storeData.state = storeData.state() // Vuex Bug!
}

// Store modules
if (!storeData.modules) {
  storeData.modules = {}
}

for (let filename of filenames) {
  let name = filename.replace(/^\.\//, '').replace(/\.(js|ts)$/, '')
  if (name === 'index') continue

  let namePath = name.split(/\//)
  let module = getModuleNamespace(storeData, namePath)

  name = namePath.pop()
  module[name] = getModule(filename)
  module[name].namespaced = true
}

// createStore
export const createStore = storeData === 'function' ? storeData : () => new Vuex.Store(storeData)

// Dynamically require module
function getModule (filename) {
  const file = files(filename)
  const module = Object.assign({}, file.default || file)
  if (module.state && typeof module.state !== 'function') {
    // eslint-disable-next-line no-console
    console.error('[nuxt] store state should be a function.')
    return
  }
  if (module.commit) {
    // eslint-disable-next-line no-console
    console.error('[nuxt] store should export raw store options instead of an instance.')
    return
  }
  return module
}

function getModuleNamespace (storeData, namePath) {
  if (namePath.length === 1) {
    return storeData.modules
  }
  let namespace = namePath.shift()
  storeData.modules[namespace] = storeData.modules[namespace] || {}
  storeData.modules[namespace].namespaced = true
  storeData.modules[namespace].modules = storeData.modules[namespace].modules || {}
  return getModuleNamespace(storeData.modules[namespace], namePath)
}
<|endoftext|>