<commit_before>(function (angular, buildfire, location) {
    'use strict';
    //created mediaCenterWidget module
    var settings, appId;
    var Settings = {
        setSettings: function (newSettings) {
            settings = newSettings;
        },
        setAppId: function (newId) {
            appId = newId;
        },
        getSetting: function () {
            return settings;
        },
        getAppId: function () {
            return appId;
        }
    };
    angular
        .module('placesWidgetServices', ['placesEnums'])
        .provider('Buildfire', [function () {
            this.$get = function () {
                return buildfire;
            };
        }])
        .provider('Messaging', [function () {
            this.$get = function () {
                return buildfire.messaging;
            };
        }])
        .provider('ImageLib', [function () {
            this.$get = function () {
                return buildfire.imageLib;
            };
        }])
        .factory('Location', [function () {
            var _location = location;
            return {
                go: function (path) {
                    _location.href = path;
                },
                goToHome: function () {
                    _location.href = _location.href.substr(0, _location.href.indexOf('#'));
                }
            };
        }])
        .factory('Orders', [function () {
            var ordersMap = {
                Manually: "Manually",
                Default: "Manually",
                Newest: "Newest",
                Oldest: "Oldest",
                SectionAZ: "Section Name A-Z",
                SectionZA: "Section Name Z-A"
            };
            var orders = [
                {id: 1, name: "Manually", value: "Manually", key: "rank", order: 1},
                {id: 1, name: "Newest", value: "Newest", key: "dateCreated", order: -1},
                {id: 1, name: "Oldest", value: "Oldest", key: "dateCreated", order: 1},
                {id: 1, name: "Section Name A-Z", value: "Section Name A-Z", key: "secTitle", order: 1},
                {id: 1, name: "Section Name Z-A", value: "Section Name Z-A", key: "secTitle", order: -1}
            ];
            return {
                ordersMap: ordersMap,
                options: orders,
                getOrder: function (name) {
                    return orders.filter(function (order) {
                        return order.name === name;
                    })[0];
                }
            };
        }])
        .factory('OrdersItems', [function () {
            var ordersMap = {
                Manually: "Manually",
                Default: "Newest",
                Newest: "Newest",
                Oldest: "Oldest",
                ItemAZ: "Item A-Z",
                ItemZA: "Item Z-A"
            };
            var orders = [
                {id: 1, name: "Manually", value: "Manually", key: "rank", order: 1},
                {id: 1, name: "Newest", value: "Newest", key: "dateCreated", order: -1},
                {id: 1, name: "Oldest", value: "Oldest", key: "dateCreated", order: 1},
                {id: 1, name: "ItemA-Z", value: "Item A-Z", key: "itemTitle", order: 1},
                {id: 1, name: "ItemZ-A", value: "Item Z-A", key: "itemTitle", order: -1}
            ];
            return {
                ordersMap: ordersMap,
                options: orders,
                getOrder: function (name) {
                    return orders.filter(function (order) {
                        return order.name === name;
                    })[0];
                }
            };
        }])
        .factory("DB", ['Buildfire', '$q', 'MESSAGES', 'CODES', function (Buildfire, $q, MESSAGES, CODES) {
            function DB(tagName) {
                this._tagName = tagName;
            }

            DB.prototype.get = function () {
                var that = this;
                var deferred = $q.defer();
                Buildfire.datastore.get(that._tagName, function (err, result) {
                    if (err && err.code == CODES.NOT_FOUND) {
                        return deferred.resolve();
                    }
                    else if (err) {
                        return deferred.reject(err);
                    }
                    else {
                        return deferred.resolve(result);
                    }
                });
                return deferred.promise;
            };
            DB.prototype.getById = function (id) {
                var that = this;
                var deferred = $q.defer();
                Buildfire.datastore.getById(id, that._tagName, function (err, result) {
                    if (err) {
                        return deferred.reject(err);
                    }
                    else if (result && result.data) {
                        return deferred.resolve(result);
                    } else {
                        return deferred.reject(new Error(MESSAGES.ERROR.NOT_FOUND));
                    }
                });
                return deferred.promise;
            };
            DB.prototype.find = function (options) {
                var that = this;
                var deferred = $q.defer();
                if (typeof options == 'undefined') {
                    return deferred.reject(new Error(MESSAGES.ERROR.OPTION_REQUIRES));
                }
                Buildfire.datastore.search(options, that._tagName, function (err, result) {
                    if (err) {
                        return deferred.reject(err);
                    }
                    else if (result) {
                        return deferred.resolve(result);
                    } else {
                        return deferred.reject(new Error(MESSAGES.ERROR.NOT_FOUND));
                    }
                });
                return deferred.promise;
            };

            return DB;
        }])
        .value('Settings', Settings)
        .factory("AppConfig", ['$rootScope', 'Buildfire', 'Settings', function ($rootScope, Buildfire, Settings) {
            return {
                setSettings: function (newSettings) {
                    Settings.setSettings(newSettings);
                },
                setAppId: function (newAppId) {
                    Settings.setAppId(newAppId);
                },
                getSettings: function () {
                    return Settings.getSetting();
                },
                getAppId: function () {
                    return Settings.getAppId();
                },
                changeBackgroundTheme: function (url) {
                    if (url) {
                        $rootScope.currentBackgroundImage = {
                            "background-image": "url(" + Buildfire.imageLib.resizeImage(url, {
                                width: 342,
                                height: 770
                            }) + ")"
                        };
                    } else {
                        $rootScope.currentBackgroundImage = "";
                    }
                }
            };
        }])
        .factory('GeoDistance', ['$q', '$http', function ($q, $http) {
            var _getDistance = function (origin, items, distanceUnit) {
                var deferred = $q.defer();
                var originMap = {lat: origin[1], lng: origin[0]};
                var destinationsMap = [];

                if (!origin || !Array.isArray(origin)) {
                    deferred.reject({
                        code: 'NOT_ARRAY',
                        message: 'origin is not an Array'
                    });
                }
                if (!items || !Array.isArray(items) || !items.length) {
                    deferred.reject({
                        code: 'NOT_ARRAY',
                        message: 'destinations is not an Array'
                    });
                }

                items.forEach(function (_dest) {
                    if (_dest.data && _dest.data.address && _dest.data.address.lat && _dest.data.address.lng)
                        destinationsMap.push({lat: _dest.data.address.lat, lng: _dest.data.address.lng});
                    else
                        destinationsMap.push({lat: 0, lng: 0});
                });

                var service = new google.maps.DistanceMatrixService;
                service.getDistanceMatrix({
                    origins: [originMap],
                    destinations: destinationsMap,
                    travelMode: google.maps.TravelMode.DRIVING,
                    unitSystem: distanceUnit == 'kilometers' ? google.maps.UnitSystem.METRIC : google.maps.UnitSystem.IMPERIAL,
                    avoidHighways: false,
                    avoidTolls: false
                }, function (response, status) {
                    if (status !== google.maps.DistanceMatrixStatus.OK) {
                        deferred.reject(status);
                    } else {
                        deferred.resolve(response);
                    }
                });
                return deferred.promise;
            };
            return {
                getDistance: _getDistance
            }
        }]);
})(window.angular, window.buildfire, window.location);<commit_msg>Backround image css changes<commit_after>(function (angular, buildfire, location) {
    'use strict';
    //created mediaCenterWidget module
    var settings, appId;
    var Settings = {
        setSettings: function (newSettings) {
            settings = newSettings;
        },
        setAppId: function (newId) {
            appId = newId;
        },
        getSetting: function () {
            return settings;
        },
        getAppId: function () {
            return appId;
        }
    };
    angular
        .module('placesWidgetServices', ['placesEnums'])
        .provider('Buildfire', [function () {
            this.$get = function () {
                return buildfire;
            };
        }])
        .provider('Messaging', [function () {
            this.$get = function () {
                return buildfire.messaging;
            };
        }])
        .provider('ImageLib', [function () {
            this.$get = function () {
                return buildfire.imageLib;
            };
        }])
        .factory('Location', [function () {
            var _location = location;
            return {
                go: function (path) {
                    _location.href = path;
                },
                goToHome: function () {
                    _location.href = _location.href.substr(0, _location.href.indexOf('#'));
                }
            };
        }])
        .factory('Orders', [function () {
            var ordersMap = {
                Manually: "Manually",
                Default: "Manually",
                Newest: "Newest",
                Oldest: "Oldest",
                SectionAZ: "Section Name A-Z",
                SectionZA: "Section Name Z-A"
            };
            var orders = [
                {id: 1, name: "Manually", value: "Manually", key: "rank", order: 1},
                {id: 1, name: "Newest", value: "Newest", key: "dateCreated", order: -1},
                {id: 1, name: "Oldest", value: "Oldest", key: "dateCreated", order: 1},
                {id: 1, name: "Section Name A-Z", value: "Section Name A-Z", key: "secTitle", order: 1},
                {id: 1, name: "Section Name Z-A", value: "Section Name Z-A", key: "secTitle", order: -1}
            ];
            return {
                ordersMap: ordersMap,
                options: orders,
                getOrder: function (name) {
                    return orders.filter(function (order) {
                        return order.name === name;
                    })[0];
                }
            };
        }])
        .factory('OrdersItems', [function () {
            var ordersMap = {
                Manually: "Manually",
                Default: "Newest",
                Newest: "Newest",
                Oldest: "Oldest",
                ItemAZ: "Item A-Z",
                ItemZA: "Item Z-A"
            };
            var orders = [
                {id: 1, name: "Manually", value: "Manually", key: "rank", order: 1},
                {id: 1, name: "Newest", value: "Newest", key: "dateCreated", order: -1},
                {id: 1, name: "Oldest", value: "Oldest", key: "dateCreated", order: 1},
                {id: 1, name: "ItemA-Z", value: "Item A-Z", key: "itemTitle", order: 1},
                {id: 1, name: "ItemZ-A", value: "Item Z-A", key: "itemTitle", order: -1}
            ];
            return {
                ordersMap: ordersMap,
                options: orders,
                getOrder: function (name) {
                    return orders.filter(function (order) {
                        return order.name === name;
                    })[0];
                }
            };
        }])
        .factory("DB", ['Buildfire', '$q', 'MESSAGES', 'CODES', function (Buildfire, $q, MESSAGES, CODES) {
            function DB(tagName) {
                this._tagName = tagName;
            }

            DB.prototype.get = function () {
                var that = this;
                var deferred = $q.defer();
                Buildfire.datastore.get(that._tagName, function (err, result) {
                    if (err && err.code == CODES.NOT_FOUND) {
                        return deferred.resolve();
                    }
                    else if (err) {
                        return deferred.reject(err);
                    }
                    else {
                        return deferred.resolve(result);
                    }
                });
                return deferred.promise;
            };
            DB.prototype.getById = function (id) {
                var that = this;
                var deferred = $q.defer();
                Buildfire.datastore.getById(id, that._tagName, function (err, result) {
                    if (err) {
                        return deferred.reject(err);
                    }
                    else if (result && result.data) {
                        return deferred.resolve(result);
                    } else {
                        return deferred.reject(new Error(MESSAGES.ERROR.NOT_FOUND));
                    }
                });
                return deferred.promise;
            };
            DB.prototype.find = function (options) {
                var that = this;
                var deferred = $q.defer();
                if (typeof options == 'undefined') {
                    return deferred.reject(new Error(MESSAGES.ERROR.OPTION_REQUIRES));
                }
                Buildfire.datastore.search(options, that._tagName, function (err, result) {
                    if (err) {
                        return deferred.reject(err);
                    }
                    else if (result) {
                        return deferred.resolve(result);
                    } else {
                        return deferred.reject(new Error(MESSAGES.ERROR.NOT_FOUND));
                    }
                });
                return deferred.promise;
            };

            return DB;
        }])
        .value('Settings', Settings)
        .factory("AppConfig", ['$rootScope', 'Buildfire', 'Settings', function ($rootScope, Buildfire, Settings) {
            return {
                setSettings: function (newSettings) {
                    Settings.setSettings(newSettings);
                },
                setAppId: function (newAppId) {
                    Settings.setAppId(newAppId);
                },
                getSettings: function () {
                    return Settings.getSetting();
                },
                getAppId: function () {
                    return Settings.getAppId();
                },
                changeBackgroundTheme: function (url) {
                    if (url) {
                        $rootScope.currentBackgroundImage = {
                            "background-image": "url(" + Buildfire.imageLib.resizeImage(url, {
                                width: 342,
                                height: 770
                            }) + ") !important"
                        };
                    } else {
                        $rootScope.currentBackgroundImage = "";
                    }
                }
            };
        }])
        .factory('GeoDistance', ['$q', '$http', function ($q, $http) {
            var _getDistance = function (origin, items, distanceUnit) {
                var deferred = $q.defer();
                var originMap = {lat: origin[1], lng: origin[0]};
                var destinationsMap = [];

                if (!origin || !Array.isArray(origin)) {
                    deferred.reject({
                        code: 'NOT_ARRAY',
                        message: 'origin is not an Array'
                    });
                }
                if (!items || !Array.isArray(items) || !items.length) {
                    deferred.reject({
                        code: 'NOT_ARRAY',
                        message: 'destinations is not an Array'
                    });
                }

                items.forEach(function (_dest) {
                    if (_dest.data && _dest.data.address && _dest.data.address.lat && _dest.data.address.lng)
                        destinationsMap.push({lat: _dest.data.address.lat, lng: _dest.data.address.lng});
                    else
                        destinationsMap.push({lat: 0, lng: 0});
                });

                var service = new google.maps.DistanceMatrixService;
                service.getDistanceMatrix({
                    origins: [originMap],
                    destinations: destinationsMap,
                    travelMode: google.maps.TravelMode.DRIVING,
                    unitSystem: distanceUnit == 'kilometers' ? google.maps.UnitSystem.METRIC : google.maps.UnitSystem.IMPERIAL,
                    avoidHighways: false,
                    avoidTolls: false
                }, function (response, status) {
                    if (status !== google.maps.DistanceMatrixStatus.OK) {
                        deferred.reject(status);
                    } else {
                        deferred.resolve(response);
                    }
                });
                return deferred.promise;
            };
            return {
                getDistance: _getDistance
            }
        }]);
})(window.angular, window.buildfire, window.location);<|endoftext|>


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

define(function (require, exports, module) {
    "use strict";

    var EventEmitter = require("eventEmitter"),
        adapter = require("./adapter"),
        util = require("./util"),
        Promise = require("bluebird");

    /**
     * The LayerManager provides an API for dealing with the layers of the
     * currently active document
     *
     * Right now, this is purely demonstration code. This will need to be elaborated
     * to deal with all documents (or changed to be document specific / not a singleton).
     *
     * Emits "selectionChanged" event whenever the currently selected layer changes
     * with the following parameters
     *    1. @param {String} the selected layer name
     *
     * @extends EventEmitter
     * @constructor
     * @private
     */
    var LayerManager = function () {
        EventEmitter.call(this);

        adapter.on("select", this._handleSelect.bind(this));
        adapter.on("make", this._handleSelect.bind(this));
    };
    util.inherits(LayerManager, EventEmitter);

    /**
     * Holds the currently selected layer indices
     */
    LayerManager.prototype._currentSelection = [];

    /**
     * Event handler for low level select and make events
     * "Make" layer may cause selection to change as well
     * Grabs the current selected layer indices, saves them in _currentSelection
     * and emits a "selectionChanged" event with the current Selection array
     *
     */
    LayerManager.prototype._handleSelect = function () {
        this.getSelectedLayerIndices().bind(this).then(function (layers) {
            this._currentSelection = layers;
            this.emit("selectionChanged", this._currentSelection);
        }).bind(this);

    };

    LayerManager.prototype.getLayerAtIndex = function (index) {
        return adapter.getProperty("document", "numberOfLayers").then(function (layerCount) {
            if (typeof index === undefined || index < 0 || index > layerCount) {
                throw new Error("Invalid layer index");
            }

            // If only background layer, count is 0, and background layer cannot be unselected
            if (layerCount === 0) {
                return adapter.get({ref: "$Lyr", value: "$Trgt", enum: "$Ordn"});
            } else {
                return adapter.get({ref: "$Lyr", "index": index});
            }
        });
    };

    /**
     * Gets an array of layer references for all selected layers in the current document
     *
     * @return {Promise.<Array.<Object>>} Resolves to an array of layers with index and ref(:layer) keys
     */
    LayerManager.prototype.getSelectedLayers = function () {
        return adapter.get("document").then(function (document) {
            return document.targetLayers || [];
        });
    };

    /**
     * Gets an array of layer indices for all selected layers in the current document
     *
     * @return {Promise.<Array.<Number>>} Resolves to an array of numbers for each index of layers
     */
    LayerManager.prototype.getSelectedLayerIndices = function () {
        return this.getSelectedLayers().then(function (layers) {
            return layers.map(function (layer) {
                return layer.index;
            });
        });
    };

    LayerManager.prototype.getSelectedLayerDescriptors = function () {
        return this.getSelectedLayerIndices().then(function (indices) {
            var layerGets = [];
            indices.map(function (index) {
                layerGets.push(adapter.get({ref: "layer", index: index}));
            });
            return Promise.all(layerGets);
        });
    };

    /**
     * Creates a new layer in the currently active document.
     * The returned promise resolves/rejects when the operation is complete/has an error
     *
     * @return {Promise.<Object>} Result of the layer creation call
     */
    LayerManager.prototype.createNewLayer = function () {
        return adapter.call("$Mk", {"null" : { "ref" : "$Lyr " }});
    };

    /**
     * Gets all layers in the document with their properties
     *
     * @return {Promise.<ActionDescriptor>} Result of the layer creation call
     */
    LayerManager.prototype.getAllLayers = function () {
        return adapter.getProperty("document", "numberOfLayers").then(function (layerCount) {
            return adapter.getProperty("document", "hasBackgroundLayer").then(function (hasBackground) {
                var layerGets = [];
                var startIndex = hasBackground ? 0 : 1;

                for (var i = startIndex; i <= layerCount; i++) {
                    layerGets.push(adapter.get({ref: "layer", index: i}));
                }
                return Promise.all(layerGets);
            });
        });
    };

    /**
     * Duplicates layers.
     * If index is supplied, will only duplicate the indexed layer
     *
     * If only one layer is selected, and newLayerName is not null, copy will be renamed
     * Otherwise layers get copied with their original names
     * The returned promise resolves to the dupeArgs object.
     *
     * @param {?number} index Index of the layer to duplicate, default is currently selected layer(s)
     * @param {?string} newLayerName If supplied, renames the new layer, only applies when a single layer is selected
     * @return {Promise.<Object>} Promise that resolves to a reference to currently selected layer
     */
    LayerManager.prototype.duplicateLayer = function (index, newLayerName) {
        var nullArgs = { "ref": "$Lyr" };

        // This way we can either choose the current layer or a layer by index
        if (typeof index !== undefined) {
            nullArgs.index = index;
        } else {
            nullArgs.enum = "$Ordn";
            nullArgs.value = "$Trgt";
        }

        var dupeArgs = { "null" : nullArgs };
        dupeArgs.$Vrsn = 5;

        if (newLayerName) {
            dupeArgs["$Nm  "] = newLayerName;
        }

        return adapter.call("$Dplc", dupeArgs);
    };

    /**
     * Moves a layer
     * If index is null, will move the selected layer
     *
     * @param {?number} index Index of the layer to move, default is currently selected layer
     * @param {?number} dx Pixel value to move the layer horizontally (Default 0)
     * @param {?number} dy Pixel value to move the layer vertically (Default 0)
     * @return {Promise.<Object>} Promise that resolves to empty object
     */
    LayerManager.prototype.moveLayer = function (index, dx, dy) {
        var nullArgs = { "ref": "$Lyr" };

        if (typeof index !== undefined) {
            nullArgs.index = index;
        } else {
            nullArgs.enum = "$Ordn";
            nullArgs.value = "$Trgt";
        }

        var selectArgs = {"null": nullArgs};

        // If index is given, this ensures that the layer with given index is selected first
        // Otherwise, is a no-op and will move on to copying the layer
        return adapter.call("$slct", selectArgs).then(function () {
            var moveArgs = { "null": nullArgs };

            moveArgs.to = {
                "obj": "Offset",
                "value": {
                    "horizontal": {
                        "unit": "pixelsUnit",
                        "value": dx || 0
                    },
                    "vertical": {
                        "unit": "pixelsUnit",
                        "value": dy || 0
                    }
                }
            };

            return adapter.call("move", moveArgs);
        });
    };

    /**
     * Copies a layer and moves it
     * If index is null, will copy the selected layer
     *
     * @param {?number=} index Index of the layer to copy, default is currently selected layer
     * @param {?number} dx Pixel value to move the copied layer horizontally (Default 0)
     * @param {?number} dy Pixel value to move the copied layer vertically (Default 0)
     * @return {Promise.<Object>} Promise that resolves to empty object
     */
    LayerManager.prototype.copyLayer = function (index, dx, dy) {
        var nullArgs = { "ref": "$Lyr" };

        if (typeof index !== undefined) {
            nullArgs.index = index;
        } else {
            nullArgs.enum = "$Ordn";
            nullArgs.value = "$Trgt";
        }

        var selectArgs = {"null": nullArgs};

        // If index is given, this ensures that the layer with given index is selected first
        // Otherwise, is a no-op and will move on to copying the layer
        return adapter.call("$slct", selectArgs).then(function () {
            var copyArgs = { "null": nullArgs };

            copyArgs.to = {
                "obj": "Offset",
                "value": {
                    "horizontal": {
                        "unit": "pixelsUnit",
                        "value": dx || 0
                    },
                    "vertical": {
                        "unit": "pixelsUnit",
                        "value": dy || 0
                    }
                }
            };

            return adapter.call("copyEvent", copyArgs);
        });
    };

    /** @type {LayerManager} The LayerManager singleton */
    var theLayerManager = new LayerManager();

    module.exports = theLayerManager;

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

define(function (require, exports, module) {
    "use strict";

    var EventEmitter = require("eventEmitter"),
        adapter = require("./adapter"),
        util = require("./util"),
        Promise = require("bluebird");

    /**
     * The LayerManager provides an API for dealing with the layers of the
     * currently active document
     *
     * Right now, this is purely demonstration code. This will need to be elaborated
     * to deal with all documents (or changed to be document specific / not a singleton).
     *
     * Emits "selectionChanged" event whenever the currently selected layer changes
     * with the following parameters
     *    1. @param {String} the selected layer name
     *
     * @extends EventEmitter
     * @constructor
     * @private
     */
    var LayerManager = function () {
        EventEmitter.call(this);

        adapter.on("select", this._handleSelect.bind(this));
        adapter.on("make", this._handleSelect.bind(this));
    };
    util.inherits(LayerManager, EventEmitter);

    /**
     * Holds the currently selected layer indices
     */
    LayerManager.prototype._currentSelection = [];

    /**
     * Event handler for low level select and make events
     * "Make" layer may cause selection to change as well
     * Grabs the current selected layer indices, saves them in _currentSelection
     * and emits a "selectionChanged" event with the current Selection array
     *
     */
    LayerManager.prototype._handleSelect = function () {
        this.getSelectedLayerIndices().bind(this).then(function (layers) {
            this._currentSelection = layers;
            this.emit("selectionChanged", this._currentSelection);
        });

    };

    LayerManager.prototype.getLayerAtIndex = function (index) {
        return adapter.getProperty("document", "numberOfLayers").then(function (layerCount) {
            if (typeof index === undefined || index < 0 || index > layerCount) {
                throw new Error("Invalid layer index");
            }

            // If only background layer, count is 0, and background layer cannot be unselected
            if (layerCount === 0) {
                return adapter.get({ref: "$Lyr", value: "$Trgt", enum: "$Ordn"});
            } else {
                return adapter.get({ref: "$Lyr", "index": index});
            }
        });
    };

    /**
     * Gets an array of layer references for all selected layers in the current document
     *
     * @return {Promise.<Array.<Object>>} Resolves to an array of layers with index and ref(:layer) keys
     */
    LayerManager.prototype.getSelectedLayers = function () {
        return adapter.get("document").then(function (document) {
            return document.targetLayers || [];
        });
    };

    /**
     * Gets an array of layer indices for all selected layers in the current document
     *
     * @return {Promise.<Array.<Number>>} Resolves to an array of numbers for each index of layers
     */
    LayerManager.prototype.getSelectedLayerIndices = function () {
        return this.getSelectedLayers().then(function (layers) {
            return layers.map(function (layer) {
                return layer.index;
            });
        });
    };

    LayerManager.prototype.getSelectedLayerDescriptors = function () {
        return this.getSelectedLayerIndices().then(function (indices) {
            var layerGets = [];
            indices.map(function (index) {
                layerGets.push(adapter.get({ref: "layer", index: index}));
            });
            return Promise.all(layerGets);
        });
    };

    /**
     * Creates a new layer in the currently active document.
     * The returned promise resolves/rejects when the operation is complete/has an error
     *
     * @return {Promise.<Object>} Result of the layer creation call
     */
    LayerManager.prototype.createNewLayer = function () {
        return adapter.call("$Mk", {"null" : { "ref" : "$Lyr " }});
    };

    /**
     * Gets all layers in the document with their properties
     *
     * @return {Promise.<ActionDescriptor>} Result of the layer creation call
     */
    LayerManager.prototype.getAllLayers = function () {
        return adapter.getProperty("document", "numberOfLayers").then(function (layerCount) {
            return adapter.getProperty("document", "hasBackgroundLayer").then(function (hasBackground) {
                var layerGets = [];
                var startIndex = hasBackground ? 0 : 1;

                for (var i = startIndex; i <= layerCount; i++) {
                    layerGets.push(adapter.get({ref: "layer", index: i}));
                }
                return Promise.all(layerGets);
            });
        });
    };

    /**
     * Duplicates layers.
     * If index is supplied, will only duplicate the indexed layer
     *
     * If only one layer is selected, and newLayerName is not null, copy will be renamed
     * Otherwise layers get copied with their original names
     * The returned promise resolves to the dupeArgs object.
     *
     * @param {?number} index Index of the layer to duplicate, default is currently selected layer(s)
     * @param {?string} newLayerName If supplied, renames the new layer, only applies when a single layer is selected
     * @return {Promise.<Object>} Promise that resolves to a reference to currently selected layer
     */
    LayerManager.prototype.duplicateLayer = function (index, newLayerName) {
        var nullArgs = { "ref": "$Lyr" };

        // This way we can either choose the current layer or a layer by index
        if (typeof index !== undefined) {
            nullArgs.index = index;
        } else {
            nullArgs.enum = "$Ordn";
            nullArgs.value = "$Trgt";
        }

        var dupeArgs = { "null" : nullArgs };
        dupeArgs.$Vrsn = 5;

        if (newLayerName) {
            dupeArgs["$Nm  "] = newLayerName;
        }

        return adapter.call("$Dplc", dupeArgs);
    };

    /**
     * Moves a layer
     * If index is null, will move the selected layer
     *
     * @param {?number} index Index of the layer to move, default is currently selected layer
     * @param {?number} dx Pixel value to move the layer horizontally (Default 0)
     * @param {?number} dy Pixel value to move the layer vertically (Default 0)
     * @return {Promise.<Object>} Promise that resolves to empty object
     */
    LayerManager.prototype.moveLayer = function (index, dx, dy) {
        var nullArgs = { "ref": "$Lyr" };

        if (typeof index !== undefined) {
            nullArgs.index = index;
        } else {
            nullArgs.enum = "$Ordn";
            nullArgs.value = "$Trgt";
        }

        var selectArgs = {"null": nullArgs};

        // If index is given, this ensures that the layer with given index is selected first
        // Otherwise, is a no-op and will move on to copying the layer
        return adapter.call("$slct", selectArgs).then(function () {
            var moveArgs = { "null": nullArgs };

            moveArgs.to = {
                "obj": "Offset",
                "value": {
                    "horizontal": {
                        "unit": "pixelsUnit",
                        "value": dx || 0
                    },
                    "vertical": {
                        "unit": "pixelsUnit",
                        "value": dy || 0
                    }
                }
            };

            return adapter.call("move", moveArgs);
        });
    };

    /**
     * Copies a layer and moves it
     * If index is null, will copy the selected layer
     *
     * @param {?number=} index Index of the layer to copy, default is currently selected layer
     * @param {?number} dx Pixel value to move the copied layer horizontally (Default 0)
     * @param {?number} dy Pixel value to move the copied layer vertically (Default 0)
     * @return {Promise.<Object>} Promise that resolves to empty object
     */
    LayerManager.prototype.copyLayer = function (index, dx, dy) {
        var nullArgs = { "ref": "$Lyr" };

        if (typeof index !== undefined) {
            nullArgs.index = index;
        } else {
            nullArgs.enum = "$Ordn";
            nullArgs.value = "$Trgt";
        }

        var selectArgs = {"null": nullArgs};

        // If index is given, this ensures that the layer with given index is selected first
        // Otherwise, is a no-op and will move on to copying the layer
        return adapter.call("$slct", selectArgs).then(function () {
            var copyArgs = { "null": nullArgs };

            copyArgs.to = {
                "obj": "Offset",
                "value": {
                    "horizontal": {
                        "unit": "pixelsUnit",
                        "value": dx || 0
                    },
                    "vertical": {
                        "unit": "pixelsUnit",
                        "value": dy || 0
                    }
                }
            };

            return adapter.call("copyEvent", copyArgs);
        });
    };

    /** @type {LayerManager} The LayerManager singleton */
    var theLayerManager = new LayerManager();

    module.exports = theLayerManager;

});
<|endoftext|>


<commit_before>var convertRatio = function(val) {
	if (typeof (val) == 'number') {
		val = (val * 100).toFixed(2);
		if (val > 0) {
			return '' + val + '%';
		} else if (val < 0) {
			return '' + val + '%';
		}
	}
	return val;
};

var convertFloat = function(val) {
	if (typeof (val) == 'number') {
		val = val.toFixed(2);
	}
	return val;
};

Ext.define('Stockholm.view.StockGrid', {
	extend : 'Ext.grid.Panel',
	xtype : 'stockgrid',
	collapsible : true,
	autoScroll : true,
	multiSelect : true,
	viewConfig : {
		stripeRows : true,
		enableTextSelection : true
	},

	initComponent : function() {
		this.columns = [ {
			text : '代码',
			width : 75,
			align : 'center',
			sortable : true,
			locked : true,
			dataIndex : 'Symbol',
			renderer : function(val) {
				var url = "http://q.stock.sohu.com/cn/" + val.substr(0, 6) + "/index.shtml";
				return '' + val + '';
			}
		}, {
			text : '名称',
			width : 70,
			align : 'center',
			sortable : true,
			locked : true,
			dataIndex : 'Name'
		}, {
			text : '日期',
			width : 75,
			align : 'center',
			sortable : true,
			locked : true,
			// renderer : Ext.util.Format.dateRenderer('m/d/Y'),
			dataIndex : 'Date'
		}, {
			text : '选股方法',
			width : 85,
			align : 'center',
			sortable : true,
			locked : true,
			dataIndex : 'Method'
		}, {
			text : '基本指标',
			id : 'basicStCol',
			defaults : {
				sortable : true,
				lockable : false
			},
			columns : [ {
				text : '类型',
				width : 55,
				align : 'center',
				dataIndex : 'Type'
			}, {
				text : '收盘价',
				width : 55,
				align : 'right',
				dataIndex : 'Close'
			}, {
				text : '涨跌',
				width : 55,
				align : 'right',
				dataIndex : 'Change',
				renderer : convertRatio
			} ]
		}, {
			text : '详细技术指标',
			id : 'advStCol',
			hidden : true,
			defaults : {
				align : 'right',
				sortable : true,
				lockable : false
			},
			columns : [ {
				text : '成交量变化',
				width : 70,
				dataIndex : 'Vol_Change',
				renderer : convertRatio
			}, {
				text : '10天均线',
				width : 70,
				dataIndex : 'MA_10'
			}, {
				text : 'KDJ/K',
				width : 50,
				renderer : convertFloat,
				dataIndex : 'KDJ_K'
			}, {
				text : 'KDJ/D',
				width : 50,
				renderer : convertFloat,
				dataIndex : 'KDJ_D'
			}, {
				text : 'KDJ/J',
				width : 50,
				renderer : convertFloat,
				dataIndex : 'KDJ_J'
			} ]
		}, {
			text : '收益回测',
			id : 'backTestCol',
			defaults : {
				width : 95,
				align : 'right',
				sortable : true,
				lockable : false,
				renderer : convertRatio
			},
			columns : [ {
				text : '1天相对收益 %',
				dataIndex : 'Day_1_Differ'
			}, {
				text : '1天沪深300变化 %',
				dataIndex : 'Day_1_INDEX_Change'
			}, {
				text : '1天实际收益 %',
				dataIndex : 'Day_1_Profit'
			}, {
				text : '3天相对收益 %',
				dataIndex : 'Day_3_Differ'
			}, {
				text : '3天沪深300变化 %',
				dataIndex : 'Day_3_INDEX_Change'
			}, {
				text : '3天实际收益 %',
				dataIndex : 'Day_3_Profit'
			}, {
				text : '5天相对收益 %',
				dataIndex : 'Day_5_Differ'
			}, {
				text : '5天沪深300变化 %',
				dataIndex : 'Day_5_INDEX_Change'
			}, {
				text : '5天实际收益 %',
				dataIndex : 'Day_5_Profit'
			}, {
				text : '9天相对收益 %',
				dataIndex : 'Day_9_Differ'
			}, {
				text : '9天沪深300变化 %',
				dataIndex : 'Day_9_INDEX_Change'
			}, {
				text : '9天实际收益 %',
				dataIndex : 'Day_9_Profit'
			} ]
		} ];

		this.dockedItems.push({
			xtype : 'pagingtoolbar',
			store : this.store,
			dock : 'bottom',
			displayInfo : true,
			listeners : {
				afterrender : function() {
					Ext.Array.each(this.items.items, function(item) {
						item.hide();
					});
					this.child('tbfill').show();
					this.child('#displayItem').show();
				}
			}
		});
		this.callParent();
	}
});<commit_msg>bug fix<commit_after>var convertRatio = function(val) {
	if (typeof (val) == 'number') {
		val = (val * 100).toFixed(2);
		if (val > 0) {
			return '' + val + '%';
		} else if (val < 0) {
			return '' + val + '%';
		}
	}
	return val;
};

var convertFloat = function(val) {
	if (typeof (val) == 'number') {
		val = val.toFixed(2);
	}
	return val;
};

Ext.define('Stockholm.view.StockGrid', {
	extend : 'Ext.grid.Panel',
	xtype : 'stockgrid',
	collapsible : true,
	autoScroll : true,
	multiSelect : true,
	viewConfig : {
		stripeRows : true,
		enableTextSelection : true
	},

	initComponent : function() {
		this.columns = [ {
			text : '代码',
			width : 75,
			align : 'center',
			sortable : true,
			locked : true,
			dataIndex : 'Symbol',
			renderer : function(val) {
				var url = "http://q.stock.sohu.com/cn/" + val.substr(0, 6) + "/index.shtml";
				return '' + val + '';
			}
		}, {
			text : '名称',
			width : 70,
			align : 'center',
			sortable : true,
			locked : true,
			dataIndex : 'Name'
		}, {
			text : '日期',
			width : 75,
			align : 'center',
			sortable : true,
			locked : true,
			// renderer : Ext.util.Format.dateRenderer('m/d/Y'),
			dataIndex : 'Date'
		}, {
			text : '选股方法',
			width : 85,
			align : 'center',
			sortable : true,
			locked : true,
			dataIndex : 'Method'
		}, {
			text : '基本指标',
			id : 'basicStCol',
			defaults : {
				sortable : true,
				lockable : false
			},
			columns : [ {
				text : '类型',
				width : 55,
				align : 'center',
				dataIndex : 'Type'
			}, {
				text : '收盘价',
				width : 55,
				align : 'right',
				dataIndex : 'Close'
			}, {
				text : '涨跌',
				width : 55,
				align : 'right',
				dataIndex : 'Change',
				renderer : convertRatio
			} ]
		}, {
			text : '详细技术指标',
			id : 'advStCol',
			hidden : true,
			defaults : {
				align : 'right',
				sortable : true,
				hidden : true,
				lockable : false
			},
			columns : [ {
				text : '成交量变化',
				width : 70,
				dataIndex : 'Vol_Change',
				renderer : convertRatio
			}, {
				text : '10天均线',
				width : 70,
				dataIndex : 'MA_10'
			}, {
				text : 'KDJ/K',
				width : 50,
				renderer : convertFloat,
				dataIndex : 'KDJ_K'
			}, {
				text : 'KDJ/D',
				width : 50,
				renderer : convertFloat,
				dataIndex : 'KDJ_D'
			}, {
				text : 'KDJ/J',
				width : 50,
				renderer : convertFloat,
				dataIndex : 'KDJ_J'
			} ]
		}, {
			text : '收益回测',
			id : 'backTestCol',
			defaults : {
				width : 95,
				align : 'right',
				sortable : true,
				lockable : false,
				renderer : convertRatio
			},
			columns : [ {
				text : '1天相对收益 %',
				dataIndex : 'Day_1_Differ'
			}, {
				text : '1天沪深300变化 %',
				dataIndex : 'Day_1_INDEX_Change'
			}, {
				text : '1天实际收益 %',
				dataIndex : 'Day_1_Profit'
			}, {
				text : '3天相对收益 %',
				dataIndex : 'Day_3_Differ'
			}, {
				text : '3天沪深300变化 %',
				dataIndex : 'Day_3_INDEX_Change'
			}, {
				text : '3天实际收益 %',
				dataIndex : 'Day_3_Profit'
			}, {
				text : '5天相对收益 %',
				dataIndex : 'Day_5_Differ'
			}, {
				text : '5天沪深300变化 %',
				dataIndex : 'Day_5_INDEX_Change'
			}, {
				text : '5天实际收益 %',
				dataIndex : 'Day_5_Profit'
			}, {
				text : '9天相对收益 %',
				dataIndex : 'Day_9_Differ'
			}, {
				text : '9天沪深300变化 %',
				dataIndex : 'Day_9_INDEX_Change'
			}, {
				text : '9天实际收益 %',
				dataIndex : 'Day_9_Profit'
			} ]
		} ];

		this.dockedItems.push({
			xtype : 'pagingtoolbar',
			store : this.store,
			dock : 'bottom',
			displayInfo : true,
			listeners : {
				afterrender : function() {
					Ext.Array.each(this.items.items, function(item) {
						item.hide();
					});
					this.child('tbfill').show();
					this.child('#displayItem').show();
				}
			}
		});
		this.callParent();
	}
});<|endoftext|>


<commit_before>var childProcess = require('child_process')
var request = require('request')
var baseN = require('base-n');

var charset = process.argv[2];
var strlength = process.argv[3];
var salt = process.argv[4];
var author = process.argv[5];
var baseurl = process.argv[6];
var nbCores = require('os').cpus().length;

console.log("Parameters")
console.log(charset)
console.log(strlength)
console.log(salt)

console.log("Start")

main(charset, strlength, salt);

function main(charset, strlength, salt)
{
    var b36 = baseN.create({
        characters: charset
    });

    var max = b36.decode(charset[charset.length - 1].repeat(strlength));
    var each = max / nbCores;
    var limits = [];
    var workers = [];

    for (var i = 0; i < nbCores; i++) {
        var start = Math.ceil(i * each);
        if (i != nbCores - 1) {
            var end = start + Math.ceil(each);
        } else {
            var end = max;
        }

        limits.push({start: b36.encode(start), end: b36.encode(end)});
    };

    // Request
    var propertiesObject = { author: author };
    request({url: baseurl + '/GetHash', qs:propertiesObject}, function(err, response, body) {
        if(err) { console.log(err); return; }
        var hash = JSON.parse(body).hash;

	console.time('score');

        if (!hash) {
            return main(charset, strlength, salt);
        };

        console.log(JSON.parse(body).random);

        var endedWorkers = 0;
        for (var i=0 ; i<nbCores; i++) {
            var worker = childProcess.fork('child.js', [limits[i].start, limits[i].end, hash, charset, strlength, salt])
            workers.push(worker);
            worker.on('message', function (m) {
                if (m.status === 'found') {
                    killAllWorkers(workers);
        		    console.log('found');
        		    console.log(m.string);
        		    console.timeEnd('score');

                    return sendResult(m.string);
                } else if (m.status === 'end') {
                    endedWorkers++;
                    if (endedWorkers == nbCores-1) {
                        killAllWorkers(workers);
                        console.log('Not Found, Mother fucker.');
                        return main(charset, strlength, salt);
                    };
                }
            })
        }
    });
}

function killAllWorkers(workers)
{
    for (var i in workers) {
        workers[i].kill('SIGINT');
    };
}

function sendResult(result)
{
    var options = {
      uri: baseurl + '/PostSuccess',
      method: 'POST',
      json: {
        "author": author,
        "result": result
      }
    };

    request(options, function(err, response, body) {
        if (!error && response.statusCode == 200) {
            return main(charset, strlength, salt);
        } else {
            setTimeout(function() {
                return sendResult(result);
            }, 100);
        }
    });
}
<commit_msg>add monitor<commit_after>var childProcess = require('child_process')
var request = require('request')
var baseN = require('base-n');

var charset = process.argv[2];
var strlength = process.argv[3];
var salt = process.argv[4];
var author = process.argv[5];
var baseurl = process.argv[6];
var nbCores = require('os').cpus().length;

console.log("Parameters")
console.log(charset)
console.log(strlength)
console.log(salt)

console.log("Start")

main(charset, strlength, salt);

function main(charset, strlength, salt)
{
    var b36 = baseN.create({
        characters: charset
    });

    var max = b36.decode(charset[charset.length - 1].repeat(strlength));
    var each = max / nbCores;
    var limits = [];
    var workers = [];

    for (var i = 0; i < nbCores; i++) {
        var start = Math.ceil(i * each);
        if (i != nbCores - 1) {
            var end = start + Math.ceil(each);
        } else {
            var end = max;
        }

        limits.push({start: b36.encode(start), end: b36.encode(end)});
    };

    // Request
    var propertiesObject = { author: author };
    request({url: baseurl + '/GetHash', qs:propertiesObject}, function(err, response, body) {
        if(err) { console.log(err); return; }
        var hash = JSON.parse(body).hash;

	console.time('score');

        if (!hash) {
            return main(charset, strlength, salt);
        };

        console.log(JSON.parse(body).random);

        var endedWorkers = 0;
        for (var i=0 ; i<nbCores; i++) {
            var worker = childProcess.fork('child.js', [limits[i].start, limits[i].end, hash, charset, strlength, salt])
            workers.push(worker);
            worker.on('message', function (m) {
                if (m.status === 'found') {
                    killAllWorkers(workers);
        		    console.log('found');
        		    console.log(m.string);
        		    console.timeEnd('score');

                    return sendResult(m.string);
                } else if (m.status === 'end') {
                    endedWorkers++;
                    if (endedWorkers == nbCores-1) {
                        killAllWorkers(workers);
                        console.log('Not Found, Mother fucker.');
                        return main(charset, strlength, salt);
                    };
                }
            })
        }
    });
}

function killAllWorkers(workers)
{
    for (var i in workers) {
        workers[i].kill('SIGINT');
    };
}

function sendResult(result)
{
    var options = {
      uri: baseurl + '/PostSuccess',
      method: 'POST',
      json: {
        "author": author,
        "result": result
      }
    };

    request(options, function(err, response, body) {
        if (!error && response.statusCode == 200) {
            console.log('result sent');
            return main(charset, strlength, salt);
        } else {
            console.log('result error');
            setTimeout(function() {
                return sendResult(result);
            }, 100);
        }
    });
}
<|endoftext|>


<commit_before>  var sheetdata=null;
  var idx_template=[-1,-1];

  function savedata(json) {

    sheetdata=json.feed.entry;

    for (var i=0; i<sheetdata.length; i++) {
      if (sheetdata[i].gsx$keyword.$t == 'template') {
        idx_template[0]=i;
        idx_template[1]=i;
        break;
      }
    }

    sheetdata[idx_template[0]].gsx$value1.$t
    document.write('<script src="https://spreadsheets.google.com/feeds/list/' + gsheet + '/1/public/values?alt=json-in-script&callback=savedata"></'+'script>');
  }
  document.write('<script src="https://spreadsheets.google.com/feeds/list/' + gsheet + '/1/public/values?alt=json-in-script&callback=savedata"></'+'script>');
<commit_msg>Update test4-load.js<commit_after>  var sheetdata=null;
  var idx_template=[-1,-1];

  function savedata(json) {

    sheetdata=json.feed.entry;

    for (var i=0; i<sheetdata.length; i++) {
      if (sheetdata[i].gsx$keyword.$t == 'template') {
        idx_template[0]=i;
        idx_template[1]=i;
        break;
      }
    }

    document.write('<script src="//mortenkjarulff.github.io/gsheet2page/test4-' + sheetdata[idx_template[0]].gsx$value1.$t + '.js"></'+'script>');

  }
  document.write('<script src="https://spreadsheets.google.com/feeds/list/' + gsheet + '/1/public/values?alt=json-in-script&callback=savedata"></'+'script>');
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import ConcludedIssue from './ConcludedIssue';
import css from './ConcludedIssueList.css';
import { getConcludedIssues } from '../selectors/issues';
import Button from './Button';

// Maps over alternatives to see if any of them got majority vote
const calculateMajority = (alternatives, votes, voteDemand) => {
  const numTotalVotes = Object.keys(votes).length;
  return alternatives.some(alternative => Object.keys(votes)
    .map(key => votes[key])
    .filter(vote => vote.alternative === alternative.id)
    .length / numTotalVotes >= voteDemand,
  );
};

class ConcludedIssueList extends React.Component {
  constructor() {
    super();

    this.state = {
      visible: false,
    };
  }

  toggleVisibility() {
    this.setState(prevState => ({
      visible: !prevState.visible,
    }));
  }

  render() {
    const issues = this.props.issues;
    const { visible } = this.state;

    return (

        {Object.keys(issues).length > 0 && <Button
          background
          size="lg"
          onClick={() => this.toggleVisibility()}
        >
          {visible ? 'Skjul' : 'Vis'} konkluderte saker
        </Button>}

          {this.state.visible && Object.keys(issues).map(issue => (
            <ConcludedIssue
              key={issues[issue].id}
              majority={calculateMajority(
                issues[issue].alternatives,
                issues[issue].votes,
                issues[issue].voteDemand,
              )}
              {...issues[issue]}
            />
          ))}

    );
  }
}

ConcludedIssueList.propTypes = {
  issues: PropTypes.shape({
    votes: React.PropTypes.objectOf(React.PropTypes.string),
  }).isRequired,
};

export default ConcludedIssueList;

const mapStateToProps = state => ({
  issues: state.votingEnabled ?
    getConcludedIssues(state) : state.issues,
});

export const ConcludedIssueListContainer = connect(
  mapStateToProps,
)(ConcludedIssueList);
<commit_msg>Minor rewrite of calculateMajority<commit_after>import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import ConcludedIssue from './ConcludedIssue';
import css from './ConcludedIssueList.css';
import { getConcludedIssues } from '../selectors/issues';
import Button from './Button';

// Maps over alternatives to see if any of them got majority vote
const calculateMajority = (issue) => {
  const { alternatives, votes, voteDemand } = issue;
  const numTotalVotes = Object.keys(votes).length;
  const voteObjects = Object.keys(votes).map(key => votes[key]);
  return alternatives.some(
    (alternative) => {
      const votesForAlternative = voteObjects
        .filter(vote => vote.alternative === alternative.id).length;
      return votesForAlternative / numTotalVotes > voteDemand;
    },
  );
};

class ConcludedIssueList extends React.Component {
  constructor() {
    super();

    this.state = {
      visible: false,
    };
  }

  toggleVisibility() {
    this.setState(prevState => ({
      visible: !prevState.visible,
    }));
  }

  render() {
    const issues = this.props.issues;
    const { visible } = this.state;

    return (

        {Object.keys(issues).length > 0 && <Button
          background
          size="lg"
          onClick={() => this.toggleVisibility()}
        >
          {visible ? 'Skjul' : 'Vis'} konkluderte saker
        </Button>}

          {this.state.visible && Object.keys(issues).map(issue => (
            <ConcludedIssue
              key={issues[issue].id}
              majority={calculateMajority(issues[issue])}
              {...issues[issue]}
            />
          ))}

    );
  }
}

ConcludedIssueList.propTypes = {
  issues: PropTypes.shape({
    votes: React.PropTypes.objectOf(React.PropTypes.string),
  }).isRequired,
};

export default ConcludedIssueList;

const mapStateToProps = state => ({
  issues: state.votingEnabled ?
    getConcludedIssues(state) : state.issues,
});

export const ConcludedIssueListContainer = connect(
  mapStateToProps,
)(ConcludedIssueList);
<|endoftext|>


<commit_before>var fs = require('fs');

// Reads the entrie contents of a file.
fs.readFile("./index.html", {encoding: 'utf8'}, function(err, data) {
  if (err) throw err;
  parseFileContents(data);
});

// The entry function of content parsing.
function parseFileContents(contents) {
  console.log(removeIgnoreParts(contents));
}

function removeIgnoreParts(contents) {
  var pattern = /<!--\s*ignore\s*-->[\s\S]*?<!--\s*\/ignore\s*-->/gi;
  return contents.replace(pattern, '');
}<commit_msg>Update parser.js<commit_after>var fs = require('fs');

var templateRegExpStr = "<!--\\s*template:(\\S+)\\s*-->([\\s\\S]*?)<!--\\s*\/template\\s*-->";
var templateRegExp = new RegExp(templateRegExpStr, "gi");
var templateRegExpSingle = new RegExp(templateRegExpStr, "i");

// Reads the entrie contents of a file.
fs.readFile("./index.html", {encoding: 'utf8'}, function(err, data) {
  if (err) throw err;
  parseFileContents(data);
});

// The entry function of content parsing.
function parseFileContents(contents) {
  contents = removeIgnoreParts(contents);
  contents = replacePlaceHolders(contents);
  var templateParsedResult = subtractTemplate(contents);
  contents = insertTemplateTags(templateParsedResult);
  saveParsedTemplate(contents);
}

function saveParsedTemplate(contents) {
  fs.writeFile("index-tpl.html", contents, function(err) {
    if (err) throw err;
    console.log("It's saved!");
  });
}

function insertTemplateTags(templateParsedResult) {
  var contents = templateParsedResult.contents;
  var templatesArr = templateParsedResult.templatesArr;

  var templateStrArr = [];
  if (templatesArr.length) {
    for(var i = 0, len = templatesArr.length; i < len; i++) {
      templateStrArr.push(generateTemplateTag(templatesArr[i]));
    }
  }
  var templateStr = templateStrArr.join('\n\t\t\t');

  var templatesRegExp = /<!--\s*templates\s*-->/i;
  contents = contents.replace(templatesRegExp, templateStr);
  return contents;
}

/**
 * Remove all ignored HTML markups.
 * @param {string} contents
 * @returns {string}
 */
function removeIgnoreParts(contents) {
  var pattern = /<!--\s*ignore\s*-->[\s\S]*?<!--\s*\/ignore\s*-->/gi;
  return contents.replace(pattern, '');
}

/**
 * Replace place holder contents with the values we specified.
 * Note: not works well on the <img> tag.
 * @param {string} contents
 * @returns {string}
 */
function replacePlaceHolders(contents) {
  var pattern = /<!--\s*placeholder:\s*([\s\S]*?)\s*-->[\s\S]*?<!--\s*\/placeholder\s*-->/gi;
  return contents.replace(pattern, '$1');
}

/**
 * Subtract all templates from a static HTML file.
 * @param {String} contents
 * @returns {Object}
 */
function subtractTemplate(contents) {
  var templatesArr = [];
  var pattern = templateRegExp;
  var matchResult = contents.match(pattern);
  if (matchResult) {
    for (var i = 0, len = matchResult.length; i < len; i++) {
      templatesArr.push(matchResult[i]);
    }
     contents = contents.replace(pattern, '');
  }
  return {
    "contents": contents,
    "templatesArr": templatesArr
  };
}

/**
 * Generates a <script> tag to hold a template.
 * @param {String} rawTemplateString
 * @returns {String}
 */
function generateTemplateTag(rawTemplateString) {
  var pattern = templateRegExpSingle;
  var matchResult = rawTemplateString.match(pattern);
  if (matchResult) {
    var templateId = matchResult[1];
    var templateContent = matchResult[2];
    var templateString = "<script type='text/html' id='"+templateId+"'>" + templateContent + "</script>";
    return templateString;
  }
  return '';
}<|endoftext|>


<commit_before>var newBlock = require('./new-block.js');

function getColorValue(string) {
  var color = string.split('rgb(')[1];
  color = color.split(')')[0];
  return color;
}

function unitsMatch() {
  var args = Array.prototype.slice.call(arguments, 0);
  var re = /(px|%|em|rem|vh|vw)$/gi;
  var extension = args[0].match(re).toString();

  for(var i = 1; i < args.length; i++) {
    if(args[i].match(re).toString() !== extension) {
      return false;
    }
  }
  return true;
}

module.exports = function lostUtilityDecl(css) {
  css.walkDecls('lost-utility', function lostUtilityDeclFunction(decl) {
    var utilityArray = decl.value.split(' ');
    var utility = utilityArray[0];
    var color;

    if (utility === 'edit') {
      if (utilityArray[1]) {
        color = getColorValue(decl.value);

        newBlock(
          decl,
          ' *:not(input):not(textarea):not(select)',
          ['background-color'],
          ['rgba(' + color + ', 0.1)']
        );
      } else {
        newBlock(
          decl,
          ' *:not(input):not(textarea):not(select)',
          ['background-color'],
          ['rgba(0, 0, 255, 0.1)']
        );
      }
    }

    if (utility === 'clearfix') {
      newBlock(
        decl,
        ':after',
        ['content', 'display', 'clear'],
        ['\'\'', 'table', 'both']
      );

      newBlock(
        decl,
        ':before',
        ['content', 'display'],
        ['\'\'', 'table']
      );
    }

    if (utility === 'overlay') {
      var maxWidth = utilityArray[1] || '1024px',
        numCols = utilityArray[2] || 12,
        gutter = utilityArray[3] || '20px',
        totalGutter = parseFloat(gutter) * (numCols - 1),
        colWidth = (((parseFloat(maxWidth) - totalGutter) / numCols) / parseFloat(maxWidth)) * 100,
        gutterPercentage = parseFloat(gutter) / parseFloat(maxWidth) * 100,
        position = 0,
        gradient = 'to right, ';

        color = utilityArray[4] || '#e6f6ff';

      if(!unitsMatch(maxWidth, gutter)) {
        throw decl.error('lost-utility: Please use the same units for width and gutter.', { plugin: 'lost', word: 'lost-utility' });
      }

      for(var i = 1; i < numCols; i++) {
        // Start of color column
        gradient = gradient + color + ' ' + position + '%, ';

        // Move position to end of color column
        position = position + colWidth;

        // End of color column + Start of gutter column
        gradient = gradient + color + ' ' + position + '%, transparent ' + position + '%, ';

        // Move position to end of gutter column
        position = position + gutterPercentage;

        // End of gutter column
        gradient = gradient + 'transparent ' + position + '%, ';
      }

      gradient = gradient + color + ' ' + position + '%, ' + color + ' 100%';

      newBlock(
        decl,
        ':before',
        ['background-image', 'content', 'display', 'height', 'left', 'margin', 'max-width', 'opacity', 'pointer-events', 'position', 'right', 'width', 'z-index'],
        ['linear-gradient(' + gradient + ')', '\'\'', 'inline-block', '100%', '0', '0 auto', maxWidth, '0.4', 'none', 'fixed', '0', '100%', '1']
      );
    }

    if (decl.parent.nodes.length === 1) {
      decl.parent.remove();
    } else {
      decl.remove();
    }
  });
};
<commit_msg>Updates incorrect spacing introduced in last commit.<commit_after>var newBlock = require('./new-block.js');

function getColorValue(string) {
  var color = string.split('rgb(')[1];
  color = color.split(')')[0];
  return color;
}

function unitsMatch() {
  var args = Array.prototype.slice.call(arguments, 0);
  var re = /(px|%|em|rem|vh|vw)$/gi;
  var extension = args[0].match(re).toString();

  for(var i = 1; i < args.length; i++) {
    if(args[i].match(re).toString() !== extension) {
      return false;
    }
  }
  return true;
}

module.exports = function lostUtilityDecl(css) {
  css.walkDecls('lost-utility', function lostUtilityDeclFunction(decl) {
    var utilityArray = decl.value.split(' ');
    var utility = utilityArray[0];
    var color;

    if (utility === 'edit') {
      if (utilityArray[1]) {
        color = getColorValue(decl.value);

        newBlock(
          decl,
          ' *:not(input):not(textarea):not(select)',
          ['background-color'],
          ['rgba(' + color + ', 0.1)']
        );
      } else {
        newBlock(
          decl,
          ' *:not(input):not(textarea):not(select)',
          ['background-color'],
          ['rgba(0, 0, 255, 0.1)']
        );
      }
    }

    if (utility === 'clearfix') {
      newBlock(
        decl,
        ':after',
        ['content', 'display', 'clear'],
        ['\'\'', 'table', 'both']
      );

      newBlock(
        decl,
        ':before',
        ['content', 'display'],
        ['\'\'', 'table']
      );
    }

    if (utility === 'overlay') {
      var maxWidth = utilityArray[1] || '1024px',
        numCols = utilityArray[2] || 12,
        gutter = utilityArray[3] || '20px',
        totalGutter = parseFloat(gutter) * (numCols - 1),
        colWidth = (((parseFloat(maxWidth) - totalGutter) / numCols) / parseFloat(maxWidth)) * 100,
        gutterPercentage = parseFloat(gutter) / parseFloat(maxWidth) * 100,
        position = 0,
        gradient = 'to right, ';

      color = utilityArray[4] || '#e6f6ff';

      if(!unitsMatch(maxWidth, gutter)) {
        throw decl.error('lost-utility: Please use the same units for width and gutter.', { plugin: 'lost', word: 'lost-utility' });
      }

      for(var i = 1; i < numCols; i++) {
        // Start of color column
        gradient = gradient + color + ' ' + position + '%, ';

        // Move position to end of color column
        position = position + colWidth;

        // End of color column + Start of gutter column
        gradient = gradient + color + ' ' + position + '%, transparent ' + position + '%, ';

        // Move position to end of gutter column
        position = position + gutterPercentage;

        // End of gutter column
        gradient = gradient + 'transparent ' + position + '%, ';
      }

      gradient = gradient + color + ' ' + position + '%, ' + color + ' 100%';

      newBlock(
        decl,
        ':before',
        ['background-image', 'content', 'display', 'height', 'left', 'margin', 'max-width', 'opacity', 'pointer-events', 'position', 'right', 'width', 'z-index'],
        ['linear-gradient(' + gradient + ')', '\'\'', 'inline-block', '100%', '0', '0 auto', maxWidth, '0.4', 'none', 'fixed', '0', '100%', '1']
      );
    }

    if (decl.parent.nodes.length === 1) {
      decl.parent.remove();
    } else {
      decl.remove();
    }
  });
};
<|endoftext|>


<commit_before>import React, {Component} from 'react'
import API from 'api'
import dict from 'dictionary'
import autobind from 'autobind-decorator'
import {Button} from 'react-bootstrap'

import BarChart from 'components/BarChart'
import Fieldset from 'components/Fieldset'
import ReportCollection from 'components/ReportCollection'

const d3 = require('d3')
const colors = {
  barColor: '#F5CA8D',
  selectedBarColor: '#EC971F'
}
const chartId = 'not_approved_reports_chart'

/*
 * Component displaying reports submitted for approval up to the given date but
 * which have not been approved yet. They are displayed in different
 * presentation forms: chart, summary, table and map.
 */
export default class NotApprovedReports extends Component {
  static propTypes = {
    date: React.PropTypes.object,
  }

  constructor(props) {
    super(props)

    this.state = {
      date: props.date,
      graphData: [],
      reports: {list: []},
      reportsPageNum: 0,
      focusedOrg: '',
      updateChart: true  // whether the chart needs to be updated
    }
  }

  get queryParams() {
    return {
      state: ['PENDING_APPROVAL'],
      updatedAtEnd: this.state.date.valueOf(),
    }
  }

  render() {
    let chartPart = ''
    if (this.state.graphData.length) {
      chartPart = <BarChart
        chartId={chartId}
        data={this.state.graphData}
        xProp='advisorOrg.id'
        yProp='notApproved'
        xLabel='advisorOrg.shortName'
        onBarClick={this.goToOrg}
        barColor={colors.barColor}
        updateChart={this.state.updateChart}
      />
    }
    let focusDetails = this.getFocusDetails()
    return (

        {chartPart}
        <Fieldset
            title={`Not Approved Reports ${focusDetails.titleSuffix}`}
            id='not-approved-reports-details'
            action={!focusDetails.resetFnc
              ? '' : <Button onClick={() => this[focusDetails.resetFnc]()}>{focusDetails.resetButtonLabel}</Button>
            }
          >
          <ReportCollection paginatedReports={this.state.reports} goToPage={this.goToReportsPage} />
        </Fieldset>

    )
  }

  getFocusDetails() {
    let titleSuffix = ''
    let resetFnc = ''
    let resetButtonLabel = ''
    if (this.state.focusedOrg) {
      titleSuffix = `for ${this.state.focusedOrg.shortName}`
      resetFnc = 'goToOrg'
      resetButtonLabel = 'All organizations'
    }
    return {
      titleSuffix: titleSuffix,
      resetFnc: resetFnc,
      resetButtonLabel: resetButtonLabel
    }
  }

  fetchData() {
    let pinned_ORGs = dict.lookup('pinned_ORGs')
    const chartQueryParams = {}
    Object.assign(chartQueryParams, this.queryParams)
    Object.assign(chartQueryParams, {
      pageSize: 0,  // retrieve all the filtered reports
    })
    // Query used by the chart
    let chartQuery = API.query(/* GraphQL */`
        reportList(f:search, query:$chartQueryParams) {
          totalCount, list {
            ${ReportCollection.GQL_REPORT_FIELDS}
          }
        }
      `, {chartQueryParams}, '($chartQueryParams: ReportSearchQuery)')
    Promise.all([chartQuery]).then(values => {
      this.setState({
        updateChart: true,  // update chart after fetching the data
        graphData: values[0].reportList.list
          .filter((item, index, d) => d.findIndex(t => {return t.advisorOrg.id === item.advisorOrg.id }) === index)
          .map(d => {d.notApproved = values[0].reportList.list.filter(item => item.advisorOrg.id === d.advisorOrg.id).length; return d})
          .sort((a, b) => {
            let a_index = pinned_ORGs.indexOf(a.advisorOrg.shortName)
            let b_index = pinned_ORGs.indexOf(b.advisorOrg.shortName)
            if (a_index < 0)
              return (b_index < 0) ?  a.advisorOrg.shortName.localeCompare(b.advisorOrg.shortName) : 1
            else
              return (b_index < 0) ? -1 : a_index-b_index
          })
      })
    })
    this.fetchOrgData()
  }

  fetchOrgData() {
    const reportsQueryParams = {}
    Object.assign(reportsQueryParams, this.queryParams)
    Object.assign(reportsQueryParams, {pageNum: this.state.reportsPageNum})
    if (this.state.focusedOrg) {
      Object.assign(reportsQueryParams, {advisorOrgId: this.state.focusedOrg.id})
    }
    // Query used by the reports collection
    let reportsQuery = API.query(/* GraphQL */`
        reportList(f:search, query:$reportsQueryParams) {
          pageNum, pageSize, totalCount, list {
            ${ReportCollection.GQL_REPORT_FIELDS}
          }
        }
      `, {reportsQueryParams}, '($reportsQueryParams: ReportSearchQuery)')
    Promise.all([reportsQuery]).then(values => {
      this.setState({
        updateChart: false,  // only update the report list
        reports: values[0].reportList
      })
    })
  }

  @autobind
  goToReportsPage(newPage) {
    this.setState({updateChart: false, reportsPageNum: newPage}, () => this.fetchOrgData())
  }

  resetChartSelection() {
    d3.selectAll('#' + chartId + ' rect').attr('fill', colors.barColor)
  }

  @autobind
  goToOrg(item) {
    // Note: we set updateChart to false as we do not want to rerender the chart
    // when changing the focus organization.
    this.setState({updateChart: false, reportsPageNum: 0, focusedOrg: (item ? item.advisorOrg : '')}, () => this.fetchOrgData())
    // remove highlighting of the bars
    this.resetChartSelection()
    if (item) {
      // highlight the bar corresponding to the selected organization
      d3.select('#' + chartId + ' #bar_' + item.advisorOrg.id).attr('fill', colors.selectedBarColor)
    }
  }

  componentWillReceiveProps(nextProps, nextContext) {
    if (nextProps.date.valueOf() !== this.props.date.valueOf()) {
      this.setState({date: nextProps.date, focusedOrg: ''})  // reset focus when changing the date
    }
  }

  componentDidMount() {
    this.fetchData()
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevState.date.valueOf() !== this.state.date.valueOf()) {
      this.fetchData()
    }
  }

}
<commit_msg>NCI-Agency/anet#160: Turn method into getter<commit_after>import React, {Component} from 'react'
import API from 'api'
import dict from 'dictionary'
import autobind from 'autobind-decorator'
import {Button} from 'react-bootstrap'

import BarChart from 'components/BarChart'
import Fieldset from 'components/Fieldset'
import ReportCollection from 'components/ReportCollection'

const d3 = require('d3')
const colors = {
  barColor: '#F5CA8D',
  selectedBarColor: '#EC971F'
}
const chartId = 'not_approved_reports_chart'

/*
 * Component displaying reports submitted for approval up to the given date but
 * which have not been approved yet. They are displayed in different
 * presentation forms: chart, summary, table and map.
 */
export default class NotApprovedReports extends Component {
  static propTypes = {
    date: React.PropTypes.object,
  }

  constructor(props) {
    super(props)

    this.state = {
      date: props.date,
      graphData: [],
      reports: {list: []},
      reportsPageNum: 0,
      focusedOrg: '',
      updateChart: true  // whether the chart needs to be updated
    }
  }

  get queryParams() {
    return {
      state: ['PENDING_APPROVAL'],
      updatedAtEnd: this.state.date.valueOf(),
    }
  }

  render() {
    let chartPart = ''
    if (this.state.graphData.length) {
      chartPart = <BarChart
        chartId={chartId}
        data={this.state.graphData}
        xProp='advisorOrg.id'
        yProp='notApproved'
        xLabel='advisorOrg.shortName'
        onBarClick={this.goToOrg}
        barColor={colors.barColor}
        updateChart={this.state.updateChart}
      />
    }
    let focusDetails = this.focusDetails
    return (

        {chartPart}
        <Fieldset
            title={`Not Approved Reports ${focusDetails.titleSuffix}`}
            id='not-approved-reports-details'
            action={!focusDetails.resetFnc
              ? '' : <Button onClick={() => this[focusDetails.resetFnc]()}>{focusDetails.resetButtonLabel}</Button>
            }
          >
          <ReportCollection paginatedReports={this.state.reports} goToPage={this.goToReportsPage} />
        </Fieldset>

    )
  }

  get focusDetails() {
    let titleSuffix = ''
    let resetFnc = ''
    let resetButtonLabel = ''
    if (this.state.focusedOrg) {
      titleSuffix = `for ${this.state.focusedOrg.shortName}`
      resetFnc = 'goToOrg'
      resetButtonLabel = 'All organizations'
    }
    return {
      titleSuffix: titleSuffix,
      resetFnc: resetFnc,
      resetButtonLabel: resetButtonLabel
    }
  }

  fetchData() {
    let pinned_ORGs = dict.lookup('pinned_ORGs')
    const chartQueryParams = {}
    Object.assign(chartQueryParams, this.queryParams)
    Object.assign(chartQueryParams, {
      pageSize: 0,  // retrieve all the filtered reports
    })
    // Query used by the chart
    let chartQuery = API.query(/* GraphQL */`
        reportList(f:search, query:$chartQueryParams) {
          totalCount, list {
            ${ReportCollection.GQL_REPORT_FIELDS}
          }
        }
      `, {chartQueryParams}, '($chartQueryParams: ReportSearchQuery)')
    Promise.all([chartQuery]).then(values => {
      this.setState({
        updateChart: true,  // update chart after fetching the data
        graphData: values[0].reportList.list
          .filter((item, index, d) => d.findIndex(t => {return t.advisorOrg.id === item.advisorOrg.id }) === index)
          .map(d => {d.notApproved = values[0].reportList.list.filter(item => item.advisorOrg.id === d.advisorOrg.id).length; return d})
          .sort((a, b) => {
            let a_index = pinned_ORGs.indexOf(a.advisorOrg.shortName)
            let b_index = pinned_ORGs.indexOf(b.advisorOrg.shortName)
            if (a_index < 0)
              return (b_index < 0) ?  a.advisorOrg.shortName.localeCompare(b.advisorOrg.shortName) : 1
            else
              return (b_index < 0) ? -1 : a_index-b_index
          })
      })
    })
    this.fetchOrgData()
  }

  fetchOrgData() {
    const reportsQueryParams = {}
    Object.assign(reportsQueryParams, this.queryParams)
    Object.assign(reportsQueryParams, {pageNum: this.state.reportsPageNum})
    if (this.state.focusedOrg) {
      Object.assign(reportsQueryParams, {advisorOrgId: this.state.focusedOrg.id})
    }
    // Query used by the reports collection
    let reportsQuery = API.query(/* GraphQL */`
        reportList(f:search, query:$reportsQueryParams) {
          pageNum, pageSize, totalCount, list {
            ${ReportCollection.GQL_REPORT_FIELDS}
          }
        }
      `, {reportsQueryParams}, '($reportsQueryParams: ReportSearchQuery)')
    Promise.all([reportsQuery]).then(values => {
      this.setState({
        updateChart: false,  // only update the report list
        reports: values[0].reportList
      })
    })
  }

  @autobind
  goToReportsPage(newPage) {
    this.setState({updateChart: false, reportsPageNum: newPage}, () => this.fetchOrgData())
  }

  resetChartSelection() {
    d3.selectAll('#' + chartId + ' rect').attr('fill', colors.barColor)
  }

  @autobind
  goToOrg(item) {
    // Note: we set updateChart to false as we do not want to rerender the chart
    // when changing the focus organization.
    this.setState({updateChart: false, reportsPageNum: 0, focusedOrg: (item ? item.advisorOrg : '')}, () => this.fetchOrgData())
    // remove highlighting of the bars
    this.resetChartSelection()
    if (item) {
      // highlight the bar corresponding to the selected organization
      d3.select('#' + chartId + ' #bar_' + item.advisorOrg.id).attr('fill', colors.selectedBarColor)
    }
  }

  componentWillReceiveProps(nextProps, nextContext) {
    if (nextProps.date.valueOf() !== this.props.date.valueOf()) {
      this.setState({date: nextProps.date, focusedOrg: ''})  // reset focus when changing the date
    }
  }

  componentDidMount() {
    this.fetchData()
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevState.date.valueOf() !== this.state.date.valueOf()) {
      this.fetchData()
    }
  }

}
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { addSource, generateStyle, fullscreen } from '../utils';
import Video from './Video';

import './CollageCanvas.css';
// import DogGridSvg from '../svgs/dot-grid.svg';
// import PlaySvg from '../svgs/play.svg';
import FullscreenSvg from '../svgs/fullscreen.svg';
import FullscreenOffSvg from '../svgs/fullscreen-off.svg';

class CollageCanvas extends Component {

  resources = {};

  state = {
    controlsVisible: false,
    facebookHref: 'http://www.facebook.com/sharer.php?u='
  };

  constructor() {
    super();
    this.resized = this.resized.bind(this);
    this.play = this.play.bind(this);
    this.fullscreen = this.fullscreen.bind(this);
    this.redraw = this.redraw.bind(this);
  }

  redraw() {
    const devicePixelRatio = window.devicePixelRatio || 1;
    // Initiate the canvas
    const ctx = this.canvas.getContext('2d');

    if(this.resources.background) {
      const background = this.backgroundPosition();

      ctx.drawImage(this.resources.background,
                    background.x,
                    background.y,
                    background.width,
                    background.height);

      if(this.resources.videos) {
        this.resources.videos.forEach(video => {
          const width = video.width * background.width;
          const height = video.height * background.height;
          const x = background.x + video.x * background.width;
          const y = background.y + video.y * background.height;
          const rotationDeg = video.rotation / (2 * Math.PI) * 360;

          if(video.player.isFullscreen()) {
            // Make sure full-screening is not distroyed by a strange position.
            video.player.setAttribute('style', '');
          } else {
            const style = {
              width: width / devicePixelRatio + 'px',
              height: height / devicePixelRatio + 'px',
              left: x / devicePixelRatio + 'px',
              top: y / devicePixelRatio + 'px',
              transform: 'rotate(' + rotationDeg + 'deg)',
              'transform-origin': '0 0' // Rotate around the upper left corner
            };
            video.player.setAttribute('style', generateStyle(style));
          }
        });
      }
    }
  }

  resized() {
    // Considering the device pixels might be different from "pixels"
    const devicePixelRatio = window.devicePixelRatio || 1;
    // Set the height to the height of the element
    this.canvas.height = this.canvas.offsetHeight * devicePixelRatio;
    this.canvas.width = this.canvas.offsetWidth * devicePixelRatio;
    this.redraw();
  }

  /* Loads the background image and all the videos that makes up the collage */
  loadResources() {
    const collage = this.props.collage;
    // The background image
    const backgroundElement = document.createElement('img');
    backgroundElement.addEventListener('load', () => {
      // When loaded, add this as a resource
      this.resources.background = backgroundElement;
      // Add a class to display the videos
      this.videoContainer.className += ' CollageCanvas__video-container--visible';
      this.redraw();
    });
    backgroundElement.src = collage.image;
    // The videos
    this.resources.videos = [];
    collage.videos.forEach(video => {
      const element = document.createElement('video');
      const classes = 'video-js vjs-default-skin CollageCanvas__video';
      element.setAttribute('class', classes);
      // TODO: Consider putting a thumbnail in the videos poster attribute
      addSource(element, video.videoData.files.hls, 'application/x-mpegURL');
      addSource(element, video.videoData.files.rtmpMpeg4, 'rtmp/mp4');
      addSource(element, video.videoData.files.rtmpFlv, 'rtmp/flv');

      this.videoContainer.appendChild(element);
      // Initialize the videojs player
      const player = window.videojs(element, {
        controls: 'auto',
        loop: true,
        autoplay: true,
        preload: 'auto',
        muted: true,
        bigPlayButton: false,
        inactivityTimeout: 500,
        poster: video.videoData.files.thumbnail,
        techOrder: ['html5', 'flash'],
        controlBar: {
          playToggle: false,
          progressControl: false,
          remainingTimeDisplay: false,
          fullscreenToggle: false
        }
      });

      this.resources.videos.push({
        element,
        player,
        x: video.xPos,
        y: video.yPos,
        width: video.width,
        height: video.height,
        rotation: video.rotation
      });

      // If the video needs a user gesture to start, we show the controls.
      player.on('suspend', (e) => {
        if(player.paused()) {
          this.showControls();
        }
      });
      // When the video starts playing the large collage control get hidden.
      player.on('play', this.hideControls);
      player.on('useractive', () => {
        // and start playing this
        player.play();
        // unmute
        player.muted(false);
        // Mute all other players
        this.muteAllPlayers(player);
      });
      // TODO: Add a listner on error as well ...
    });
    this.redraw();
  }

  play() {
    // Loop though all the video elements and start playback
    this.resources.videos.forEach(video => {
      if(!video.player.paused()) {
        video.player.pause();
      }
      video.player.play();
    });
  }

  fullscreen() {
    if (!fullscreen.is()) {
      fullscreen.request(this.everything);
    } else {
      fullscreen.exit();
    }
    // Update the state
    this.setState({
      fullscreen: fullscreen.is()
    });
  }

  muteAllPlayers(exceptPlayer) {
    this.resources.videos.forEach(video => {
      if(video.player !== exceptPlayer) {
        video.player.muted(true);
      }
    });
  }

  backgroundPosition() {
    const background = this.resources.background;
    const canvas = this.canvas;

    const canvasRatio = canvas.width / canvas.height;
    const backgroundRatio = background.width / background.height;

    if(canvasRatio > backgroundRatio) {
      const height = canvas.height;
      const width = canvas.height * backgroundRatio;
      return {
        height,
        width,
        x: (canvas.width - width) / 2,
        y: 0
      }
    } else {
      const height = canvas.width / backgroundRatio;
      const width = canvas.width;
      return {
        height,
        width,
        x: 0,
        y: (canvas.height - height) / 2
      }
    }
  }

  componentDidMount() {
    window.addEventListener('resize', this.resized);
    this.resized();
    this.loadResources();
    // Redraw when fullscreen changes
    fullscreen.addListener(this.redraw);
    // Set the facebook url to share the current URL
    const url = location.href;
    this.setState({
      facebookHref: 'http://www.facebook.com/sharer.php?u=' + url
    });
  }

  componentDidUpdate(prevProps, prevState) {
    if(prevProps.collage.id !== this.props.collage.id) {
      this.loadResources();
    }
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.resized);
    this.resources.videos.forEach(video => {
      video.player.off('suspend');
      video.player.off('play');
      video.player.off('volumechange');
    });
    // Redraw when fullscreen changes
    fullscreen.removeListener(this.redraw);
  }

  render() {
    return (

 { this.everything = e; }}>
        <canvas className="CollageCanvas__canvas"
          ref={(e) => { this.canvas = e; }} />

 { this.videoContainer = e; }} />

          Del på Facebook

          {this.state.fullscreen ? (

          ) : (

          )}

    );
  }
}

CollageCanvas.propTypes = {
  collage: PropTypes.object.isRequired
};

export default CollageCanvas;
<commit_msg>Added name and proptypes to start of component<commit_after>import React, { Component, PropTypes } from 'react';
import { addSource, generateStyle, fullscreen } from '../utils';
import Video from './Video';

import './CollageCanvas.css';
// import DogGridSvg from '../svgs/dot-grid.svg';
// import PlaySvg from '../svgs/play.svg';
import FullscreenSvg from '../svgs/fullscreen.svg';
import FullscreenOffSvg from '../svgs/fullscreen-off.svg';

export default class CollageCanvas extends Component {
  static propTypes = {
    collage: PropTypes.object.isRequired
  }

  constructor() {
    super();
    this.resized = this.resized.bind(this);
    this.play = this.play.bind(this);
    this.fullscreen = this.fullscreen.bind(this);
    this.redraw = this.redraw.bind(this);
  }

  redraw() {
    const devicePixelRatio = window.devicePixelRatio || 1;
    // Initiate the canvas
    const ctx = this.canvas.getContext('2d');

    if(this.resources.background) {
      const background = this.backgroundPosition();

      ctx.drawImage(this.resources.background,
                    background.x,
                    background.y,
                    background.width,
                    background.height);

      if(this.resources.videos) {
        this.resources.videos.forEach(video => {
          const width = video.width * background.width;
          const height = video.height * background.height;
          const x = background.x + video.x * background.width;
          const y = background.y + video.y * background.height;
          const rotationDeg = video.rotation / (2 * Math.PI) * 360;

          if(video.player.isFullscreen()) {
            // Make sure full-screening is not distroyed by a strange position.
            video.player.setAttribute('style', '');
          } else {
            const style = {
              width: width / devicePixelRatio + 'px',
              height: height / devicePixelRatio + 'px',
              left: x / devicePixelRatio + 'px',
              top: y / devicePixelRatio + 'px',
              transform: 'rotate(' + rotationDeg + 'deg)',
              'transform-origin': '0 0' // Rotate around the upper left corner
            };
            video.player.setAttribute('style', generateStyle(style));
          }
        });
      }
    }
  }

  resized() {
    // Considering the device pixels might be different from "pixels"
    const devicePixelRatio = window.devicePixelRatio || 1;
    // Set the height to the height of the element
    this.canvas.height = this.canvas.offsetHeight * devicePixelRatio;
    this.canvas.width = this.canvas.offsetWidth * devicePixelRatio;
    this.redraw();
  }

  /* Loads the background image and all the videos that makes up the collage */
  loadResources() {
    const collage = this.props.collage;
    // The background image
    const backgroundElement = document.createElement('img');
    backgroundElement.addEventListener('load', () => {
      // When loaded, add this as a resource
      this.resources.background = backgroundElement;
      // Add a class to display the videos
      this.videoContainer.className += ' CollageCanvas__video-container--visible';
      this.redraw();
    });
    backgroundElement.src = collage.image;
    // The videos
    this.resources.videos = [];
    collage.videos.forEach(video => {
      const element = document.createElement('video');
      const classes = 'video-js vjs-default-skin CollageCanvas__video';
      element.setAttribute('class', classes);
      // TODO: Consider putting a thumbnail in the videos poster attribute
      addSource(element, video.videoData.files.hls, 'application/x-mpegURL');
      addSource(element, video.videoData.files.rtmpMpeg4, 'rtmp/mp4');
      addSource(element, video.videoData.files.rtmpFlv, 'rtmp/flv');

      this.videoContainer.appendChild(element);
      // Initialize the videojs player
      const player = window.videojs(element, {
        controls: 'auto',
        loop: true,
        autoplay: true,
        preload: 'auto',
        muted: true,
        bigPlayButton: false,
        inactivityTimeout: 500,
        poster: video.videoData.files.thumbnail,
        techOrder: ['html5', 'flash'],
        controlBar: {
          playToggle: false,
          progressControl: false,
          remainingTimeDisplay: false,
          fullscreenToggle: false
        }
      });

      this.resources.videos.push({
        element,
        player,
        x: video.xPos,
        y: video.yPos,
        width: video.width,
        height: video.height,
        rotation: video.rotation
      });

      // If the video needs a user gesture to start, we show the controls.
      player.on('suspend', (e) => {
        if(player.paused()) {
          this.showControls();
        }
      });
      // When the video starts playing the large collage control get hidden.
      player.on('play', this.hideControls);
      player.on('useractive', () => {
        // and start playing this
        player.play();
        // unmute
        player.muted(false);
        // Mute all other players
        this.muteAllPlayers(player);
      });
      // TODO: Add a listner on error as well ...
    });
    this.redraw();
  }

  play() {
    // Loop though all the video elements and start playback
    this.resources.videos.forEach(video => {
      if(!video.player.paused()) {
        video.player.pause();
      }
      video.player.play();
    });
  }

  fullscreen() {
    if (!fullscreen.is()) {
      fullscreen.request(this.everything);
    } else {
      fullscreen.exit();
    }
    // Update the state
    this.setState({
      fullscreen: fullscreen.is()
    });
  }

  muteAllPlayers(exceptPlayer) {
    this.resources.videos.forEach(video => {
      if(video.player !== exceptPlayer) {
        video.player.muted(true);
      }
    });
  }

  backgroundPosition() {
    const background = this.resources.background;
    const canvas = this.canvas;

    const canvasRatio = canvas.width / canvas.height;
    const backgroundRatio = background.width / background.height;

    if(canvasRatio > backgroundRatio) {
      const height = canvas.height;
      const width = canvas.height * backgroundRatio;
      return {
        height,
        width,
        x: (canvas.width - width) / 2,
        y: 0
      }
    } else {
      const height = canvas.width / backgroundRatio;
      const width = canvas.width;
      return {
        height,
        width,
        x: 0,
        y: (canvas.height - height) / 2
      }
    }
  }

  componentDidMount() {
    window.addEventListener('resize', this.resized);
    this.resized();
    this.loadResources();
    // Redraw when fullscreen changes
    fullscreen.addListener(this.redraw);
    // Set the facebook url to share the current URL
    const url = location.href;
    this.setState({
      facebookHref: 'http://www.facebook.com/sharer.php?u=' + url
    });
  }

  componentDidUpdate(prevProps, prevState) {
    if(prevProps.collage.id !== this.props.collage.id) {
      this.loadResources();
    }
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.resized);
    this.resources.videos.forEach(video => {
      video.player.off('suspend');
      video.player.off('play');
      video.player.off('volumechange');
    });
    // Redraw when fullscreen changes
    fullscreen.removeListener(this.redraw);
  }

  render() {
    return (

 { this.everything = e; }}>
        <canvas className="CollageCanvas__canvas"
          ref={(e) => { this.canvas = e; }} />

 { this.videoContainer = e; }} />

          Del på Facebook

          {this.state.fullscreen ? (

          ) : (

          )}

    );
  }
}

<|endoftext|>


<commit_before>Template.dashboardCounts.created = function () {
    this.subscribe("linensCount");
};

Template.dashboardCounts.helpers({
    'linensCount': function () {
        // Return the linens count
        return linensCount = Counts.get('linensCount');
    }
});
<commit_msg>Add jymCount and yafCount helpers; cleanup<commit_after>Template.dashboardCounts.created = function () {
    this.subscribe("linensCount");
    this.subscribe("jymCount");
    this.subscribe("yafCount");
};

Template.dashboardCounts.helpers({
    'linensCount': function () {
        // Return the linens count
        return Counts.get('linensCount');
    },
    'jymCount': function () {
        // Return the linens count
        return Counts.get('jymCount');
    },
    'yafCount': function () {
        // Return the linens count
        return Counts.get('yafCount');
    }
});
<|endoftext|>