<commit_before>//
//  attachmentRemoval.js
//
//  Created by Rebecca Stankus on 9/26/17.
//  Copyright 2017 High Fidelity, Inc.
//
//  Distributed under the Apache License, Version 2.0.
//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
//  This script acts on a zone to make it remove all avatar attachments when an avatar enters the zone.

(function () {
    var shared = Script.require('./attachmentZoneShared.js');
    var _this = this;
    _this.enterEntity = function (entityID) {
        shared.getAvatarChildEntities(MyAvatar).forEach(function (entityID) {
            var childUserData = Entities.getEntityProperties(entityID).userData;
            var isAttachment = childUserData.indexOf("Attachment");
            if (isAttachment !== -1) {
                Entities.deleteEntity(entityID);
            }
        });
    };
});
<commit_msg>fixed getEntityProperties<commit_after>//
//  attachmentRemoval.js
//
//  Created by Rebecca Stankus on 9/26/17.
//  Copyright 2017 High Fidelity, Inc.
//
//  Distributed under the Apache License, Version 2.0.
//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
//  This script acts on a zone to make it remove all avatar attachments when an avatar enters the zone.

(function () {
    var shared = Script.require('./attachmentZoneShared.js');
    var _this = this;
    _this.enterEntity = function (entityID) {
        shared.getAvatarChildEntities(MyAvatar).forEach(function (entityID) {
            var childUserData = Entities.getEntityProperties(entityID, 'userData').userData;
            var isAttachment = childUserData.indexOf("Attachment");
            if (isAttachment !== -1) {
                Entities.deleteEntity(entityID);
            }
        });
    };
});
<|endoftext|>


<commit_before>import MK from 'matreshka';
import Tabs from './tabs/tabs';
import CodeMirror from 'codemirror';

export default class Main extends MK.Object {
    constructor() {
        super()
            .setClassFor({
                tabs: Tabs
            })
            .initRouter('mode/id')
            .set({
                memo: {},
                mode: this.mode || 'simple',
                defaultView: this.toJSONString(),
                saved: true
            })
            .bindNode({
                sandbox: 'body',
                reformat: ':sandbox .reformat',
                saveButton: ':sandbox .save',
                win: window
            })
            .bindNode('saved', ':bound(saveButton)', MK.binders.className('disabled'))
            .events();

        if (this.id) {
            this.restore(this.id);
        }
    }

    events() {
        return this
            .on({
                'tabs@change:activeTab': evt => {
                    this.mode = evt.value.name;
                },
                'dragover::sandbox drop::sandbox': evt => evt.preventDefault(),
                'click::saveButton': this.save,
                'change:id': ({ fromSave }) => {
                    if (this.id && !fromSave) {
                        this.restore(this.id);
                    }
                },
                addevent: evt => {
                    const prefix = 'codemirror:';
                    if (evt.name.indexOf(prefix) === 0) {
                        CodeMirror.on(CodeMirror, evt.name.replace(prefix, ''), evt.callback);
                    }
                },
                'codemirror:validate': editor => {
                    if (this.reformat) {
                        const value = JSON.parse(editor.getValue());
                        if (this.reformat === 'minify') {
                            editor.setValue(JSON.stringify(value));
                        } else if (this.reformat === 'beautify') {
                            editor.setValue(JSON.stringify(value, null, '\t'));
                        }
                    }
                },
                'keydown::win': evt => {
                    const S_KEY_CODE = 83;
                    const { domEvent: { ctrlKey, keyCode } } = evt;
                    if (keyCode === S_KEY_CODE && ctrlKey) {
                        evt.preventDefault();
                        if (!this.saved) {
                            this.save();
                        }
                    }
                }
            })
            .on('change:mode', () => {
                this.tabs[this.mode].active = true;
            }, true)
            .onDebounce({
                'tabs.*@modify': () => {
                    const currentView = this.toJSONString();
                    this.saved = this.defaultView === currentView
                        || this.memo[this.id] === currentView;
                }
            }, 300);
    }

    toJSONString() {
        const data = {};
        this.tabs.each((tab, name) => {
            data[name] = tab.toJSON();
        });

        return JSON.stringify(data);
    }

    fromJSONString(str) {
        const data = JSON.parse(str);

        this.tabs.each((tab, name) => {
            tab.fromJSON(typeof data[name] === 'undefined' ? null : data[name]);
        });

        return this;
    }

    async save() {
        const body = this.toJSONString();
        let foundId;

        for (const [memoId, memoBody] of Object.entries(this.memo)) {
            if (memoBody === body) {
                foundId = memoId;
            }
        }

        if (foundId) {
            this.set('id', foundId, {
                fromSave: true
            });

            this.saved = true;
        } else {
            const resp = await (
                await fetch('/api/save', {
                    method: 'post',
                    body
                })
            ).json();

            if (!resp.error) {
                this.set('id', resp.key, {
                    fromSave: true
                });
                this.memo[resp.key] = body;
                this.saved = true;
            }
        }
    }

    async restore(id) {
        if (this.memo[id]) {
            this.fromJSONString(this.memo[id]);
        } else {
            const resp = await (
                await fetch(`//jsonlintcom.s3.amazonaws.com/${id}.json`)
            ).text();

            this.memo[id] = resp;
            this.fromJSONString(resp);
        }
    }
}
<commit_msg>warn user if he leaves unsaved page<commit_after>import MK from 'matreshka';
import Tabs from './tabs/tabs';
import CodeMirror from 'codemirror';

export default class Main extends MK.Object {
    constructor() {
        super()
            .setClassFor({
                tabs: Tabs
            })
            .initRouter('mode/id')
            .set({
                memo: {},
                mode: this.mode || 'simple',
                defaultView: this.toJSONString(),
                saved: true
            })
            .bindNode({
                sandbox: 'body',
                reformat: ':sandbox .reformat',
                saveButton: ':sandbox .save',
                win: window
            })
            .bindNode('saved', ':bound(saveButton)', MK.binders.className('disabled'))
            .events();

        if (this.id) {
            this.restore(this.id);
        }

        window.onbeforeunload = this.beforeUnload.bind(this);
    }

    beforeUnload() {
        if (!this.saved) {
            return 'Entered data is not saved. Are you sure want to leave the page?';
        }

        return undefined;
    }

    events() {
        return this
            .on({
                'tabs@change:activeTab': evt => {
                    this.mode = evt.value.name;
                },
                'dragover::sandbox drop::sandbox': evt => evt.preventDefault(),
                'click::saveButton': this.save,
                'change:id': ({ fromSave }) => {
                    if (this.id && !fromSave) {
                        this.restore(this.id);
                    }
                },
                addevent: evt => {
                    const prefix = 'codemirror:';
                    if (evt.name.indexOf(prefix) === 0) {
                        CodeMirror.on(CodeMirror, evt.name.replace(prefix, ''), evt.callback);
                    }
                },
                'codemirror:validate': editor => {
                    if (this.reformat) {
                        const value = JSON.parse(editor.getValue());
                        if (this.reformat === 'minify') {
                            editor.setValue(JSON.stringify(value));
                        } else if (this.reformat === 'beautify') {
                            editor.setValue(JSON.stringify(value, null, '\t'));
                        }
                    }
                },
                'keydown::win': evt => {
                    const S_KEY_CODE = 83;
                    const { domEvent: { ctrlKey, keyCode } } = evt;
                    if (keyCode === S_KEY_CODE && ctrlKey) {
                        evt.preventDefault();
                        if (!this.saved) {
                            this.save();
                        }
                    }
                }
            })
            .on('change:mode', () => {
                this.tabs[this.mode].active = true;
            }, true)
            .onDebounce({
                'tabs.*@modify': () => {
                    const currentView = this.toJSONString();
                    this.saved = this.defaultView === currentView
                        || this.memo[this.id] === currentView;
                }
            }, 300);
    }

    toJSONString() {
        const data = {};
        this.tabs.each((tab, name) => {
            data[name] = tab.toJSON();
        });

        return JSON.stringify(data);
    }

    fromJSONString(str) {
        const data = JSON.parse(str);

        this.tabs.each((tab, name) => {
            tab.fromJSON(typeof data[name] === 'undefined' ? null : data[name]);
        });

        return this;
    }

    async save() {
        const body = this.toJSONString();
        let foundId;

        for (const [memoId, memoBody] of Object.entries(this.memo)) {
            if (memoBody === body) {
                foundId = memoId;
            }
        }

        if (foundId) {
            this.set('id', foundId, {
                fromSave: true
            });

            this.saved = true;
        } else {
            const resp = await (
                await fetch('/api/save', {
                    method: 'post',
                    body
                })
            ).json();

            if (!resp.error) {
                this.set('id', resp.key, {
                    fromSave: true
                });
                this.memo[resp.key] = body;
                this.saved = true;
            }
        }
    }

    async restore(id) {
        if (this.memo[id]) {
            this.fromJSONString(this.memo[id]);
        } else {
            const resp = await (
                await fetch(`//jsonlintcom.s3.amazonaws.com/${id}.json`)
            ).text();

            this.memo[id] = resp;
            this.fromJSONString(resp);
        }
    }
}
<|endoftext|>


<commit_before>// Downloads node-webkit runtime and unpacks it into proper place.

'use strict';

var Q = require('q');
var childProcess = require('child_process');
var projectDir = require('fs-jetpack');
var utils = require('./utils');

// --------------------------------------------------------
// Preparations
// --------------------------------------------------------

var devManifest = projectDir.read('package.json', 'json');
var appManifest = projectDir.read('app/package.json', 'json');

// Version of Node-Webkit we need
var runtimeVersion = devManifest.config.nodeWebkit.version;
// The directory where runtime should be placed
var destDir = projectDir.dir('nw/' + utils.os());

// First check if we already haven't downloaded this version of runtime.
if (destDir.read('version') === runtimeVersion) {
    // No need for continuing
    process.exit();
}

// Figure out the URL we have to download.
var url = devManifest.config.nodeWebkit.downloadUrls[utils.os()];
// URL has places where we have to inject version we are interested with.
url = utils.replace(url, { version: runtimeVersion });

var finalize = function () {
    var deferred = Q.defer();

    // Place file with version next to downloaded runtime,
    // so we know in the future what we have there.
    destDir.file('version', { content: runtimeVersion });

    // Special preparations necessary for linux runtime
    if (utils.os() === 'linux') {
        // The hack for problems with libudev.so.0 on Linux platform.
        // Read more: https://github.com/rogerwang/node-webkit/wiki/The-solution-of-lacking-libudev.so.0
        childProcess.exec("sed -i 's/udev\.so\.0/udev.so.1/g' nw", { cwd: destDir.path() },
            function (error, stdout, stderr) {
                if (error || stderr) {
                    console.log('ERROR while patching libudev:');
                    console.log(error);
                    console.log(stderr);
                } else {
                    // Next make sure all files has broad read permission...
                    childProcess.exec("chmod -R a+r .", { cwd: destDir.path() }, function (error, stdout, stderr) {
                        if (error || stderr) {
                            console.log(error);
                            console.log(stderr);
                        } else {
                            // ...and finally that main file has broad execution premission.
                            destDir.file('nw', { mode: '755' });
                            deferred.resolve();
                        }
                    });
                }
            });
    } else {
        deferred.resolve();
    }

    return deferred.promise;
};

// --------------------------------------------------------
// Let's get started
// --------------------------------------------------------

destDir.dir('.', { empty: true });

var Download = require('download');

var download = new Download({ extract: true, strip: 1 })
.get(url)
.dest(destDir.path());

console.log('Downloading node-webkit...');

download.run(function (err, files) {
    if (err) {
        console.error(err);
    } else {
        finalize()
        .then(function () {
            console.log('Node-webkit v' + runtimeVersion + ' downloaded successfully!');
        });
    }
});
<commit_msg>Linux download finalization simplified<commit_after>// Downloads node-webkit runtime and unpacks it into proper place.

'use strict';

var Q = require('q');
var childProcess = require('child_process');
var projectDir = require('fs-jetpack');
var utils = require('./utils');

// --------------------------------------------------------
// Preparations
// --------------------------------------------------------

var devManifest = projectDir.read('package.json', 'json');
var appManifest = projectDir.read('app/package.json', 'json');

// Version of Node-Webkit we need
var runtimeVersion = devManifest.config.nodeWebkit.version;
// The directory where runtime should be placed
var destDir = projectDir.dir('nw/' + utils.os());

// First check if we already haven't downloaded this version of runtime.
if (destDir.read('version') === runtimeVersion) {
    // No need for continuing
    process.exit();
}

// Figure out the URL we have to download.
var url = devManifest.config.nodeWebkit.downloadUrls[utils.os()];
// URL has places where we have to inject version we are interested with.
url = utils.replace(url, { version: runtimeVersion });

var finalize = function () {
    var deferred = Q.defer();

    // Place file with version next to downloaded runtime,
    // so we know in the future what we have there.
    destDir.file('version', { content: runtimeVersion });

    // Special preparations necessary for linux runtime
    if (utils.os() === 'linux') {
        // The hack for problems with libudev.so.0 on Linux platform.
        // Read more: https://github.com/rogerwang/node-webkit/wiki/The-solution-of-lacking-libudev.so.0
        childProcess.exec("sed -i 's/udev\.so\.0/udev.so.1/g' nw", { cwd: destDir.path() },
            function (error, stdout, stderr) {
                if (error || stderr) {
                    console.log('ERROR while patching libudev:');
                    console.log(error);
                    console.log(stderr);
                } else {
                    deferred.resolve();
                }
            });
    } else {
        deferred.resolve();
    }

    return deferred.promise;
};

// --------------------------------------------------------
// Let's get started
// --------------------------------------------------------

destDir.dir('.', { empty: true });

var Download = require('download');

var download = new Download({ extract: true, strip: 1, mode: '755' })
.get(url)
.dest(destDir.path());

console.log('Downloading node-webkit...');

download.run(function (err, files) {
    if (err) {
        console.error(err);
    } else {
        finalize()
        .then(function () {
            console.log('Node-webkit v' + runtimeVersion + ' downloaded successfully!');
        });
    }
});
<|endoftext|>


<commit_before>(function (_, $, util) {
    'use strict';

    var ns = util.namespace('kpp.view'),
        defaultOptions = {
            selectors: [],
            cancelSelectors: [],
            target: 'body',
            step: 1
        };

    /**
     * ドラッグアンドドロップで画面をスクロールするView
     *
     */
    ns.Scroller = ns.Scroller || Scroller;

    function Scroller(o) {
        var that = this;

        that.init = function () {
            that.opts = _.extend(defaultOptions, o || {});
            that.$contexts = that.opts.selectors.map(function (selector) { return $(selector); });
            that.$target = $(that.opts.target);

            that.isClicked = false;
            that.beforeX = null;

            // scroll event
            that.opts.selectors.forEach(function (selector) {
                $('body')
                    .delegate(selector, 'mousedown', that.onMousedown)
                    .delegate(selector, 'mouseup', that.onMouseup);
            });

            // cancel
            that.opts.cancelSelectors.forEach(function (selector) {
                $('body')
                    .delegate(selector, 'mousedown', that.cancel)
                    .delegate(selector, 'mouseup', that.cancel)
                    .delegate(selector, 'mousemove', that.cancel);
            });

            // move event
            $(window).mousemove(that.onMousemove);
        };

        that.cancel = function () {
            that.isClicked = false;
            that.beforeX = null;
        };

        that.onMousedown = function (e) {
            that.isClicked = true;
            that.beforeX = e.screenX;
        };

        that.onMouseup = that.cancel;

        that.onMousemove = function (e) {
            var now, diff;

            if (that.isClicked) {
                now = e.screenX;
                diff = now - that.beforeX;
                that.$target.scrollLeft(that.$target.scrollLeft() - diff * that.opts.step);
                that.beforeX = now;

                return false;
            }
        };

        that.init();
    }

}(_, jQuery, window.nakazawa.util));<commit_msg>背景スクロールの細かい挙動修正<commit_after>(function (_, $, util) {
    'use strict';

    var ns = util.namespace('kpp.view'),
        defaultOptions = {
            selectors: [],
            cancelSelectors: [],
            target: 'body',
            step: 1
        };

    /**
     * ドラッグアンドドロップで画面をスクロールするView
     *
     */
    ns.Scroller = ns.Scroller || Scroller;

    function Scroller(o) {
        var that = this;

        that.init = function () {
            that.opts = _.extend(defaultOptions, o || {});
            that.$contexts = that.opts.selectors.map(function (selector) { return $(selector); });
            that.$target = $(that.opts.target);

            that.isClicked = false;
            that.beforeX = null;

            // scroll event
            that.opts.selectors.forEach(function (selector) {
                $('body')
                    .delegate(selector, 'mousedown', that.onMousedown)
                    .delegate(selector, 'mouseup', that.onMouseup);
            });

            // cancel
            that.opts.cancelSelectors.forEach(function (selector) {
                $('body')
                    .delegate(selector, 'mousedown', that.cancel)
                    .delegate(selector, 'mouseup', that.cancel);
            });

            // move event
            $(window).mousemove(that.onMousemove);
        };

        that.cancel = function (e) {
            e.canceled = true;
            that.isClicked = false;
            that.beforeX = null;
        };

        that.onMousedown = function (e) {
            if (!e.canceled && e.button === 0) { // 左クリックのみ作動
                that.isClicked = true;
                that.beforeX = e.screenX;
            }
        };

        that.onMouseup = that.cancel;

        that.onMousemove = function (e) {
            var now, diff;

            if (that.isClicked) {
                now = e.screenX;
                diff = now - that.beforeX;
                that.$target.scrollLeft(that.$target.scrollLeft() - diff * that.opts.step);
                that.beforeX = now;

                return false;
            }
        };

        that.init();
    }

}(_, jQuery, window.nakazawa.util));<|endoftext|>


<commit_before>rpgPhase = function(game) {
    Phaser.State.call(this);

    this._game = game;
    this._freeTiles = [];
    this._game.stage.smoothed = false;
}

//Extend the rpgPhase object to be a Phaser.State
rpgPhase.prototype = Object.create(Phaser.State.prototype);
rpgPhase.prototype.constructor = rpgPhase;

rpgPhase.prototype.update = function(){
    var map = this._game.state.getCurrentState()._map;
    var items = map._items;

    //Check whether the collectables are collected,and whether we are not yet in the last level of the phase.
        if(items.children.length == 0 && !ran && this._game._level != 12){
            ran = true;
            run = true;
            this._game._level++;
        }
}

rpgPhase.prototype.create = function(){
    //instantiate worldmap and create layer (this displays the map)
    this._map = new WorldMap(this._game, 'level', 'tiles_rpg', 32, 'collectable_rpg', 'enemy_dungeon1', 5);
    this._layer = this._map.createLayer(0);
    this._layer.resizeWorld();

    //add items to the game
    this._game.add.existing(this._map._items);

    //Instantiate new player object
    this._player = new Player(this._game, 1, 'player_rpg', 150);

    this._game.add.existing(this._map._npcs);
    this._game.add.existing(this._map._enemies);

    //postpone character creation for a sec to avoid rendering problems
    setTimeout((function(self) { return function() {
            self._game.add.existing(self._player);
        }})(this),200);

    this._score = new Phaser.Group(this._game, null, "score", false);

    var collectable = this._game.add.sprite(this._game.camera.width - 25, this._game.camera.height - 25, 'collectable_rpg');
    collectable.anchor.setTo(0.5, 0.5);
    this._collectableText = this._game.add.text(this._game.camera.width - 60, this._game.camera.height - 25, "0x",{ font: "14px 'Press Start 2P'", fill: "#fff" });
    this._collectableText.anchor.setTo(0.5, 0.5);

    this._score.fixedToCamera = true;
    this._score.add(collectable);
    this._score.add(this._collectableText);
    this._game.add.existing(this._score);
};

//Returns a position on the map where the player or an item can spawn
rpgPhase.prototype.getItemPosition =
rpgPhase.prototype.getEnemyPosition =
rpgPhase.prototype.getPlayerPosition = function(){
    //shuffle the array of free tiles
    shuffle(this._freeTiles);

    //returns an array of x and y position (nth tile) that is free,
    //and remove it from the list so no other item can spawn on this position.
    var randomPosition = this._freeTiles.pop();
    return [randomPosition[0]*32, randomPosition[1]*32];
}

//map generation for RPG (cellular automata)
rpgPhase.prototype.generate = function(){
    this._freeTiles = [];

    var w = 80, h = 60;
    var map = new ROT.Map.Cellular(w, h, {
        born: [5,6,7,8],
        survive: [4,5,6,7,8]
    });
    map.randomize(0.52);

    var display;
    var digCallback = function(x, y, value) {
        if (value) {
            var tile = [x, y+1]; //+1 for border tile compensation
            this._freeTiles.push(tile);
        }

        //channel info to debug so the preview can be rendered.
        display.DEBUG(x,y,value);
    }

    //[> generate x generations <]
    for (var i=0; i<10; i++) {
        display = new ROT.Display({width:w, height:h, fontSize:4});

        if(i < 9){
            map.create();
        } else {
            map.create(digCallback.bind(this));
        }
    }

    //add a row to the TOP of the map
    for(var i = 0; i < map._map.length; i++){ map._map[i].unshift("border"); }

    //add a column to the LEFT of the map
    map._map[0] = [];
    for(var i = 0; i < map._map[1].length; i++){ map._map[0].push("border"); }

    //add a column to the RIGHT of the map
    map._map[map._map.length-1] = [];
    for(var i = 0; i < map._map[1].length; i++){ map._map[map._map.length-1].push("border"); }

    //add a row to the BOTTOM of the map
    for(var i = 0; i < map._map.length; i++){ map._map[i].push("border"); }

    //show map in canvas
    if (pixelEvolution._showMinimap){
        $('#minimap').html(display.getContainer());
    }

    // calculate the biggest part of the map where we can freely move around
    var union = new UnionFind(this._freeTiles.length);

    // the sets are already made, create reverse free tiles

    var h = map._map.length;
    var w = map._map[0].length;

    var rFreeTiles = new Array(h);
    for (var i = 0; i < h; i++) {
        rFreeTiles[i] = new Array(w);
    }

    for (var i = 0; i < this._freeTiles.length; i++) {
        var tile = this._freeTiles[i];
        rFreeTiles[tile[0]][tile[1]] = i;
    }

    // now, unionize all free tiles together

    for (var i = 0; i < this._freeTiles.length; i++) {
        var tile = this._freeTiles[i];
        if (tile[0] > 0) {
            var val = map._map[tile[0] - 1][tile[1]];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0] - 1][tile[1]]);
            }
        }
        if (tile[0] < h - 1) {
            var val = map._map[tile[0] + 1][tile[1]];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0] + 1][tile[1]]);
            }
        }
        if (tile[1] > 0) {
            var val = map._map[tile[0]][tile[1] - 1];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0]][tile[1] - 1]);
            }
        }
        if (tile[1] < w - 1) {
            var val = map._map[tile[0]][tile[1] + 1];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0]][tile[1] + 1]);
            }
        }
    }

    // find all open fields
    var fields = {};

    for (var i = 0; i < this._freeTiles.length; i++) {
        var field = union.find(i);
        if (!(field in fields)) {
            fields[field] = [];
        }
        fields[field].push(this._freeTiles[i]);
    }

    // find the largest open fields
    var max = 10000;
    var secondMax = 10000;
    var largest;
    var secondLargest;
    $.each(fields, function(index, field) {
        if (field.length < max) {
            secondMax = max;
            secondLargest = largest;
            max = field.length;
            largest = field;
        } else if (field.length < secondMax) {
            secondMax = field.length;
            secondLargest = field;
        }
    });

    // create a path between the two largest open fields.
    // we do this by simply selecting two random tiles, and making sure there
    // is a (L-shaped) path between them.

    var tileA = largest[Math.floor(Math.random() * largest.length)];
    var tileB = secondLargest[Math.floor(Math.random() * secondLargest.length)];

    // path of tiles in between
    var path = [];

    for (var i = Math.min(tileA[0], tileB[0]); i < Math.max(tileA[0], tileB[0]); i++) {
        path.push([i, tileA[1]]);
    }
    for (var i = Math.min(tileA[1], tileB[1]); i < Math.max(tileA[1], tileB[1]); i++) {
        path.push([tileB[0], i]);
    }

    this._treeTiles = [];

    // make sure the path is cleared, and select fields that might be good for a tree
    $.each(path, function(idx, item) {
        if (map._map[item[0]][item[1]] == 0) {
            map._map[item[0]][item[1]] = 1;
        }
        var localTiles = [];
        localTiles.push([item[0] + 1, item[1]]);
        localTiles.push([item[0] - 1, item[1]]);
        localTiles.push([item[0], item[1] + 1]);
        localTiles.push([item[0], item[1] - 1]);
        var openCount = 0;
        $.each(localTiles, function(idx, localTile) {
            if (map._map[localTile[0]][localTile[1]] == 0) {
                openCount++;
            }
        });
        if (openCount == 2) {
            this._treeTiles.push(item);
        }
    });

    // we have more spaaaccee!!
    this._freeTiles = largest.concat(secondLargest);

    var level = "";

    for (var i=0; i<map._map[0].length; i++) {
        for (var j=0; j<map._map.length; j++) {
            var point = map._map[j][i]+"";

            if(point=="0" || point=="border"){
                point = "1";
            } else {
                point = "0";
            }

            level += point + ",";
        }
        level = level.substring(0,level.length-1) + "\n";
    }

    return level;
};

//helper method: shuffles arrays
function shuffle(o){
    for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};
<commit_msg>Made trees working again.<commit_after>rpgPhase = function(game) {
    Phaser.State.call(this);

    this._game = game;
    this._freeTiles = [];
    this._game.stage.smoothed = false;
}

//Extend the rpgPhase object to be a Phaser.State
rpgPhase.prototype = Object.create(Phaser.State.prototype);
rpgPhase.prototype.constructor = rpgPhase;

rpgPhase.prototype.update = function(){
    var map = this._game.state.getCurrentState()._map;
    var items = map._items;

    //Check whether the collectables are collected,and whether we are not yet in the last level of the phase.
        if(items.children.length == 0 && !ran && this._game._level != 12){
            ran = true;
            run = true;
            this._game._level++;
        }
}

rpgPhase.prototype.create = function(){
    //instantiate worldmap and create layer (this displays the map)
    this._map = new WorldMap(this._game, 'level', 'tiles_rpg', 32, 'collectable_rpg', 'enemy_dungeon1', 5);
    this._layer = this._map.createLayer(0);
    this._layer.resizeWorld();

    //add items to the game
    this._game.add.existing(this._map._items);

    //Instantiate new player object
    this._player = new Player(this._game, 1, 'player_rpg', 150);

    this._game.add.existing(this._map._npcs);
    this._game.add.existing(this._map._enemies);

    //postpone character creation for a sec to avoid rendering problems
    setTimeout((function(self) { return function() {
            self._game.add.existing(self._player);
        }})(this),200);

    this._score = new Phaser.Group(this._game, null, "score", false);

    var collectable = this._game.add.sprite(this._game.camera.width - 25, this._game.camera.height - 25, 'collectable_rpg');
    collectable.anchor.setTo(0.5, 0.5);
    this._collectableText = this._game.add.text(this._game.camera.width - 60, this._game.camera.height - 25, "0x",{ font: "14px 'Press Start 2P'", fill: "#fff" });
    this._collectableText.anchor.setTo(0.5, 0.5);

    var pos = this.getTreePosition();
    var tree = this._game.add.sprite(pos[0], pos[1], 'fragile_tree');

    this._score.fixedToCamera = true;
    this._score.add(collectable);
    this._score.add(this._collectableText);
    this._game.add.existing(this._score);
};

//Returns a position on the map where the player or an item can spawn
rpgPhase.prototype.getItemPosition =
rpgPhase.prototype.getEnemyPosition =
rpgPhase.prototype.getPlayerPosition = function(){
    //shuffle the array of free tiles
    shuffle(this._freeTiles);

    //returns an array of x and y position (nth tile) that is free,
    //and remove it from the list so no other item can spawn on this position.
    var randomPosition = this._freeTiles.pop();
    return [randomPosition[0]*32, randomPosition[1]*32];
}

rpgPhase.prototype.getTreePosition = function() {
    //shuffle the array of tree tiles
    shuffle(this._treeTiles);

    //returns an array of x and y position (nth tile) that is free,
    //and remove it from the list so no other item can spawn on this position.
    var randomPosition = this._treeTiles.pop();
    return [randomPosition[0]*32, randomPosition[1]*32];
}

//map generation for RPG (cellular automata)
rpgPhase.prototype.generate = function(){
    this._freeTiles = [];

    var w = 80, h = 60;
    var map = new ROT.Map.Cellular(w, h, {
        born: [5,6,7,8],
        survive: [4,5,6,7,8]
    });
    map.randomize(0.52);

    var display;
    var digCallback = function(x, y, value) {
        if (value) {
            var tile = [x, y+1]; //+1 for border tile compensation
            this._freeTiles.push(tile);
        }

        //channel info to debug so the preview can be rendered.
        display.DEBUG(x,y,value);
    }

    //[> generate x generations <]
    for (var i=0; i<10; i++) {
        display = new ROT.Display({width:w, height:h, fontSize:4});

        if(i < 9){
            map.create();
        } else {
            map.create(digCallback.bind(this));
        }
    }

    //add a row to the TOP of the map
    for(var i = 0; i < map._map.length; i++){ map._map[i].unshift("border"); }

    //add a column to the LEFT of the map
    map._map[0] = [];
    for(var i = 0; i < map._map[1].length; i++){ map._map[0].push("border"); }

    //add a column to the RIGHT of the map
    map._map[map._map.length-1] = [];
    for(var i = 0; i < map._map[1].length; i++){ map._map[map._map.length-1].push("border"); }

    //add a row to the BOTTOM of the map
    for(var i = 0; i < map._map.length; i++){ map._map[i].push("border"); }

    //show map in canvas
    if (pixelEvolution._showMinimap){
        $('#minimap').html(display.getContainer());
    }

    // calculate the biggest part of the map where we can freely move around
    var union = new UnionFind(this._freeTiles.length);

    // the sets are already made, create reverse free tiles

    var h = map._map.length;
    var w = map._map[0].length;

    var rFreeTiles = new Array(h);
    for (var i = 0; i < h; i++) {
        rFreeTiles[i] = new Array(w);
    }

    for (var i = 0; i < this._freeTiles.length; i++) {
        var tile = this._freeTiles[i];
        rFreeTiles[tile[0]][tile[1]] = i;
    }

    // now, unionize all free tiles together

    for (var i = 0; i < this._freeTiles.length; i++) {
        var tile = this._freeTiles[i];
        if (tile[0] > 0) {
            var val = map._map[tile[0] - 1][tile[1]];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0] - 1][tile[1]]);
            }
        }
        if (tile[0] < h - 1) {
            var val = map._map[tile[0] + 1][tile[1]];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0] + 1][tile[1]]);
            }
        }
        if (tile[1] > 0) {
            var val = map._map[tile[0]][tile[1] - 1];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0]][tile[1] - 1]);
            }
        }
        if (tile[1] < w - 1) {
            var val = map._map[tile[0]][tile[1] + 1];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0]][tile[1] + 1]);
            }
        }
    }

    // find all open fields
    var fields = {};

    for (var i = 0; i < this._freeTiles.length; i++) {
        var field = union.find(i);
        if (!(field in fields)) {
            fields[field] = [];
        }
        fields[field].push(this._freeTiles[i]);
    }

    // find the largest open fields
    var max = 0;
    var secondMax = 0;
    var largest;
    var secondLargest;
    $.each(fields, function(index, field) {
        if (field.length > max) {
            secondMax = max;
            secondLargest = largest;
            max = field.length;
            largest = field;
        } else if (field.length > secondMax) {
            secondMax = field.length;
            secondLargest = field;
        }
    });

    // create a path between the two largest open fields.
    // we do this by simply selecting two random tiles, and making sure there
    // is a (L-shaped) path between them.

    var tileA = largest[Math.floor(Math.random() * largest.length)];
    var tileB = secondLargest[Math.floor(Math.random() * secondLargest.length)];

    // path of tiles in between
    var path = [];

    for (var i = Math.min(tileA[0], tileB[0]); i < Math.max(tileA[0], tileB[0]); i++) {
        path.push([i, tileA[1]]);
    }
    for (var i = Math.min(tileA[1], tileB[1]); i < Math.max(tileA[1], tileB[1]); i++) {
        path.push([tileB[0], i]);
    }

    this._treeTiles = [];

    // make sure the path is cleared, and select fields that might be good for a tree
    (function(self){$.each(path, function(idx, item) {
        if (map._map[item[0]][item[1]] == 0) {
            map._map[item[0]][item[1]] = 1;
        }
    });
    $.each(path, function(idx, item) {
        var localTiles = [];
        localTiles.push([item[0] + 1, item[1]]);
        localTiles.push([item[0] - 1, item[1]]);
        localTiles.push([item[0], item[1] + 1]);
        localTiles.push([item[0], item[1] - 1]);
        var openCount = 0;
        $.each(localTiles, function(idx, localTile) {
            if (map._map[localTile[0]][localTile[1]] == 0) {
                openCount++;
            }
        });
        if (openCount == 2) {
            self._treeTiles.push(item);
        }
    })})(this);

    // we have more spaaaccee!!
    this._freeTiles = largest.concat(secondLargest);

    var level = "";

    for (var i=0; i<map._map[0].length; i++) {
        for (var j=0; j<map._map.length; j++) {
            var point = map._map[j][i]+"";

            if(point=="0" || point=="border"){
                point = "1";
            } else {
                point = "0";
            }

            level += point + ",";
        }
        level = level.substring(0,level.length-1) + "\n";
    }

    return level;
};

//helper method: shuffles arrays
function shuffle(o){
    for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};
<|endoftext|>


<commit_before>/**
 * These are rules designed to respect some conventions in your project.
 * @module rules/angular/conventions
 * @see https://github.com/Gillespie59/eslint-plugin-angular#conventions
 */

'use strict';

module.exports = {
  rules: {
    // require a consistent DI syntax
    'angular/di': [2, '$inject'],
    // require DI parameters to be sorted alphabetically
    'angular/di-order': [0, true],
    // unittest inject functions should only consist of assignments from injected values to describe block variables
    'angular/dumb-inject': 0,
    // require and specify a consistent function style for components ('named' or 'anonymous')
    'angular/function-type': [2, 'named'],
    // require a consistent order of module dependencies
    'angular/module-dependency-order': 0,
    // use factory() instead of service() (y040)
    'angular/no-service-method': 0,
    // require all DI parameters to be located in their own line
    'angular/one-dependency-per-line': 0,
    // disallow different rest service and specify one of '$http', '$resource', 'Restangular'
    'angular/rest-service': 0,
    // require and specify consistent use $scope.digest() or $scope.apply()
    'angular/watchers-execution': [0, '$digest']
  }
};
<commit_msg>fix(conventions): switch angular/di rule from $inject to function<commit_after>/**
 * These are rules designed to respect some conventions in your project.
 * @module rules/angular/conventions
 * @see https://github.com/Gillespie59/eslint-plugin-angular#conventions
 */

'use strict';

module.exports = {
  rules: {
    // require a consistent DI syntax
    'angular/di': [2, 'function'],
    // require DI parameters to be sorted alphabetically
    'angular/di-order': [0, true],
    // unittest inject functions should only consist of assignments from injected values to describe block variables
    'angular/dumb-inject': 0,
    // require and specify a consistent function style for components ('named' or 'anonymous')
    'angular/function-type': [2, 'named'],
    // require a consistent order of module dependencies
    'angular/module-dependency-order': 0,
    // use factory() instead of service() (y040)
    'angular/no-service-method': 0,
    // require all DI parameters to be located in their own line
    'angular/one-dependency-per-line': 0,
    // disallow different rest service and specify one of '$http', '$resource', 'Restangular'
    'angular/rest-service': 0,
    // require and specify consistent use $scope.digest() or $scope.apply()
    'angular/watchers-execution': [0, '$digest']
  }
};
<|endoftext|>


<commit_before>Vue.component('multiselect', window.VueMultiselect.default);
Vue.component('vue-loading', window.VueLoading);

Vue.component('logview', {
    template: '

',
    props: ["linesOfHistory"],
    data: function() {
        return {
            history: [],
            lastSpan: null,
            lastSpanClasses: '',
            autoScroll: true
        };
    },
    watch: {
        linesOfHistory: function(val) {
            this.trimHistory();
        }
    },
    methods: {
        clearLines: function () {
            this.$el.innerHTML = '';
            this.history = [],
            this.lastSpan = null;
        },
        createSpan: function (innerHtml, classNames) {
            var span = document.createElement('span');
            span.innerHTML = innerHtml;
            span.className = classNames;
            return span;
        },

        createLogEntrySpan: function (innerHtml) {
            return this.createSpan(innerHtml, 'log-entry');
        },

        createNoticePan: function (innerHtml) {
            return createSpan(innerHtml, 'log-entry log-notice');
        },

        trimHistory: function () {
            if (this.linesOfHistory !== 0 && this.history.length > this.linesOfHistory) {
                for (var i = 0; i < (this.history.length - this.linesOfHistory + 1); i++) {
                    this.$el.removeChild(this.history.shift());
                }
            }
        },

        isScrolledToBottom: function () {
            var elParent = this.$el.parentElement;
            var autoScrollOffset = elParent.scrollTop - (elParent.scrollHeight - elParent.offsetHeight);
            return Math.abs(autoScrollOffset) < 50;
        },

        scroll: function() {
            this.$el.parentElement.scrollTop = this.$el.parentElement.scrollHeight;
        },

        write: function (source, line) {
            var span;
            if (source === "o") {
                line = escapeHtml(line).replace(/\n$/, '');
                span = this.createLogEntrySpan(line);

                this.writeSpans([span]);
            }
        },

        writeSpans: function (spanArray) {
            if (spanArray.length === 0) {
                return;
            }

            var scrollAfterWrite = this.isScrolledToBottom();

            // Create spans from all elements and add them to a temporary DOM.
            var fragment = document.createDocumentFragment();
            for (var i = 0; i < spanArray.length; i++) {
                var span = spanArray[i];
                this.history.push(span);
                fragment.appendChild(span);
            }

            if (this.lastSpan) {
                this.lastSpan.className = this.lastSpanClasses;
            }

            this.$el.appendChild(fragment);
            this.trimHistory();

            if (this.autoScroll && scrollAfterWrite) {
                this.scroll();
            }

            this.lastSpan = this.history[this.history.length-1];
            this.lastSpanClasses = this.lastSpan.className;
            this.lastSpan.className = this.lastSpanClasses + ' log-entry-current';

        }
    }
});

var apiURL = endsWith(window.relativeRoot, '/') ? 'ws' : '/ws';
var apiURL = [window.location.protocol, '//', window.location.host, window.relativeRoot, apiURL].join('');

var app = new Vue({
    el: '#app',
    delimiters: ['<%', '%>'],
    data: {
        'relativeRoot': relativeRoot,
        'commandScripts': commandScripts,

        'fileList': [],
        'allowedCommandNames': allowedCommandNames,

        'file': null,
        'command': null,
        'script': null,

        'linesOfHistory': 2000,  // 0 for infinite history
        'linesToTail': 10,
        'wrapLines': false,

        'hideToolbar': false,
        'showConfig': false,
        'showLoadingOverlay': false,

        'socket': null,
        'isConnected': false
    },
    created: function () {
        this.backendConnect();
        this.command = this.allowedCommandNames[0];
    },
    computed: {
        scriptInputEnabled: function () {
            return this.commandScripts[this.command] !== "";
        },
        downloadLink: function () {
            if (this.file) {
                return relativeRoot + 'files/' + this.file;
            }
            return '#';
        }
    },
    methods: {
        clearLogview: function () {
            this.$refs.logview.clearLines();
        },
        backendConnect: function ( ){
            console.log('connecting to ' + apiURL);
            this.showLoadingOverlay = true;
            this.socket = new SockJS(apiURL);
            this.socket.onopen = this.onBackendOpen;
            this.socket.onclose = this.onBackendClose;
            this.socket.onmessage = this.onBackendMessage;
        },
        onBackendOpen: function () {
            console.log('connected to backend');
            this.isConnected = true;
            this.refreshFiles();
        },
        onBackendClose: function () {
            console.log('disconnected from backend');
            this.isConnected = false;
            backendConnect = this.backendConnect;
            window.setTimeout(function () {
                backendConnect();
            }, 1000);
        },
        onBackendMessage: function (message) {
            var data = JSON.parse(message.data);

            if (data.constructor === Object) {
                // Reshape into something that vue-multiselect :group-select can use.
                var fileList = [];
                Object.keys(data).forEach(function (key) {
                    var group = ("__default__" === key) ? "Ungrouped Files" : key;
                    fileList.push({
                        "group": group,
                        "files": data[key]
                    });
                });

                this.fileList = fileList;

                // Set file input to first entry in list.
                if (!this.file) {
                    this.file = fileList[0].files[0];
                }
            } else {
                var stream = data[0];
                var line = data[1];
                this.$refs.logview.write(stream, line);
            }
        },
        refreshFiles: function () {
            console.log("updating file list");
            this.socket.send("list");
        },
        notifyBackend: function () {
            var msg = {
                command: this.command,
                script: this.script,
                entry: this.file,
                nlines: this.linesToTail
            };
            console.log("sending msg: ", msg);
            this.socket.send(JSON.stringify(msg));
        }
    },
    watch: {
        isConnected: function(val) {
            this.showLoadingOverlay = !val;
        },
        command: function(val) {
            if (val && this.isConnected) {
                this.script = this.commandScripts[val];
                this.notifyBackend();
            }
        },
        file: function(val) {
            if (val && this.isConnected) {
                this.notifyBackend();
            }
        }
    }
});
<commit_msg>Clear logview between backend commands<commit_after>Vue.component('multiselect', window.VueMultiselect.default);
Vue.component('vue-loading', window.VueLoading);

Vue.component('logview', {
    template: '

',
    props: ["linesOfHistory"],
    data: function() {
        return {
            history: [],
            lastSpan: null,
            lastSpanClasses: '',
            autoScroll: true
        };
    },
    watch: {
        linesOfHistory: function(val) {
            this.trimHistory();
        }
    },
    methods: {
        clearLines: function () {
            this.$el.innerHTML = '';
            this.history = [],
            this.lastSpan = null;
        },
        createSpan: function (innerHtml, classNames) {
            var span = document.createElement('span');
            span.innerHTML = innerHtml;
            span.className = classNames;
            return span;
        },

        createLogEntrySpan: function (innerHtml) {
            return this.createSpan(innerHtml, 'log-entry');
        },

        createNoticePan: function (innerHtml) {
            return createSpan(innerHtml, 'log-entry log-notice');
        },

        trimHistory: function () {
            if (this.linesOfHistory !== 0 && this.history.length > this.linesOfHistory) {
                for (var i = 0; i < (this.history.length - this.linesOfHistory + 1); i++) {
                    this.$el.removeChild(this.history.shift());
                }
            }
        },

        isScrolledToBottom: function () {
            var elParent = this.$el.parentElement;
            var autoScrollOffset = elParent.scrollTop - (elParent.scrollHeight - elParent.offsetHeight);
            return Math.abs(autoScrollOffset) < 50;
        },

        scroll: function() {
            this.$el.parentElement.scrollTop = this.$el.parentElement.scrollHeight;
        },

        write: function (source, line) {
            var span;
            if (source === "o") {
                line = escapeHtml(line).replace(/\n$/, '');
                span = this.createLogEntrySpan(line);

                this.writeSpans([span]);
            }
        },

        writeSpans: function (spanArray) {
            if (spanArray.length === 0) {
                return;
            }

            var scrollAfterWrite = this.isScrolledToBottom();

            // Create spans from all elements and add them to a temporary DOM.
            var fragment = document.createDocumentFragment();
            for (var i = 0; i < spanArray.length; i++) {
                var span = spanArray[i];
                this.history.push(span);
                fragment.appendChild(span);
            }

            if (this.lastSpan) {
                this.lastSpan.className = this.lastSpanClasses;
            }

            this.$el.appendChild(fragment);
            this.trimHistory();

            if (this.autoScroll && scrollAfterWrite) {
                this.scroll();
            }

            this.lastSpan = this.history[this.history.length-1];
            this.lastSpanClasses = this.lastSpan.className;
            this.lastSpan.className = this.lastSpanClasses + ' log-entry-current';

        }
    }
});

var apiURL = endsWith(window.relativeRoot, '/') ? 'ws' : '/ws';
var apiURL = [window.location.protocol, '//', window.location.host, window.relativeRoot, apiURL].join('');

var app = new Vue({
    el: '#app',
    delimiters: ['<%', '%>'],
    data: {
        'relativeRoot': relativeRoot,
        'commandScripts': commandScripts,

        'fileList': [],
        'allowedCommandNames': allowedCommandNames,

        'file': null,
        'command': null,
        'script': null,

        'linesOfHistory': 2000,  // 0 for infinite history
        'linesToTail': 10,
        'wrapLines': false,

        'hideToolbar': false,
        'showConfig': false,
        'showLoadingOverlay': false,

        'socket': null,
        'isConnected': false
    },
    created: function () {
        this.backendConnect();
        this.command = this.allowedCommandNames[0];
    },
    computed: {
        scriptInputEnabled: function () {
            return this.commandScripts[this.command] !== "";
        },
        downloadLink: function () {
            if (this.file) {
                return relativeRoot + 'files/' + this.file;
            }
            return '#';
        }
    },
    methods: {
        clearLogview: function () {
            this.$refs.logview.clearLines();
        },
        backendConnect: function ( ){
            console.log('connecting to ' + apiURL);
            this.showLoadingOverlay = true;
            this.socket = new SockJS(apiURL);
            this.socket.onopen = this.onBackendOpen;
            this.socket.onclose = this.onBackendClose;
            this.socket.onmessage = this.onBackendMessage;
        },
        onBackendOpen: function () {
            console.log('connected to backend');
            this.isConnected = true;
            this.refreshFiles();
        },
        onBackendClose: function () {
            console.log('disconnected from backend');
            this.isConnected = false;
            backendConnect = this.backendConnect;
            window.setTimeout(function () {
                backendConnect();
            }, 1000);
        },
        onBackendMessage: function (message) {
            var data = JSON.parse(message.data);

            if (data.constructor === Object) {
                // Reshape into something that vue-multiselect :group-select can use.
                var fileList = [];
                Object.keys(data).forEach(function (key) {
                    var group = ("__default__" === key) ? "Ungrouped Files" : key;
                    fileList.push({
                        "group": group,
                        "files": data[key]
                    });
                });

                this.fileList = fileList;

                // Set file input to first entry in list.
                if (!this.file) {
                    this.file = fileList[0].files[0];
                }
            } else {
                var stream = data[0];
                var line = data[1];
                this.$refs.logview.write(stream, line);
            }
        },
        refreshFiles: function () {
            console.log("updating file list");
            this.socket.send("list");
        },
        notifyBackend: function () {
            var msg = {
                command: this.command,
                script: this.script,
                entry: this.file,
                nlines: this.linesToTail
            };
            console.log("sending msg: ", msg);
            this.clearLogview();
            this.socket.send(JSON.stringify(msg));
        }
    },
    watch: {
        isConnected: function(val) {
            this.showLoadingOverlay = !val;
        },
        command: function(val) {
            if (val && this.isConnected) {
                this.script = this.commandScripts[val];
                this.notifyBackend();
            }
        },
        file: function(val) {
            if (val && this.isConnected) {
                this.notifyBackend();
            }
        }
    }
});
<|endoftext|>


<commit_before>var path = require('path');
module.exports = function(grunt) {

  /**
   * Resolve include `name` relative to `filename`.
   *
   * @param {String} name
   * @param {String} filename
   * @return {String}
   * @api private
   */

  function resolveInclude(name, filename) {
    var retPath = path.join(path.dirname(filename), name);
    var ext = path.extname(name);
    if (!ext) retPath += '.ejs';
    return retPath;
  }

  'use strict';
  grunt.registerMultiTask('ejs_include', 'concat ejs templates that will be included', function() {
    var options = this.options();
    grunt.verbose.writeflags(options, 'Options');
    function loadTemplate(filename) {
      grunt.log.debug('filename',filename);
      var template = grunt.file.read(filename);
      var replacedTemplate = template;
      var includeRegex = new RegExp(/\<\%-?\s*include\s(\S+)\s*\%\>/g);
      var match,path;
      while (match = includeRegex.exec(template)) {
        path = resolveInclude(match[1],filename);
        //TODO: change replace to replaceAt to improve performance
        replacedTemplate = replacedTemplate.replace(match[0],loadTemplate(path));
      }
      return replacedTemplate;
    }
    this.files.forEach(function(file) {
      //var out = file.src.map(grunt.file.read).join('');
      file.src.forEach(function (filename){
        var replaced = loadTemplate(filename);
        grunt.log.debug('dest',file.dest);
        grunt.file.write(file.dest,replaced);
      });
    });

    grunt.log.ok('generated template');
  });
};
<commit_msg>white space bug fix<commit_after>var path = require('path');
module.exports = function(grunt) {

  /**
   * Resolve include `name` relative to `filename`.
   *
   * @param {String} name
   * @param {String} filename
   * @return {String}
   * @api private
   */

  function resolveInclude(name, filename) {
    var retPath = path.join(path.dirname(filename), name);
    var ext = path.extname(name);
    if (!ext) retPath += '.ejs';
    return retPath;
  }

  'use strict';
  grunt.registerMultiTask('ejs_include', 'concat ejs templates that will be included', function() {
    var options = this.options();
    grunt.verbose.writeflags(options, 'Options');
    function loadTemplate(filename) {
      grunt.log.debug('filename',filename);
      var template = grunt.file.read(filename);
      var replacedTemplate = template;
      var includeRegex = new RegExp(/\<\%-?\s*include\s*(\S+)\s*\%\>/g);
      var match,path;
      while (match = includeRegex.exec(template)) {
        path = resolveInclude(match[1],filename);
        //TODO: change replace to replaceAt to improve performance
        replacedTemplate = replacedTemplate.replace(match[0],loadTemplate(path));
      }
      return replacedTemplate;
    }
    this.files.forEach(function(file) {
      //var out = file.src.map(grunt.file.read).join('');
      file.src.forEach(function (filename){
        var replaced = loadTemplate(filename);
        grunt.log.debug('dest',file.dest);
        grunt.file.write(file.dest,replaced);
      });
    });

    grunt.log.ok('generated template');
  });
};
<|endoftext|>


<commit_before>(function(w, d, $) {

	var state = {};
	state.dom = {};
	state.canScroll = true; // For page scroll checks
	state.sliderIndex = 0; // For slider rotations

	state.resetScroll = function() {
		state.canScroll = false;
		setTimeout(function() {
			return state.canScroll = true;
		}, 600);
	 };

	// Gather elements
	//
	var collectDom = function() {
		state.dom.responsiveNavButton = d.getElementById("responsive-nav-button");
		state.dom.slider = d.getElementById("slider");
		state.dom.splashDownArrow = d.getElementById("splash-down-arrow");
		state.dom.logo = d.getElementById("logo");
		state.dom.contactForm = d.forms["contact-form"];
		state.dom.contactFormErrorMessage = d.getElementById("contact-form-error-message");
		state.dom.formSubmissionOverlay = d.getElementById("successful-form-submission-overlay");
		state.dom.$navigators = $("[data-navigate]");
		state.dom.$parallaxImages = $(".parallax > img");
		state.dom.$footerLinks = $("footer ul li:not(:last-child)");
	};

	// Navigation for desktop and mobile
	//
	var controlNavigation = function() {

		var $responsiveNav = $("header nav").clone();

		$(d).on(services.interaction(), "[data-navigate]", function() {

			var section = $(this).attr("data-navigate");

			if (section === "home") {
				services.navigate(0);
			} else {
				var scrollTo = $("#" + section + "-content").offset().top;
				services.navigate(scrollTo - 80); // -80 here accounts for adjustments in CSS for the sticky header
			}
		});

		// Create responsive nav menu
		//
		$responsiveNav
			.insertAfter("header")
			.attr("id", "responsive-menu")
			.attr("class", "responsive-menu");

		// Controls responsive nav/menu button and opening/closing of the nav menu while in mobile/responsive view
		//
		$(state.dom.responsiveNavButton).on(services.interaction(), function() {
			services.show("#responsive-menu", true);
		});

		$("#responsive-menu li, header .logo").on(services.interaction(), function() {
			services.hide("#responsive-menu");
		});

		$(w).resize(function() {
			if ($(this).width() > 740 && $("#responsive-menu").hasClass("SHOW")) services.hide("#responsive-menu");
		});

	};

	// Control parallax banner
	//
	var controlParallax = function() {

		if (!services.isMobile()) {

			$(w)
				.scroll(function() {
					if ($(this).width() > 1000) {
						services.parallax();
					} else {
						state.dom.$parallaxImages.css("top", "0px");
					}
				})
				.resize(function() {
					if ($(this).width() > 1000) state.dom.$parallaxImages.css("top", "0px");
				});
		}
	};

	// Control slider animations
	//
	var controlSlider = function() {

		var curHeight = w.innerHeight;
		var slides = d.querySelectorAll("#slider .slide");
		var list = d.getElementById("slider-bullets");

		$(state.dom.slider).height(curHeight - 80); // -80 here accounts for adjustments in CSS for the sticky header

		$(w).resize(function() {
			if ($(this).height() > curHeight) {
				$(state.dom.slider).height(w.innerHeight - 80);
				curHeight = w.innerHeight;
			}
		})
		.on("load resize", function() {
			if ($(this).width() <= 760) {
				var minHeight = $("#responsive-slide").height() + 150;
				$(state.dom.slider).css("min-height", minHeight + "px");
			}
		})
		.on("orientationchange", function() {

			var newHeight = w.innerHeight - 80;

			$(state.dom.slider)
				.height(newHeight)
				.css("min-height", newHeight);
		});

		// Build bullets
		//
		for (var i = 0; i < slides.length; i++) {
			var bullet = d.createElement("li");
			if (i === 0) bullet.className = "SELECTED";
			list.appendChild(bullet);
		}

		// Auto rotations
		//
		function rotate() {

			var bullets = d.querySelectorAll("#slider-bullets li");

			state.sliderIndex++;

			if (state.sliderIndex === slides.length) state.sliderIndex = 0;

			services
				.hide("#slider .slide")
				.show(slides[state.sliderIndex])
				.deselect("#slider-bullets li")
				.select(bullets[state.sliderIndex]);

			setTimeout(rotate, 8000); // Recursively trigger rotation every 8 seconds
		};

		setTimeout(rotate, 8000); // Init slider
	};

	// Contact form validation
	//
	var validateContactForm = function() {

		var name = state.dom.contactForm["name"];
		var email = state.dom.contactForm["email"];
		var subject = state.dom.contactForm["subject"];
		var comments = state.dom.contactForm["comments"];

		$(state.dom.contactForm).on("submit", function() {

			var hasErrors = false;

			function validate(selector, regx) {
				if (!selector.value.match(regx)) {
					if (!hasErrors) hasErrors = true;
					selector.className = "invalid";
				} else {
					selector.className = "";
				}
			};

			validate(name, /^\s*\S/);
			validate(email, /^\S+@\S+$/);
			validate(subject, /^\s*\S/);
			validate(comments, /^\s*\S/);

			if (hasErrors) {
				if (!$(state.dom.contactFormErrorMessage).hasClass("SHOW")) services.show(state.dom.contactFormErrorMessage);
				return false;
			} else {
				if ($(state.dom.contactFormErrorMessage).hasClass("SHOW")) services.hide(state.dom.contactFormErrorMessage);
			}

		});
	};

	// Control successful form submission overlay
	//
	var controlFormSubmissionOverlay = function() {
		if (state.dom.formSubmissionOverlay !== null) {
			var closeButton = d.querySelector("#successful-form-submission-overlay .close-button");
			$(closeButton).on(services.interaction(), function() {
				return w.location.href = "http://www.drzwebdev.com/sites/StreamYourAd/";
			});
		}
	};

	// Control automatic header > nav > ul > li "SELECTED" states updates while scrolling
	//
	var controlSelectedStates = function() {

		$(w).scroll(function() {

			if (state.canScroll) { // Necessary to prevent weird transition errors after clicking/tapping on nav items

				var scrolled = $(w).scrollTop();
				var threshold = ($(w).height() * 0.4);
				var aboutOffset = $("#about-content").offset().top;
				var servicesOffset = $("#services-content").offset().top;
				var contactOffset = $("#contact-content").offset().top;

				if (aboutOffset - scrolled < threshold) {
					services
						.deselect("[data-navigate]")
						.select("[data-navigate='about']"); // How it Works

					if (servicesOffset - scrolled < threshold) {
						services
							.deselect("[data-navigate]")
							.select("[data-navigate='services']"); // Our Services

						if (contactOffset - scrolled < threshold) {
							services
								.deselect("[data-navigate]")
								.select("[data-navigate='contact']"); // Contact Us
						}
					}

				} else {
					services
						.deselect("[data-navigate]")
						.select("[data-navigate='home']"); // Home
				}

			} // End state.canScroll check
		});

		// Control "SELECTED" states in header > nav > ul > li based on user location
		//
		state.dom.$navigators.on(services.interaction(), function() {

			var section = $(this).attr("data-navigate");

			services
				.deselect("[data-navigate]")
				.select("[data-navigate='" + section + "']");

			state.resetScroll();
		});

		$(state.dom.logo).on(services.interaction(), function() {
			services
				.deselect("[data-navigate]")
				.select("[data-navigate='home']");

			state.resetScroll();
		});

		$(state.dom.splashDownArrow).on(services.interaction(), function() {
			services
				.deselect("[data-navigate='home']")
				.select("[data-navigate='about']");

			state.resetScroll();
		});

	};

	// "Privacy Policy" / "Terms & Conditions" alerts
	//
	var controlAlerts = function() {
		state.dom.$footerLinks.on(services.interaction(), function() {
			var delay = ("ontouchend" in d) ? 50 : 0;
			setTimeout(function() {
				alert("'StreamYourAd' the company no longer exists as a legal entity, thus I am prohibited from sharing any legal bric-a-brac on the site. This site now serves as a dummy practice environment for my portfolio :)");
			}, delay);
		});
	};

	// Create hover/active states
	//
	var setMousables = function() {
		return $("nav li, #responsive-nav-button, .blue-button, footer ul li:not(:last-child)").mouseable();
	};

	// Start
	//
	var init = function() {
		collectDom();
		controlNavigation();
		controlParallax();
		controlSlider();
		validateContactForm();
		controlAlerts();
		controlFormSubmissionOverlay();
		controlSelectedStates();
		setMousables();
	};

	$(d).ready(init);

})(window, document, jQuery);<commit_msg>Minor refactor<commit_after>(function(w, d, $) {

	var state = {};
	state.dom = {};
	state.canScroll = true; // For page scroll checks
	state.sliderIndex = 0; // For slider rotations

	state.resetScroll = function() {
		state.canScroll = false;
		setTimeout(function() {
			return state.canScroll = true;
		}, 600);
	 };

	// Gather elements
	var collectDom = function() {
		state.dom.responsiveNavButton = d.getElementById("responsive-nav-button");
		state.dom.slider = d.getElementById("slider");
		state.dom.splashDownArrow = d.getElementById("splash-down-arrow");
		state.dom.logo = d.getElementById("logo");
		state.dom.contactForm = d.forms["contact-form"];
		state.dom.contactFormErrorMessage = d.getElementById("contact-form-error-message");
		state.dom.formSubmissionOverlay = d.getElementById("successful-form-submission-overlay");
		state.dom.$navigators = $("[data-navigate]");
		state.dom.$parallaxImages = $(".parallax > img");
		state.dom.$footerLinks = $("footer ul li:not(:last-child)");
	};

	// Navigation for desktop and mobile
	var controlNavigation = function() {
		var $responsiveNav = $("header nav").clone();
		$(d).on(services.interaction(), "[data-navigate]", function() {
			var section = $(this).attr("data-navigate");
			if (section === "home") {
				services.navigate(0);
			} else {
				var scrollTo = $("#" + section + "-content").offset().top;
				services.navigate(scrollTo - 80); // -80 here accounts for adjustments in CSS for the sticky header
			}
		});

		// Create/control responsive nav menu
		$responsiveNav
			.insertAfter("header")
			.attr("id", "responsive-menu")
			.attr("class", "responsive-menu");

		$(state.dom.responsiveNavButton).on(services.interaction(), function() {
			services.show("#responsive-menu", true);
		});

		$("#responsive-menu li, header .logo").on(services.interaction(), function() {
			services.hide("#responsive-menu");
		});

		$(w).resize(function() {
			if ($(this).width() > 740 && $("#responsive-menu").hasClass("SHOW")) services.hide("#responsive-menu");
		});

	};

	// Control parallax banner
	var controlParallax = function() {
		if (!services.isMobile()) {
			$(w)
				.scroll(function() {
					if ($(this).width() > 1000) {
						services.parallax();
					} else {
						state.dom.$parallaxImages.css("top", "0px");
					}
				})
				.resize(function() {
					if ($(this).width() > 1000) state.dom.$parallaxImages.css("top", "0px");
				});
		}
	};

	// Control slider animations
	var controlSlider = function() {

		var curHeight = w.innerHeight;
		var slides = d.querySelectorAll("#slider .slide");
		var list = d.getElementById("slider-bullets");

		$(state.dom.slider).height(curHeight - 80); // -80 here accounts for adjustments in CSS for the sticky header

		$(w).resize(function() {
			if ($(this).height() > curHeight) {
				$(state.dom.slider).height(w.innerHeight - 80);
				curHeight = w.innerHeight;
			}
		})
		.on("load resize", function() {
			if ($(this).width() <= 760) {
				var minHeight = $("#responsive-slide").height() + 150;
				$(state.dom.slider).css("min-height", minHeight + "px");
			}
		})
		.on("orientationchange", function() {

			var newHeight = w.innerHeight - 80;

			$(state.dom.slider)
				.height(newHeight)
				.css("min-height", newHeight);
		});

		// Build bullets
		for (var i = 0; i < slides.length; i++) {
			var bullet = d.createElement("li");
			if (i === 0) bullet.className = "SELECTED";
			list.appendChild(bullet);
		}

		// Auto rotations
		function rotate() {
			var bullets = d.querySelectorAll("#slider-bullets li");
			state.sliderIndex++;
			if (state.sliderIndex === slides.length) state.sliderIndex = 0;
			services
				.hide("#slider .slide")
				.show(slides[state.sliderIndex])
				.deselect("#slider-bullets li")
				.select(bullets[state.sliderIndex]);
			setTimeout(rotate, 8000); // Recursively trigger rotation every 8 seconds
		};
		setTimeout(rotate, 8000); // Init slider
	};

	// Contact form validation
	var validateContactForm = function() {

		var name = state.dom.contactForm["name"];
		var email = state.dom.contactForm["email"];
		var subject = state.dom.contactForm["subject"];
		var comments = state.dom.contactForm["comments"];

		$(state.dom.contactForm).on("submit", function() {

			var hasErrors = false;

			function validate(selector, regx) {
				if (!selector.value.match(regx)) {
					if (!hasErrors) hasErrors = true;
					selector.className = "invalid";
				} else {
					selector.className = "";
				}
			};

			validate(name, /^\s*\S/);
			validate(email, /^\S+@\S+$/);
			validate(subject, /^\s*\S/);
			validate(comments, /^\s*\S/);

			if (hasErrors) {
				if (!$(state.dom.contactFormErrorMessage).hasClass("SHOW")) services.show(state.dom.contactFormErrorMessage);
				return false;
			} else {
				if ($(state.dom.contactFormErrorMessage).hasClass("SHOW")) services.hide(state.dom.contactFormErrorMessage);
			}

		});
	};

	// Control successful form submission overlay
	var controlFormSubmissionOverlay = function() {
		if (state.dom.formSubmissionOverlay !== null) {
			var closeButton = d.querySelector("#successful-form-submission-overlay .close-button");
			$(closeButton).on(services.interaction(), function() {
				return w.location.href = "http://www.drzwebdev.com/sites/StreamYourAd/";
			});
		}
	};

	// Control automatic header > nav > ul > li "SELECTED" states updates while scrolling
	var controlSelectedStates = function() {

		$(w).scroll(function() {

			if (state.canScroll) { // Necessary to prevent weird transition errors after clicking/tapping on nav items

				var scrolled = $(w).scrollTop();
				var threshold = ($(w).height() * 0.4);
				var aboutOffset = $("#about-content").offset().top;
				var servicesOffset = $("#services-content").offset().top;
				var contactOffset = $("#contact-content").offset().top;

				if (aboutOffset - scrolled < threshold) {
					services
						.deselect("[data-navigate]")
						.select("[data-navigate='about']"); // How it Works

					if (servicesOffset - scrolled < threshold) {
						services
							.deselect("[data-navigate]")
							.select("[data-navigate='services']"); // Our Services

						if (contactOffset - scrolled < threshold) {
							services
								.deselect("[data-navigate]")
								.select("[data-navigate='contact']"); // Contact Us
						}
					}

				} else {
					services
						.deselect("[data-navigate]")
						.select("[data-navigate='home']"); // Home
				}

			} // End state.canScroll check
		});

		// Control "SELECTED" states in header > nav > ul > li based on user location
		state.dom.$navigators.on(services.interaction(), function() {
			var section = $(this).attr("data-navigate");
			services
				.deselect("[data-navigate]")
				.select("[data-navigate='" + section + "']");
			state.resetScroll();
		});

		$(state.dom.logo).on(services.interaction(), function() {
			services
				.deselect("[data-navigate]")
				.select("[data-navigate='home']");
			state.resetScroll();
		});

		$(state.dom.splashDownArrow).on(services.interaction(), function() {
			services
				.deselect("[data-navigate='home']")
				.select("[data-navigate='about']");
			state.resetScroll();
		});

	};

	// "Privacy Policy" / "Terms & Conditions" alerts
	var controlAlerts = function() {
		state.dom.$footerLinks.on(services.interaction(), function() {
			var delay = ("ontouchend" in d) ? 50 : 0;
			setTimeout(function() {
				alert("'StreamYourAd' the company no longer exists as a legal entity, thus I am prohibited from sharing any legal bric-a-brac on the site. This site now serves as a dummy practice environment for my portfolio :)");
			}, delay);
		});
	};

	// Create hover/active states
	var setMousables = function() {
		return $("nav li, #responsive-nav-button, .blue-button, footer ul li:not(:last-child)").mouseable();
	};

	// Start
	var init = function() {
		collectDom();
		controlNavigation();
		controlParallax();
		controlSlider();
		validateContactForm();
		controlAlerts();
		controlFormSubmissionOverlay();
		controlSelectedStates();
		setMousables();
	};

	$(d).ready(init);

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


<commit_before>requirejs.config({
    // Path mappings for the logical module names
    paths:
    //injector:mainReleasePaths
    {
        'knockout': 'libs/knockout/knockout-3.4.0',
        'jquery': 'libs/jquery/jquery-3.1.0',
        'jqueryui-amd': 'libs/jquery/jqueryui-amd-1.12.0',
        'promise': 'libs/es6-promise/es6-promise',
        'hammerjs': 'libs/hammer/hammer-2.0.8',
        'ojdnd': 'libs/dnd-polyfill/dnd-polyfill-1.0.0.min',
        'ojs': 'libs/oj/v2.1.0/debug',
        'ojL10n': 'libs/oj/v2.1.0/ojL10n',
        'ojtranslations': 'libs/oj/v2.1.0/resources',
        'signals': 'libs/js-signals/signals',
        'text': 'libs/require/text',
        'mcs': 'libs/mcs/mcs'
    }
    //endinjector
    ,
    // Shim configurations for modules that do not expose AMD
    shim: {
        'jquery': {
            exports: ['jQuery', '$']
      }
    }
});

require(['ojs/ojcore', 'knockout', 'jquery', 'mobilebackend', 'ojs/ojbutton', 'ojs/ojknockout', 'ojs/ojmenu', 'ojs/ojmodule', 'ojs/ojrouter', 'ojs/ojtoolbar', 'text'],
function(oj, ko, $, mbe)
{
    oj.Router.defaults['urlAdapter'] = new oj.Router.urlParamAdapter();
    var router = oj.Router.rootInstance;
    router.configure({
        'Home':       { label: 'Home',       value: 'home',      isDefault: true },
        'Preference': { label: 'Preference', value: 'preference' },
        'Sign out':   { label: 'Sign out',   value: 'sign out' }
    });

    function viewModel() {
        var self = this;
        self.appName = '2fauth Sample';

        self.router = router;

        self.selectMenuItem = function(event, ui) {
            var item = ui.item.children("a").text();
            if (item == 'Sign out') {
                mbe.logout();
                location.href = "./login.html";
            } else {
                self.router.go(item);
            }
        }

        self.username = ko.observable();
        mbe.getCurrentUser(
                function(statusCode, user) {
                    self.username(user.getEmail());
                },
                function(statusCode, user) {}
        );
    };

    oj.Router.sync().then(
        function() {
            ko.applyBindings(viewModel);
            $('#globalBody').show();
        },
        function(error) {
            oj.Logger.error('Error when starting router: ' + error.message);
        }
    );
}
);
<commit_msg>Redirect unauthorized request to index.html<commit_after>requirejs.config({
    // Path mappings for the logical module names
    paths:
    //injector:mainReleasePaths
    {
        'knockout': 'libs/knockout/knockout-3.4.0',
        'jquery': 'libs/jquery/jquery-3.1.0',
        'jqueryui-amd': 'libs/jquery/jqueryui-amd-1.12.0',
        'promise': 'libs/es6-promise/es6-promise',
        'hammerjs': 'libs/hammer/hammer-2.0.8',
        'ojdnd': 'libs/dnd-polyfill/dnd-polyfill-1.0.0.min',
        'ojs': 'libs/oj/v2.1.0/debug',
        'ojL10n': 'libs/oj/v2.1.0/ojL10n',
        'ojtranslations': 'libs/oj/v2.1.0/resources',
        'signals': 'libs/js-signals/signals',
        'text': 'libs/require/text',
        'mcs': 'libs/mcs/mcs'
    }
    //endinjector
    ,
    // Shim configurations for modules that do not expose AMD
    shim: {
        'jquery': {
            exports: ['jQuery', '$']
      }
    }
});

require(['ojs/ojcore', 'knockout', 'jquery', 'mobilebackend', 'ojs/ojbutton', 'ojs/ojknockout', 'ojs/ojmenu', 'ojs/ojmodule', 'ojs/ojrouter', 'ojs/ojtoolbar', 'text'],
function(oj, ko, $, mbe)
{
    if (!mbe.isAuthorized()) {
        location.href = "./login.html";
    }

    oj.Router.defaults['urlAdapter'] = new oj.Router.urlParamAdapter();
    var router = oj.Router.rootInstance;
    router.configure({
        'Home':       { label: 'Home',       value: 'home',      isDefault: true },
        'Preference': { label: 'Preference', value: 'preference' },
        'Sign out':   { label: 'Sign out',   value: 'sign out' }
    });

    function viewModel() {
        var self = this;
        self.appName = '2fauth Sample';

        self.router = router;

        self.selectMenuItem = function(event, ui) {
            var item = ui.item.children("a").text();
            if (item == 'Sign out') {
                mbe.logout();
                location.href = "./login.html";
            } else {
                self.router.go(item);
            }
        }

        self.username = ko.observable();
        mbe.getCurrentUser(
                function(statusCode, user) {
                    self.username(user.getEmail());
                },
                function(statusCode, user) {}
        );
    };

    oj.Router.sync().then(
        function() {
            ko.applyBindings(viewModel);
            $('#globalBody').show();
        },
        function(error) {
            oj.Logger.error('Error when starting router: ' + error.message);
        }
    );
}
);
<|endoftext|>


<commit_before>Garp.Wysiwygct = Ext.extend(Ext.Panel,{

	cls: 'wysiwyg-ct',

	tbar: new Ext.Toolbar({
		scope: this,
		defaults: {
			scope: this,
			xtype: 'button'
		},
		items: [{
			iconCls: 'icon-new',
			text: 'Add',
			ref: 'addBtn'

		}, {
			iconCls: 'icon-delete',
			text: 'Remove',
			ref: 'removeBtn'

		}, '-', {
			text: 'Bold',
			handler: function(){
				document.execCommand('Bold', false, null);
			}
		},{
			text: 'Italic',
			handler: function(){
				document.execCommand('Italic', false, null);
			}
		}]
	}),

	addWysiwygBox: function(){
		var newRow = this.getEl().child('.row:last').insertSibling({
			tag: 'div',
			cls: 'row'
		}, 'after');
		var wysiwyg = new Garp.Wysiwyg({
			renderTo: newRow,
			cls: 'grid-col-12-12'
		});
		this.setupDD();

	},

	removeWysiwygBox: function(){
		var box = Ext.get(Ext.get(window.getSelection().focusNode.parentNode).findParent('.wysiwyg-box'));
		box.remove();
		this.fixRows();
	},

	maxCols: 12,

	/**
	 * ColClasses be gone
	 * @param {Object} el
	 */
	removeColClasses: function(el){
		if (!el) {
			return;
		}
		for (var i = 1; i <= this.maxCols; i++) {
			Ext.get(el).removeClass('grid-col-' + i + '-' + this.maxCols);
		}
	},

	/**
	 * Fix all Rows
	 */
	fixRows: function(){
		var rows = Ext.query('.wysiwyg-ct .row');
		Ext.each(rows, this.fixRow, this);
	},

	/**
	 * Distributes rowWidth (col classes) according to number of items in a row. Removes unnecessary (empty) rows.
	 * @param {Object} el
	 */
	fixRow: function(el){
		var rowElm = Ext.get(el);
		var elms = rowElm.query('.wysiwyg-box');
		var nrOfItems = elms.length;
		if (nrOfItems === 0) {
			rowElm.remove();
		} else {
			var total = 0;
			Ext.each(elms, function(el){
				if (el) {
					el = Ext.get(el);
					total += this.getCurrentColCount(el);
				}
			}, this);
			if (total > this.maxCols || total < this.maxCols) {
				Ext.each(elms, function(el){
					if (el) {
						el = Ext.get(el);
						this.removeColClasses(el);
						el.addClass('grid-col-' + Math.floor(this.maxCols / nrOfItems) + '-' + this.maxCols);
					}
				}, this);
			}
		}
	},

	/**
	 * What width does this item have?
	 * @param {Object} el
	 */
	getCurrentColCount: function(el){
		for (var i = this.maxCols; i > 0; i--) {
			if (el.hasClass('grid-col-' + i + '-' + this.maxCols)) {
				return i;
			}
		}
		return this.maxCols;
	},

	/**
	 * Return all other items in this row
	 * @param {Object} el
	 */
	getOtherCols: function(el){
		var others = Ext.get(el.parent('.row').query('.wysiwyg-box'));
		return others.removeElement(el);
	},

	/**
	 * Setup Drag 'n Drop handlers & Ext resizer for all 'boxes'
	 */
	setupDD: function(){

		var wysiwygct = this;
		var dragables = Ext.query('.wysiwyg-box');
		Ext.each(dragables, function(elm){

			if (elm.resizer) {
				elm.resizer.destroy();
			}

			var w = null;
			var currentSize;
			elm.resizer = new Ext.Resizable(elm.id, {
				handles: 'e',
				dynamic: true,
				listeners: {
					'beforeresize': function(){
						w = this.getEl().getWidth();
					},
					'resize': function(){
						var el = this.getEl();
						var nw = el.getWidth();
						var count = wysiwygct.getCurrentColCount(el);
						var others = wysiwygct.getOtherCols(el);

						el.setStyle('width', '');
						if (others && others.elements.length) {

							var theOtherEl = el.next();
							if (!theOtherEl) {
								theOtherEl = el.prev();
							}

							var theOtherCount = wysiwygct.getCurrentColCount(theOtherEl);

							//var delta = Math.floor(1 / wysiwygct.maxCols * (Math.abs(w - nw) / Ext.getBody().getWidth() * 100));
							var delta = Math.floor(Math.abs(w - nw) / (Ext.getBody().getWidth() / wysiwygct.maxCols));
							if (delta < 0) {
								delta = 1;
							}

							if (w < nw) {
								others.removeElement(theOtherEl);
								others.each(function(elm){
									theOtherCount += wysiwygct.getCurrentColCount(elm);
								});
								if (count >= wysiwygct.maxCols || theOtherCount <= 1) {
									return;
								}
								wysiwygct.removeColClasses(el);
								wysiwygct.removeColClasses(theOtherEl);
								el.addClass('grid-col-' + (count + delta) + '-' + wysiwygct.maxCols);
								theOtherEl.addClass('grid-col-' + (theOtherCount - delta) + '-' + wysiwygct.maxCols);
							} else {
								others.removeElement(theOtherEl);
								others.each(function(elm){
									theOtherCount -= wysiwygct.getCurrentColCount(elm);
								});
								if (theOtherCount >= wysiwygct.maxCols || count <= 1) {
									return;
								}
								wysiwygct.removeColClasses(el);
								wysiwygct.removeColClasses(theOtherEl);
								el.addClass('grid-col-' + (count - delta) + '-' + wysiwygct.maxCols);
								theOtherEl.addClass('grid-col-' + (theOtherCount + delta) + '-' + wysiwygct.maxCols);
							}
						}
					}
				}
			});

			var dd = new Ext.dd.DD(elm, 'wysiwyg-dragables-group', {
				isTarget: false,
				ignoreSelf: true
			});

			Ext.apply(dd, {

				wysiwygct: wysiwygct,

				possibleSuspect: null,

				b4StartDrag: function(){
					if (!this.el) {
						this.el = Ext.get(this.getEl());
					}
					this.el.addClass('in-drag');
					this.originalXY = this.el.getXY();

				},

				startDrag:function(){
					this.wysiwygct.getEl().removeClass('disabled-targets');
				},

				onInvalidDrop: function(){
					this.invalidDrop = true;
				},

				removeDropHiglight: function(){
					Ext.select('.wysiwyg-box .active').each(function(el){
						el.removeClass('active');
					});
					delete this.possibleSuspect;
				},

				onDragOver: function(e, id){
					var possible = Ext.get(id);
					if (possible.parent('#' + this.el.id)) {
						return; // Don't allow DD on self!
					}
					this.removeDropHiglight();
					possible.addClass('active');
					this.possibleSuspect = possible;
				},

				onDragOut: function(e, id){
					this.removeDropHiglight();
				},

				endDrag: function(e, id){
					this.el.removeClass('in-drag');
					this.wysiwygct.getEl().addClass('disabled-targets');

					if (this.possibleSuspect) {

						var p = Ext.get(this.possibleSuspect);
						var top = p.hasClass('top');
						var bottom = p.hasClass('bottom');
						var left = p.hasClass('left');
						var right = p.hasClass('right');

						p = p.findParent('.wysiwyg-box');

						Ext.get(p).frame();

						this.wysiwygct.fixRows();
						if (top) {
							this.el.insertBefore(Ext.get(p).findParent('.row'));
							this.el.wrap({
								tag: 'div',
								cls: 'row'
							});
						}
						if (bottom) {
							this.el.insertAfter(Ext.get(p).findParent('.row'));
							this.el.wrap({
								tag: 'div',
								cls: 'row'
							});
						}
						if (left) {
							this.el.insertBefore(p);
						}
						if (right) {
							this.el.insertAfter(p);
						}
						this.wysiwygct.fixRows();

						this.el.clearPositioning();

					} else {
						this.el.moveTo(this.originalXY[0], this.originalXY[1]);
						delete this.invalidDrop;
					}

					this.removeDropHiglight();
					wysiwygct.setupDD();
				}

			});
			var handle = Ext.get(elm).child('.dd-handle').id;
			dd.setHandleElId(handle);

			var targetTop = new Ext.dd.DDTarget(Ext.get(elm).child('.top').id, 'wysiwyg-dragables-group', {});
			var targetRight = new Ext.dd.DDTarget(Ext.get(elm).child('.right').id, 'wysiwyg-dragables-group', {});
			var targetBottom = new Ext.dd.DDTarget(Ext.get(elm).child('.bottom').id, 'wysiwyg-dragables-group', {});
			var targetLeft = new Ext.dd.DDTarget(Ext.get(elm).child('.left').id, 'wysiwyg-dragables-group', {});

		});

		this.getEl().addClass('disabled-targets');

	},

	/**
	 * I.N.I.T.
	 * @param {Object} ct
	 */
	initComponent: function(ct){
		Garp.Wysiwygct.superclass.initComponent.call(this, ct);

		this.on('afterlayout', this.setupDD, this, {
			single: true
		});
		this.on('render', function(){
			this.getTopToolbar().addBtn.setHandler(this.addWysiwygBox.createDelegate(this));
			this.getTopToolbar().removeBtn.setHandler(this.removeWysiwygBox.createDelegate(this));
		}, this);
	}

});
Ext.reg('wysiwygct', Garp.Wysiwygct);

Garp.Wysiwyg = Ext.extend(Ext.Panel, {

	html:
		'

' +
		'
Enter text
' +
		'

' +
		'

' +
		'

' +
		'

',

	initComponent: function(ct){
		Garp.Wysiwyg.superclass.initComponent.call(this, ct);

		this.on('afterrender', function(){
			this.addClass('wysiwyg-box');
			//this.body.child('.contenteditable').dom.setAttribute('contentEditable', 'true');
			this.body.select('.dd-handle, .target').each(function(el){
				el.dom.setAttribute(id, Ext.id());
			});
			//Ext.get(this.body.child('.contenteditable')).update(Math.floor(Math.random() * 1000));
			var i = new Ext.form.FormPanel({
				title: 'Lalala',
				items: [{
					xtype: 'textfield',
					fieldLabel: 'Aap'
				}, {
					xtype: 'xdatetime',
					fieldLabel: 'Datum'
				}],
				applyTo: this.body.child('.contenteditable')
			});
		}, this);
	}
});
Ext.reg('wysiwyg', Garp.Wysiwyg);
<commit_msg>ScrollManager FINALLY!@@#$@!!<commit_after>
Garp.Wysiwygct = Ext.extend(Ext.Panel,{

	cls: 'wysiwyg-ct',
	autoScroll: true,
	height: 300,

	tbar: new Ext.Toolbar({
		scope: this,
		defaults: {
			scope: this,
			xtype: 'button'
		},
		items: [{
			iconCls: 'icon-new',
			text: 'Add',
			ref: 'addBtn'

		}, {
			iconCls: 'icon-delete',
			text: 'Remove',
			ref: 'removeBtn'

		}, '-', {
			text: 'Bold',
			handler: function(){
				document.execCommand('Bold', false, null);
			}
		},{
			text: 'Italic',
			handler: function(){
				document.execCommand('Italic', false, null);
			}
		}]
	}),

	addWysiwygBox: function(){
		var wysiwyg = new Garp.Wysiwyg({
			cls: 'grid-col-12-12'
		});
		this.add(wysiwyg);
		this.doLayout();
		this.setupDD();

	},

	removeWysiwygBox: function(){
		var box = Ext.get(Ext.get(window.getSelection().focusNode.parentNode).findParent('.wysiwyg-box'));
		box.remove();
		this.fixRows();
	},

	maxCols: 12,

	/**
	 * ColClasses be gone
	 * @param {Object} el
	 */
	removeColClasses: function(el){
		if (!el) {
			return;
		}
		for (var i = 1; i <= this.maxCols; i++) {
			Ext.get(el).removeClass('grid-col-' + i + '-' + this.maxCols);
		}
	},

	/**
	 * What width does this item have?
	 * @param {Object} el
	 */
	getCurrentColCount: function(el){
		for (var i = this.maxCols; i > 0; i--) {
			if (el.hasClass('grid-col-' + i + '-' + this.maxCols)) {
				return i;
			}
		}
		return this.maxCols;
	},

	/**
	 * Setup Drag 'n Drop handlers & Ext resizer for all 'boxes'
	 */
	setupDD: function(){

		var wysiwygct = this;
		var dragables = Ext.query('.wysiwyg-box');
		this.getEl().addClass('disabled-targets');

		Ext.dd.ScrollManager.register(this.body);
		this.body.ddScrollConfig = {
	        vthresh: 50,
	        hthresh: -1,
	        animate: true,
	        increment: 200
	    };

		Ext.each(dragables, function(elm){

			if (elm.resizer) {
				elm.resizer.destroy();
			}

			var w = null;
			var currentSize;

			// set up resizer:
			elm.resizer = new Ext.Resizable(elm.id, {
				handles: 'e',
				dynamic: true,
				listeners: {
					'beforeresize': function(){
						w = this.getEl().getWidth();
					},
					'resize': function(){
						var el = this.getEl();
						var nw = el.getWidth();
						var count = wysiwygct.getCurrentColCount(el);
						el.setStyle('width', '');

						var newCol = Math.ceil(wysiwygct.maxCols / (wysiwygct.getWidth() / nw));
						if (newCol < 1) {
							newCol = 1;
						}

						if (w < nw) {
							if (count >= wysiwygct.maxCols) {
								return;
							}
							wysiwygct.removeColClasses(el);
							el.addClass('grid-col-' + (newCol) + '-' + wysiwygct.maxCols);
						} else {
							if (count <= 1) {
								return;
							}
							wysiwygct.removeColClasses(el);
							el.addClass('grid-col-' + (newCol) + '-' + wysiwygct.maxCols);
						}
					}
				}
			});

			var dd = new Ext.dd.DD(elm, 'wysiwyg-dragables-group', {
				isTarget: false,
				ignoreSelf: true,
				scroll: true
			});

			Ext.apply(dd, {

				wysiwygct: wysiwygct,

				possibleSuspect: null,

				b4StartDrag: function(){
					if (!this.el) {
						this.el = Ext.get(this.getEl());
					}
					this.el.addClass('in-drag');
					this.originalXY = this.el.getXY();
				},

				startDrag: function(){
					this.wysiwygct.getEl().removeClass('disabled-targets');
				},

				onInvalidDrop: function(){
					this.invalidDrop = true;
				},

				removeDropHiglight: function(){
					Ext.select('.wysiwyg-box .active').each(function(el){
						el.removeClass('active');
					});
					delete this.possibleSuspect;
				},

				onDragOver: function(e, id){
					var possible = Ext.get(id);
					if (possible.parent('#' + this.el.id)) {
						return; // Don't allow DD on self!
					}
					this.removeDropHiglight();
					possible.addClass('active');
					this.possibleSuspect = possible;
				},

				onDragOut: function(e, id){
					this.removeDropHiglight();
				},

				endDrag: function(e, id){

					this.el.removeClass('in-drag');
					this.wysiwygct.getEl().addClass('disabled-targets');

					if (this.possibleSuspect) {

						var p = Ext.get(this.possibleSuspect);
						var top = p.hasClass('top');
						var bottom = p.hasClass('bottom');
						var left = p.hasClass('left');
						var right = p.hasClass('right');

						p = p.findParent('.wysiwyg-box');

						if (top || left) {
							this.el.insertBefore(p);
						} else {
							this.el.insertAfter(p);
						}
						this.el.frame();

						this.el.clearPositioning();

					} else {
						this.el.moveTo(this.originalXY[0], this.originalXY[1]);
						delete this.invalidDrop;
					}

					this.removeDropHiglight();
					wysiwygct.setupDD();
				}

			});
			var handle = Ext.get(elm).child('.dd-handle').id;
			dd.setHandleElId(handle);

			var targetTop = new Ext.dd.DDTarget(Ext.get(elm).child('.top').id, 'wysiwyg-dragables-group', {});
			var targetRight = new Ext.dd.DDTarget(Ext.get(elm).child('.right').id, 'wysiwyg-dragables-group', {});
			var targetBottom = new Ext.dd.DDTarget(Ext.get(elm).child('.bottom').id, 'wysiwyg-dragables-group', {});
			var targetLeft = new Ext.dd.DDTarget(Ext.get(elm).child('.left').id, 'wysiwyg-dragables-group', {});

		});

		this.getEl().addClass('disabled-targets');

	},

	/**
	 * I.N.I.T.
	 * @param {Object} ct
	 */
	initComponent: function(ct){
		Garp.Wysiwygct.superclass.initComponent.call(this, ct);

		this.on('afterlayout', this.setupDD, this, {
			single: true
		});
		this.on('render', function(){
			this.getTopToolbar().addBtn.setHandler(this.addWysiwygBox.createDelegate(this));
			this.getTopToolbar().removeBtn.setHandler(this.removeWysiwygBox.createDelegate(this));
		}, this);
	}

});
Ext.reg('wysiwygct', Garp.Wysiwygct);

Garp.Wysiwyg = Ext.extend(Ext.Panel, {

	html:
		'

' +
		'
Enter text
' +
		'

' +
		'

' +
		'

' +
		'

',

	initComponent: function(ct){
		Garp.Wysiwyg.superclass.initComponent.call(this, ct);

		this.on('afterrender', function(){
			this.addClass('wysiwyg-box');
			this.body.select('.dd-handle, .target').each(function(el){
				el.dom.setAttribute(id, Ext.id());
			});

			var mdl = 'Snippet';
			var items = Ext.apply({}, Garp.dataTypes[mdl].formConfig[0].items[0]);

			var i = new Ext.form.FormPanel({
				title: mdl,
				layout: 'form',
				ref: 'form',
				defaults: {
					autoWidth: true,
					border: false,
					bodyCssClass: 'garp-formpanel' // visual styling
				},
				items: items,
				applyTo: this.body.child('.contenteditable')
			});
		}, this);
	}
});
Ext.reg('wysiwyg', Garp.Wysiwyg);
<|endoftext|>