<commit_before>/*
 *  Project:        Symfony2Admingenerator
 *  Description:    jQuery plugin for List Batch actions
 *  Author:         loostro <loostro@gmail.com>
 *  License:        MIT
 */

// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
;(function ( $, window, undefined ) {

    // undefined is used here as the undefined global variable in ECMAScript 3 is
    // mutable (ie. it can be changed by someone else). undefined isn't really being
    // passed in so we can ensure the value of it is truly undefined. In ES5, undefined
    // can no longer be modified.

    // window is passed through as local variable rather than global
    // as this (slightly) quickens the resolution process and can be more efficiently
    // minified (especially when both are regularly referenced in your plugin).

    // Create the defaults once
    var pluginName = 'agen$collection',
        document = window.document,
        defaults = {
            allow_add:        false,
            allow_delete:     false,
            sortable:         false,
            sortable_field:   'position',
            prototype_name:   '__name__',
            trans: {
                new_label:      'New item',
                confirm:        'Are you sure you want to delete this element?',
                confirm_batch:  'Are you sure you want to delete all selected elements?'
            }
        };

    // The actual plugin constructor
    function Plugin( element, options ) {
        this.element = element;

        // jQuery has an extend method which merges the contents of two or
        // more objects, storing the result in the first object. The first object
        // is generally empty as we don't want to alter the default options for
        // future instances of the plugin
        this.options = $.extend( {}, defaults, options) ;

        this._defaults = defaults;
        this._name = pluginName;

        this._init();
    }

    Plugin.prototype = {

        _init: function() {
            // Plugin-scope helper
            var that = this;

            // Configure allow add
            if (this.options.allow_add) {
                this.$new   = $('#'+ this.element.id +'_toolbar > .new');
                this.nextId = $('#'+ this.element.id +' > .collection > .collection-item').length;

                this.$new.on('click', function(e) {
                    e.preventDefault();
                    that._onAdd();
                });
            }

            // Configure allow delete
            if (this.options.allow_delete) {

                // remove item
                $('.'+ this.element.id + '_actions .delete').click(function(e){
                    e.preventDefault();
                    that._onDelete();
                });

                // select/deselect all
                this.$selectAll = $('#'+ this.element.id + '_toolbar > .btn-toggle > input[name="toggle"]');

                this.$selectAll.on('change', function(e) {
                    e.preventDefault();
                    that._onSelectAll();
                });

                // delete selected
                $('#'+ this.element.id + '_toolbar > .batch-delete').click(function() {
                    this._onDeleteAll();
                });
            }

            // Init sortable
            if (this.options.sortable) {
                $('#' + this.element.id + ' > .collection').sortable({
                    update: function(e, ui) {
                        that._onChange();
                    }
                });
            }
        },

        _onAdd: function() {
            var new_item = $('#'+ this.element.id).data('prototype');
            var new_id = this.nextId;
            new_item = new_item.replace('/' + this.options.prototype_name + 'label__/g', this.options.trans.new_label);
            new_item = new_item.replace('/' + this.options.prototype_name + '/g', new_id);
            $new_item = $(new_item);

            if (this.options.allow_delete) {
                var that = this;
                $new_item.find('.delete').click(function(){
                    that._onDelete(this);
                });
            }

            this.nextId++;
            $('#'+ this.element.id +' > .collection').append($new_item);

            console.log('here we should enable any javascript for the new field');

            if (this.options.sortable) {
                this._onChange();
            }
        },

        _onDelete: function(button) {
            if (confirm(this.options.trans.confirm)) {
                $(button).closest('.collection-item').remove();

                if (this.options.sortable) {
                    this._onChange();
                }
            }
        },

        _onChange: function() {
            // update sortable positions
            $('[id^="'+ this.element.id +'"][id$="'+ this.options.sortable_field +'"]').each(function(i){
                $(this).val(i);
            });
        },

        _onSelectAll: function() {
            if (this.$selectAll.is(':checked')) {
                $('.'+ this.element.id + '_actions > .btn-toggle > input[name="delete"]').attr('checked', true);
            } else {
                $('.'+ this.element.id + '_actions > .btn-toggle > input[name="delete"]').attr('checked', false);
            }
        },

        _onUnselectAll: function() {
            $('#'+ this.element.id + '_toolbar > .btn-toggle > input[name="toggle"]').attr('checked', false);
        },

        _onDeleteAll: function() {
            if (confirm(this.options.trans.confirm_batch)) {
                $('.'+ this.element.id + '_actions > .btn-toggle > input[name="delete"]:checked').each(function(){
                      $(this).closest('.collection-item').remove();
                });

                if (this.options.sortable) {
                    this._onChange();
                }

                this._onUnselectAll();
            }
        }

    };

    // You don't need to change something below:
    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations and allowing any
    // public function (ie. a function whose name doesn't start
    // with an underscore) to be called via the jQuery plugin,
    // e.g. $(element).defaultPluginName('functionName', arg1, arg2)
    $.fn[pluginName] = function ( options ) {
        var args = arguments;

        // Is the first parameter an object (options), or was omitted,
        // instantiate a new instance of the plugin.
        if (options === undefined || typeof options === 'object') {
            return this.each(function () {

                // Only allow the plugin to be instantiated once,
                // so we check that the element has no plugin instantiation yet
                if (!$.data(this, 'plugin_' + pluginName)) {

                    // if it has no instance, create a new one,
                    // pass options to our plugin constructor,
                    // and store the plugin instance
                    // in the elements jQuery data object.
                    $.data(this, 'plugin_' + pluginName, new Plugin( this, options ));
                }
            });

        // If the first parameter is a string and it doesn't start
        // with an underscore or "contains" the `init`-function,
        // treat this as a call to a public method.
        } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {

            // Cache the method call
            // to make it possible
            // to return a value
            var returns;

            this.each(function () {
                var instance = $.data(this, 'plugin_' + pluginName);

                // Tests that there's already a plugin-instance
                // and checks that the requested public method exists
                if (instance instanceof Plugin && typeof instance[options] === 'function') {

                    // Call the method of our plugin instance,
                    // and pass it the supplied arguments.
                    returns = instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) );
                }

                // Allow instances to be destroyed via the 'destroy' method
                if (options === 'destroy') {
                  $.data(this, 'plugin_' + pluginName, null);
                }
            });

            // If the earlier cached method
            // gives a value back return the value,
            // otherwise return this to preserve chainability.
            return returns !== undefined ? returns : this;
        }
    };

}(jQuery, window));
<commit_msg>Update collection.js<commit_after>/*
 *  Project:        Symfony2Admingenerator
 *  Description:    jQuery plugin for List Batch actions
 *  Author:         loostro <loostro@gmail.com>
 *  License:        MIT
 */

// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
;(function ( $, window, undefined ) {

    // undefined is used here as the undefined global variable in ECMAScript 3 is
    // mutable (ie. it can be changed by someone else). undefined isn't really being
    // passed in so we can ensure the value of it is truly undefined. In ES5, undefined
    // can no longer be modified.

    // window is passed through as local variable rather than global
    // as this (slightly) quickens the resolution process and can be more efficiently
    // minified (especially when both are regularly referenced in your plugin).

    // Create the defaults once
    var pluginName = 'agen$collection',
        document = window.document,
        defaults = {
            allow_add:        false,
            allow_delete:     false,
            sortable:         false,
            sortable_field:   'position',
            prototype_name:   '__name__',
            trans: {
                new_label:      'New item',
                confirm:        'Are you sure you want to delete this element?',
                confirm_batch:  'Are you sure you want to delete all selected elements?'
            }
        };

    // The actual plugin constructor
    function Plugin( element, options ) {
        this.element = element;

        // jQuery has an extend method which merges the contents of two or
        // more objects, storing the result in the first object. The first object
        // is generally empty as we don't want to alter the default options for
        // future instances of the plugin
        this.options = $.extend( {}, defaults, options) ;

        this._defaults = defaults;
        this._name = pluginName;

        this._init();
    }

    Plugin.prototype = {

        _init: function() {
            // Plugin-scope helper
            var that = this;

            // Configure allow add
            if (this.options.allow_add) {
                this.$new   = $('#'+ this.element.id +'_toolbar > .new');
                this.nextId = $('#'+ this.element.id +' > .collection > .collection-item').length;

                this.$new.on('click', function(e) {
                    e.preventDefault();
                    that._onAdd();
                });
            }

            // Configure allow delete
            if (this.options.allow_delete) {

                // remove item
                $('.'+ this.element.id + '_actions .delete').click(function(e){
                    e.preventDefault();
                    that._onDelete(this);
                });

                // select/deselect all
                this.$selectAll = $('#'+ this.element.id + '_toolbar > .btn-toggle > input[name="toggle"]');

                this.$selectAll.on('change', function(e) {
                    e.preventDefault();
                    that._onSelectAll();
                });

                // delete selected
                $('#'+ this.element.id + '_toolbar > .batch-delete').click(function() {
                    this._onDeleteAll();
                });
            }

            // Init sortable
            if (this.options.sortable) {
                $('#' + this.element.id + ' > .collection').sortable({
                    update: function(e, ui) {
                        that._onChange();
                    }
                });
            }
        },

        _onAdd: function() {
            var new_item = $('#'+ this.element.id).data('prototype');
            var new_id = this.nextId;
            new_item = new_item.replace('/' + this.options.prototype_name + 'label__/g', this.options.trans.new_label);
            new_item = new_item.replace('/' + this.options.prototype_name + '/g', new_id);
            $new_item = $(new_item);

            if (this.options.allow_delete) {
                var that = this;
                $new_item.find('.delete').click(function(){
                    that._onDelete(this);
                });
            }

            this.nextId++;
            $('#'+ this.element.id +' > .collection').append($new_item);

            console.log('here we should enable any javascript for the new field');

            if (this.options.sortable) {
                this._onChange();
            }
        },

        _onDelete: function(button) {
            if (confirm(this.options.trans.confirm)) {
                $(button).closest('.collection-item').remove();

                if (this.options.sortable) {
                    this._onChange();
                }
            }
        },

        _onChange: function() {
            // update sortable positions
            $('[id^="'+ this.element.id +'"][id$="'+ this.options.sortable_field +'"]').each(function(i){
                $(this).val(i);
            });
        },

        _onSelectAll: function() {
            if (this.$selectAll.is(':checked')) {
                $('.'+ this.element.id + '_actions > .btn-toggle > input[name="delete"]').attr('checked', true);
            } else {
                $('.'+ this.element.id + '_actions > .btn-toggle > input[name="delete"]').attr('checked', false);
            }
        },

        _onUnselectAll: function() {
            $('#'+ this.element.id + '_toolbar > .btn-toggle > input[name="toggle"]').attr('checked', false);
        },

        _onDeleteAll: function() {
            if (confirm(this.options.trans.confirm_batch)) {
                $('.'+ this.element.id + '_actions > .btn-toggle > input[name="delete"]:checked').each(function(){
                      $(this).closest('.collection-item').remove();
                });

                if (this.options.sortable) {
                    this._onChange();
                }

                this._onUnselectAll();
            }
        }

    };

    // You don't need to change something below:
    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations and allowing any
    // public function (ie. a function whose name doesn't start
    // with an underscore) to be called via the jQuery plugin,
    // e.g. $(element).defaultPluginName('functionName', arg1, arg2)
    $.fn[pluginName] = function ( options ) {
        var args = arguments;

        // Is the first parameter an object (options), or was omitted,
        // instantiate a new instance of the plugin.
        if (options === undefined || typeof options === 'object') {
            return this.each(function () {

                // Only allow the plugin to be instantiated once,
                // so we check that the element has no plugin instantiation yet
                if (!$.data(this, 'plugin_' + pluginName)) {

                    // if it has no instance, create a new one,
                    // pass options to our plugin constructor,
                    // and store the plugin instance
                    // in the elements jQuery data object.
                    $.data(this, 'plugin_' + pluginName, new Plugin( this, options ));
                }
            });

        // If the first parameter is a string and it doesn't start
        // with an underscore or "contains" the `init`-function,
        // treat this as a call to a public method.
        } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {

            // Cache the method call
            // to make it possible
            // to return a value
            var returns;

            this.each(function () {
                var instance = $.data(this, 'plugin_' + pluginName);

                // Tests that there's already a plugin-instance
                // and checks that the requested public method exists
                if (instance instanceof Plugin && typeof instance[options] === 'function') {

                    // Call the method of our plugin instance,
                    // and pass it the supplied arguments.
                    returns = instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) );
                }

                // Allow instances to be destroyed via the 'destroy' method
                if (options === 'destroy') {
                  $.data(this, 'plugin_' + pluginName, null);
                }
            });

            // If the earlier cached method
            // gives a value back return the value,
            // otherwise return this to preserve chainability.
            return returns !== undefined ? returns : this;
        }
    };

}(jQuery, window));
<|endoftext|>


<commit_before>/*global define*/
define(['../Core/defined',
        '../Core/AssociativeArray',
        '../Core/ShowGeometryInstanceAttribute',
        '../Scene/Primitive',
        '../Scene/Material',
        '../Scene/PrimitiveState',
        './MaterialProperty'
    ], function(
        defined,
        AssociativeArray,
        ShowGeometryInstanceAttribute,
        Primitive,
        Material,
        PrimitiveState,
        MaterialProperty) {
    "use strict";

    var Batch = function(primitives, appearanceType, materialProperty, closed) {
        this.primitives = primitives;
        this.appearanceType = appearanceType;
        this.materialProperty = materialProperty;
        this.closed = closed;
        this.updaters = new AssociativeArray();
        this.createPrimitive = true;
        this.primitive = undefined;
        this.geometry = new AssociativeArray();
        this.material = Material.fromType('Color');
        this.updatersWithAttributes = new AssociativeArray();
        this.attributes = new AssociativeArray();
        this.invalidated = false;
        this.removeMaterialSubscription = materialProperty.definitionChanged.addEventListener(Batch.prototype.onMaterialChanged, this);
    };

    Batch.prototype.onMaterialChanged = function() {
        this.invalidated = true;
    };

    Batch.prototype.isMaterial = function(updater) {
        var material = this.materialProperty;
        var updaterMaterial = updater.fillMaterialProperty;
        if (updaterMaterial === material) {
            return true;
        }
        if (defined(material)) {
            return material.equals(updaterMaterial);
        }
        return false;
    };

    Batch.prototype.add = function(time, updater) {
        var id = updater.dynamicObject.id;
        this.updaters.set(id, updater);
        this.geometry.set(id, updater.createFillGeometryInstance(time));
        if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant) {
            this.updatersWithAttributes.set(id, updater);
        }
        this.createPrimitive = true;
    };

    Batch.prototype.remove = function(updater) {
        var id = updater.dynamicObject.id;
        this.createPrimitive = this.updaters.remove(id);
        this.geometry.remove(id);
        this.updatersWithAttributes.remove(id);
        return this.createPrimitive;
    };

    Batch.prototype.update = function(time) {
        var primitive = this.primitive;
        var primitives = this.primitives;
        var geometries = this.geometry.values;
        if (this.createPrimitive) {
            if (defined(primitive)) {
                primitives.remove(primitive);
            }
            if (geometries.length > 0) {
                primitive = new Primitive({
                    asynchronous : false,
                    geometryInstances : geometries,
                    appearance : new this.appearanceType({
                        material : MaterialProperty.getValue(time, this.materialProperty, this.material),
                        translucent : this.material.isTranslucent(),
                        closed : this.closed
                    })
                });

                primitives.add(primitive);
            }
            this.primitive = primitive;
            this.createPrimitive = false;
        } else if (defined(primitive) && primitive._state === PrimitiveState.COMPLETE){
            this.primitive.appearance.material = MaterialProperty.getValue(time, this.materialProperty, this.material);

            var updatersWithAttributes = this.updatersWithAttributes.values;
            var length = updatersWithAttributes.length;
            for (var i = 0; i < length; i++) {
                var updater = updatersWithAttributes[i];
                var instance = this.geometry.get(updater.dynamicObject.id);

                var attributes = this.attributes.get(instance.id.id);
                if (!defined(attributes)) {
                    attributes = primitive.getGeometryInstanceAttributes(instance.id);
                    this.attributes.set(instance.id.id, attributes);
                }

                if (!updater.hasConstantFill) {
                    attributes.show = ShowGeometryInstanceAttribute.toValue(updater.isFilled(time), attributes.show);
                }
            }
        }
    };

    Batch.prototype.destroy = function(time) {
        var primitive = this.primitive;
        var primitives = this.primitives;
        if (defined(primitive)) {
            primitives.remove(primitive);
        }
        this.removeMaterialSubscription();
    };

    /**
     * @private
     */
    var StaticGeometryPerMaterialBatch = function(primitives, appearanceType, closed) {
        this._items = [];
        this._primitives = primitives;
        this._appearanceType = appearanceType;
        this._closed = closed;
    };

    StaticGeometryPerMaterialBatch.prototype.add = function(time, updater) {
        var items = this._items;
        var length = items.length;
        for (var i = 0; i < length; i++) {
            var item = items[i];
            if (item.isMaterial(updater)) {
                item.add(time, updater);
                return;
            }
        }
        var batch = new Batch(this._primitives, this._appearanceType, updater.fillMaterialProperty, this._closed);
        batch.add(time, updater);
        items.push(batch);
    };

    StaticGeometryPerMaterialBatch.prototype.remove = function(updater) {
        var items = this._items;
        var length = items.length;
        for (var i = length - 1; i >= 0; i--) {
            var item = items[i];
            if (item.remove(updater)) {
                if (item.updaters.length === 0) {
                    items.splice(i, 1);
                    item.destroy();
                }
                break;
            }
        }
    };

    StaticGeometryPerMaterialBatch.prototype.update = function(time) {
        var i;
        var items = this._items;
        var length = items.length;

        for (i = length - 1; i >= 0; i--) {
            var item = items[i];
            if (item.invalidated) {
                items.splice(i, 1);
                var updaters = item.updaters.values;
                var updatersLength = updaters.length;
                for (var h = 0; h < updatersLength; i++) {
                    this.add(updaters[h]);
                }
                item.destroy();
            }
        }

        for (i = 0; i < length; i++) {
            items[i].update(time);
        }
    };

    StaticGeometryPerMaterialBatch.prototype.removeAllPrimitives = function() {
        var items = this._items;
        var length = items.length;
        for (var i = 0; i < length; i++) {
            items[i].destroy();
        }
        this._items.length = 0;
    };

    return StaticGeometryPerMaterialBatch;
});
<commit_msg>Fix memory pressure issue with StaticGeometryPerMaterialBatch<commit_after>/*global define*/
define(['../Core/defined',
        '../Core/AssociativeArray',
        '../Core/ShowGeometryInstanceAttribute',
        '../Scene/Primitive',
        '../Scene/Material',
        '../Scene/PrimitiveState',
        './MaterialProperty'
    ], function(
        defined,
        AssociativeArray,
        ShowGeometryInstanceAttribute,
        Primitive,
        Material,
        PrimitiveState,
        MaterialProperty) {
    "use strict";

    var Batch = function(primitives, appearanceType, materialProperty, closed) {
        this.primitives = primitives;
        this.appearanceType = appearanceType;
        this.materialProperty = materialProperty;
        this.closed = closed;
        this.updaters = new AssociativeArray();
        this.createPrimitive = true;
        this.primitive = undefined;
        this.geometry = new AssociativeArray();
        this.material = Material.fromType('Color');
        this.updatersWithAttributes = new AssociativeArray();
        this.attributes = new AssociativeArray();
        this.invalidated = false;
        this.removeMaterialSubscription = materialProperty.definitionChanged.addEventListener(Batch.prototype.onMaterialChanged, this);
    };

    Batch.prototype.onMaterialChanged = function() {
        this.invalidated = true;
    };

    Batch.prototype.isMaterial = function(updater) {
        var material = this.materialProperty;
        var updaterMaterial = updater.fillMaterialProperty;
        if (updaterMaterial === material) {
            return true;
        }
        if (defined(material)) {
            return material.equals(updaterMaterial);
        }
        return false;
    };

    Batch.prototype.add = function(time, updater) {
        var id = updater.dynamicObject.id;
        this.updaters.set(id, updater);
        this.geometry.set(id, updater.createFillGeometryInstance(time));
        if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant) {
            this.updatersWithAttributes.set(id, updater);
        }
        this.createPrimitive = true;
    };

    Batch.prototype.remove = function(updater) {
        var id = updater.dynamicObject.id;
        this.createPrimitive = this.updaters.remove(id);
        this.geometry.remove(id);
        this.updatersWithAttributes.remove(id);
        return this.createPrimitive;
    };

    Batch.prototype.update = function(time) {
        var primitive = this.primitive;
        var primitives = this.primitives;
        var geometries = this.geometry.values;
        if (this.createPrimitive) {
            if (defined(primitive)) {
                primitives.remove(primitive);
            }
            if (geometries.length > 0) {
                this.material = MaterialProperty.getValue(time, this.materialProperty, this.material);
                primitive = new Primitive({
                    asynchronous : false,
                    geometryInstances : geometries,
                    appearance : new this.appearanceType({
                        material : this.material,
                        translucent : this.material.isTranslucent(),
                        closed : this.closed
                    })
                });

                primitives.add(primitive);
            }
            this.primitive = primitive;
            this.createPrimitive = false;
        } else if (defined(primitive) && primitive._state === PrimitiveState.COMPLETE) {
            this.material = MaterialProperty.getValue(time, this.materialProperty, this.material);
            this.primitive.appearance.material = this.material;

            var updatersWithAttributes = this.updatersWithAttributes.values;
            var length = updatersWithAttributes.length;
            for (var i = 0; i < length; i++) {
                var updater = updatersWithAttributes[i];
                var instance = this.geometry.get(updater.dynamicObject.id);

                var attributes = this.attributes.get(instance.id.id);
                if (!defined(attributes)) {
                    attributes = primitive.getGeometryInstanceAttributes(instance.id);
                    this.attributes.set(instance.id.id, attributes);
                }

                if (!updater.hasConstantFill) {
                    attributes.show = ShowGeometryInstanceAttribute.toValue(updater.isFilled(time), attributes.show);
                }
            }
        }
    };

    Batch.prototype.destroy = function(time) {
        var primitive = this.primitive;
        var primitives = this.primitives;
        if (defined(primitive)) {
            primitives.remove(primitive);
        }
        this.removeMaterialSubscription();
    };

    /**
     * @private
     */
    var StaticGeometryPerMaterialBatch = function(primitives, appearanceType, closed) {
        this._items = [];
        this._primitives = primitives;
        this._appearanceType = appearanceType;
        this._closed = closed;
    };

    StaticGeometryPerMaterialBatch.prototype.add = function(time, updater) {
        var items = this._items;
        var length = items.length;
        for (var i = 0; i < length; i++) {
            var item = items[i];
            if (item.isMaterial(updater)) {
                item.add(time, updater);
                return;
            }
        }
        var batch = new Batch(this._primitives, this._appearanceType, updater.fillMaterialProperty, this._closed);
        batch.add(time, updater);
        items.push(batch);
    };

    StaticGeometryPerMaterialBatch.prototype.remove = function(updater) {
        var items = this._items;
        var length = items.length;
        for (var i = length - 1; i >= 0; i--) {
            var item = items[i];
            if (item.remove(updater)) {
                if (item.updaters.length === 0) {
                    items.splice(i, 1);
                    item.destroy();
                }
                break;
            }
        }
    };

    StaticGeometryPerMaterialBatch.prototype.update = function(time) {
        var i;
        var items = this._items;
        var length = items.length;

        for (i = length - 1; i >= 0; i--) {
            var item = items[i];
            if (item.invalidated) {
                items.splice(i, 1);
                var updaters = item.updaters.values;
                var updatersLength = updaters.length;
                for (var h = 0; h < updatersLength; i++) {
                    this.add(updaters[h]);
                }
                item.destroy();
            }
        }

        for (i = 0; i < length; i++) {
            items[i].update(time);
        }
    };

    StaticGeometryPerMaterialBatch.prototype.removeAllPrimitives = function() {
        var items = this._items;
        var length = items.length;
        for (var i = 0; i < length; i++) {
            items[i].destroy();
        }
        this._items.length = 0;
    };

    return StaticGeometryPerMaterialBatch;
});
<|endoftext|>


<commit_before>/**
 * Created by 3er on 1/9/15.
 */

var qs = require('querystring');
var path = require('path');
var fs = require('fs');
var PRIVATE = require('./config/private')

var AND = ' && ';
var FFMPEG = ' ./ffmpeg ';

//前面有可能跟路径不能带空格
var h = function (d) {
    return {
        dir: d,
        origin: d + '/h.mp4 ',
        compo: d + '/h.list ',
        output: d + '/outputh.mp4 ',
        target: 'high/'
    }
};

var m = function (d) {
    return {
        dir: d,
        origin: d + '/m.mp4 ',
        compo: d + '/m.list ',
        output: d + '/outputm.mp4 ',
        target: 'medium/'
    }
};

var l = function (d) {
    return {
        dir: d,
        origin: d + '/l.mp4 ',
        compo: d + '/l.list ',
        output: d + '/outputl.mp4 ',
        target: 'low/'
    }
};

var LOOP = function (A, f, param1, param2) {
    var ret = new String();
    for (var i = 0; i < A.length; i++) {
        ret = ret + f(A[i], param1, param2) + AND;
    }
    return ret;
};

video = {
    ULTRAFAST: 'ultrafast',
    ULTRASLOW: 'ultraslow',
    param: function (w, h) {
        return '-vf setsar=sar=1:1,setdar=dar=16/9  -c:v libx264 -r 25 -s ' + w + '*' + h + ' -benchmark -threads 0 -preset ' + video.ULTRAFAST;
    }
};

audio = {
    param: function (a, b, vbr) {
        //TODO: vba need compilation
        return ' -strict -2 -ar ' + a + ' -b:a ' + b + 'k ';
    }
};

origin = {
    ver: function (F, w, h, a, b, vbr) {
        return  video.param(w, h) + audio.param(a, b, vbr) + F.origin;
    },
    generate: function (H, M, L) {
        return this.ver(H, 1280, 720, 48000, 128)
            + this.ver(M, 854, 480, 44100, 96)
            + this.ver(L, 480, 270, 22050, 64) + AND;
    }
};

bash = {
    cp: function (src, dest) {
        return ' cp ' + src + ' ' + dest + ' ';
    },
    mv: function (src, dest) {
        return ' mv ' + src + ' ' + dest + ' ';
    },
    rmDir: function (dir) {
        return ' rm -rf ' + dir + ' ';
    },
    cpO2O: function (F) {
        return ' cp ' + F.origin + F.output;
    },
    mvO2T: function (F, target, fileName) {
        return ' mv ' + F.output + target + F.target + fileName;
    }
};

var oped = function() {
    this.op_name = '';
    this.op_duration = 0;
    this.ed_name = '';
    this.ed_duration = 0;
};

oped.prototype.metadata = function () {
    return qs.stringify(this);
};

exports.oped = oped;

concat = {
    concat: function (F, oped) {
        return FFMPEG + '-y -f concat -i ' + F.compo + ' -c copy -metadata "'
            + oped.metadata() + '" ' + F.output;
    },

    cmd: function (A, oped) {
        return LOOP(A, this.concat, oped);
    }
};

ffmpeg = {
    input: function (path) {
        return FFMPEG + '-y -i "' + path + '" ';
    }
};

command = {

    addOped: function (A, oe) {
        if (oe.op_name == 'null' && oe.ed_name == 'null') {
            return LOOP(A, bash.cpO2O);
        }
        else {
            return concat.cmd(A, oe);
        }
    },

    mv: function (A, target, fileName) {
        // origin h
        var ret = bash.cp(A[0].output, target + 'origin/' + fileName) + AND;
        // high/medium/low
        ret = ret + LOOP(A, bash.mvO2T, target, fileName);
        return ret;
    },

    all: function (p, oe) {
        var dir = path.dirname(p);
        var fileName = path.basename(p);
        var H = h(dir), M = m(dir), L = l(dir);
        var A = [H, M, L];

        // output: h.mp4 m.mp4 l.mp4
        var ret = ffmpeg.input(p) + origin.generate(H, M, L);
        // output: outputh.mp4 outputm.mp4 outputl.mp4
        ret = ret + this.addOped(A, oe);
        // output: rsync 4 folders
        ret = ret + this.mv(A, PRIVATE.dir.rsync, fileName);
        // rm
        ret = ret + bash.rmDir(dir) + '\n';
        return ret;
    }
};

var file = {
    content: function(opedDir, inputDir, oe, v){
        var f;
        var VMP4 = v + '.mp4\n';
        if(oe.op_name != 'null')
            f = 'file ' + opedDir + oe.op_name + VMP4;
        else
            f = ''

        f = f + 'file ' + inputDir + VMP4;

        if(oe.ed_name != 'null')
            f = f + 'file ' + opedDir + oe.ed_name + VMP4;
        else
            f = f;
        return f;
    },

    write: function(inputPath, opedDir, oped){
        var inputDir = path.dirname(inputPath) + '/';
        fs.writeFileSync(inputDir + 'h.list', this.content(opedDir, inputDir, oped, 'h'));
        fs.writeFileSync(inputDir + 'm.list', this.content(opedDir, inputDir, oped, 'm'));
        fs.writeFileSync(inputDir + 'l.list', this.content(opedDir, inputDir, oped, 'l'));
    }
};

exports.generate = function (filePath, oe) {
//    oe.op_name = 'null'
//    oe.ed_name = 'null'
    var cmd = command.all(filePath, oe);
    if (oe.op_name != 'null' || oe.ed_name != 'null') {
        file.write(filePath, PRIVATE.dir.oped, oe);
    }
    fs.writeFileSync(path.dirname(filePath) + '/' + 'command', cmd);
    return cmd;
};

<commit_msg>fix ffmpeg path<commit_after>/**
 * Created by 3er on 1/9/15.
 */

var qs = require('querystring');
var path = require('path');
var fs = require('fs');
var PRIVATE = require('./config/private')

var AND = ' && ';
var FFMPEG = ' ' + PRIVATE.dir.ffmpeg + 'ffmpeg';

//前面有可能跟路径不能带空格
var h = function (d) {
    return {
        dir: d,
        origin: d + '/h.mp4 ',
        compo: d + '/h.list ',
        output: d + '/outputh.mp4 ',
        target: 'high/'
    }
};

var m = function (d) {
    return {
        dir: d,
        origin: d + '/m.mp4 ',
        compo: d + '/m.list ',
        output: d + '/outputm.mp4 ',
        target: 'medium/'
    }
};

var l = function (d) {
    return {
        dir: d,
        origin: d + '/l.mp4 ',
        compo: d + '/l.list ',
        output: d + '/outputl.mp4 ',
        target: 'low/'
    }
};

var LOOP = function (A, f, param1, param2) {
    var ret = new String();
    for (var i = 0; i < A.length; i++) {
        ret = ret + f(A[i], param1, param2) + AND;
    }
    return ret;
};

video = {
    ULTRAFAST: 'ultrafast',
    ULTRASLOW: 'ultraslow',
    param: function (w, h) {
        return '-vf setsar=sar=1:1,setdar=dar=16/9  -c:v libx264 -r 25 -s ' + w + '*' + h + ' -benchmark -threads 0 -preset ' + video.ULTRAFAST;
    }
};

audio = {
    param: function (a, b, vbr) {
        //TODO: vba need compilation
        return ' -strict -2 -ar ' + a + ' -b:a ' + b + 'k ';
    }
};

origin = {
    ver: function (F, w, h, a, b, vbr) {
        return  video.param(w, h) + audio.param(a, b, vbr) + F.origin;
    },
    generate: function (H, M, L) {
        return this.ver(H, 1280, 720, 48000, 128)
            + this.ver(M, 854, 480, 44100, 96)
            + this.ver(L, 480, 270, 22050, 64) + AND;
    }
};

bash = {
    cp: function (src, dest) {
        return ' cp ' + src + ' ' + dest + ' ';
    },
    mv: function (src, dest) {
        return ' mv ' + src + ' ' + dest + ' ';
    },
    rmDir: function (dir) {
        return ' rm -rf ' + dir + ' ';
    },
    cpO2O: function (F) {
        return ' cp ' + F.origin + F.output;
    },
    mvO2T: function (F, target, fileName) {
        return ' mv ' + F.output + target + F.target + fileName;
    }
};

var oped = function() {
    this.op_name = '';
    this.op_duration = 0;
    this.ed_name = '';
    this.ed_duration = 0;
};

oped.prototype.metadata = function () {
    return qs.stringify(this);
};

exports.oped = oped;

concat = {
    concat: function (F, oped) {
        return FFMPEG + '-y -f concat -i ' + F.compo + ' -c copy -metadata "'
            + oped.metadata() + '" ' + F.output;
    },

    cmd: function (A, oped) {
        return LOOP(A, this.concat, oped);
    }
};

ffmpeg = {
    input: function (path) {
        return FFMPEG + '-y -i "' + path + '" ';
    }
};

command = {

    addOped: function (A, oe) {
        if (oe.op_name == 'null' && oe.ed_name == 'null') {
            return LOOP(A, bash.cpO2O);
        }
        else {
            return concat.cmd(A, oe);
        }
    },

    mv: function (A, target, fileName) {
        // origin h
        var ret = bash.cp(A[0].output, target + 'origin/' + fileName) + AND;
        // high/medium/low
        ret = ret + LOOP(A, bash.mvO2T, target, fileName);
        return ret;
    },

    all: function (p, oe) {
        var dir = path.dirname(p);
        var fileName = path.basename(p);
        var H = h(dir), M = m(dir), L = l(dir);
        var A = [H, M, L];

        // output: h.mp4 m.mp4 l.mp4
        var ret = ffmpeg.input(p) + origin.generate(H, M, L);
        // output: outputh.mp4 outputm.mp4 outputl.mp4
        ret = ret + this.addOped(A, oe);
        // output: rsync 4 folders
        ret = ret + this.mv(A, PRIVATE.dir.rsync, fileName);
        // rm
        ret = ret + bash.rmDir(dir) + '\n';
        return ret;
    }
};

var file = {
    content: function(opedDir, inputDir, oe, v){
        var f;
        var VMP4 = v + '.mp4\n';
        if(oe.op_name != 'null')
            f = 'file ' + opedDir + oe.op_name + VMP4;
        else
            f = ''

        f = f + 'file ' + inputDir + VMP4;

        if(oe.ed_name != 'null')
            f = f + 'file ' + opedDir + oe.ed_name + VMP4;
        else
            f = f;
        return f;
    },

    write: function(inputPath, opedDir, oped){
        var inputDir = path.dirname(inputPath) + '/';
        fs.writeFileSync(inputDir + 'h.list', this.content(opedDir, inputDir, oped, 'h'));
        fs.writeFileSync(inputDir + 'm.list', this.content(opedDir, inputDir, oped, 'm'));
        fs.writeFileSync(inputDir + 'l.list', this.content(opedDir, inputDir, oped, 'l'));
    }
};

exports.generate = function (filePath, oe) {
//    oe.op_name = 'null'
//    oe.ed_name = 'null'
    var cmd = command.all(filePath, oe);
    if (oe.op_name != 'null' || oe.ed_name != 'null') {
        file.write(filePath, PRIVATE.dir.oped, oe);
    }
    fs.writeFileSync(path.dirname(filePath) + '/' + 'command', cmd);
    return cmd;
};

<|endoftext|>


<commit_before>var http = require('http');
var blake = require('blake');
var gits = require('/home/ubuntu/node_modules/gits/main.js');
var reflect = require('/home/ubuntu/reflector/index.js').main;

var INPUT = '/home/ubuntu/michaelnisi';
var TEMPLATES = INPUT + '/templates/';
var OUTPUT = '/var/www/michaelnisi';

var server;

server = http.createServer(function (request, response) {
	if (request.method !== 'POST') {
		response.end();
		return;
	}

	// Continue if request comes from github

	var data, payload;

	data = '';

	request.on('data', function (chunk) {
		data += chunk;
	});

	request.on('end', function () {
		if (!data) {
			return;
		}

		var value;

		value = data.split('payload=')[1];

		if (!value) {
			return;
		}

		payload = JSON.parse(unescape(value) || null);

		if (!payload) {
			return;
		}

		console.log(payload);

		// Analyze payload, bake granuarly.

		gits.git(INPUT, ['pull'], function (error) {
			blake.bake(INPUT, OUTPUT, function(error) {
				reflect(TEMPLATES, OUTPUT);
			});
		});
	});

	response.writeHead(200);
	response.end();
});

server.listen(3000, '127.0.0.1');

setInterval(function () {
	reflect(TEMPLATES, OUTPUT);
}, 1000 * 60 * 60);
<commit_msg>Adjust blake parameters in app<commit_after>var http = require('http');
var blake = require('blake');
var gits = require('/home/ubuntu/node_modules/gits/main.js');
var reflect = require('/home/ubuntu/reflector/index.js').main;

var INPUT = '/home/ubuntu/michaelnisi';
var TEMPLATES = INPUT + '/templates/';
var OUTPUT = '/var/www/michaelnisi';

var server;

server = http.createServer(function (request, response) {
	if (request.method !== 'POST') {
		response.end();
		return;
	}

	// Continue if request comes from github

	var data, payload;

	data = '';

	request.on('data', function (chunk) {
		data += chunk;
	});

	request.on('end', function () {
		if (!data) {
			return;
		}

		var value;

		value = data.split('payload=')[1];

		if (!value) {
			return;
		}

		payload = JSON.parse(unescape(value) || null);

		if (!payload) {
			return;
		}

		console.log(payload);

		// Analyze payload, bake granuarly.

		gits.git(INPUT, ['pull'], function (error) {
			blake.bake([INPUT, OUTPUT], function(error) {
				reflect(TEMPLATES, OUTPUT);
			});
		});
	});

	response.writeHead(200);
	response.end();
});

server.listen(3000, '127.0.0.1');

setInterval(function () {
	reflect(TEMPLATES, OUTPUT);
}, 1000 * 60 * 60);
<|endoftext|>


<commit_before>/*
@deploy
@title HN Who is hiring?
@output
{
  "content-type" : "application/json"
}
@cache 3600
*/

var rp      = require('request-promise')
  , Promise = require('bluebird')
  , _       = require('underscore')
  , math    = require('mathjs')
  ;

module.exports = function(req, res, next) {
  rp
    .get('https://hacker-news.firebaseio.com/v0/item/10311580.json')
    .then(function(data){
      return JSON.parse(data);
    })
    .then(function(post){
      var post_age = (Date.now() - new Date(post.time * 1000)) / 1000;

      Promise
        .resolve(post.kids)
        .map(function(i){
          return rp
                  .get('https://hacker-news.firebaseio.com/v0/item/' + i + '.json')
                  .then(function(data){ return JSON.parse(data); })
                  .then(function(comment){
                    return _.pick(comment, 'by', 'id', 'text', 'time');
                  })
                  ;
        }, { concurrency : 30 })
        .then(function(jobs){
          var cache_for = Math.floor(math.eval('60 + (x / 60) + (x / (60 * 60 * 24)) ^ e', { x : post_age }));
          res.set('x-tm-cache-max-age', cache_for);
          res.set('x-hn-post-age', post_age);
          res.send(jobs);
        });
    })
    .catch(function(err){
      next(err);
    });
};
<commit_msg>update from taskmill.io editor<commit_after>/*
@deploy
@title HN Who is hiring?
@output
{
  "content-type" : "application/json"
}
@cache 3600
*/

var rp      = require('request-promise')
  , Promise = require('bluebird')
  , _       = require('underscore')
  , math    = require('mathjs')
  ;

module.exports = function(req, res, next) {
  rp
    .get('https://hacker-news.firebaseio.com/v0/item/10492086.json')
    .then(function(data){
      return JSON.parse(data);
    })
    .then(function(post){
      var post_age = (Date.now() - new Date(post.time * 1000)) / 1000;

      Promise
        .resolve(post.kids)
        .map(function(i){
          return rp
                  .get('https://hacker-news.firebaseio.com/v0/item/' + i + '.json')
                  .then(function(data){ return JSON.parse(data); })
                  .then(function(comment){
                    return _.pick(comment, 'by', 'id', 'text', 'time');
                  })
                  ;
        }, { concurrency : 30 })
        .then(function(jobs){
          var cache_for = Math.floor(math.eval('60 + (x / 60) + (x / (60 * 60 * 24)) ^ e', { x : post_age }));
          res.set('x-tm-cache-max-age', cache_for);
          res.set('x-hn-post-age', post_age);
          res.send(jobs);
        });
    })
    .catch(function(err){
      next(err);
    });
};
<|endoftext|>


<commit_before>/* @flow */

import { List, is }  from 'immutable'
import * as Sunshine from 'sunshine/react'
import React         from 'react'
import moment        from 'moment'
import repa          from 'repa'
import marked        from 'marked'
import { mailtoUri } from '../../../lib/activity'
import { asideToConversation, flatParticipants } from '../../../lib/conversation'
import { displayName } from '../../../lib/notmuch'
import * as Ev       from '../event'
import * as State    from '../state'
import { ComposeReply, EditNote }  from '../../../lib/components/compose'
import { ActivityOptsMenu } from '../../../lib/components/activityMenu'
import { actorAvatar } from '../../../lib/components/avatar'
import { activityId
       , actor
       , edited
       , lastEdited
       , likes
       , likeCount
       , objectContent
       , objectType
       , published
       , verb
       } from '../../../lib/derivedActivity'
import { Card
       , CardHeader
       , FlatButton
       , Paper
       , Styles
       } from 'material-ui'

import type { DerivedActivity } from '../../../lib/derivedActivity'
import type { Conversation }    from '../../../lib/conversation'

export type ActivityProps = {
  activity:     DerivedActivity,
  conversation: Conversation,
  editing:      ?DerivedActivity,
  loading:      boolean,
  username:     string,
  useremail:    string,
  nestLevel:    ?number,
}

var { Colors } = Styles

var styles = {
  body: {
    padding: '16px',
    paddingTop: 0,
  },
  activityCard: {
    paddingTop: '0.6em'
  },
  asideContainer: {
    padding: '1em',
    paddingTop: 0,
  },
  inlineNotice: {
    padding: '16px',
    paddingBottom: 0,
  },
  inlineNoticeUnderHeader: {
    padding: '16px',
    paddingBottom: 0,
    paddingTop: 0,
  },
  menu: {
    float: 'right',
  },
}

export class ActivityView extends Sunshine.Component<{},ActivityProps,{}> {
  render(): React.Element {
    var activity = this.props.activity
    var v = verb(activity)
    if (v === 'conflict') {
      return <ConflictView {...this.props} />
    }
    else if (v === 'join') {
      return <JoinView {...this.props} />
    }
    else if (v === 'aside') {
      return <AsideView {...this.props} />
    }
    else if (objectType(activity) === 'note') {
      return this.editingThis() ?
        <EditNote {...this.props} /> :
        <NoteView {...this.props} />
    }
    else {
      return (
        <UnknownView {...this.props} />
      )
    }
  }

  unknown(): React.Element {
    return (
      <ActivityCard nestLevel={this.props.nestLevel}>
        {displayUnknown()}
      </ActivityCard>
    )
  }

  editingThis(): boolean {
    var { activity, editing } = this.props
    return editing && activityId(editing) === activityId(activity)
  }
}

class ActivityCard extends Sunshine.Component<{},{ nestLevel: ?number, children: React.Element },{}> {
  render(): React.Element {
    return (

        <Paper {...this.props} zDpeth={this.props.nestLevel || 1}>
          {this.props.children}
        </Paper>

    )
  }
}

class NoteView extends Sunshine.Component<{},ActivityProps,{}> {
  render(): React.Element {
    var { activity, useremail } = this.props
    var from    = actor(activity)
    var fromStr = (from && from.displayName) || '[unknown sender]'
    var dateStr = published(activity).fromNow()
    return (
      <ActivityCard nestLevel={this.props.nestLevel}>
        <CardHeader
          title={fromStr}
          subtitle={dateStr}
          avatar={from && actorAvatar(from)}
          >
          <LikeButton style={{ float:'right' }} {...this.props} />
          <ActivityOptsMenu style={styles.menu} {...this.props} />
        </CardHeader>
        {edited(activity) ?

            Last edited {lastEdited(activity).fromNow()}

 : ''}
        {displayContent(activity)}
      </ActivityCard>
    )
  }
}

class ConflictView extends Sunshine.Component<{},ActivityProps,{}> {
  render(): React.Element {
    var { activity, useremail } = this.props
    var from    = actor(activity)
    var fromStr = (from && from.displayName) || '[unknown sender]'
    var dateStr = published(activity).fromNow()
    return (
      <ActivityCard nestLevel={this.props.nestLevel}>

          Edit failed due to a conflict with another edit.

        {displayContent(activity)}
      </ActivityCard>
    )
  }
}

class JoinView extends Sunshine.Component<{},ActivityProps,{}> {
  render(): React.Element {
    var { activity } = this.props
    var from    = actor(activity)
    var fromStr = (from && from.displayName) || '[unknown sender]'
    return (
      <ActivityCard nestLevel={this.props.nestLevel}>
        <CardHeader
          title={fromStr}
          subtitle='joined the discussion'
          avatar={from && actorAvatar(from)}
          >
        </CardHeader>
      </ActivityCard>
    )
  }
}

class AsideView extends Sunshine.Component<{},ActivityProps,{}> {
  render(): React.Element {
    var nestLevel = this.props.nestLevel || 1
    var { activity, conversation } = this.props

    var conv = asideToConversation(activity)
    var ppl = flatParticipants(conv).map(p => displayName(p)).join(', ')

    // TODO: a bit hackish
    var showReplyForm = is(activity, conversation.activities.findLast(act => (
      act.verb === 'aside' && is(act.allActivities, activity.allActivities)
    )))

    var activities = (activity.aside || List()).map(act => (
      <ActivityView
        {...this.props}
        activity={act}
        conversation={conv}
        key={activityId(act)}
        nestLevel={nestLevel+1}
        />
    ))

    return (
      <ActivityCard nestLevel={nestLevel} style={{backgroundColor: Colors.deepOrange200}}>
        <CardHeader
          title='private aside'
          subtitle={ppl}
          avatar={}
          >
        </CardHeader>

          {activities}
          {showReplyForm ?
            <ComposeReply
              inReplyTo={conv}
              hintText='Compose private reply'
              /> : ''}

      </ActivityCard>
    )
  }
}

class UnknownView extends Sunshine.Component<{},ActivityProps,{}> {
  render(): React.Element {
    var activity = this.props.activity
    var from     = actor(activity)
    var fromStr  = (from && from.displayName) || '[unknown sender]'
    var dateStr  = published(activity).fromNow()
    return (
      <ActivityCard nestLevel={this.props.nestLevel}>
        <CardHeader
          title={fromStr}
          subtitle={dateStr}
          avatar={from && actorAvatar(from)}
          />
        {displayContent(activity)}
      </ActivityCard>
    )
  }
}

type LikeButtonProps = ActivityProps & {
  style?: Object
}

class LikeButton extends Sunshine.Component<{},LikeButtonProps,{}> {
  render(): React.Element {
    var { activity, loading, useremail, style } = this.props
    var me           = mailtoUri(useremail)
    var alreadyLiked = likes(activity).some(l => l.uri === me)
    var mine         = myContent(activity, useremail)
    return (
      <FlatButton
        style={style || {}}
        label={`+${likeCount(activity)+1}`}
        onTouchTap={this.like.bind(this)}
        disabled={mine || alreadyLiked || loading}
        />
    )
  }

  like() {
    this.emit(new Ev.Like(this.props.activity, this.props.conversation))
  }
}

function displayContent(activity: DerivedActivity): React.Element {
  var content = objectContent(activity)
  .sort((a,b) => {
    // prefer text/plain
    if (a.contentType === 'text/plain' && b.contentType !== 'text/plain') {
      return -1
    }
    else if (a.contentType !== 'text/plain' && b.contentType === 'text/plain') {
      return 1
    }
    else {
      return 0
    }
  })
  .filter(({ contentType }) => contentType === 'text/plain' || contentType === 'text/html')  // TODO: support other content types
  [0]
  if (content && content.contentType === 'text/plain') {
    return displayText(content.content)
  }
  else if (content && content.contentType === 'text/html') {
    return displayHtml(content.content)
  }
  else {
    return displayUnknown()
  }
}

function displayText(content: Buffer): React.Element {
  var content = repa(content.toString('utf8'))
  var out = {
    __html: marked(content, { sanitized: true })
  }
  return

}

function displayHtml(content: Buffer): React.Element {
  return (

TODO: display HTML

  )
}

function displayUnknown(): React.Element {
  return

[no content]

}

function myContent(activity: DerivedActivity, email: string): boolean {
  var me   = mailtoUri(email)
  var them = actor(activity)
  return !!them && (them.uri === me)
}
<commit_msg>Tones down color of private asides a little<commit_after>/* @flow */

import { List, is }  from 'immutable'
import * as Sunshine from 'sunshine/react'
import React         from 'react'
import moment        from 'moment'
import repa          from 'repa'
import marked        from 'marked'
import { mailtoUri } from '../../../lib/activity'
import { asideToConversation, flatParticipants } from '../../../lib/conversation'
import { displayName } from '../../../lib/notmuch'
import * as Ev       from '../event'
import * as State    from '../state'
import { ComposeReply, EditNote }  from '../../../lib/components/compose'
import { ActivityOptsMenu } from '../../../lib/components/activityMenu'
import { actorAvatar } from '../../../lib/components/avatar'
import { activityId
       , actor
       , edited
       , lastEdited
       , likes
       , likeCount
       , objectContent
       , objectType
       , published
       , verb
       } from '../../../lib/derivedActivity'
import { Card
       , CardHeader
       , FlatButton
       , Paper
       , Styles
       } from 'material-ui'

import type { DerivedActivity } from '../../../lib/derivedActivity'
import type { Conversation }    from '../../../lib/conversation'

export type ActivityProps = {
  activity:     DerivedActivity,
  conversation: Conversation,
  editing:      ?DerivedActivity,
  loading:      boolean,
  username:     string,
  useremail:    string,
  nestLevel:    ?number,
}

var { Colors } = Styles

var styles = {
  body: {
    padding: '16px',
    paddingTop: 0,
  },
  activityCard: {
    paddingTop: '0.6em'
  },
  asideContainer: {
    padding: '1em',
    paddingTop: 0,
  },
  inlineNotice: {
    padding: '16px',
    paddingBottom: 0,
  },
  inlineNoticeUnderHeader: {
    padding: '16px',
    paddingBottom: 0,
    paddingTop: 0,
  },
  menu: {
    float: 'right',
  },
}

export class ActivityView extends Sunshine.Component<{},ActivityProps,{}> {
  render(): React.Element {
    var activity = this.props.activity
    var v = verb(activity)
    if (v === 'conflict') {
      return <ConflictView {...this.props} />
    }
    else if (v === 'join') {
      return <JoinView {...this.props} />
    }
    else if (v === 'aside') {
      return <AsideView {...this.props} />
    }
    else if (objectType(activity) === 'note') {
      return this.editingThis() ?
        <EditNote {...this.props} /> :
        <NoteView {...this.props} />
    }
    else {
      return (
        <UnknownView {...this.props} />
      )
    }
  }

  unknown(): React.Element {
    return (
      <ActivityCard nestLevel={this.props.nestLevel}>
        {displayUnknown()}
      </ActivityCard>
    )
  }

  editingThis(): boolean {
    var { activity, editing } = this.props
    return editing && activityId(editing) === activityId(activity)
  }
}

class ActivityCard extends Sunshine.Component<{},{ nestLevel: ?number, children: React.Element },{}> {
  render(): React.Element {
    return (

        <Paper {...this.props} zDpeth={this.props.nestLevel || 1}>
          {this.props.children}
        </Paper>

    )
  }
}

class NoteView extends Sunshine.Component<{},ActivityProps,{}> {
  render(): React.Element {
    var { activity, useremail } = this.props
    var from    = actor(activity)
    var fromStr = (from && from.displayName) || '[unknown sender]'
    var dateStr = published(activity).fromNow()
    return (
      <ActivityCard nestLevel={this.props.nestLevel}>
        <CardHeader
          title={fromStr}
          subtitle={dateStr}
          avatar={from && actorAvatar(from)}
          >
          <LikeButton style={{ float:'right' }} {...this.props} />
          <ActivityOptsMenu style={styles.menu} {...this.props} />
        </CardHeader>
        {edited(activity) ?

            Last edited {lastEdited(activity).fromNow()}

 : ''}
        {displayContent(activity)}
      </ActivityCard>
    )
  }
}

class ConflictView extends Sunshine.Component<{},ActivityProps,{}> {
  render(): React.Element {
    var { activity, useremail } = this.props
    var from    = actor(activity)
    var fromStr = (from && from.displayName) || '[unknown sender]'
    var dateStr = published(activity).fromNow()
    return (
      <ActivityCard nestLevel={this.props.nestLevel}>

          Edit failed due to a conflict with another edit.

        {displayContent(activity)}
      </ActivityCard>
    )
  }
}

class JoinView extends Sunshine.Component<{},ActivityProps,{}> {
  render(): React.Element {
    var { activity } = this.props
    var from    = actor(activity)
    var fromStr = (from && from.displayName) || '[unknown sender]'
    return (
      <ActivityCard nestLevel={this.props.nestLevel}>
        <CardHeader
          title={fromStr}
          subtitle='joined the discussion'
          avatar={from && actorAvatar(from)}
          >
        </CardHeader>
      </ActivityCard>
    )
  }
}

class AsideView extends Sunshine.Component<{},ActivityProps,{}> {
  render(): React.Element {
    var nestLevel = this.props.nestLevel || 1
    var { activity, conversation } = this.props

    var conv = asideToConversation(activity)
    var ppl = flatParticipants(conv).map(p => displayName(p)).join(', ')

    // TODO: a bit hackish
    var showReplyForm = is(activity, conversation.activities.findLast(act => (
      act.verb === 'aside' && is(act.allActivities, activity.allActivities)
    )))

    var activities = (activity.aside || List()).map(act => (
      <ActivityView
        {...this.props}
        activity={act}
        conversation={conv}
        key={activityId(act)}
        nestLevel={nestLevel+1}
        />
    ))

    return (
      <ActivityCard nestLevel={nestLevel} style={{backgroundColor: Colors.deepOrange100}}>
        <CardHeader
          title='private aside'
          subtitle={ppl}
          avatar={}
          >
        </CardHeader>

          {activities}
          {showReplyForm ?
            <ComposeReply
              inReplyTo={conv}
              hintText='Compose private reply'
              /> : ''}

      </ActivityCard>
    )
  }
}

class UnknownView extends Sunshine.Component<{},ActivityProps,{}> {
  render(): React.Element {
    var activity = this.props.activity
    var from     = actor(activity)
    var fromStr  = (from && from.displayName) || '[unknown sender]'
    var dateStr  = published(activity).fromNow()
    return (
      <ActivityCard nestLevel={this.props.nestLevel}>
        <CardHeader
          title={fromStr}
          subtitle={dateStr}
          avatar={from && actorAvatar(from)}
          />
        {displayContent(activity)}
      </ActivityCard>
    )
  }
}

type LikeButtonProps = ActivityProps & {
  style?: Object
}

class LikeButton extends Sunshine.Component<{},LikeButtonProps,{}> {
  render(): React.Element {
    var { activity, loading, useremail, style } = this.props
    var me           = mailtoUri(useremail)
    var alreadyLiked = likes(activity).some(l => l.uri === me)
    var mine         = myContent(activity, useremail)
    return (
      <FlatButton
        style={style || {}}
        label={`+${likeCount(activity)+1}`}
        onTouchTap={this.like.bind(this)}
        disabled={mine || alreadyLiked || loading}
        />
    )
  }

  like() {
    this.emit(new Ev.Like(this.props.activity, this.props.conversation))
  }
}

function displayContent(activity: DerivedActivity): React.Element {
  var content = objectContent(activity)
  .sort((a,b) => {
    // prefer text/plain
    if (a.contentType === 'text/plain' && b.contentType !== 'text/plain') {
      return -1
    }
    else if (a.contentType !== 'text/plain' && b.contentType === 'text/plain') {
      return 1
    }
    else {
      return 0
    }
  })
  .filter(({ contentType }) => contentType === 'text/plain' || contentType === 'text/html')  // TODO: support other content types
  [0]
  if (content && content.contentType === 'text/plain') {
    return displayText(content.content)
  }
  else if (content && content.contentType === 'text/html') {
    return displayHtml(content.content)
  }
  else {
    return displayUnknown()
  }
}

function displayText(content: Buffer): React.Element {
  var content = repa(content.toString('utf8'))
  var out = {
    __html: marked(content, { sanitized: true })
  }
  return

}

function displayHtml(content: Buffer): React.Element {
  return (

TODO: display HTML

  )
}

function displayUnknown(): React.Element {
  return

[no content]

}

function myContent(activity: DerivedActivity, email: string): boolean {
  var me   = mailtoUri(email)
  var them = actor(activity)
  return !!them && (them.uri === me)
}
<|endoftext|>


<commit_before>Template.cardStub.onCreated(function() {
  var self =  this;
    if (self.isBeingEdited == undefined) {
      self.isBeingEdited = new ReactiveVar;
      self.isBeingEdited.set( false );
    };
});

Template.cardStub.helpers({
  isBeingEdited: function(){
    return Template.instance().isBeingEdited.get();
  }
});

Template.cardStub.events({
  "click .edit-this-card": function(event, template){
    event.preventDefault();
    if (template.isBeingEdited == undefined) {
        template.isBeingEdited = new ReactiveVar(true);
      }
      if ( template.isBeingEdited.get() == false) {
        template.isBeingEdited.set(true);
      }
  },
});

//Autoform Hooks
var updateCardHooks = {
  formToModifier: {
    "method-update": function(error, result) {
      var self = this;
      if(error){
        toastr.error(error.reason,'Error');
      }
      if(result){
        self.template.get("isBeingEdited").set(false);
        toastr.success(result.toastrMessage, result.toastrTitle);
      }
    }
  },
};

AutoForm.hooks({
  updateCardForm: updateCardHooks,
});
<commit_msg>fixed #24<commit_after>Template.cardStub.onCreated(function() {
  var self =  this;
    if (self.isBeingEdited == undefined) {
      self.isBeingEdited = new ReactiveVar;
      self.isBeingEdited.set( false );
    };
});

Template.cardStub.helpers({
  isBeingEdited: function(){
    return Template.instance().isBeingEdited.get();
  }
});

Template.cardStub.events({
  "click .edit-this-card": function(event, template){
    event.preventDefault();
    if (template.isBeingEdited == undefined) {
        template.isBeingEdited = new ReactiveVar(true);
      }
      if ( template.isBeingEdited.get() == false) {
        template.isBeingEdited.set(true);
      }
  },
});

//Autoform Hooks
var updateCardHooks = {
  after:{
    "method-update": function(error,result) {
      var self = this;
      console.log(self);
      if(error){
        toastr.error(error,'Error');
      }
      if(result){
        console.log(result);
        self.template.get("isBeingEdited").set(false);
        toastr.success(result.toastrMessage, result.toastrTitle);
      }
    }

  }
};

AutoForm.hooks({
  updateCardForm: updateCardHooks,
});
<|endoftext|>


<commit_before>import '../apps/hello_world_graphql/app';
<commit_msg>Remove more hello world<commit_after><|endoftext|>


<commit_before>'use strict';

var fs = require( 'fs' ),
    missingLogos = {
        lowresLogos : [],
        sortedLogos : [],
        teamsChecked : 0,
        markdown : '|Team|Current size|\n|---|---|\n',
        start: function(){
            this.teams = fs.readdirSync( 'teams/' );
            this.checkAllLogoSizes();
        },
        checkAllLogoSizes: function(){
            for( var i = 0; i < this.teams.length; i = i + 1 ){
                this.checkLogoSize( this.teams[ i ] );
            }
        },
        checkLogoSize: function( teamName ){
            var _this = this;

            fs.readdir( 'teams/' + teamName, function( error, files ){
                _this.teamsChecked = _this.teamsChecked + 1;

                if( files === undefined ){
                    return false;
                }

                files.forEach( function( filename ){
                    var size;

                    if( filename.substr( 0, 4 ) === 'logo' ){
                        size = filename.substr( 5, 3 );
                        if( size !== 'hig' ){
                            _this.lowresLogos.push({
                                name: teamName,
                                size: parseInt( size, 10 )
                            });
                        }
                    }
                });

                _this.checkDone();
            });
        },
        checkDone : function(){
            var _this = this;

            if( _this.teamsChecked == _this.teams.length - 1 ){
                _this.lowresLogos.forEach( function( data ){
                    var i,
                        hasAdded = false;

                    for( i = 0; i < _this.sortedLogos.length; i = i + 1 ){
                        if( data.size < _this.sortedLogos[ i ].size ){
                            _this.sortedLogos.splice( i, 0, data );
                            hasAdded = true;
                            break;
                        }
                    }

                    if( !hasAdded ){
                        _this.sortedLogos.push( data );
                    }

                });

                _this.sortedLogos.forEach( function( data ){
                    _this.markdown = _this.markdown + '|' + data.name + '|' + data.size + '|\n';
                });

                fs.writeFile( 'logos-missing.md', _this.markdown, function( error ){
                    if( error ){
                        console.log( error );
                    } else {
                        console.log( 'Missing logos updated' );
                    }
                });
            }

        }
    };

missingLogos.start();
<commit_msg>Make sure we only check the .png versions of the logos<commit_after>'use strict';

var fs = require( 'fs' ),
    missingLogos = {
        lowresLogos : [],
        sortedLogos : [],
        teamsChecked : 0,
        markdown : '|Team|Current size|\n|---|---|\n',
        start: function(){
            this.teams = fs.readdirSync( 'teams/' );
            this.checkAllLogoSizes();
        },
        checkAllLogoSizes: function(){
            for( var i = 0; i < this.teams.length; i = i + 1 ){
                this.checkLogoSize( this.teams[ i ] );
            }
        },
        checkLogoSize: function( teamName ){
            var _this = this;

            fs.readdir( 'teams/' + teamName, function( error, files ){
                _this.teamsChecked = _this.teamsChecked + 1;

                if( files === undefined ){
                    return false;
                }

                files.forEach( function( filename ){
                    var size;

                    if( filename.substr( 0, 4 ) === 'logo' && filename.substr( -4 ) == '.png' ){
                        size = filename.substr( 5, 3 );
                        if( size !== 'hig' ){
                            _this.lowresLogos.push({
                                name: teamName,
                                size: parseInt( size, 10 )
                            });
                        }
                    }
                });

                _this.checkDone();
            });
        },
        checkDone : function(){
            var _this = this;

            if( _this.teamsChecked == _this.teams.length - 1 ){
                _this.lowresLogos.forEach( function( data ){
                    var i,
                        hasAdded = false;

                    for( i = 0; i < _this.sortedLogos.length; i = i + 1 ){
                        if( data.size < _this.sortedLogos[ i ].size ){
                            _this.sortedLogos.splice( i, 0, data );
                            hasAdded = true;
                            break;
                        }
                    }

                    if( !hasAdded ){
                        _this.sortedLogos.push( data );
                    }

                });

                _this.sortedLogos.forEach( function( data ){
                    _this.markdown = _this.markdown + '|' + data.name + '|' + data.size + '|\n';
                });

                fs.writeFile( 'logos-missing.md', _this.markdown, function( error ){
                    if( error ){
                        console.log( error );
                    } else {
                        console.log( 'Missing logos updated' );
                    }
                });
            }

        }
    };

missingLogos.start();
<|endoftext|>


<commit_before>import {SKILL_LEVEL} from '../../skill-levels';
import * as tag from '../../tags';
import {toUtcDate}  from '../../date';
import * as date from '../../date';

const OBJECT_FROMENTRIES = 1;

export const all = {
  name: 'ES10 Katas',
  groups: {
    'Object API': {
      items: {
        [OBJECT_FROMENTRIES]: {
          name: 'basics',
          description: '',
          path: 'object-api/fromEntries',
          level: SKILL_LEVEL.BEGINNER,
          requiresKnowledgeFrom: [],
          publishDateUTC: toUtcDate(2019, date.JUNE, 25, 19, 55),
          links: [
            {
              url: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries',
              comment: 'Description of Object.fromEntries() on MDN.',
              tags: [tag.MDN, tag.DOCS]
            },
            {
              url: 'https://www.ecma-international.org/ecma-262/10.0/#sec-object.fromentries',
              comment: 'The specification describing `Object.fromEntries()`.',
              tags: [tag.SPECIFICATION]
            },
          ],
        },
      },
    },
  },
};
<commit_msg>More links.<commit_after>import {SKILL_LEVEL} from '../../skill-levels';
import * as tag from '../../tags';
import {toUtcDate}  from '../../date';
import * as date from '../../date';

const OBJECT_FROMENTRIES = 1;

export const all = {
  name: 'ES10 Katas',
  groups: {
    'Object API': {
      items: {
        [OBJECT_FROMENTRIES]: {
          name: 'basics',
          description: '',
          path: 'object-api/fromEntries',
          level: SKILL_LEVEL.BEGINNER,
          requiresKnowledgeFrom: [],
          publishDateUTC: toUtcDate(2019, date.JUNE, 25, 19, 55),
          links: [
            {
              url: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries',
              comment: 'Description of Object.fromEntries() on MDN.',
              tags: [tag.MDN, tag.DOCS]
            },
            {
              url: 'https://www.ecma-international.org/ecma-262/10.0/#sec-object.fromentries',
              comment: 'The specification describing `Object.fromEntries()`.',
              tags: [tag.SPECIFICATION]
            },
            {
              url: 'https://github.com/tc39/proposal-object-from-entries',
              comment: 'The (now archived) proposal, before it went into the spec, interesting read if you wanna go deep.',
              tags: [tag.DISCUSSION, tag.DOCS]
            },
            {
              url: 'https://github.com/tc39/proposal-object-from-entries/blob/master/DETAILS.md',
              comment: 'Very interesting details about some decisions on this method.',
              tags: [tag.DISCUSSION, tag.DOCS]
            },
          ],
        },
      },
    },
  },
};
<|endoftext|>