<commit_before>var App = App || {};
App.LoadAssetsState = App.LoadAssetsState || {};

App.LoadAssetsState = (function () {
    "use strict";

    // constructor: Run only once at compile time
    var fn = function (game) {
        Phaser.State.call(this, game);
    };
    fn.prototype = Object.create(Phaser.State.prototype);
    fn.prototype.constructor = fn;

    // init: Run every time this state is started or restart:
    fn.prototype.init = function (args) {
        console.debug("loadAssets.init",args);
        args = args || {};
        if (args.assetsConfig) {
            var must = args.assetsConfig;
            if (typeof must === 'string') must = {'Config':must};
            this.game.assetsMustLoad = {"assets":must};
        }
        if (args.nextState) this.game.assetsNextState = args.nextState;
        if (!this.game.assetsNextState || !this.game.assetsMustLoad) console.error("SYNTAX: state.start('loadAssets',undefined,undefined,{'assetsConfig':ASSETS_JSON_FILE},'nextState':STATE_KEY})");
        this.game.assets = this.game.assets || {};
        this.game.assetsMustLoad = this.game.assetsMustLoad || {};
        this.game.assetsPreLoad = this.game.assetsPreLoad || {};
        this.game.assetsLoaded = this.game.assetsLoaded || {};
        // Intended to run game.assetsSpawn() within init() of the State world to Spawn the assets:
        this.game.assetsSpawn = fn.prototype.spawn;
    };

    // preload: Call "preload_TYPE" routine on each asset
    fn.prototype.preload = function () {
        console.log("LoadAssetsState.preload: Running ...");
        for (var type in this.game.assetsMustLoad) {
            this.game.assetsLoaded[type] = this.game.assetsLoaded[type] || {};
            var handler = this["preload_" + type];
            if (handler && "function" === typeof handler) {
                this.game.assetsPreLoad[type] = this.game.assetsPreLoad[type] || {};
                for (var key in this.game.assetsMustLoad[type]) {
                    if (!this.game.assetsLoaded[type][key] &&
                        !this.game.assetsPreLoad[type][key]) {
                        var data = this.game.assetsMustLoad[type][key];
                        this.game.assetsPreLoad[type][key] = this["preload_" + type](key,data);
                    }
                    delete this.game.assetsMustLoad[type][key];
                }
            }
            else {
                console.log('Asset handler "preload_' + type + '" not defined');
            }
            delete this.game.assetsMustLoad[type];
        }
    };

    // create: Call "process_TYPE" routine on each asset once preload is complete
    fn.prototype.create = function () {
        console.log("LoadAssetsState.create: Running ...");
        for (var type in this.game.assetsPreLoad) {
            this.game.assetsLoaded[type] = this.game.assetsLoaded[type] || {};
            var handler = this["process_" + type];
            if (handler && "function" === typeof handler) {
                for (var key in this.game.assetsPreLoad[type]) {
                    if (!this.game.assetsLoaded[type][key]) {
                        this.game.assetsLoaded[type][key] = 1;
                        var preload_data = this.game.assetsPreLoad[type][key];
                        this["process_" + type](key,preload_data);
                    }
                    delete this.game.assetsPreLoad[type][key];
                }
            }
            else {
                console.log('WARNING: Asset handler "process_' + type + '" not defined');
            }
            delete this.game.assetsPreLoad[type];
        }

        if (_.keys(this.game.assetsMustLoad).length) {
            // Found more assets to left to load?
            // Need to run through this process again:
            console.log("Restarting STATE because found more assets not loaded yet",this.game.assetsMustLoad);
            this.game.state.restart();
        }
        else {
            // Everything is loaded?
            // Finally we can process to the next state:
            this.game.state.start(this.game.assetsNextState);
        }
    };

    // spawn: Call "spawn_TYPE" routine on each asset once State is launched
    fn.prototype.spawn = function (config) {
        console.log("LoadAssetsState.spawn: Running ...");
        for (var type in config) {
            var handler = fn.prototype["spawn_" + type];
            if (handler && "function" === typeof handler) {
                for (var key in config[type]) {
                    if (game.assets[key]) {
                        var loaded_data = game.assets[key];
                        handler(key,loaded_data);
                    }
                }
            }
            else {
                console.log('WARNING: Asset handler "spawn_' + type + '" not defined');
            }
        }
    };

    // ==== HELPER FUNCTIONS ====
    fn.prototype.dirname = function (filename) {
        return filename.match( /.*\// );
        //return filename.replace(/^(.*\/)[^\/]*/,'$1');
    };

    fn.prototype.basename = function (filename) {
        return filename.replace( /.*\//, "" );
    };

    // ==== ASSET TYPE DEFINITIONS ====
    // preload_TYPE(KEY,DATA):
    //   Define how to preload TYPE asset into KEY from DATA
    // process_TYPE(KEY,DATA):
    //   Now that asset has been loaded, populate any final data into game.assets.KEY
    //   If other assets are required to be loaded, then also populate
    //   this.game.assetsMustLoad.<NEWTYPE>.<NEWKEY> with more dependency DATA assets
    // spawn_TYPE(KEY,DATA):
    //   Use game.assets.KEY to Spawn and generate all State dependent Objects,
    //   such as sprites or anything that relies on the current game.world.

    // ==== assets ====

    // preload_assets
    fn.prototype.preload_assets = function(key, data) {
        console.log("loadAssets.preload_assets",key,data);
        this.game.load.json(key, data);
        return data;
    };

    // process_assets
    fn.prototype.process_assets = function(key, data) {
        console.log("loadAssets.process_assets",key);
        var assetsRequire = this.game.cache.getJSON(key);
        console.log("Must Load More Assets:",assetsRequire);
        // Merge assetsRequire into assetsMustLoad
        for (var type in assetsRequire) {
            this.game.assetsMustLoad[type] = this.game.assetsMustLoad[type] || {};
            for (var k in assetsRequire[type]) {
                this.game.assetsMustLoad[type][k] = assetsRequire[type][k];
            }
        }
        this.game.assets[key] = assetsRequire;
    };

    // spawn_assets
    fn.prototype.spawn_assets = function(key, data) {
        // nothing to do
    };

    // ==== spritesheet ====

    // preload_spritesheet
    fn.prototype.preload_spritesheet = function(key, data) {
        console.log("loadAssets.preload_spritesheet",key,data);
        this.game.load.spritesheet(key, data.file, data.frameWidth, data.frameHeight);
        return data;
    };

    // process_spritesheet
    fn.prototype.process_spritesheet = function(key, data) {
        console.log("loadAssets.process_spritesheet",key,data);
        //this.game.assets[key] = Object.create(Phaser.Sprite.prototype);
    };

    // spawn_spritesheet
    fn.prototype.spawn_spritesheet = function(key, data) {
        // nothing to do
    };

    // ==== atlas ====

    // preload_atlas
    fn.prototype.preload_atlas = function(key, data) {
        console.log("loadAssets.preload_atlas",key,data);
        this.game.load.atlas(key, data.file, data.json, Phaser.Loader.TEXTURE_ATLAS_JSON_HASH);
        return data;
    };

    // process_atlas
    fn.prototype.process_atlas = function(key, data) {
        console.log("loadAssets.process_atlas",key,data);
        // nothing to do yet
    };

    // spawn_atlas
    fn.prototype.spawn_atlas = function(key, data) {
        // nothing to do
    };

    // ==== sound ====

    // preload_sound
    fn.prototype.preload_sound = function(key, data) {
        console.log("loadAssets.preload_sound",key,data.file);
        this.game.load.audio(key, data.file);
        return data;
    };

    // process_sound
    fn.prototype.process_sound = function(key, data) {
        // nothing to do yet
    };

    // spawn_sound
    fn.prototype.spawn_sound = function(key, data) {
        // nothing to do
    };

    // ==== image ====

    // preload_image
    fn.prototype.preload_image = function (key, data) {
        console.log("loadAssets.preload_image",key,data.file);
        this.game.load.image(key, data.file);
    };

    // process_image
    fn.prototype.process_image = function (key, data) {
        // nothing to do yet
    };

    // spawn_image
    fn.prototype.spawn_image = function(key, data) {
        // nothing to do
    };

    // ==== json ====

    // preload_json
    fn.prototype.preload_json = function (key, data) {
        console.log("loadAssets.preload_json",key,data.file);
        this.game.load.json(key, data);
    };

    // process_json
    fn.prototype.process_json = function (key, data) {
        this.game.assets[key] = this.game.cache.getJSON(key);
    };

    // spawn_json
    fn.prototype.spawn_json = function(key, data) {
        // nothing to do
    };

    // ==== tilemap ====

    // preload_tilemap
    fn.prototype.preload_tilemap = function (key, data) {
        console.log("loadAssets.preload_tilemap",key,data.json);
        this.game.load.json("tilemap_json_" + key, data.json);
        return data;
    };

    // process_tilemap
    fn.prototype.process_tilemap = function (key, data) {
        console.log("loadAssets.process_tilemap",key,data);
        var tilemap_data = this.game.cache.getJSON("tilemap_json_" + key);
        var tilesets = tilemap_data.tilesets || [];
        for (var tileset in tilesets) {
            var fullpath = fn.prototype.dirname(data.json) + tilesets[tileset].image;
            this.game.assetsMustLoad.image = this.game.assetsMustLoad.image || {};
            this.game.assetsMustLoad.image[tilesets[tileset].name] = {"file":fullpath};
        }
        this.game.assetsMustLoad.tilemap2 = this.game.assetsMustLoad.tilemap2 || {};
        this.game.assetsMustLoad.tilemap2[key] = data;
        this.game.assets.tilemap_json = this.game.assets.tilemap || {};
        this.game.assets.tilemap_json[key] = tilemap_data;
    };

    // preload_tilemap2
    fn.prototype.preload_tilemap2 = function (key, data) {
        console.log("loadAssets.preload_tilemap2",key,data.json);
        this.game.load.tilemap(key, data.json, null, Phaser.Tilemap.TILED_JSON);
        return data;
    };

    // process_tilemap2
    fn.prototype.process_tilemap2 = function (key, data) {
        console.log("loadAssets.process_tilemap2",key);
        this.game.assets[key] = data;
    };

    // spawn_tilemap
    fn.prototype.spawn_tilemap = function(key, data) {
        console.log("loadAssets.spawn_tilemap",key,data);
        var tilemap = {};

        tilemap.map = game.add.tilemap(key);

        for (var tileset in data.tilesets) {
            tilemap.map.addTilesetImage(data.tilesets[tileset].tiled_set_name, tileset);
        }

        tilemap.layers = {};

        for (var layer in data.layers) {
            var tiled_layer_name = data.layers[layer].tiled_layer_name;

            tilemap.layers[layer] = tilemap.map.createLayer(tiled_layer_name);

            var collision_id_first = data.layers[layer].collision_id_first;
            var collision_id_last  = data.layers[layer].collision_id_last;
            if (collision_id_first && collision_id_last) {
                tilemap.map.setCollisionBetween(collision_id_first, collision_id_last, true, tiled_layer_name);
            }
        }

        for (var object_group in data.objects) {
            for (var gid in data.objects[object_group]) {
                tilemap.map.createFromObjects(
                    object_group,
                    gid,
                    data.objects[object_group][gid].key,
                    data.objects[object_group][gid].frame,
                    true,
                    false,
                    game.world,
                    eval('App.' + data.objects[object_group][gid].class_name),
                    true
                );
            }
        }
        game.assets[key] = tilemap;
    };

    return fn;
})();
<commit_msg>Don't look at assets.json for tilesets<commit_after>var App = App || {};
App.LoadAssetsState = App.LoadAssetsState || {};

App.LoadAssetsState = (function () {
    "use strict";

    // constructor: Run only once at compile time
    var fn = function (game) {
        Phaser.State.call(this, game);
    };
    fn.prototype = Object.create(Phaser.State.prototype);
    fn.prototype.constructor = fn;

    // init: Run every time this state is started or restart:
    fn.prototype.init = function (args) {
        console.debug("loadAssets.init",args);
        args = args || {};
        if (args.assetsConfig) {
            var must = args.assetsConfig;
            if (typeof must === 'string') must = {'Config':must};
            this.game.assetsMustLoad = {"assets":must};
        }
        if (args.nextState) this.game.assetsNextState = args.nextState;
        if (!this.game.assetsNextState || !this.game.assetsMustLoad) console.error("SYNTAX: state.start('loadAssets',undefined,undefined,{'assetsConfig':ASSETS_JSON_FILE},'nextState':STATE_KEY})");
        this.game.assets = this.game.assets || {};
        this.game.assetsMustLoad = this.game.assetsMustLoad || {};
        this.game.assetsPreLoad = this.game.assetsPreLoad || {};
        this.game.assetsLoaded = this.game.assetsLoaded || {};
        // Intended to run game.assetsSpawn() within init() of the State world to Spawn the assets:
        this.game.assetsSpawn = fn.prototype.spawn;
    };

    // preload: Call "preload_TYPE" routine on each asset
    fn.prototype.preload = function () {
        console.log("LoadAssetsState.preload: Running ...");
        for (var type in this.game.assetsMustLoad) {
            this.game.assetsLoaded[type] = this.game.assetsLoaded[type] || {};
            var handler = this["preload_" + type];
            if (handler && "function" === typeof handler) {
                this.game.assetsPreLoad[type] = this.game.assetsPreLoad[type] || {};
                for (var key in this.game.assetsMustLoad[type]) {
                    if (!this.game.assetsLoaded[type][key] &&
                        !this.game.assetsPreLoad[type][key]) {
                        var data = this.game.assetsMustLoad[type][key];
                        this.game.assetsPreLoad[type][key] = this["preload_" + type](key,data);
                    }
                    delete this.game.assetsMustLoad[type][key];
                }
            }
            else {
                console.log('Asset handler "preload_' + type + '" not defined');
            }
            delete this.game.assetsMustLoad[type];
        }
    };

    // create: Call "process_TYPE" routine on each asset once preload is complete
    fn.prototype.create = function () {
        console.log("LoadAssetsState.create: Running ...");
        for (var type in this.game.assetsPreLoad) {
            this.game.assetsLoaded[type] = this.game.assetsLoaded[type] || {};
            var handler = this["process_" + type];
            if (handler && "function" === typeof handler) {
                for (var key in this.game.assetsPreLoad[type]) {
                    if (!this.game.assetsLoaded[type][key]) {
                        this.game.assetsLoaded[type][key] = 1;
                        var preload_data = this.game.assetsPreLoad[type][key];
                        this["process_" + type](key,preload_data);
                    }
                    delete this.game.assetsPreLoad[type][key];
                }
            }
            else {
                console.log('WARNING: Asset handler "process_' + type + '" not defined');
            }
            delete this.game.assetsPreLoad[type];
        }

        if (_.keys(this.game.assetsMustLoad).length) {
            // Found more assets to left to load?
            // Need to run through this process again:
            console.log("Restarting STATE because found more assets not loaded yet",this.game.assetsMustLoad);
            this.game.state.restart();
        }
        else {
            // Everything is loaded?
            // Finally we can process to the next state:
            this.game.state.start(this.game.assetsNextState);
        }
    };

    // spawn: Call "spawn_TYPE" routine on each asset once State is launched
    fn.prototype.spawn = function (config) {
        console.log("LoadAssetsState.spawn: Running ...");
        for (var type in config) {
            var handler = fn.prototype["spawn_" + type];
            if (handler && "function" === typeof handler) {
                for (var key in config[type]) {
                    if (game.assets[key]) {
                        var loaded_data = game.assets[key];
                        handler(key,loaded_data);
                    }
                }
            }
            else {
                console.log('WARNING: Asset handler "spawn_' + type + '" not defined');
            }
        }
    };

    // ==== HELPER FUNCTIONS ====
    fn.prototype.dirname = function (filename) {
        return filename.match( /.*\// );
        //return filename.replace(/^(.*\/)[^\/]*/,'$1');
    };

    fn.prototype.basename = function (filename) {
        return filename.replace( /.*\//, "" );
    };

    // ==== ASSET TYPE DEFINITIONS ====
    // preload_TYPE(KEY,DATA):
    //   Define how to preload TYPE asset into KEY from DATA
    // process_TYPE(KEY,DATA):
    //   Now that asset has been loaded, populate any final data into game.assets.KEY
    //   If other assets are required to be loaded, then also populate
    //   this.game.assetsMustLoad.<NEWTYPE>.<NEWKEY> with more dependency DATA assets
    // spawn_TYPE(KEY,DATA):
    //   Use game.assets.KEY to Spawn and generate all State dependent Objects,
    //   such as sprites or anything that relies on the current game.world.

    // ==== assets ====

    // preload_assets
    fn.prototype.preload_assets = function(key, data) {
        console.log("loadAssets.preload_assets",key,data);
        this.game.load.json(key, data);
        return data;
    };

    // process_assets
    fn.prototype.process_assets = function(key, data) {
        console.log("loadAssets.process_assets",key);
        var assetsRequire = this.game.cache.getJSON(key);
        console.log("Must Load More Assets:",assetsRequire);
        // Merge assetsRequire into assetsMustLoad
        for (var type in assetsRequire) {
            this.game.assetsMustLoad[type] = this.game.assetsMustLoad[type] || {};
            for (var k in assetsRequire[type]) {
                this.game.assetsMustLoad[type][k] = assetsRequire[type][k];
            }
        }
        this.game.assets[key] = assetsRequire;
    };

    // spawn_assets
    fn.prototype.spawn_assets = function(key, data) {
        // nothing to do
    };

    // ==== spritesheet ====

    // preload_spritesheet
    fn.prototype.preload_spritesheet = function(key, data) {
        console.log("loadAssets.preload_spritesheet",key,data);
        this.game.load.spritesheet(key, data.file, data.frameWidth, data.frameHeight);
        return data;
    };

    // process_spritesheet
    fn.prototype.process_spritesheet = function(key, data) {
        console.log("loadAssets.process_spritesheet",key,data);
        //this.game.assets[key] = Object.create(Phaser.Sprite.prototype);
    };

    // spawn_spritesheet
    fn.prototype.spawn_spritesheet = function(key, data) {
        // nothing to do
    };

    // ==== atlas ====

    // preload_atlas
    fn.prototype.preload_atlas = function(key, data) {
        console.log("loadAssets.preload_atlas",key,data);
        this.game.load.atlas(key, data.file, data.json, Phaser.Loader.TEXTURE_ATLAS_JSON_HASH);
        return data;
    };

    // process_atlas
    fn.prototype.process_atlas = function(key, data) {
        console.log("loadAssets.process_atlas",key,data);
        // nothing to do yet
    };

    // spawn_atlas
    fn.prototype.spawn_atlas = function(key, data) {
        // nothing to do
    };

    // ==== sound ====

    // preload_sound
    fn.prototype.preload_sound = function(key, data) {
        console.log("loadAssets.preload_sound",key,data.file);
        this.game.load.audio(key, data.file);
        return data;
    };

    // process_sound
    fn.prototype.process_sound = function(key, data) {
        // nothing to do yet
    };

    // spawn_sound
    fn.prototype.spawn_sound = function(key, data) {
        // nothing to do
    };

    // ==== image ====

    // preload_image
    fn.prototype.preload_image = function (key, data) {
        console.log("loadAssets.preload_image",key,data.file);
        this.game.load.image(key, data.file);
    };

    // process_image
    fn.prototype.process_image = function (key, data) {
        // nothing to do yet
    };

    // spawn_image
    fn.prototype.spawn_image = function(key, data) {
        // nothing to do
    };

    // ==== json ====

    // preload_json
    fn.prototype.preload_json = function (key, data) {
        console.log("loadAssets.preload_json",key,data.file);
        this.game.load.json(key, data);
    };

    // process_json
    fn.prototype.process_json = function (key, data) {
        this.game.assets[key] = this.game.cache.getJSON(key);
    };

    // spawn_json
    fn.prototype.spawn_json = function(key, data) {
        // nothing to do
    };

    // ==== tilemap ====

    // preload_tilemap
    fn.prototype.preload_tilemap = function (key, data) {
        console.log("loadAssets.preload_tilemap",key,data.json);
        this.game.load.json("tilemap_json_" + key, data.json);
        return data;
    };

    // process_tilemap
    fn.prototype.process_tilemap = function (key, data) {
        console.log("loadAssets.process_tilemap",key,data);
        var tilemap_data = this.game.cache.getJSON("tilemap_json_" + key);
        var tilesets = tilemap_data.tilesets || [];
        for (var tileset in tilesets) {
            var fullpath = fn.prototype.dirname(data.json) + tilesets[tileset].image;
            this.game.assetsMustLoad.image = this.game.assetsMustLoad.image || {};
            this.game.assetsMustLoad.image[tilesets[tileset].name] = {"file":fullpath};
        }
        this.game.assetsMustLoad.tilemap2 = this.game.assetsMustLoad.tilemap2 || {};
        this.game.assetsMustLoad.tilemap2[key] = data;
        this.game.assets.tilemap_json = this.game.assets.tilemap || {};
        this.game.assets.tilemap_json[key] = tilemap_data;
    };

    // preload_tilemap2
    fn.prototype.preload_tilemap2 = function (key, data) {
        console.log("loadAssets.preload_tilemap2",key,data.json);
        this.game.load.tilemap(key, data.json, null, Phaser.Tilemap.TILED_JSON);
        return data;
    };

    // process_tilemap2
    fn.prototype.process_tilemap2 = function (key, data) {
        console.log("loadAssets.process_tilemap2",key);
        this.game.assets[key] = data;
    };

    // spawn_tilemap
    fn.prototype.spawn_tilemap = function(key, data) {
        console.log("loadAssets.spawn_tilemap",key,data);
        var tilemap = {};

        tilemap.map = game.add.tilemap(key);

        var tilemap_data = game.assets.tilemap_json[key];
        var tilesets = tilemap_data.tilesets || [];
        for (var tileset in tilesets) {
            tilemap.map.addTilesetImage(tilesets[tileset].name, tilesets[tileset].name);
        }

        tilemap.layers = {};

        for (var layer in data.layers) {
            var tiled_layer_name = data.layers[layer].tiled_layer_name;

            tilemap.layers[layer] = tilemap.map.createLayer(tiled_layer_name);

            var collision_id_first = data.layers[layer].collision_id_first;
            var collision_id_last  = data.layers[layer].collision_id_last;
            if (collision_id_first && collision_id_last) {
                tilemap.map.setCollisionBetween(collision_id_first, collision_id_last, true, tiled_layer_name);
            }
        }

        for (var object_group in data.objects) {
            for (var gid in data.objects[object_group]) {
                tilemap.map.createFromObjects(
                    object_group,
                    gid,
                    data.objects[object_group][gid].key,
                    data.objects[object_group][gid].frame,
                    true,
                    false,
                    game.world,
                    eval('App.' + data.objects[object_group][gid].class_name),
                    true
                );
            }
        }
        game.assets[key] = tilemap;
    };

    return fn;
})();
<|endoftext|>


<commit_before>var dep = new Deps.Dependency;
// XXX: we have to store the state internally (rather than just calling out
// to window.location) due to an android 2.3 bug. See:
//   https://github.com/EventedMind/iron-router/issues/350
var currentState = {
  path: location.pathname + location.search + location.hash
};

function onpopstate (e) {
  setState(e.originalEvent.state, null, location.pathname + location.search + location.hash);
}

IronLocation = {};

IronLocation.origin = function () {
  return location.protocol + '//' + location.host;
};

IronLocation.isSameOrigin = function (href) {
  var origin = IronLocation.origin();
  return href.indexOf(origin) === 0;
};

IronLocation.get = function () {
  dep.depend();
  return currentState;
};

IronLocation.path = function () {
  dep.depend();
  return currentState.path;
};

IronLocation.set = function (url, options) {
  options = options || {};

  var state = options.state || {};

  if (/^http/.test(url))
    href = url;
  else {
    if (url.charAt(0) !== '/')
      url = '/' + url;
    href = IronLocation.origin() + url;
  }

  if (!IronLocation.isSameOrigin(href))
    window.location = href;
  else if (options.where === 'server')
    window.location = href;
  else if (options.replaceState)
    IronLocation.replaceState(state, options.title, url, options.skipReactive);
  else
    IronLocation.pushState(state, options.title, url, options.skipReactive);
};

// store the state for later access
setState = function(newState, title, url, skipReactive) {
  if (!skipReactive && (currentState.path !== url))
    dep.changed();

  currentState = newState || {};
  currentState.path = url;
  currentState.title = title;
}

IronLocation.pushState = function (state, title, url, skipReactive) {
  setState(state, title, url, skipReactive);

  if (history.pushState)
    history.pushState(state, title, url);
  else
    window.location = url;
};

IronLocation.replaceState = function (state, title, url, skipReactive) {
  // allow just the state or title to be set
  if (arguments.length < 2)
    title = currentState.title;
  if (arguments.length < 3)
    url = currentState.path;

  setState(state, title, url, skipReactive);

  if (history.replaceState)
    history.replaceState(state, title, url);
  else
    window.location = url;
};

IronLocation.bindEvents = function(){
  $(window).on('popstate', onpopstate);
};

IronLocation.unbindEvents = function(){
  $(window).off('popstate', onpopstate);
};

IronLocation.start = function () {
  if (this.isStarted)
    return;

  IronLocation.bindEvents();
  this.isStarted = true;

  // store the fact that this is the first route we hit.
  // this serves two purposes
  //   1. We can tell when we've reached an unhandled route and need to show a
  //      404 (rather than bailing out to let the server handle it)
  //   2. Users can look at the state to tell if the history.back() will stay
  //      inside the app (this is important for mobile apps).
  if (history.replaceState)
    history.replaceState({initial: true}, null, location.pathname + location.search + location.hash);
};

IronLocation.stop = function () {
  IronLocation.unbindEvents();
  this.isStarted = false;
};
<commit_msg>Be a little cleverer about when we trigger dep changes.<commit_after>var dep = new Deps.Dependency;
// XXX: we have to store the state internally (rather than just calling out
// to window.location) due to an android 2.3 bug. See:
//   https://github.com/EventedMind/iron-router/issues/350
var currentState = {
  path: location.pathname + location.search + location.hash
};

function onpopstate (e) {
  setState(e.originalEvent.state, null, location.pathname + location.search + location.hash);
}

IronLocation = {};

IronLocation.origin = function () {
  return location.protocol + '//' + location.host;
};

IronLocation.isSameOrigin = function (href) {
  var origin = IronLocation.origin();
  return href.indexOf(origin) === 0;
};

IronLocation.get = function () {
  dep.depend();
  return currentState;
};

IronLocation.path = function () {
  dep.depend();
  return currentState.path;
};

IronLocation.set = function (url, options) {
  options = options || {};

  var state = options.state || {};

  if (/^http/.test(url))
    href = url;
  else {
    if (url.charAt(0) !== '/')
      url = '/' + url;
    href = IronLocation.origin() + url;
  }

  if (!IronLocation.isSameOrigin(href))
    window.location = href;
  else if (options.where === 'server')
    window.location = href;
  else if (options.replaceState)
    IronLocation.replaceState(state, options.title, url, options.skipReactive);
  else
    IronLocation.pushState(state, options.title, url, options.skipReactive);
};

// store the state for later access
setState = function(newState, title, url, skipReactive) {
  newState = _.extend({}, newState);
  newState.path = url;
  newState.title = title;

  if (!skipReactive && ! EJSON.equals(currentState, newState))
    dep.changed();

  currentState = newState;
}

IronLocation.pushState = function (state, title, url, skipReactive) {
  setState(state, title, url, skipReactive);

  if (history.pushState)
    history.pushState(state, title, url);
  else
    window.location = url;
};

IronLocation.replaceState = function (state, title, url, skipReactive) {
  // allow just the state or title to be set
  if (arguments.length < 2)
    title = currentState.title;
  if (arguments.length < 3)
    url = currentState.path;

  setState(state, title, url, skipReactive);

  if (history.replaceState)
    history.replaceState(state, title, url);
  else
    window.location = url;
};

IronLocation.bindEvents = function(){
  $(window).on('popstate', onpopstate);
};

IronLocation.unbindEvents = function(){
  $(window).off('popstate', onpopstate);
};

IronLocation.start = function () {
  if (this.isStarted)
    return;

  IronLocation.bindEvents();
  this.isStarted = true;

  // store the fact that this is the first route we hit.
  // this serves two purposes
  //   1. We can tell when we've reached an unhandled route and need to show a
  //      404 (rather than bailing out to let the server handle it)
  //   2. Users can look at the state to tell if the history.back() will stay
  //      inside the app (this is important for mobile apps).
  if (history.replaceState)
    history.replaceState({initial: true}, null, location.pathname + location.search + location.hash);
};

IronLocation.stop = function () {
  IronLocation.unbindEvents();
  this.isStarted = false;
};
<|endoftext|>


<commit_before>var https = require('https'),
    cheerio = require('cheerio');

var ptt_url = "https://www.ptt.cc";

function ptt_get(url, cb) {
    var req = https.get(url, function(res) {
        var out = "";
        res.on('data', function(chunk) {
            out = out + chunk;
        });
        res.on('end', function() {
            cb(out);
        })
    });
    req.end();
}

function harvest_board_indices(board_url, board_name, cb) {
    ptt_get(
        board_url,
        function(body) {
            var $ = cheerio.load(body);
            var ret = [];
            $("a[href^='/bbs/" + board_name + "/index']").each(function(i, el) {
                var href = $(el).attr("href");
                var m;
                if (m = href.match(/index([0-9]+)\.html/)) {
                    ret.push({
                        page_number: m[1],
                        url: ptt_url + href
                    });
                }
            });
            cb(ret);
        }
    )
}

function harvest_articles(board_index_url, board_name, cb) {
   ptt_get(
        board_index_url,
        function(body) {
            var $ = cheerio.load(body);
            var ret = [];
            $("a[href^='/bbs/" + board_name + "/']").each(function(i, el) {
                var href = $(el).attr("href");
                var m;
                if (m = href.match(/(M.+)\.html/)) {
                    ret.push({
                        id: m[1],
                        url: ptt_url + href
                    });
                }
            });
            cb(ret);
        }
    )
}

if ( process.argv.length != 4) {
    process.abort();
}

var board_name = process.argv[2];
var output_dir = process.argv[3];

harvest_board_indices(
    ptt_url + "/bbs/" + board_name + "/index.html",
    board_name,
    function(board_indices) {
        for (var i = 0; i < board_indices.length; i++) {
            harvest_articles(
                board_indices[i]["url"],
                board_name,
                function(articles) {
                    console.log(articles);
                }
            );
        }
    }
);
<commit_msg>download-articles -- make sure we download one by one.<commit_after>"use strict";

const https = require('https'),
      cheerio = require('cheerio'),
      fs = require('fs');

var ptt_url = "https://www.ptt.cc";

function ptt_get(url, cb) {
    var req = https.get(url, function(res) {
        var out = "";
        res.on('data', function(chunk) {
            out = out + chunk;
        });
        res.on('end', function() {
            cb(out);
        })
    });
    req.end();
}

function harvest_board_indices(board_url, board_name, cb) {
    ptt_get(
        board_url,
        function(body) {
            var $ = cheerio.load(body);
            var ret = [];
            $("a[href^='/bbs/" + board_name + "/index']").each(function(i, el) {
                var href = $(el).attr("href");
                var m;
                if (m = href.match(/index([0-9]+)\.html/)) {
                    ret.push({
                        page_number: m[1],
                        url: ptt_url + href
                    });
                }
            });
            cb(ret);
        }
    )
}

function harvest_articles(board_index_url, board_name, cb) {
   ptt_get(
        board_index_url,
        function(body) {
            var $ = cheerio.load(body);
            var ret = [];
            $("a[href^='/bbs/" + board_name + "/']").each(function(i, el) {
                var href = $(el).attr("href");
                var m;
                if (m = href.match(/(M.+)\.html/)) {
                    ret.push({
                        id: m[1],
                        url: ptt_url + href
                    });
                }
            });
            cb(ret);
        }
    )
}

function download_articles( articles, board_name, qoutput_dir ) {
    var article;
    var board_dir = output_dir + "/" + board_name;

    var download_one_and_next = function(i, l) {
        if (i >= l) return;
        (function(article) {
            ptt_get(
                article["url"],
                function(html) {
                    var fn = board_dir + "/" + article["id"] + ".html";
                    fs.writeFileSync(fn, html);
                    console.log("==> " + fn);
                    download_one_and_next( i+1, l );
                }
            );
        })(articles[i]);
    };
    download_one_and_next(0, articles.length);
}

if ( process.argv.length != 4) {
    process.abort();
}

var board_name = process.argv[2];
var output_dir = process.argv[3];

harvest_board_indices(
    ptt_url + "/bbs/" + board_name + "/index.html",
    board_name,
    function(board_indices) {
        for (var i = 0; i < board_indices.length; i++) {
            harvest_articles(
                board_indices[i]["url"],
                board_name,
                function(a) { download_articles(a, board_name, output_dir) }
            );
        }
    }
);
<|endoftext|>


<commit_before>module.exports = function(grunt) {
    "use strict";

    // Load grunt plugins
    require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);

    // Paths configuration
    var pathConfig     = {};
    pathConfig.rootDir = "./";
    pathConfig.webDir  = pathConfig.rootDir + "www/";

    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON("package.json"),
        pathConfig: pathConfig,
        compass: {
            dist: {
                options: {
                    sassDir: "<%= pathConfig.rootDir %>preprocess/scss",
                    cssDir: "<%= pathConfig.webDir %>css",
                    outputStyle: "compressed"
                }
            }
        },
        copy: {
            js: {
                expand: true,
                cwd: "<%= pathConfig.rootDir %>preprocess/js",
                src: "**/**",
                dest: "<%= pathConfig.webDir %>js"
            },
            server: {
                expand: true,
                cwd: "<%= pathConfig.rootDir %>preprocess/server",
                src: "**/**",
                dest: "<%= pathConfig.rootDir %>server"
            }
        },
        uglify: {
            options: {
                compress: true
            },
            js: {
                files: [
                    {
                        expand: true,
                        cwd: "www/js",
                        src: "**.js",
                        dest: "www/js"
                    }
                ]
            },
            jsx: {
                files: [
                    {
                        expand: true,
                        cwd: "www/js",
                        src: "**/**.js",
                        dest: "www/js"
                    }
                ]
            }
        },
        watch: {
            js: {
                files: ["<%= pathConfig.rootDir %>preprocess/js/**/**"],
                tasks: ["copy:js"],
                options: {
                    spawn: false
                }
            },
            jsx: {
                files: ["<%= pathConfig.rootDir %>preprocess/jsx/**/**"],
                tasks: ["react"],
                options: {
                    spawn: false
                }
            },
            server: {
                files: ["<%= pathConfig.rootDir %>preprocess/server/**"],
                tasks: ["copy:server"],
                options: {
                    spawn: false
                }
            },
            css: {
                files: ["<%= pathConfig.rootDir %>preprocess/scss/**.scss"],
                tasks: ["compass"]
            }
        },
        jshint: {
            all: {
                src: [
                    "*.js",
                    "*.json",
                    "preprocess/js/**"
                ],
                options: {
                    jshintrc: true
                }
            }
        },
        jscs: {
            src: [
                "Gruntfile.js",
                "preprocess/js/**"
            ]
        },
        react: {
            dynamicMappings: {
                files: [
                    {
                        expand: true,
                        cwd: "<%= pathConfig.rootDir %>preprocess/jsx/",
                        src: ["**/**.jsx"],
                        dest: "<%= pathConfig.webDir %>js/",
                        ext: ".js"
                    }
                ]
            }
        },
        karma: {
            unit: {
                configFile: "karma.conf.js",
                singleRun: true
            }
        },
        connect: {
            frontend: {
                options: {
                    port: 9000,
                    hostname: "0.0.0.0",
                    base: "www",
                    keepalive: true
                }
            }
        }
    });

    // Tasks
    grunt.registerTask("test", [ "karma" ]);
    grunt.registerTask("start", [ "connect" ]);
    grunt.registerTask("sca", [ "jshint", "jscs" ]);
    grunt.registerTask("compile", [ "copy", "react", "compass"]);
    grunt.registerTask("build", [ "test", "sca", "compile", "uglify" ]);

    grunt.registerTask("default", [ "compile"]);

};
<commit_msg>Made node server location dynamic<commit_after>module.exports = function(grunt) {
    "use strict";

    // Load grunt plugins
    require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);

    // Paths configuration
    var pathConfig     = {};
    pathConfig.rootDir = "./";
    pathConfig.webDir  = pathConfig.rootDir + "www/";

    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON("package.json"),
        pathConfig: pathConfig,
        compass: {
            dist: {
                options: {
                    sassDir: "<%= pathConfig.rootDir %>preprocess/scss",
                    cssDir: "<%= pathConfig.webDir %>css",
                    outputStyle: "compressed"
                }
            }
        },
        copy: {
            js: {
                expand: true,
                cwd: "<%= pathConfig.rootDir %>preprocess/js",
                src: "**/**",
                dest: "<%= pathConfig.webDir %>js"
            },
            server: {
                expand: true,
                cwd: "<%= pathConfig.rootDir %>preprocess/server",
                src: "**/**",
                dest: "<%= pathConfig.rootDir %>server"
            }
        },
        uglify: {
            options: {
                compress: true
            },
            js: {
                files: [
                    {
                        expand: true,
                        cwd: "www/js",
                        src: "**.js",
                        dest: "www/js"
                    }
                ]
            },
            jsx: {
                files: [
                    {
                        expand: true,
                        cwd: "www/js",
                        src: "**/**.js",
                        dest: "www/js"
                    }
                ]
            }
        },
        watch: {
            js: {
                files: ["<%= pathConfig.rootDir %>preprocess/js/**/**"],
                tasks: ["copy:js"],
                options: {
                    spawn: false
                }
            },
            jsx: {
                files: ["<%= pathConfig.rootDir %>preprocess/jsx/**/**"],
                tasks: ["react"],
                options: {
                    spawn: false
                }
            },
            server: {
                files: ["<%= pathConfig.rootDir %>preprocess/server/**"],
                tasks: ["copy:server"],
                options: {
                    spawn: false
                }
            },
            css: {
                files: ["<%= pathConfig.rootDir %>preprocess/scss/**.scss"],
                tasks: ["compass"]
            }
        },
        jshint: {
            all: {
                src: [
                    "*.js",
                    "*.json",
                    "preprocess/js/**"
                ],
                options: {
                    jshintrc: true
                }
            }
        },
        jscs: {
            src: [
                "Gruntfile.js",
                "preprocess/js/**"
            ]
        },
        react: {
            dynamicMappings: {
                files: [
                    {
                        expand: true,
                        cwd: "<%= pathConfig.rootDir %>preprocess/jsx/",
                        src: ["**/**.jsx"],
                        dest: "<%= pathConfig.webDir %>js/",
                        ext: ".js"
                    }
                ]
            }
        },
        karma: {
            unit: {
                configFile: "karma.conf.js",
                singleRun: true
            }
        },
        connect: {
            frontend: {
                options: {
                    port: 9000,
                    hostname: "0.0.0.0",
                    base: "<%= pathConfig.webDir %>",
                    keepalive: true
                }
            }
        }
    });

    // Tasks
    grunt.registerTask("test", [ "karma" ]);
    grunt.registerTask("start", [ "connect" ]);
    grunt.registerTask("sca", [ "jshint", "jscs" ]);
    grunt.registerTask("compile", [ "copy", "react", "compass"]);
    grunt.registerTask("build", [ "test", "sca", "compile", "uglify" ]);

    grunt.registerTask("default", [ "compile"]);

};
<|endoftext|>


<commit_before>const gulp = require('gulp')
const fs = require('fs')
const request = require('request')
const jimp = require('jimp')

const configPath = process.cwd() + '/data/config.json'
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'))
const methode = config.copy.methode
const imageSizes = [ 640, 1280, 1920 ]
let imagesToDownload = []

const getImageDirectory = () => {
	const dir = methode.imageDirectory || ''
	const finalDir = dir ? `${dir}/` : dir
	return `assets/${finalDir}`
}

const createPicturefill = ({ name, extension, caption, imageDirectory }) => {
	const srcset = methode.imageLibrary === 'picturefill' ? 'srcset' : 'data-srcset'
	const lazyload = methode.imageLibrary === 'picturefill' ? '' : 'lazyload'
	const defaultSrc = `${imageDirectory}${name}placeholder.${extension}`

	const getPath = (sz) => `${imageDirectory}${name}${sz}.${extension}`
	const getSource = (src, mq) => `<source ${srcset}='${src}' media='(min-width:${mq}px)'>`
	const reversed = imageSizes.map(i => i).reverse()

	return `
		<picture>

			${
				reversed.map((sz, index) => {
					const src = getPath(sz)
					const mq = index < reversed.length - 1
						? Math.floor(reversed[index + 1] / 1.5)
						: 1
					return getSource(src, mq)
				}).join('')
			}

		</picture>
	`.trim()
}

const createFigureSource = ({ name, extension, caption }) => {
	const imageDirectory = getImageDirectory()

	if (methode.imageLibrary) {
		return createPicturefill({ name, extension, caption, imageDirectory })
	}
	// plain old image default
	const src = `${imageDirectory}${name}${imageSizes[imageSizes.length - 1]}.${extension}`
	return `<img src='${src}' alt='${caption}' />`
}

const getImageInfo = (imagePath) => {
	const imageFull = imagePath.substr(imagePath.lastIndexOf('/') + 1)
	const imageSplit = imageFull.split('.')
	const name = `${imageSplit[0]}_apps_w_`
	const extension = imageSplit[1]
	return { name, extension }
}

const replaceMethodeImageSize = ({ imagePath, imageSize }) =>
	imagePath.replace(/image_(.+\d)w/g, `image_${imageSize}w`)

const replaceLocalImageSize = ({ imagePath, imageSize }) =>
	imagePath.replace(/_apps_w_(.+\d)\./g, `_apps_w_${imageSize}.`)

const createFigure = ({ href, credit, caption, alt }) => {
	const imagePath = href.split('?')[0]
	const { name, extension } = getImageInfo(imagePath)

	// start generating markup
	const src = createFigureSource({ name, extension, caption })

	// add to download queue
	const imageSize = 1920
	const url = `http:${replaceMethodeImageSize({ imagePath, imageSize })}`
	const filename = `${name}${imageSize}.${extension}`

	imagesToDownload.push({ url, filename })

	return `

			${src}
			${credit}

${caption}

	`.trim()
}

const cleanP = (content) => {
	// check for graphic partial first
	if (content.match(/{{graphic:(.*)}}/)) {
		return content.replace(/{{graphic:(.*)}}/, (match, name, index) =>
			`{{> graphic/${name.trim()} }}`
		)
	}

	const withoutOpenSpan = content.replace(//g, '')
	const withoutCloseSpan = withoutOpenSpan.replace(/<\/span>/g, '')
	return `<p class='methode-graf'>${withoutCloseSpan}</p>`
}

const createContentMarkup = (item) => {
	const types = {
		p: ({ content }) => cleanP(content),
		image: ({ href, credit, caption, alt }) => createFigure({ href, credit, caption, alt }),
		ad: () => `<div class='ad'></div>`,
	}

	return types[item.type](item)
}

const createHTML = (stories) => {
	const html = stories.map(story => {
		const { content } = story.body
		// go thru item in content and create the proper markup
		return content.map(createContentMarkup).join('\n')
	})

	return html.join('\n')
}

const writeHTML = (html) =>
	fs.writeFileSync('src/html/partials/graphic/methode.hbs', html)

const resizeImage = ({ path, resolve, reject }) => {
	console.log('resizing image...')
	// create smaller versions of each image
	const promises = imageSizes.map(imageSize =>
		new Promise((res, rej) => {
			const out = replaceLocalImageSize({ imagePath: path, imageSize })
			jimp.read(path).then(image =>
		    	image
		    	.resize(imageSize, jimp.AUTO)
				.write(out, res)
			).catch(err => rej(err))
		})
	)

	promises.push(
		new Promise((res, rej) => {
			const imageSize = 20
			const out = replaceLocalImageSize({ imagePath: path, imageSize: 'placeholder' })
			jimp.read(path).then(image =>
		    	image
		    	.blur(40)
		    	.resize(imageSize, jimp.AUTO)
				.write(out, res)
			).catch(err => rej(err))
		})
	)

	Promise.all(promises)
		.then(result => resolve(result))
		.catch(error => reject(error))
}

const downloadImages = (cb) => {
	const promises = imagesToDownload.map(image =>
		new Promise((resolve, reject) => {
			const { url, filename } = image
			const path = `src/${getImageDirectory()}${filename}`
			try {
				const exists = fs.lstatSync(path)
				resolve()
			} catch (e) {
				console.log(`downloading: ${url}`)
				request(url, {encoding: 'binary'}, (error, response, body) => {
					if (error) reject(error)
					else {
						fs.writeFile(path, body, 'binary', (err) => {
							if (err) reject(err)
							else resizeImage({ path, resolve, reject })
						})
					}
				})
			}
		})
	)

	Promise.all(promises)
		.then(result => cb())
		.catch(error => {
			console.log(error)
			cb()
		})
}

const fetchMethode = (cb) => {
	const base = 'http://prdedit.bostonglobe.com/eom/SysConfig/WebPortal/BostonGlobe/precursor/template/api_redirect.jsp?path=/'
	const promises = methode.story.map(story =>
		new Promise((resolve, reject) => {
			const url = `${base}${story.path}`
			console.log('fetching story data:', url)
			request(url, (error, response, body) => {
				if (!error && response.statusCode === 200) {
					resolve({...story, body: JSON.parse(body)})
				} else {
					reject(error)
				}
			})
		})
	)

	Promise.all(promises)
		.then(results => {
			const html = createHTML(results)
			writeHTML(html)
			downloadImages(cb)
		})
		.catch(error => {
			console.error(error)
			cb()
		})
}

gulp.task('fetch-methode', (cb) => {
	if (methode.story.length) fetchMethode(cb)
	else {
		console.error('No methode story in config')
		cb()
	}
})
<commit_msg>fix #129 update fetch-methode<commit_after>const gulp = require('gulp')
const fs = require('fs')
const request = require('request')
const jimp = require('jimp')

const configPath = process.cwd() + '/data/config.json'
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'))
const methode = config.copy.methode
const imageSizes = [ 640, 1280, 1920 ]
let imagesToDownload = []
let firstAdSlotted = false

const getImageDirectory = () => {
	const dir = methode.imageDirectory || ''
	const finalDir = dir ? `${dir}/` : dir
	return `assets/${finalDir}`
}

const createPicturefill = ({ name, extension, caption, imageDirectory }) => {
	const srcset = methode.imageLibrary === 'picturefill' ? 'srcset' : 'data-srcset'
	const lazyload = methode.imageLibrary === 'picturefill' ? '' : 'lazyload'
	const defaultSrc = `${imageDirectory}${name}placeholder.${extension}`

	const getPath = (sz) => `${imageDirectory}${name}${sz}.${extension}`
	const getSource = (src, mq) => `<source ${srcset}='${src}' media='(min-width:${mq}px)'>`
	const reversed = imageSizes.map(i => i).reverse()

	return `
		<picture>

			${
				reversed.map((sz, index) => {
					const src = getPath(sz)
					const mq = index < reversed.length - 1
						? Math.floor(reversed[index + 1] / 1.5)
						: 1
					return getSource(src, mq)
				}).join('')
			}

		</picture>
	`.trim()
}

const createFigureSource = ({ name, extension, caption }) => {
	const imageDirectory = getImageDirectory()

	if (methode.imageLibrary) {
		return createPicturefill({ name, extension, caption, imageDirectory })
	}
	// plain old image default
	const src = `${imageDirectory}${name}${imageSizes[imageSizes.length - 1]}.${extension}`
	return `<img src='${src}' alt='${caption}' />`
}

const getImageInfo = (imagePath) => {
	const imageFull = imagePath.substr(imagePath.lastIndexOf('/') + 1)
	const imageSplit = imageFull.split('.')
	const name = `${imageSplit[0]}_apps_w_`
	const extension = imageSplit[1]
	return { name, extension }
}

const replaceMethodeImageSize = ({ imagePath, imageSize }) =>
	imagePath.replace(/image_(.+\d)w/g, `image_${imageSize}w`)

const replaceLocalImageSize = ({ imagePath, imageSize }) =>
	imagePath.replace(/_apps_w_(.+\d)\./g, `_apps_w_${imageSize}.`)

const createFigure = ({ href, credit, caption, alt }) => {
	const imagePath = href.split('?')[0]
	const { name, extension } = getImageInfo(imagePath)

	// start generating markup
	const src = createFigureSource({ name, extension, caption })

	// add to download queue
	const imageSize = 1920
	const url = `http:${replaceMethodeImageSize({ imagePath, imageSize })}`
	const filename = `${name}${imageSize}.${extension}`

	imagesToDownload.push({ url, filename })

	return `

			${src}
			${credit}

${caption}

	`.trim()
}

const cleanP = (content) => {
	// check for graphic partial first
	if (content.match(/{{graphic:(.*)}}/)) {
		return content.replace(/{{graphic:(.*)}}/, (match, name, index) =>
			`{{> graphic/${name.trim()} }}`
		)
	}

	const stripped = content
		.replace(//g, '') // remove spans
		.replace(/<\/span>/g, '')
		.replace(//g, '') // remove bolds
		.replace(/<\/b>/g, '')

	// hr
	if (stripped.match(/\*\*\*/)) return '
'
	//subhed
	if (stripped.match(/subhead>/)) {
		return stripped.replace(/<subhead(.*?)>/g, "
")
		.replace(/<\/subhead>/g, '
')
	}

	return stripped.length ? `<p class='methode-graf'>${stripped}</p>` : ''
}

const createContentMarkup = (item) => {
	const types = {
		p: ({ content }) => cleanP(content),
		image: ({ href, credit, caption, alt }) => createFigure({ href, credit, caption, alt }),
		ad: () => {
			firstAdSlotted = true
			return `{{> base/base-ad-slot}}`
		},
	}

	if (item.type === 'ad' && firstAdSlotted) return ''
	return types[item.type](item)
}

const createHTML = (stories) => {
	const { content } = story.body
	// go thru item in content and create the proper markup
	return content.map(createContentMarkup).join('\n')
}

const writeHTML = (html) =>
	fs.writeFileSync('src/html/partials/graphic/methode.hbs', html)

const resizeImage = ({ path, resolve, reject }) => {
	console.log('resizing image...')
	// create smaller versions of each image
	const promises = imageSizes.map(imageSize =>
		new Promise((res, rej) => {
			const out = replaceLocalImageSize({ imagePath: path, imageSize })
			jimp.read(path).then(image =>
		    	image
		    	.resize(imageSize, jimp.AUTO)
				.write(out, res)
			).catch(err => rej(err))
		})
	)

	promises.push(
		new Promise((res, rej) => {
			const imageSize = 20
			const out = replaceLocalImageSize({ imagePath: path, imageSize: 'placeholder' })
			jimp.read(path).then(image =>
		    	image
		    	.blur(40)
		    	.resize(imageSize, jimp.AUTO)
				.write(out, res)
			).catch(err => rej(err))
		})
	)

	Promise.all(promises)
		.then(result => resolve(result))
		.catch(error => reject(error))
}

const downloadImages = (cb) => {
	const promises = imagesToDownload.map(image =>
		new Promise((resolve, reject) => {
			const { url, filename } = image
			const path = `src/${getImageDirectory()}${filename}`
			try {
				const exists = fs.lstatSync(path)
				resolve()
			} catch (e) {
				console.log(`downloading: ${url}`)
				request(url, {encoding: 'binary'}, (error, response, body) => {
					if (error) reject(error)
					else {
						fs.writeFile(path, body, 'binary', (err) => {
							if (err) reject(err)
							else resizeImage({ path, resolve, reject })
						})
					}
				})
			}
		})
	)

	Promise.all(promises)
		.then(result => cb())
		.catch(error => {
			console.log(error)
			cb()
		})
}

const fetchMethode = (cb) => {
	const base = 'http://prdedit.bostonglobe.com/eom/SysConfig/WebPortal/BostonGlobe/precursor/template/api_redirect.jsp?path=/'
	const promises = methode.story.map(story =>
		new Promise((resolve, reject) => {
			const url = `${base}${story.path}`
			console.log('fetching story data:', url)
			request(url, (error, response, body) => {
				if (!error && response.statusCode === 200) {
					resolve({...story, body: JSON.parse(body)})
				} else {
					reject(error)
				}
			})
		})
	)

	Promise.all(promises)
		.then(results => {
			const html = createHTML(results)
			writeHTML(html)
			downloadImages(cb)
		})
		.catch(error => {
			console.error(error)
			cb()
		})
}

gulp.task('fetch-methode', (cb) => {
	if (methode.story.length) fetchMethode(cb)
	else {
		console.error('No methode story in config')
		cb()
	}
})
<|endoftext|>


<commit_before>dojo.provide("dojox.fx.flip");
dojo.experimental("dojox.fx.flip");
dojo.require("dojo.fx");
(function(){

	// because ShrinkSafe will eat this up:
	var borderConst = "border",
		widthConst = "Width",
		heightConst = "Height",
		topConst = "Top",
		rightConst = "Right",
		leftConst = "Left",
		bottomConst = "Bottom"
	;

	dojox.fx.flip = function(/*Object*/ args){
		// summary: Animate a node flipping following a specific direction
		//
		// description:
		//		Returns an animation that will flip the
		//		node around a central axis:
		//		if args.dir is "left" or "right" --> y axis
		//		if args.dir is "top" or "bottom" --> x axis
		//
		//		This effect is obtained using a border distorsion applied to a helper node.
		//
		//		The user can specify three background colors for the helper node:
		//		darkColor: the darkest color reached during the animation
		//		lightColor: the brightest color
		//		endColor: the final backgroundColor for the node
		//
		//	example:
		//	|	var anim = dojox.fx.flip({
		//	|		node: dojo.byId("nodeId"),
		//	|		dir: "top",
		//	|		darkColor: "#555555",
		//	|		lightColor: "#dddddd",
		//	|		endColor: "#666666",
		//	|		duration:300
		//	|	  });

		var helperNode = dojo.doc.createElement("div");

		var node = args.node = dojo.byId(args.node),
			s = node.style,
			dims = null,
			hs = null,
			pn = null,
			lightColor = args.lightColor || "#dddddd",
			darkColor = args.darkColor || "#555555",
			bgColor = dojo.style(node, "backgroundColor"),
			endColor = args.endColor || bgColor,
			staticProps = {},
			anims = [],
			duration = args.duration ? args.duration / 2 : 250,
			dir = args.dir || "left",
			pConst = 0.6,
			transparentColor = "transparent",
			whichAnim = args.whichAnim,
			mConst = 1
		;

		// IE6 workaround: IE6 doesn't support transparent borders
		var convertColor = function(color){
			return ((new dojo.Color(color)).toHex() === "#000000") ? "#000001" : color;
		};

		if(dojo.isIE < 7){
			endColor = convertColor(endColor);
			lightColor = convertColor(lightColor);
			darkColor = convertColor(darkColor);
			bgColor = convertColor(bgColor);
			transparentColor = "black";
			helperNode.style.filter = "chroma(color='#000000')";
		}

		var init = (function(n){
			return function(){
				var ret = dojo.coords(n, true);
				dims = {
					top: ret.y,
					left: ret.x,
					width: ret.w,
					height: ret.h
				};
			}
		})(node);
		init();
		if(whichAnim){
			pConst = .5;//.6875;
			mConst = 0;
		}
		// helperNode initialization
		hs = {
			position: "absolute",
			top: dims["top"] + "px",
			left: dims["left"] + "px",
			height: "0",
			width: "0",
			zIndex: args.zIndex || (s.zIndex || 0),
			border: "0 solid " + transparentColor,
			fontSize: "0",
			visibility: "hidden"
		};
		dims["endHeight"] = dims["height"] * pConst;
		dims["endWidth"] = dims["width"] * pConst;
		var props = [ {},
			{
				top: dims["top"],
				left: dims["left"]
			}
		];
		var dynProperties = {
			left: [leftConst, rightConst, topConst, bottomConst, widthConst, heightConst, "end" + heightConst, leftConst],
			right: [rightConst, leftConst, topConst, bottomConst, widthConst, heightConst, "end" + heightConst, leftConst],
			top: [topConst, bottomConst, leftConst, rightConst, heightConst, widthConst, "end" + widthConst, topConst],
			bottom: [bottomConst, topConst, leftConst, rightConst, heightConst, widthConst, "end" + widthConst, topConst]
		};
		// property names
		pn = dynProperties[dir];

		staticProps[pn[5].toLowerCase()] = dims[pn[5].toLowerCase()] + "px";
		staticProps[pn[4].toLowerCase()] = "0";
		staticProps[borderConst + pn[1] + widthConst] = dims[pn[4].toLowerCase()] + "px";
		staticProps[borderConst + pn[1] + "Color"] = bgColor;

		var p0 = props[0];
		p0[borderConst + pn[1] + widthConst] = 0;
		p0[borderConst + pn[1] + "Color"] = darkColor;
		p0[borderConst + pn[2] + widthConst] = dims[pn[6]] / 2;
		p0[borderConst + pn[3] + widthConst] = dims[pn[6]] / 2;
		p0[pn[2].toLowerCase()] = dims[pn[2].toLowerCase()] - mConst * (dims[pn[6]] / 8);
		p0[pn[7].toLowerCase()] = dims[pn[7].toLowerCase()] + dims[pn[4].toLowerCase()] / 2 + (args.shift || 0);
		p0[pn[5].toLowerCase()] = dims[pn[6]];

		var p1 = props[1];
		p1[borderConst + pn[0] + "Color"] = { start: lightColor, end: endColor };
		p1[borderConst + pn[0] + widthConst] = dims[pn[4].toLowerCase()];
		p1[borderConst + pn[2] + widthConst] = 0;
		p1[borderConst + pn[3] + widthConst] = 0;
		p1[pn[5].toLowerCase()] = { start: dims[pn[6]], end: dims[pn[5].toLowerCase()] };

		dojo.mixin(hs, staticProps);
		dojo.style(helperNode, hs);
		dojo.body().appendChild(helperNode);

		var finalize = function(){
			helperNode.parentNode.removeChild(helperNode);
			// fixes a flicker when the animation ends
			s.backgroundColor = endColor;
			s.visibility = "visible";
		};
		if(whichAnim == "last"){
			for(var i in p0){
				p0[i] = { start: p0[i] };
			}
			p0[borderConst + pn[1] + "Color"] = { start: darkColor, end: endColor };
			p1 = p0;
		}
		if(!whichAnim || whichAnim == "first"){
			anims.push(dojo.animateProperty({
				node: helperNode,
				duration: duration,
				properties: p0
			}));
		}
		if(!whichAnim || whichAnim == "last"){
			anims.push(dojo.animateProperty({
				node: helperNode,
				duration: duration,
				properties: p1,
				onEnd: finalize
			}));
		}

		// hide the original node
		dojo.connect(anims[0], "play", function(){
			helperNode.style.visibility = "visible";
			s.visibility = "hidden";
		});

		return dojo.fx.chain(anims); // dojo._Animation

	}

	dojox.fx.flipCube = function(/*Object*/ args){
		// summary: An extension to `dojox.fx.flip` providing a more 3d-like rotation
		//
		// description:
		//		An extension to `dojox.fx.flip` providing a more 3d-like rotation.
		//		Behaves the same as `dojox.fx.flip`, using the same attributes and
		//		other standard `dojo._Animation` properties.
		//
		//	example:
		//		See `dojox.fx.flip`
		var anims = [],
			mb = dojo.marginBox(args.node),
			shiftX = mb.w / 2,
			shiftY = mb.h / 2,
			dims = {
				top: {
					pName: "height",
					args:[
						{
							whichAnim: "first",
							dir: "top",
							shift: -shiftY
						},
						{
							whichAnim: "last",
							dir: "bottom",
							shift: shiftY
						}
					]
				},
				right: {
					pName: "width",
					args:[
						{
							whichAnim: "first",
							dir: "right",
							shift: shiftX
						},
						{
							whichAnim: "last",
							dir: "left",
							shift: -shiftX
						}
					]
				},
				bottom: {
					pName: "height",
					args:[
						{
							whichAnim: "first",
							dir: "bottom",
							shift: shiftY
						},
						{
							whichAnim: "last",
							dir: "top",
							shift: -shiftY
						}
					]
				},
				left: {
					pName: "width",
					args:[
						{
							whichAnim: "first",
							dir: "left",
							shift: -shiftX
						},
						{
							whichAnim: "last",
							dir: "right",
							shift: shiftX
						}
					]
				}
			}
		;
		var d = dims[args.dir || "left"],
			p = d.args
		;

		for(var i = p.length - 1; i >= 0; i--){
			dojo.mixin(args, p[i]);
			anims.push(dojox.fx.flip(args));
		}
		return dojo.fx.combine(anims);
	};

})();
<commit_msg>fixes #7793 - add duration for fx.flip - thanks niccola<commit_after>dojo.provide("dojox.fx.flip");
dojo.experimental("dojox.fx.flip");
dojo.require("dojo.fx");
(function(){

	// because ShrinkSafe will eat this up:
	var borderConst = "border",
		widthConst = "Width",
		heightConst = "Height",
		topConst = "Top",
		rightConst = "Right",
		leftConst = "Left",
		bottomConst = "Bottom"
	;

	dojox.fx.flip = function(/*Object*/ args){
		// summary: Animate a node flipping following a specific direction
		//
		// description:
		//		Returns an animation that will flip the
		//		node around a central axis:
		//		if args.dir is "left" or "right" --> y axis
		//		if args.dir is "top" or "bottom" --> x axis
		//
		//		This effect is obtained using a border distorsion applied to a helper node.
		//
		//		The user can specify three background colors for the helper node:
		//		darkColor: the darkest color reached during the animation
		//		lightColor: the brightest color
		//		endColor: the final backgroundColor for the node
		//
		//	example:
		//	|	var anim = dojox.fx.flip({
		//	|		node: dojo.byId("nodeId"),
		//	|		dir: "top",
		//	|		darkColor: "#555555",
		//	|		lightColor: "#dddddd",
		//	|		endColor: "#666666",
		//	|		duration:300
		//	|	  });

		var helperNode = dojo.doc.createElement("div");

		var node = args.node = dojo.byId(args.node),
			s = node.style,
			dims = null,
			hs = null,
			pn = null,
			lightColor = args.lightColor || "#dddddd",
			darkColor = args.darkColor || "#555555",
			bgColor = dojo.style(node, "backgroundColor"),
			endColor = args.endColor || bgColor,
			staticProps = {},
			anims = [],
			duration = args.duration ? args.duration / 2 : 250,
			dir = args.dir || "left",
			pConst = 0.6,
			transparentColor = "transparent",
			whichAnim = args.whichAnim,
			mConst = 1
		;

		// IE6 workaround: IE6 doesn't support transparent borders
		var convertColor = function(color){
			return ((new dojo.Color(color)).toHex() === "#000000") ? "#000001" : color;
		};

		if(dojo.isIE < 7){
			endColor = convertColor(endColor);
			lightColor = convertColor(lightColor);
			darkColor = convertColor(darkColor);
			bgColor = convertColor(bgColor);
			transparentColor = "black";
			helperNode.style.filter = "chroma(color='#000000')";
		}

		var init = (function(n){
			return function(){
				var ret = dojo.coords(n, true);
				dims = {
					top: ret.y,
					left: ret.x,
					width: ret.w,
					height: ret.h
				};
			}
		})(node);
		init();
		if(whichAnim){
			pConst = .5;//.6875;
			mConst = 0;
		}
		// helperNode initialization
		hs = {
			position: "absolute",
			top: dims["top"] + "px",
			left: dims["left"] + "px",
			height: "0",
			width: "0",
			zIndex: args.zIndex || (s.zIndex || 0),
			border: "0 solid " + transparentColor,
			fontSize: "0",
			visibility: "hidden"
		};
		dims["endHeight"] = dims["height"] * pConst;
		dims["endWidth"] = dims["width"] * pConst;
		var props = [ {},
			{
				top: dims["top"],
				left: dims["left"]
			}
		];
		var dynProperties = {
			left: [leftConst, rightConst, topConst, bottomConst, widthConst, heightConst, "end" + heightConst, leftConst],
			right: [rightConst, leftConst, topConst, bottomConst, widthConst, heightConst, "end" + heightConst, leftConst],
			top: [topConst, bottomConst, leftConst, rightConst, heightConst, widthConst, "end" + widthConst, topConst],
			bottom: [bottomConst, topConst, leftConst, rightConst, heightConst, widthConst, "end" + widthConst, topConst]
		};
		// property names
		pn = dynProperties[dir];

		staticProps[pn[5].toLowerCase()] = dims[pn[5].toLowerCase()] + "px";
		staticProps[pn[4].toLowerCase()] = "0";
		staticProps[borderConst + pn[1] + widthConst] = dims[pn[4].toLowerCase()] + "px";
		staticProps[borderConst + pn[1] + "Color"] = bgColor;

		var p0 = props[0];
		p0[borderConst + pn[1] + widthConst] = 0;
		p0[borderConst + pn[1] + "Color"] = darkColor;
		p0[borderConst + pn[2] + widthConst] = dims[pn[6]] / 2;
		p0[borderConst + pn[3] + widthConst] = dims[pn[6]] / 2;
		p0[pn[2].toLowerCase()] = dims[pn[2].toLowerCase()] - mConst * (dims[pn[6]] / 8);
		p0[pn[7].toLowerCase()] = dims[pn[7].toLowerCase()] + dims[pn[4].toLowerCase()] / 2 + (args.shift || 0);
		p0[pn[5].toLowerCase()] = dims[pn[6]];

		var p1 = props[1];
		p1[borderConst + pn[0] + "Color"] = { start: lightColor, end: endColor };
		p1[borderConst + pn[0] + widthConst] = dims[pn[4].toLowerCase()];
		p1[borderConst + pn[2] + widthConst] = 0;
		p1[borderConst + pn[3] + widthConst] = 0;
		p1[pn[5].toLowerCase()] = { start: dims[pn[6]], end: dims[pn[5].toLowerCase()] };

		dojo.mixin(hs, staticProps);
		dojo.style(helperNode, hs);
		dojo.body().appendChild(helperNode);

		var finalize = function(){
			helperNode.parentNode.removeChild(helperNode);
			// fixes a flicker when the animation ends
			s.backgroundColor = endColor;
			s.visibility = "visible";
		};
		if(whichAnim == "last"){
			for(var i in p0){
				p0[i] = { start: p0[i] };
			}
			p0[borderConst + pn[1] + "Color"] = { start: darkColor, end: endColor };
			p1 = p0;
		}
		if(!whichAnim || whichAnim == "first"){
			anims.push(dojo.animateProperty({
				node: helperNode,
				duration: duration,
				properties: p0
			}));
		}
		if(!whichAnim || whichAnim == "last"){
			anims.push(dojo.animateProperty({
				node: helperNode,
				duration: duration,
				properties: p1,
				onEnd: finalize
			}));
		}

		// hide the original node
		dojo.connect(anims[0], "play", function(){
			helperNode.style.visibility = "visible";
			s.visibility = "hidden";
		});

		return dojo.fx.chain(anims); // dojo._Animation

	}

	dojox.fx.flipCube = function(/*Object*/ args){
		// summary: An extension to `dojox.fx.flip` providing a more 3d-like rotation
		//
		// description:
		//		An extension to `dojox.fx.flip` providing a more 3d-like rotation.
		//		Behaves the same as `dojox.fx.flip`, using the same attributes and
		//		other standard `dojo._Animation` properties.
		//
		//	example:
		//		See `dojox.fx.flip`
		var anims = [],
			mb = dojo.marginBox(args.node),
			shiftX = mb.w / 2,
			shiftY = mb.h / 2,
			dims = {
				top: {
					pName: "height",
					args:[
						{
							whichAnim: "first",
							dir: "top",
							shift: -shiftY
						},
						{
							whichAnim: "last",
							dir: "bottom",
							shift: shiftY
						}
					]
				},
				right: {
					pName: "width",
					args:[
						{
							whichAnim: "first",
							dir: "right",
							shift: shiftX
						},
						{
							whichAnim: "last",
							dir: "left",
							shift: -shiftX
						}
					]
				},
				bottom: {
					pName: "height",
					args:[
						{
							whichAnim: "first",
							dir: "bottom",
							shift: shiftY
						},
						{
							whichAnim: "last",
							dir: "top",
							shift: -shiftY
						}
					]
				},
				left: {
					pName: "width",
					args:[
						{
							whichAnim: "first",
							dir: "left",
							shift: -shiftX
						},
						{
							whichAnim: "last",
							dir: "right",
							shift: shiftX
						}
					]
				}
			}
		;
		var d = dims[args.dir || "left"],
			p = d.args
		;
		args.duration = args.duration ? args.duration * 2 : 500;

		for(var i = p.length - 1; i >= 0; i--){
			dojo.mixin(args, p[i]);
			anims.push(dojox.fx.flip(args));
		}
		return dojo.fx.combine(anims);
	};

})();
<|endoftext|>


<commit_before>require('babel-polyfill');

const environment = {
  development: {
    isProduction: false
  },
  production: {
    isProduction: true
  }
}[process.env.NODE_ENV || 'development'];

module.exports = Object.assign({
  host: process.env.HOST || 'localhost',
  port: process.env.PORT || 80,
  apiHost: process.env.APIHOST || 'localhost',
  apiPort: process.env.APIPORT || 3030,
  db: 'mongodb://42.121.119.36/vendor-db',
  categories: [{ title: '微信', class: 'wechat' }, { title: '淘宝', class: 'taobao' }],
  app: {
    title: '诚宝通',
    description: 'All the modern best practices in one example.',
    head: {
      titleTemplate: '诚宝通: %s',
      meta: [
        { name: 'description', content: 'All the modern best practices in one example.' },
        { charset: 'utf-8' },
        { property: 'og:site_name', content: '诚宝通' },
        { property: 'og:image', content: 'https://react-redux.herokuapp.com/logo.jpg' },
        { property: 'og:locale', content: 'zh-CN' },
        { property: 'og:title', content: '诚宝通' },
        { property: 'og:description', content: 'All the modern best practices in one example.' },
        { property: 'og:card', content: 'summary' },
        { property: 'og:site', content: '@erikras' },
        { property: 'og:creator', content: '@erikras' },
        { property: 'og:image:width', content: '200' },
        { property: 'og:image:height', content: '200' }
      ]
    }
  },

}, environment);
<commit_msg>modify config<commit_after>require('babel-polyfill');

const environment = {
  development: {
    isProduction: false
  },
  production: {
    isProduction: true
  }
}[process.env.NODE_ENV || 'development'];

module.exports = Object.assign({
  host: process.env.HOST || 'localhost',
  port: process.env.PORT || 8001,
  apiHost: process.env.APIHOST || 'localhost',
  apiPort: process.env.APIPORT || 3030,
  db: 'mongodb://42.121.119.36/vendor-db',
  categories: [{ title: '微信', class: 'wechat' }, { title: '淘宝', class: 'taobao' }],
  app: {
    title: '诚宝通',
    description: 'All the modern best practices in one example.',
    head: {
      titleTemplate: '诚宝通: %s',
      meta: [
        { name: 'description', content: 'All the modern best practices in one example.' },
        { charset: 'utf-8' },
        { property: 'og:site_name', content: '诚宝通' },
        { property: 'og:image', content: 'https://react-redux.herokuapp.com/logo.jpg' },
        { property: 'og:locale', content: 'zh-CN' },
        { property: 'og:title', content: '诚宝通' },
        { property: 'og:description', content: 'All the modern best practices in one example.' },
        { property: 'og:card', content: 'summary' },
        { property: 'og:site', content: '@erikras' },
        { property: 'og:creator', content: '@erikras' },
        { property: 'og:image:width', content: '200' },
        { property: 'og:image:height', content: '200' }
      ]
    }
  },

}, environment);
<|endoftext|>


<commit_before>var CloudCmd, Util, DOM, CloudFunc, Terminal;
(function(CloudCmd, Util, DOM, CloudFunc) {
    'use strict';

    CloudCmd.Terminal = TerminalProto;

    function TerminalProto(CallBack) {
        var Name            = 'Terminal',
            Loading,
            Element,
            MouseBinded,
            Term,
            Cell,
            Key             = CloudCmd.Key,
            ESC             = Key.ESC,
            Images          = DOM.Images,
            Notify          = DOM.Notify,

            CHANNEL         = CloudFunc.CHANNEL_TERMINAL,
            CHANNEL_RESIZE  = CloudFunc.CHANNEL_TERMINAL_RESIZE,

            CloudTerm       = this;

        function init() {
            Loading = true;

            Util.loadOnLoad([
                DOM.jqueryLoad,
                CloudCmd.View,
                /* rm view keys, it ruin terminal */
                function(callback) {
                    CloudCmd.View.rmKeys(),
                    Util.exec(callback);
                },
                load,
                CloudCmd.Socket,
                CloudTerm.show,
                addListeners
            ]);
        }

        CloudTerm.show      = show;
        CloudTerm.write     = write;

        function show(callback) {
            var size,
                socket = CloudCmd.Socket;

            if (!Loading) {
                Images.showLoad({top:true});

                if (!Element) {
                    Element         = DOM.anyload({
                        name    : 'div',
                        id      : 'terminal',
                        style   : 'height :100%'
                    });

                   /* hack to determine console size
                     * inspired with
                     *
                     * https://github.com/petethepig/devtools-terminal
                     */
                    Cell            = DOM.anyload({
                        name    : 'div',
                        inner   : '&nbsp',
                        parent  : Element,
                        style   : 'position: absolute;' +
                                  'top      : -1000px;'
                    });

                    DOM.cssSet({
                        id      : 'terminal-css',
                        inner   : '#terminal, .terminal, #view {'   +
                                    'height'            + ': 100%;' +
                                '}'                                 +
                                  '.terminal-cursor {'              +
                                    'background'        + ': gray'  +
                                '}'
                    });

                    size    = getSize();

                    Term    = new Terminal({
                        screenKeys: true,
                        cursorBlink: false,
                        cols: size.cols,
                        rows: size.rows
                    });

                    Term.open(Element);
                }

                CloudCmd.View.show(Element, function() {
                    Element.focus();
                    Terminal.brokenBold = true;

                    Util.exec(callback);
                }, {
                    onUpdate: function() {
                        var size = getSize();
                        Term.resize(size.cols, size.rows);
                        Term.emit('resize', size);
                    }
                });
            }
        }

        function write(data) {
            Term.write(data);
        }

        function addListeners(callback) {
            var socket  = CloudCmd.Socket;

            socket.on(CHANNEL, write);

            Term.on('data', function(data) {
                socket.emit(CHANNEL, data);
            });

            Term.on('resize', function(size) {
                socket.emit(CHANNEL_RESIZE, size);
            });

            Util.exec(callback);
        }

        function getSize() {
            var wSubs   = Element.offsetWidth - Element.clientWidth,
                w       = Element.clientWidth - wSubs,

                hSubs   = Element.offsetHeight - Element.clientHeight,
                h       = Element.clientHeight - hSubs,

                x       = Cell.clientWidth,
                y       = Cell.clientHeight,

                cols    = Math.max(Math.floor(w / x), 10),
                rows    = Math.max(Math.floor(h / y), 10),

                size    = {
                    cols: cols,
                    rows: rows
                };

            return size;
        }

        function load(pCallBack) {
            var dir     =  CloudCmd.LIBDIRCLIENT + 'terminal/',
                path    = dir + 'term.js';

            Util.time(Name + ' load');

            DOM.jsload(path, function() {
                Util.timeEnd(Name + ' load');
                Loading = false;

                Util.exec(pCallBack);
            });
        }

        init();
    }

})(CloudCmd, Util, DOM, CloudFunc);
<commit_msg>fix(terminal) new line<commit_after>var CloudCmd, Util, DOM, CloudFunc, Terminal;
(function(CloudCmd, Util, DOM, CloudFunc) {
    'use strict';

    CloudCmd.Terminal = TerminalProto;

    function TerminalProto(CallBack) {
        var Name            = 'Terminal',
            Loading,
            Element,
            MouseBinded,
            Term,
            Cell,
            Key             = CloudCmd.Key,
            ESC             = Key.ESC,
            Images          = DOM.Images,
            Notify          = DOM.Notify,

            CHANNEL         = CloudFunc.CHANNEL_TERMINAL,
            CHANNEL_RESIZE  = CloudFunc.CHANNEL_TERMINAL_RESIZE,

            CloudTerm       = this;

        function init() {
            Loading = true;

            Util.loadOnLoad([
                DOM.jqueryLoad,
                CloudCmd.View,
                /* rm view keys, it ruin terminal */
                function(callback) {
                    CloudCmd.View.rmKeys(),
                    Util.exec(callback);
                },
                load,
                CloudCmd.Socket,
                CloudTerm.show,
                addListeners
            ]);
        }

        CloudTerm.show      = show;
        CloudTerm.write     = write;

        function show(callback) {
            var socket = CloudCmd.Socket;

            if (!Loading) {
                Images.showLoad({top:true});

                if (!Element) {
                    Element         = DOM.anyload({
                        name    : 'div',
                        id      : 'terminal',
                        style   : 'height :100%'
                    });

                   /* hack to determine console size
                     * inspired with
                     *
                     * https://github.com/petethepig/devtools-terminal
                     */
                    Cell            = DOM.anyload({
                        name    : 'div',
                        inner   : '&nbsp',
                        parent  : Element,
                        style   : 'position: absolute;' +
                                  'top      : -1000px;'
                    });

                    DOM.cssSet({
                        id      : 'terminal-css',
                        inner   : '#terminal, .terminal, #view {'   +
                                    'height'            + ': 100%;' +
                                '}'                                 +
                                  '.terminal-cursor {'              +
                                    'background'        + ': gray'  +
                                '}'
                    });

                    Term    = new Terminal({
                        screenKeys: true,
                        cursorBlink: false,
                    });

                    Term.open(Element);
                }

                CloudCmd.View.show(Element, function() {
                    Element.focus();
                    Terminal.brokenBold = true;

                    Util.exec(callback);
                }, {
                    onUpdate: function() {
                        var size = getSize();
                        Term.resize(size.cols, size.rows);
                        Term.emit('resize', size);
                    }
                });
            }
        }

        function write(data) {
            Term.write(data);
        }

        function addListeners(callback) {
            var socket  = CloudCmd.Socket;

            socket.on(CHANNEL, write);

            Term.on('data', function(data) {
                socket.emit(CHANNEL, data);
            });

            Term.on('resize', function(size) {
                socket.emit(CHANNEL_RESIZE, size);
            });

            Util.exec(callback);
        }

        function getSize() {
            var wSubs   = Element.offsetWidth - Element.clientWidth,
                w       = Element.clientWidth - wSubs,

                hSubs   = Element.offsetHeight - Element.clientHeight,
                h       = Element.clientHeight - hSubs,

                x       = Cell.clientWidth,
                y       = Cell.clientHeight,

                cols    = Math.max(Math.floor(w / x), 10),
                rows    = Math.max(Math.floor(h / y), 10),

                size    = {
                    cols: cols,
                    rows: rows
                };

            return size;
        }

        function load(pCallBack) {
            var dir     =  CloudCmd.LIBDIRCLIENT + 'terminal/',
                path    = dir + 'term.js';

            Util.time(Name + ' load');

            DOM.jsload(path, function() {
                Util.timeEnd(Name + ' load');
                Loading = false;

                Util.exec(pCallBack);
            });
        }

        init();
    }

})(CloudCmd, Util, DOM, CloudFunc);
<|endoftext|>


<commit_before>// Generated on <%= (new Date).toISOString().split('T')[0] %> using <%= pkg.name %> <%= pkg.version %>
'use strict';

module.exports = function (grunt) {
    require('jit-grunt')(grunt); // Load grunt tasks automatically
    require('time-grunt')(grunt); // Time how long tasks take. Can help when optimizing build times

    grunt.initConfig({
        yeoman: {
            app: 'app',
            dist: 'dist',
            test: 'test',

            // Browser support, used for autoprefixing and backwards compatible hack enabling
            // Syntax documentation: https://github.com/ai/autoprefixer#browsers
            browsers: [
                '> 1%',
                'last 2 versions',
                'Firefox ESR',
                'Opera 12.1'
            ]
        },

        // Empties folders to start fresh
        clean: {
            dist: {
                files: [{
                    dot: true,
                    src: [
                        '<%%= yeoman.dist %>'
                    ]
                }]
            }
        },

        // Make sure code styles are up to par and there are no obvious mistakes
        jshint: {
            options: {
                jshintrc: '.jshintrc',
                reporter: require('jshint-stylish')
            },
            all: [
                'Gruntfile.js',
                '<%%= yeoman.app %>',
                '<%%= yeoman.test %>'
            ]
        },

        // Development server configuration, see https://github.com/Munter/grunt-livestyle#full-configuration-example
        livestyle: {
            root: '<%%= yeoman.app %>',
            browsers: '<%%= yeoman.browsers %>'
        },

        // Production build system configuration, see https://github.com/Munter/grunt-reduce#configuration
        reduce: {
            root: '<%%= yeoman.app %>',
            outRoot: '<%%= yeoman.dist %>',
            browsers: '<%%= yeoman.browsers %>',

            // minimatch patterns of files to include as base assets
            // Dependencies of these will be automatically populated
            // Paths are relative to reduce.root
            include: [
                '**/*.html',
                '**/.htaccess',
                '*.txt',
                '*.ico'
            ]
        }
    });

    grunt.registerTask('lint', [
        'newer:jshint'
    ]);

    grunt.registerTask('serve', [
        'livestyle'
    ]);

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

    grunt.registerTask('build', [
        'clean:dist',
        'reduce'
    ]);

    grunt.registerTask('default', [
        'serve'
    ]);
};
<commit_msg>Only load root level html-files as base assets. Fixes #1<commit_after>// Generated on <%= (new Date).toISOString().split('T')[0] %> using <%= pkg.name %> <%= pkg.version %>
'use strict';

module.exports = function (grunt) {
    require('jit-grunt')(grunt); // Load grunt tasks automatically
    require('time-grunt')(grunt); // Time how long tasks take. Can help when optimizing build times

    grunt.initConfig({
        yeoman: {
            app: 'app',
            dist: 'dist',
            test: 'test',

            // Browser support, used for autoprefixing and backwards compatible hack enabling
            // Syntax documentation: https://github.com/ai/autoprefixer#browsers
            browsers: [
                '> 1%',
                'last 2 versions',
                'Firefox ESR',
                'Opera 12.1'
            ]
        },

        // Empties folders to start fresh
        clean: {
            dist: {
                files: [{
                    dot: true,
                    src: [
                        '<%%= yeoman.dist %>'
                    ]
                }]
            }
        },

        // Make sure code styles are up to par and there are no obvious mistakes
        jshint: {
            options: {
                jshintrc: '.jshintrc',
                reporter: require('jshint-stylish')
            },
            all: [
                'Gruntfile.js',
                '<%%= yeoman.app %>',
                '<%%= yeoman.test %>'
            ]
        },

        // Development server configuration, see https://github.com/Munter/grunt-livestyle#full-configuration-example
        livestyle: {
            root: '<%%= yeoman.app %>',
            browsers: '<%%= yeoman.browsers %>'
        },

        // Production build system configuration, see https://github.com/Munter/grunt-reduce#configuration
        reduce: {
            root: '<%%= yeoman.app %>',
            outRoot: '<%%= yeoman.dist %>',
            browsers: '<%%= yeoman.browsers %>',

            // minimatch patterns of files to include as base assets
            // Dependencies of these will be automatically populated
            // Paths are relative to reduce.root
            include: [
                '*.html',
                '**/.htaccess',
                '*.txt',
                '*.ico'
            ]
        }
    });

    grunt.registerTask('lint', [
        'newer:jshint'
    ]);

    grunt.registerTask('serve', [
        'livestyle'
    ]);

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

    grunt.registerTask('build', [
        'clean:dist',
        'reduce'
    ]);

    grunt.registerTask('default', [
        'serve'
    ]);
};
<|endoftext|>