<commit_before>/*
 * MelonJS Game Engine
 * Copyright (C) 2011 - 2018 Olivier Biot
 * http://www.melonjs.org
 *
 */
(function () {
    /**
     * a local constant for the -(Math.PI / 2) value
     * @ignore
     */
    var nhPI = -(Math.PI / 2);

    /**
     * A Texture atlas object

     * For portability, a global reference to this class is available through the default renderer: {@link me.video.renderer}.Texture

     *

     * Currently supports :

     * - [TexturePacker]{@link http://www.codeandweb.com/texturepacker/} : through JSON export

     * - [ShoeBox]{@link http://renderhjs.net/shoebox/} : through JSON export using the
     * melonJS setting [file]{@link https://github.com/melonjs/melonJS/raw/master/media/shoebox_JSON_export.sbx}

     * - Standard (fixed cell size) spritesheet : through a {framewidth:xx, frameheight:xx, anchorPoint:me.Vector2d} object
     * @class
     * @extends me.Object
     * @memberOf me.CanvasRenderer
     * @name Texture
     * @constructor
     * @param {Object} atlas atlas information. See {@link me.loader.getJSON}
     * @param {HTMLImageElement|HTMLCanvasElement|String} [source=atlas.meta.image] Image source
     * @param {Boolean} [cached=false] Use true to skip caching this Texture
     * @example
     * // create a texture atlas from a JSON Object
     * texture = new me.video.renderer.Texture(
     *     me.loader.getJSON("texture"),
     *     me.loader.getImage("texture")
     * );
     *
     * // create a texture atlas for a spritesheet, with (optional) an anchorPoint in the center of each frame
     * texture = new me.video.renderer.Texture(
     *     { framewidth : 32, frameheight : 32, anchorPoint : new me.Vector2d(0.5, 0.5) },
     *     me.loader.getImage("spritesheet")
     * );
     */
    me.CanvasRenderer.prototype.Texture = me.Object.extend(
    /** @scope me.video.renderer.Texture.prototype */
    {
        /**
         * @ignore
         */
        init : function (atlas, source, cache) {
            /**
             * to identify the atlas format (e.g. texture packer)
             * @ignore
             */
            this.format = null;

            /**
             * the texture source itself
             * @type {HTMLImageElement|HTMLCanvasElement}
             * @ignore
             */
            this.source = source || null;

            /**
             * the atlas dictionnary
             * @ignore
             */
            this.atlas = null;

            if (typeof (atlas) !== "undefined") {

                if (typeof(atlas.meta) !== "undefined") {
                    // Texture Packer
                    if (atlas.meta.app.includes("texturepacker")) {
                        this.format = "texturepacker";
                        // set the texture
                        if (typeof(source) === "undefined") {
                            var image = atlas.meta.image;
                            this.source = me.loader.getImage(image);
                            if (!this.source) {
                                throw new me.video.renderer.Texture.Error(
                                    "Atlas texture '" + image + "' not found"
                                );
                            }
                        }
                        this.repeat = "no-repeat";
                    }
                    // ShoeBox
                    else if (atlas.meta.app.includes("ShoeBox")) {
                        if (!atlas.meta.exporter || !atlas.meta.exporter.includes("melonJS")) {
                            throw new me.video.renderer.Texture.Error(
                                "ShoeBox requires the JSON exporter : " +
                                "https://github.com/melonjs/melonJS/tree/master/media/shoebox_JSON_export.sbx"
                            );
                        }
                        this.format = "ShoeBox";
                        this.repeat = "no-repeat";
                    }
                    // Internal texture atlas
                    else if (atlas.meta.app.includes("melonJS")) {
                        this.format = "melonJS";
                        this.repeat = atlas.meta.repeat || "no-repeat";
                    }
                    // initialize the atlas
                    this.atlas = this.parse(atlas);

                } else {
                    // a regular spritesheet ?
                    if (typeof(atlas.framewidth) !== "undefined" &&
                        typeof(atlas.frameheight) !== "undefined") {
                        this.format = "Spritesheet (fixed cell size)";
                        if (typeof(this.source) !== undefined) {
                            // overwrite if specified
                            atlas.image = this.source;
                        }
                        // initialize the atlas
                        this.atlas = this.parseFromSpriteSheet(atlas);
                        this.repeat = "no-repeat";
                    }
                }
            }
            // if format not recognized
            if (!this.atlas) {
                throw new me.video.renderer.Texture.Error("texture atlas format not supported");
            }

            // Add self to TextureCache if cache !== false
            if (cache !== false) {
                if (cache instanceof me.Renderer.TextureCache) {
                    cache.put(this.source, this);
                } else {
                    me.video.renderer.cache.put(this.source, this);
                }
            }
        },

        /**
         * create a simple 1 frame texture atlas based on the given parameters
         * @ignore
         */
        createAtlas : function (width, height, name, repeat) {
            return {
                "meta" : {
                    "app" : "melonJS",
                    "size" : { "w" : width, "h" : height },
                    "repeat" : repeat || "no-repeat"
                },
                "frames" : [{
                    "filename" : name || "default",
                    "frame" : { "x" : 0, "y" : 0, "w" : width, "h" : height }
                }]
            };
        },

        /**
         * build an atlas from the given data
         * @ignore
         */
        parse : function (data) {
            var atlas = {};
            data.frames.forEach(function (frame) {
                // fix wrongly formatted JSON (e.g. last dummy object in ShoeBox)
                if (frame.hasOwnProperty("filename")) {
                    // Source coordinates
                    var s = frame.frame;

                    var originX, originY;
                    // Pixel-based offset origin from the top-left of the source frame
                    var hasTextureAnchorPoint = (frame.spriteSourceSize && frame.sourceSize && frame.pivot);
                    if (hasTextureAnchorPoint) {
                        originX = (frame.sourceSize.w * frame.pivot.x) - ((frame.trimmed) ? frame.spriteSourceSize.x : 0);
                        originY = (frame.sourceSize.h * frame.pivot.y) - ((frame.trimmed) ? frame.spriteSourceSize.y : 0);
                    }

                    atlas[frame.filename] = {
                        name         : frame.filename, // frame name
                        offset       : new me.Vector2d(s.x, s.y),
                        anchorPoint  : (hasTextureAnchorPoint) ? new me.Vector2d(originX / s.w, originY / s.h) : null,
                        width        : s.w,
                        height       : s.h,
                        angle        : (frame.rotated === true) ? nhPI : 0
                    };
                }
            });
            return atlas;
        },

        /**
         * build an atlas from the given spritesheet
         * @ignore
         */
        parseFromSpriteSheet : function (data) {
            var atlas = {};
            var image = data.image;
            var spacing = data.spacing || 0;
            var margin = data.margin || 0;

            var width = image.width;
            var height = image.height;

            // calculate the sprite count (line, col)
            var spritecount = new me.Vector2d(
                ~~((width - margin + spacing) / (data.framewidth + spacing)),
                ~~((height - margin + spacing) / (data.frameheight + spacing))
            );

            // verifying the texture size
            if ((width % (data.framewidth + spacing)) !== 0 ||
                (height % (data.frameheight + spacing)) !== 0) {
                // "truncate size"
                width = spritecount.x * (data.framewidth + spacing);
                height = spritecount.y * (data.frameheight + spacing);
                // warning message
                console.warn(
                    "Spritesheet Texture for image: " + image.src +
                    " is not divisible by " + (data.framewidth + spacing) +
                    "x" + (data.frameheight + spacing) +
                    ", truncating effective size to " + width + "x" + height
                );
            }

            // build the local atlas
            for (var frame = 0, count = spritecount.x * spritecount.y; frame < count; frame++) {
                atlas["" + frame] = {
                    name: "" + frame,
                    offset: new me.Vector2d(
                        margin + (spacing + data.framewidth) * (frame % spritecount.x),
                        margin + (spacing + data.frameheight) * ~~(frame / spritecount.x)
                    ),
                    anchorPoint: (data.anchorPoint || null),
                    width: data.framewidth,
                    height: data.frameheight,
                    angle: 0
                };
            }

            return atlas;
        },

        /**
         * return the Atlas dictionnary
         * @name getAtlas
         * @memberOf me.CanvasRenderer.Texture
         * @function
         * @return {Object}
         */
        getAtlas : function () {
            return this.atlas;
        },

        /**
         * return the Atlas texture
         * @name getTexture
         * @memberOf me.CanvasRenderer.Texture
         * @function
         * @return {HTMLImageElement|HTMLCanvasElement}
         */
        getTexture : function () {
            return this.source;
        },

        /**
         * return a normalized region/frame information for the specified sprite name
         * @name getRegion
         * @memberOf me.CanvasRenderer.Texture
         * @function
         * @param {String} name name of the sprite
         * @return {Object}
         */
        getRegion : function (name) {
            return this.atlas[name];
        },

        /**
         * Create a sprite object using the first region found using the specified name
         * @name createSpriteFromName
         * @memberOf me.CanvasRenderer.Texture
         * @function
         * @param {String} name name of the sprite
         * @param {Object} [settings] Additional settings passed to the {@link me.Sprite} contructor
         * @return {me.Sprite}
         * @example
         * // create a new texture atlas object under the `game` namespace
         * game.texture = new me.video.renderer.Texture(
         *    me.loader.getJSON("texture"),
         *    me.loader.getImage("texture")
         * );
         * ...
         * ...
         * // add the coin sprite as renderable for the entity
         * this.renderable = game.texture.createSpriteFromName("coin.png");
         * // set the renderable position to bottom center
         * this.anchorPoint.set(0.5, 1.0);
         */
        createSpriteFromName : function (name, settings) {
            // instantiate a new sprite object
            return me.pool.pull(
                "me.Sprite",
                0, 0,
                Object.assign({
                    image: this,
                    region : name
                }, settings || {})
            );
        },

        /**
         * Create an animation object using the first region found using all specified names
         * @name createAnimationFromName
         * @memberOf me.CanvasRenderer.Texture
         * @function
         * @param {String[]|Number[]} names list of names for each sprite
         * (when manually creating a Texture out of a spritesheet, only numeric values are authorized)
         * @param {Object} [settings] Additional settings passed to the {@link me.Sprite} contructor
         * @return {me.Sprite}
         * @example
         * // create a new texture atlas object under the `game` namespace
         * game.texture = new me.video.renderer.Texture(
         *     me.loader.getJSON("texture"),
         *     me.loader.getImage("texture")
         * );
         *
         * // create a new Sprite as renderable for the entity
         * this.renderable = game.texture.createAnimationFromName([
         *     "walk0001.png", "walk0002.png", "walk0003.png",
         *     "walk0004.png", "walk0005.png", "walk0006.png",
         *     "walk0007.png", "walk0008.png", "walk0009.png",
         *     "walk0010.png", "walk0011.png"
         * ]);
         *
         * // define an additional basic walking animation
         * this.renderable.addAnimation ("simple_walk", [0,2,1]);
         * // you can also use frame name to define your animation
         * this.renderable.addAnimation ("speed_walk", ["walk0007.png", "walk0008.png", "walk0009.png", "walk0010.png"]);
         * // set the default animation
         * this.renderable.setCurrentAnimation("simple_walk");
         * // set the renderable position to bottom center
         * this.anchorPoint.set(0.5, 1.0);
         */
        createAnimationFromName : function (names, settings) {
            var tpAtlas = [], indices = {};
            var width = 0, height = 0;
            var region;
            // iterate through the given names
            // and create a "normalized" atlas
            for (var i = 0; i < names.length; ++i) {
                region = this.getRegion(names[i]);
                if (region == null) {
                    // throw an error
                    throw new me.video.renderer.Texture.Error("Texture - region for " + names[i] + " not found");
                }
                tpAtlas[i] = region;
                // save the corresponding index
                indices[names[i]] = i;
                // calculate the max size of a frame
                width = Math.max(region.width, width);
                height = Math.max(region.height, height);
            }
            // instantiate a new animation sheet object
            return new me.Sprite(0, 0, Object.assign({
                image: this,
                framewidth: width,
                frameheight: height,
                margin: 0,
                spacing: 0,
                atlas: tpAtlas,
                atlasIndices: indices
            }, settings || {}));
        }
    });

    /**
     * Base class for Texture exception handling.
     * @name Error
     * @class
     * @memberOf me.CanvasRenderer.Texture
     * @constructor
     * @param {String} msg Error message.
     */
    me.CanvasRenderer.prototype.Texture.Error = me.Error.extend({
        /**
         * @ignore
         */
        init : function (msg) {
            this._super(me.Error, "init", [ msg ]);
            this.name = "me.CanvasRenderer.Texture.Error";
        }
    });
})();
<commit_msg>recycle `spritecount` when parsing tileset<commit_after>/*
 * MelonJS Game Engine
 * Copyright (C) 2011 - 2018 Olivier Biot
 * http://www.melonjs.org
 *
 */
(function () {
    /**
     * a local constant for the -(Math.PI / 2) value
     * @ignore
     */
    var nhPI = -(Math.PI / 2);

    /**
     * A Texture atlas object

     * For portability, a global reference to this class is available through the default renderer: {@link me.video.renderer}.Texture

     *

     * Currently supports :

     * - [TexturePacker]{@link http://www.codeandweb.com/texturepacker/} : through JSON export

     * - [ShoeBox]{@link http://renderhjs.net/shoebox/} : through JSON export using the
     * melonJS setting [file]{@link https://github.com/melonjs/melonJS/raw/master/media/shoebox_JSON_export.sbx}

     * - Standard (fixed cell size) spritesheet : through a {framewidth:xx, frameheight:xx, anchorPoint:me.Vector2d} object
     * @class
     * @extends me.Object
     * @memberOf me.CanvasRenderer
     * @name Texture
     * @constructor
     * @param {Object} atlas atlas information. See {@link me.loader.getJSON}
     * @param {HTMLImageElement|HTMLCanvasElement|String} [source=atlas.meta.image] Image source
     * @param {Boolean} [cached=false] Use true to skip caching this Texture
     * @example
     * // create a texture atlas from a JSON Object
     * texture = new me.video.renderer.Texture(
     *     me.loader.getJSON("texture"),
     *     me.loader.getImage("texture")
     * );
     *
     * // create a texture atlas for a spritesheet, with (optional) an anchorPoint in the center of each frame
     * texture = new me.video.renderer.Texture(
     *     { framewidth : 32, frameheight : 32, anchorPoint : new me.Vector2d(0.5, 0.5) },
     *     me.loader.getImage("spritesheet")
     * );
     */
    me.CanvasRenderer.prototype.Texture = me.Object.extend(
    /** @scope me.video.renderer.Texture.prototype */
    {
        /**
         * @ignore
         */
        init : function (atlas, source, cache) {
            /**
             * to identify the atlas format (e.g. texture packer)
             * @ignore
             */
            this.format = null;

            /**
             * the texture source itself
             * @type {HTMLImageElement|HTMLCanvasElement}
             * @ignore
             */
            this.source = source || null;

            /**
             * the atlas dictionnary
             * @ignore
             */
            this.atlas = null;

            if (typeof (atlas) !== "undefined") {

                if (typeof(atlas.meta) !== "undefined") {
                    // Texture Packer
                    if (atlas.meta.app.includes("texturepacker")) {
                        this.format = "texturepacker";
                        // set the texture
                        if (typeof(source) === "undefined") {
                            var image = atlas.meta.image;
                            this.source = me.loader.getImage(image);
                            if (!this.source) {
                                throw new me.video.renderer.Texture.Error(
                                    "Atlas texture '" + image + "' not found"
                                );
                            }
                        }
                        this.repeat = "no-repeat";
                    }
                    // ShoeBox
                    else if (atlas.meta.app.includes("ShoeBox")) {
                        if (!atlas.meta.exporter || !atlas.meta.exporter.includes("melonJS")) {
                            throw new me.video.renderer.Texture.Error(
                                "ShoeBox requires the JSON exporter : " +
                                "https://github.com/melonjs/melonJS/tree/master/media/shoebox_JSON_export.sbx"
                            );
                        }
                        this.format = "ShoeBox";
                        this.repeat = "no-repeat";
                    }
                    // Internal texture atlas
                    else if (atlas.meta.app.includes("melonJS")) {
                        this.format = "melonJS";
                        this.repeat = atlas.meta.repeat || "no-repeat";
                    }
                    // initialize the atlas
                    this.atlas = this.parse(atlas);

                } else {
                    // a regular spritesheet ?
                    if (typeof(atlas.framewidth) !== "undefined" &&
                        typeof(atlas.frameheight) !== "undefined") {
                        this.format = "Spritesheet (fixed cell size)";
                        if (typeof(this.source) !== undefined) {
                            // overwrite if specified
                            atlas.image = this.source;
                        }
                        // initialize the atlas
                        this.atlas = this.parseFromSpriteSheet(atlas);
                        this.repeat = "no-repeat";
                    }
                }
            }
            // if format not recognized
            if (!this.atlas) {
                throw new me.video.renderer.Texture.Error("texture atlas format not supported");
            }

            // Add self to TextureCache if cache !== false
            if (cache !== false) {
                if (cache instanceof me.Renderer.TextureCache) {
                    cache.put(this.source, this);
                } else {
                    me.video.renderer.cache.put(this.source, this);
                }
            }
        },

        /**
         * create a simple 1 frame texture atlas based on the given parameters
         * @ignore
         */
        createAtlas : function (width, height, name, repeat) {
            return {
                "meta" : {
                    "app" : "melonJS",
                    "size" : { "w" : width, "h" : height },
                    "repeat" : repeat || "no-repeat"
                },
                "frames" : [{
                    "filename" : name || "default",
                    "frame" : { "x" : 0, "y" : 0, "w" : width, "h" : height }
                }]
            };
        },

        /**
         * build an atlas from the given data
         * @ignore
         */
        parse : function (data) {
            var atlas = {};
            data.frames.forEach(function (frame) {
                // fix wrongly formatted JSON (e.g. last dummy object in ShoeBox)
                if (frame.hasOwnProperty("filename")) {
                    // Source coordinates
                    var s = frame.frame;

                    var originX, originY;
                    // Pixel-based offset origin from the top-left of the source frame
                    var hasTextureAnchorPoint = (frame.spriteSourceSize && frame.sourceSize && frame.pivot);
                    if (hasTextureAnchorPoint) {
                        originX = (frame.sourceSize.w * frame.pivot.x) - ((frame.trimmed) ? frame.spriteSourceSize.x : 0);
                        originY = (frame.sourceSize.h * frame.pivot.y) - ((frame.trimmed) ? frame.spriteSourceSize.y : 0);
                    }

                    atlas[frame.filename] = {
                        name         : frame.filename, // frame name
                        offset       : new me.Vector2d(s.x, s.y),
                        anchorPoint  : (hasTextureAnchorPoint) ? new me.Vector2d(originX / s.w, originY / s.h) : null,
                        width        : s.w,
                        height       : s.h,
                        angle        : (frame.rotated === true) ? nhPI : 0
                    };
                }
            });
            return atlas;
        },

        /**
         * build an atlas from the given spritesheet
         * @ignore
         */
        parseFromSpriteSheet : function (data) {
            var atlas = {};
            var image = data.image;
            var spacing = data.spacing || 0;
            var margin = data.margin || 0;

            var width = image.width;
            var height = image.height;

            // calculate the sprite count (line, col)
            var spritecount = me.pool.pull("me.Vector2d",
                ~~((width - margin + spacing) / (data.framewidth + spacing)),
                ~~((height - margin + spacing) / (data.frameheight + spacing))
            );

            // verifying the texture size
            if ((width % (data.framewidth + spacing)) !== 0 ||
                (height % (data.frameheight + spacing)) !== 0) {
                // "truncate size"
                width = spritecount.x * (data.framewidth + spacing);
                height = spritecount.y * (data.frameheight + spacing);
                // warning message
                console.warn(
                    "Spritesheet Texture for image: " + image.src +
                    " is not divisible by " + (data.framewidth + spacing) +
                    "x" + (data.frameheight + spacing) +
                    ", truncating effective size to " + width + "x" + height
                );
            }

            // build the local atlas
            for (var frame = 0, count = spritecount.x * spritecount.y; frame < count; frame++) {
                atlas["" + frame] = {
                    name: "" + frame,
                    offset: new me.Vector2d(
                        margin + (spacing + data.framewidth) * (frame % spritecount.x),
                        margin + (spacing + data.frameheight) * ~~(frame / spritecount.x)
                    ),
                    anchorPoint: (data.anchorPoint || null),
                    width: data.framewidth,
                    height: data.frameheight,
                    angle: 0
                };
            }

            me.pool.push(spritecount);

            return atlas;
        },

        /**
         * return the Atlas dictionnary
         * @name getAtlas
         * @memberOf me.CanvasRenderer.Texture
         * @function
         * @return {Object}
         */
        getAtlas : function () {
            return this.atlas;
        },

        /**
         * return the Atlas texture
         * @name getTexture
         * @memberOf me.CanvasRenderer.Texture
         * @function
         * @return {HTMLImageElement|HTMLCanvasElement}
         */
        getTexture : function () {
            return this.source;
        },

        /**
         * return a normalized region/frame information for the specified sprite name
         * @name getRegion
         * @memberOf me.CanvasRenderer.Texture
         * @function
         * @param {String} name name of the sprite
         * @return {Object}
         */
        getRegion : function (name) {
            return this.atlas[name];
        },

        /**
         * Create a sprite object using the first region found using the specified name
         * @name createSpriteFromName
         * @memberOf me.CanvasRenderer.Texture
         * @function
         * @param {String} name name of the sprite
         * @param {Object} [settings] Additional settings passed to the {@link me.Sprite} contructor
         * @return {me.Sprite}
         * @example
         * // create a new texture atlas object under the `game` namespace
         * game.texture = new me.video.renderer.Texture(
         *    me.loader.getJSON("texture"),
         *    me.loader.getImage("texture")
         * );
         * ...
         * ...
         * // add the coin sprite as renderable for the entity
         * this.renderable = game.texture.createSpriteFromName("coin.png");
         * // set the renderable position to bottom center
         * this.anchorPoint.set(0.5, 1.0);
         */
        createSpriteFromName : function (name, settings) {
            // instantiate a new sprite object
            return me.pool.pull(
                "me.Sprite",
                0, 0,
                Object.assign({
                    image: this,
                    region : name
                }, settings || {})
            );
        },

        /**
         * Create an animation object using the first region found using all specified names
         * @name createAnimationFromName
         * @memberOf me.CanvasRenderer.Texture
         * @function
         * @param {String[]|Number[]} names list of names for each sprite
         * (when manually creating a Texture out of a spritesheet, only numeric values are authorized)
         * @param {Object} [settings] Additional settings passed to the {@link me.Sprite} contructor
         * @return {me.Sprite}
         * @example
         * // create a new texture atlas object under the `game` namespace
         * game.texture = new me.video.renderer.Texture(
         *     me.loader.getJSON("texture"),
         *     me.loader.getImage("texture")
         * );
         *
         * // create a new Sprite as renderable for the entity
         * this.renderable = game.texture.createAnimationFromName([
         *     "walk0001.png", "walk0002.png", "walk0003.png",
         *     "walk0004.png", "walk0005.png", "walk0006.png",
         *     "walk0007.png", "walk0008.png", "walk0009.png",
         *     "walk0010.png", "walk0011.png"
         * ]);
         *
         * // define an additional basic walking animation
         * this.renderable.addAnimation ("simple_walk", [0,2,1]);
         * // you can also use frame name to define your animation
         * this.renderable.addAnimation ("speed_walk", ["walk0007.png", "walk0008.png", "walk0009.png", "walk0010.png"]);
         * // set the default animation
         * this.renderable.setCurrentAnimation("simple_walk");
         * // set the renderable position to bottom center
         * this.anchorPoint.set(0.5, 1.0);
         */
        createAnimationFromName : function (names, settings) {
            var tpAtlas = [], indices = {};
            var width = 0, height = 0;
            var region;
            // iterate through the given names
            // and create a "normalized" atlas
            for (var i = 0; i < names.length; ++i) {
                region = this.getRegion(names[i]);
                if (region == null) {
                    // throw an error
                    throw new me.video.renderer.Texture.Error("Texture - region for " + names[i] + " not found");
                }
                tpAtlas[i] = region;
                // save the corresponding index
                indices[names[i]] = i;
                // calculate the max size of a frame
                width = Math.max(region.width, width);
                height = Math.max(region.height, height);
            }
            // instantiate a new animation sheet object
            return new me.Sprite(0, 0, Object.assign({
                image: this,
                framewidth: width,
                frameheight: height,
                margin: 0,
                spacing: 0,
                atlas: tpAtlas,
                atlasIndices: indices
            }, settings || {}));
        }
    });

    /**
     * Base class for Texture exception handling.
     * @name Error
     * @class
     * @memberOf me.CanvasRenderer.Texture
     * @constructor
     * @param {String} msg Error message.
     */
    me.CanvasRenderer.prototype.Texture.Error = me.Error.extend({
        /**
         * @ignore
         */
        init : function (msg) {
            this._super(me.Error, "init", [ msg ]);
            this.name = "me.CanvasRenderer.Texture.Error";
        }
    });
})();
<|endoftext|>


<commit_before>// eslint-disable-next-line
/* global notifyFormError alert alertHi enableSubmit */
import React, { Component } from 'react'
import DatePicker from 'material-ui/DatePicker'
import Checkbox from 'material-ui/Checkbox'
import IconCheckbox from '../components/iconCheckbox'
import RaisedButton from '../components/MaterializeRaisedButton'
import Dialog from 'material-ui/Dialog'
import FlatButton from 'material-ui/FlatButton'
import { Link } from 'react-router-dom'
import { Helmet } from 'react-helmet'
import '../styles/inputFile.css'
import '../styles/serviceRequest.css'
import infoLogo from '../img/info.svg'

import Formsy from 'formsy-react'
import { FormsyText, FormsyCheckbox } from 'formsy-material-ui/lib'
import {
  singleLineFields,
  multiLineFields,
  leftCheckboxes,
  rightCheckboxes
} from '../data/serviceRequestFields'

const fileExtensions =
  'application/vnd.rar, application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation, audio/mp4, audio/mpeg, text/plain, application/zip, video/quicktime, video/avi, audio/wav, image/jpeg, application/octet-stream, image/png'

const PORT = process.env.UPLOADS_PORT || 9000
const HOST = process.env.UPLOADS_HOST || window.location.host.split(':')[0]
const UPLOAD_URL = `http://${HOST}:${PORT}/uploads`

const styles = {
  checkbox: {
    marginBottom: 16
  }
}

// https://github.com/Dogfalo/materialize/blob/master/js/forms.js#L192
class ServiceRequest extends Component {
  constructor (props) {
    super(props)
    const checkboxProps = [...leftCheckboxes, ...rightCheckboxes].reduce(
      (acc, label, index) => ({
        [this.formatLabelToProperty(label.name)]: false,
        ...acc
      }),
      {}
    )
    this.state = {
      form: {
        fileInput: null,
        fileValid: true
      },
      loadingDialogOpen: false,
      resultDialogOpen: false,
      resultDialogText: null,
      resultDialogSuccess: true,
      canSubmit: false
    }
    Object.assign(this.state.form, checkboxProps)
    this.handleInputChange = this.handleInputChange.bind(this)
  }

  enableSubmit = e => {
    if (e.target.checked) {
      this.setState({
        canSubmit: true
      })
    } else {
      this.setState({
        canSubmit: false
      })
    }
  }

  notifyFormError = () => {
    this.setState({
      resultDialogOpen: true,
      resultDialogSuccess: false,
      resultDialogText: 'Something went wrong. Check for errors and try again.'
    })
  }

  formatLabelToProperty = label =>
    label
      .split(' (')[0]
      .toLowerCase()
      .split(' ')
      .join('-')

  handleInputChange (event) {
    const target = event.target
    const value = target.type === 'checkbox' ? target.checked : target.value
    const name = target.name
    const form = Object.assign({}, this.state.form)
    form[name] = value

    this.setState({ form })
  }

  handleFilePath = event => {
    const target = event.target
    // Array.from converts array-like to array (so that map works)
    const files = Array.from(target.files)
    let fileNames = null
    const formState = this.state.form
    formState.fileValid = true
    this.setState({ formState })
    if (files.length > 0) {
      fileNames = files.map(f => f.name).join(', ')
      files.map(
        f =>
          fileExtensions.match(f.type) === null
            ? (formState.fileValid = false)
            : ''
      )
    }

    const form = Object.assign({}, this.state.form)
    form.fileInput = fileNames
    this.setState({ form })
  }

  handleFormData = async () => {
    const data = new FormData()
    for (const [key, val] of Object.entries(this.state.form)) {
      data.append(key, val)
    }

    for (const file of this.uploadInput.files) data.append('file', file)

    this.setState({ loadingDialogOpen: true })

    try {
      const response = await fetch(UPLOAD_URL, {
        method: 'post',
        body: data
      }).then(res => res.json())

      if (!response.success) throw response.status

      this.setState({
        resultDialogOpen: true,
        resultDialogSuccess: true,
        resultDialogText: 'Your service request was sent successfully.'
      })
    } catch (err) {
      const msg =
        typeof err === 'string'
          ? err
          : 'An error occurred while sending the request.'
      this.setState({
        resultDialogOpen: true,
        resultDialogSuccess: false,
        resultDialogText: msg
      })
    }

    this.setState({ loadingDialogOpen: false })
  }

  handleDialogClose = () => {
    this.setState({ resultDialogOpen: false })
  }

  render () {
    const fileValue = this.state.form.fileInput || 'Select a file to upload'

    return (

        <Helmet>
          <title>Service Request | Resource Center</title>
        </Helmet>

Please use this form to request services.

          <Formsy.Form
            onValidSubmit={this.handleFormData}
            onInvalidSubmit={this.notifyFormError}
          >
            {singleLineFields.map((field, index) => (

                <FormsyText
                  floatingLabelText={field.name}
                  name={field.name.toLowerCase()}
                  value={this.state.form[field.name]}
                  onChange={this.handleInputChange}
                  fullWidth
                  id={`${field.name.toLowerCase()}-field`}
                  required={field.required}
                  validations={field.type}
                  validationError={field.error}
                />

            ))}
            {multiLineFields.map((field, index) => (

                <FormsyText
                  floatingLabelText={field.name}
                  name={field.name.toLowerCase()}
                  value={this.state.form[field.name]}
                  onChange={this.handleInputChange}
                  fullWidth
                  id={`${field.name.toLowerCase()}-field`}
                  multiLine
                  required={field.required}
                  validations={field.type}
                  validationError={field.error}
                />

            ))}

              <DatePicker hintText='Desired Completion Date' />

                  Upload Files
                  <input
                    id='upload'
                    name='upload[]'
                    type='file'
                    multiple
                    accept={fileExtensions}
                    onChange={this.handleFilePath}
                    ref={input => {
                      this.uploadInput = input
                    }}
                  />

                  <FormsyText
                    className='file-path validate'
                    value={fileValue}
                    multiLine
                    rows={1}
                    fullWidth
                    readOnly
                    name='upload-text-field'
                    id='file-path-field'
                    validations={{
                      myCustomIsFiveValidation: () => this.state.form.fileValid
                    }}
                    validationError='Error'
                  />

              {leftCheckboxes.map((label, index) => (
                <IconCheckbox
                  label={label.name}
                  name={label.name.toLowerCase()}
                  isChecked={this.state.form[label.name.toLowerCase()]}
                  key={index + label.name}
                  handleCheck={event => this.handleInputChange(event)}
                  style={styles.checkbox}
                  inputStyle={styles.inputStyle}
                  src={infoLogo}
                  alt='Info Button'
                  icon={label.icon ? label.icon : false}
                  dialogText={label.dialogText && label.dialogText}
                  dialogTitle={label.dialogTitle && label.dialogTitle}
                />
              ))}

              {rightCheckboxes.map((label, index) => (

                  <Checkbox
                    label={label.name}
                    name={label.name.toLowerCase()}
                    checked={this.state.form[label.name.toLowerCase()]}
                    onCheck={this.handleInputChange}
                    style={styles.checkbox}
                    inputStyle={styles.inputStyle}
                  />

              ))}

              <RaisedButton
                label='Submit'
                type='submit'
                id='submit-button'
                primary
                disabled={!this.state.canSubmit}
              />

                <FormsyCheckbox
                  name='planning-guide-check'
                  required
                  label={

                      I have read the{' '}
                      <Link
                        to='/planning-guide'
                        target='_blank'
                        style={{ fontWeight: 500 }}
                      >
                        Planning Guide
                      </Link>

                  }
                  style={styles.checkbox}
                  inputStyle={{ width: '35px' }}
                  onChange={this.enableSubmit}
                />

          </Formsy.Form>

        <Dialog title='Loading...' modal open={this.state.loadingDialogOpen}>
          Sending service request
        </Dialog>
        <Dialog
          title={this.state.resultDialogSuccess ? 'Done' : 'Error'}
          modal={false}
          open={this.state.resultDialogOpen}
          onRequestClose={this.handleDialogClose}
          actions={[
            <FlatButton
              label='Ok'
              onTouchTap={this.handleDialogClose}
              keyboardFocused
            />
          ]}
        >
          {this.state.resultDialogText}
        </Dialog>

    )
  }
}

export default ServiceRequest
<commit_msg>Fix path for production uploads<commit_after>// eslint-disable-next-line
/* global notifyFormError alert alertHi enableSubmit */
import React, { Component } from 'react'
import DatePicker from 'material-ui/DatePicker'
import Checkbox from 'material-ui/Checkbox'
import IconCheckbox from '../components/iconCheckbox'
import RaisedButton from '../components/MaterializeRaisedButton'
import Dialog from 'material-ui/Dialog'
import FlatButton from 'material-ui/FlatButton'
import { Link } from 'react-router-dom'
import { Helmet } from 'react-helmet'
import '../styles/inputFile.css'
import '../styles/serviceRequest.css'
import infoLogo from '../img/info.svg'

import Formsy from 'formsy-react'
import { FormsyText, FormsyCheckbox } from 'formsy-material-ui/lib'
import {
  singleLineFields,
  multiLineFields,
  leftCheckboxes,
  rightCheckboxes
} from '../data/serviceRequestFields'

const fileExtensions =
  'application/vnd.rar, application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation, audio/mp4, audio/mpeg, text/plain, application/zip, video/quicktime, video/avi, audio/wav, image/jpeg, application/octet-stream, image/png'

const PROTOCOL = process.env.PROTOCOL || 'http'
const HOSTNAME = process.env.HOST || 'localhost'
const PORT = process.env.UPLOADS_PORT || 9000
const HOST = process.env.UPLOADS_HOST || window.location.host.split(':')[0]
const UPLOAD_URL =
  process.env.NODE_ENV === 'production'
    ? `${PROTOCOL}://${HOSTNAME}`
    : `http://${HOST}:${PORT}/uploads`

const styles = {
  checkbox: {
    marginBottom: 16
  }
}

// https://github.com/Dogfalo/materialize/blob/master/js/forms.js#L192
class ServiceRequest extends Component {
  constructor (props) {
    super(props)
    const checkboxProps = [...leftCheckboxes, ...rightCheckboxes].reduce(
      (acc, label, index) => ({
        [this.formatLabelToProperty(label.name)]: false,
        ...acc
      }),
      {}
    )
    this.state = {
      form: {
        fileInput: null,
        fileValid: true
      },
      loadingDialogOpen: false,
      resultDialogOpen: false,
      resultDialogText: null,
      resultDialogSuccess: true,
      canSubmit: false
    }
    Object.assign(this.state.form, checkboxProps)
    this.handleInputChange = this.handleInputChange.bind(this)
  }

  enableSubmit = e => {
    if (e.target.checked) {
      this.setState({
        canSubmit: true
      })
    } else {
      this.setState({
        canSubmit: false
      })
    }
  }

  notifyFormError = () => {
    this.setState({
      resultDialogOpen: true,
      resultDialogSuccess: false,
      resultDialogText: 'Something went wrong. Check for errors and try again.'
    })
  }

  formatLabelToProperty = label =>
    label
      .split(' (')[0]
      .toLowerCase()
      .split(' ')
      .join('-')

  handleInputChange (event) {
    const target = event.target
    const value = target.type === 'checkbox' ? target.checked : target.value
    const name = target.name
    const form = Object.assign({}, this.state.form)
    form[name] = value

    this.setState({ form })
  }

  handleFilePath = event => {
    const target = event.target
    // Array.from converts array-like to array (so that map works)
    const files = Array.from(target.files)
    let fileNames = null
    const formState = this.state.form
    formState.fileValid = true
    this.setState({ formState })
    if (files.length > 0) {
      fileNames = files.map(f => f.name).join(', ')
      files.map(
        f =>
          fileExtensions.match(f.type) === null
            ? (formState.fileValid = false)
            : ''
      )
    }

    const form = Object.assign({}, this.state.form)
    form.fileInput = fileNames
    this.setState({ form })
  }

  handleFormData = async () => {
    const data = new FormData()
    for (const [key, val] of Object.entries(this.state.form)) {
      data.append(key, val)
    }

    for (const file of this.uploadInput.files) data.append('file', file)

    this.setState({ loadingDialogOpen: true })

    try {
      const response = await fetch(UPLOAD_URL, {
        method: 'post',
        body: data
      }).then(res => res.json())

      if (!response.success) throw response.status

      this.setState({
        resultDialogOpen: true,
        resultDialogSuccess: true,
        resultDialogText: 'Your service request was sent successfully.'
      })
    } catch (err) {
      const msg =
        typeof err === 'string'
          ? err
          : 'An error occurred while sending the request.'
      this.setState({
        resultDialogOpen: true,
        resultDialogSuccess: false,
        resultDialogText: msg
      })
    }

    this.setState({ loadingDialogOpen: false })
  }

  handleDialogClose = () => {
    this.setState({ resultDialogOpen: false })
  }

  render () {
    const fileValue = this.state.form.fileInput || 'Select a file to upload'

    return (

        <Helmet>
          <title>Service Request | Resource Center</title>
        </Helmet>

Please use this form to request services.

          <Formsy.Form
            onValidSubmit={this.handleFormData}
            onInvalidSubmit={this.notifyFormError}
          >
            {singleLineFields.map((field, index) => (

                <FormsyText
                  floatingLabelText={field.name}
                  name={field.name.toLowerCase()}
                  value={this.state.form[field.name]}
                  onChange={this.handleInputChange}
                  fullWidth
                  id={`${field.name.toLowerCase()}-field`}
                  required={field.required}
                  validations={field.type}
                  validationError={field.error}
                />

            ))}
            {multiLineFields.map((field, index) => (

                <FormsyText
                  floatingLabelText={field.name}
                  name={field.name.toLowerCase()}
                  value={this.state.form[field.name]}
                  onChange={this.handleInputChange}
                  fullWidth
                  id={`${field.name.toLowerCase()}-field`}
                  multiLine
                  required={field.required}
                  validations={field.type}
                  validationError={field.error}
                />

            ))}

              <DatePicker hintText='Desired Completion Date' />

                  Upload Files
                  <input
                    id='upload'
                    name='upload[]'
                    type='file'
                    multiple
                    accept={fileExtensions}
                    onChange={this.handleFilePath}
                    ref={input => {
                      this.uploadInput = input
                    }}
                  />

                  <FormsyText
                    className='file-path validate'
                    value={fileValue}
                    multiLine
                    rows={1}
                    fullWidth
                    readOnly
                    name='upload-text-field'
                    id='file-path-field'
                    validations={{
                      myCustomIsFiveValidation: () => this.state.form.fileValid
                    }}
                    validationError='Error'
                  />

              {leftCheckboxes.map((label, index) => (
                <IconCheckbox
                  label={label.name}
                  name={label.name.toLowerCase()}
                  isChecked={this.state.form[label.name.toLowerCase()]}
                  key={index + label.name}
                  handleCheck={event => this.handleInputChange(event)}
                  style={styles.checkbox}
                  inputStyle={styles.inputStyle}
                  src={infoLogo}
                  alt='Info Button'
                  icon={label.icon ? label.icon : false}
                  dialogText={label.dialogText && label.dialogText}
                  dialogTitle={label.dialogTitle && label.dialogTitle}
                />
              ))}

              {rightCheckboxes.map((label, index) => (

                  <Checkbox
                    label={label.name}
                    name={label.name.toLowerCase()}
                    checked={this.state.form[label.name.toLowerCase()]}
                    onCheck={this.handleInputChange}
                    style={styles.checkbox}
                    inputStyle={styles.inputStyle}
                  />

              ))}

              <RaisedButton
                label='Submit'
                type='submit'
                id='submit-button'
                primary
                disabled={!this.state.canSubmit}
              />

                <FormsyCheckbox
                  name='planning-guide-check'
                  required
                  label={

                      I have read the{' '}
                      <Link
                        to='/planning-guide'
                        target='_blank'
                        style={{ fontWeight: 500 }}
                      >
                        Planning Guide
                      </Link>

                  }
                  style={styles.checkbox}
                  inputStyle={{ width: '35px' }}
                  onChange={this.enableSubmit}
                />

          </Formsy.Form>

        <Dialog title='Loading...' modal open={this.state.loadingDialogOpen}>
          Sending service request
        </Dialog>
        <Dialog
          title={this.state.resultDialogSuccess ? 'Done' : 'Error'}
          modal={false}
          open={this.state.resultDialogOpen}
          onRequestClose={this.handleDialogClose}
          actions={[
            <FlatButton
              label='Ok'
              onTouchTap={this.handleDialogClose}
              keyboardFocused
            />
          ]}
        >
          {this.state.resultDialogText}
        </Dialog>

    )
  }
}

export default ServiceRequest
<|endoftext|>


<commit_before>import math.geom.Vec2D as Vec2D;

import ui.View as View;
import ui.ImageView as ImageView;
import ui.TextView as TextView;
import ui.ScoreView as ScoreView;
import animate;

import ..ViewPool;

exports = Class(ImageView, function (supr) {
	var invert = function(direction) {
		var ret,
			pos = {
				left: 'right',
				right: 'left'
			};

		if (direction !== '') {
			ret = pos[direction];
		}
		return ret;
	};

	this.init = function (opts) {
		opts.width = opts.tileSettings.tileWidth;
		opts.height = opts.tileSettings.tileHeight;

		supr(this, 'init', [opts]);

		this._adventureMapView = opts.adventureMapView;
		this._ongoing = false;

		this._itemView = null;

		this._tileX = 0;
		this._tileY = 0;

		this._editMode = opts.editMode;

		/*this._doodadView = new ImageView({
			superview: this
		});*/
		this._itemView = new ImageView({
			superview: this,
			zIndex: 1
		});

		this._idText = new ScoreView({
			superview: this._itemView,
			visible: false,
			blockEvents: true,
		});

		this._characterSettings = null;
		this._addItemEmitter = true;
		this._locSet = false;

		this._itemCtors = opts.nodeSettings.itemCtors;
		this._hideViews = {};

		this._tileSettings = opts.tileSettings;
		/*this._doodads = opts.tileSettings.doodads;*/
		this._nodes = opts.nodeSettings.nodes;

		this.canHandleEvents(false);
	};

	this.update = function (grid, tileX, tileY) {
		this._tileX = tileX;
		this._tileY = tileY;

		var tile = grid[tileY][tileX];
		if (tile && tile.node) {
			var node = this._nodes[tile.node - 1];
			var style = this._itemView.style;
			var x = this.style.width * tile.x;
			var y = this.style.height * tile.y;
			if(!this._locSet)
			{
				this.initial = [this.style.x, this.style.y];
				style.x = x - node.width * 0.5;
				style.y = y - node.height * 0.5;
				this.style.x = this.style.x + style.x;
				this.style.y = this.style.y + style.y;
				style.x = 0;
				style.y = 0;
				style.width = node.width;
				style.height = node.height;
				this._locSet = true;
			}

			style.visible = true;
			this._itemView.setImage(node.image);

			this._hideViews = {};
			var itemViews = tile.itemViews;
			if (!itemViews) {
				itemViews = {};
				tile.itemViews = itemViews;
			}

			var hideViews = this._hideViews;
			for (var tag in itemViews) {
				var itemView = itemViews[tag];
				if (itemView.style.visible) {
					hideViews[tag] = itemView;
				}
			}

			for (var tag in tile.tags) {
				if (this._itemCtors[tag]) {
					var itemView = this._adventureMapView._playerView;
					if (!itemView) {
						itemView = new this._itemCtors[tag]({
							superview: this.getSuperview(),
							adventureMapView: this._adventureMapView,
							zIndex: 999999999,
							tag: tag,
							tile: tile
						});
						this._adventureMapView._playerView = itemView;
					}
					else {
						itemView.updateOpts({
							tile: tile
						});
						itemView.removeAllListeners('InputSelect');
					}
					itemView.on('InputSelect', bind(this, 'onSelectTag', tag, tile, itemView));

					if (!('centerTag' in this._tileSettings) || this._tileSettings.centerTag) {
						itemView.style.x = this.style.x + (this.style.width * 0.15);
						itemView.style.y = this.style.y - (itemView.style.height * 0.3 + this.style.height);
					} else {
						itemView.style.x = this.style.x + (this.style.width * 0.15);
						itemView.style.y = this.style.y - (itemView.style.height * 0.3 + this.style.height);
					}
					itemView.update && itemView.update(tile);

					hideViews[tag] = null;
				}
			}

			for (var tag in hideViews) {
				if (hideViews[tag]) {
					hideViews[tag].style.visible = false;
				}
			}

			if (tile.id && node.characterSettings && !tile.tags.locked) {
				this._idText.updateOpts({
					x: node.characterSettings.x || 0,
					y: node.characterSettings.y || 0,
					width: node.width,
					height: node.characterSettings.height || node.height,
					visible: true
				});
				this._idText.setCharacterData(node.characterSettings.data);
				this._idText.setText(tile.id);
				if (node.characterSettings !== this._characterSettings) {
					this._characterSettings = node.characterSettings.data;
				}
				this._idText._container.style.x = -10;
				this._idText._container.style.y = (node.height - node.characterSettings.height) * 0.5-30;
			}

			if (this._addItemEmitter) {
				this._addItemEmitter = false;
				this._itemView.on('InputSelect', bind(this, 'onSelectNode', tile));
			}
		} else {
			this._itemView.style.visible = false;
		}

		/*if (tile && tile.doodad) {
			var doodad = this._doodads[tile.doodad - 1];
			if (doodad) {
				var style = this._doodadView.style;

				this._doodadView.setImage(doodad.image);
				style.x = tile.doodadX * this._tileSettings.tileWidth - doodad.width * 0.5;
				style.y = tile.doodadY * this._tileSettings.tileHeight - doodad.height * 0.5;
				style.width = doodad.width;
				style.height = doodad.height;
				style.visible = true;
			} else {
				this._doodadView.style.visible = false;
			}
		} else {
			this._doodadView.style.visible = false;
		}*/

		var friendsView = this._friendsView;
		if (tile && tile.friends.views) {
			var friends = tile.friends,
				views = friends.views,
				tileSettings = this._tileSettings,
				position = friends.position || invert(tile.position) || 'right',
				left = (position === 'left'),
				right = (position === 'right'),
				top = (position === 'top'),
				bottom = (position === 'bottom'),
				deltaX = (left ? -1 : (right ? 1 : 0)),
				deltaY = (top ? -1 : (bottom ? 1 : 0)),
				// with and height of the container
				friendsWidth =  (left || right ? friends.width : friends.height),
				friendsHeight = (left || right ? friends.height : friends.width),
				// position of the container if it is after the milestone icon
				// if position is right, then x position should come after the node, on left it should be 0, before the node
				// otherwise (top and bottom) it should take x value from tile settings.
				friendsRight = (right && isNaN(parseFloat(friends.x)) && node ? node.width : (left ? 0 : tileSettings.friendsX)),
				// if position is bottom, then y position should come after the node, on top it should be 0, before the node
				// otherwise (left and right) it should take y value from tile settings.
				friendsBottom = (bottom && isNaN(parseFloat(friends.y)) && node ? node.height : (top ? 0 : tileSettings.friendsY)),
				// position of the container if it is before the milestone icon
				friendsLeft = (left ? friendsWidth : 0),
				friendsTop = (top ? friendsHeight : 0),
				// x and y value for inner views
				x = (deltaX === -1 ? friendsWidth - tileSettings.friendWidth : 0),
				y = (deltaY === -1 ? friendsHeight - tileSettings.friendHeight : 0),
				padding = 25,
				len = views.length,
				view, i;

			if (!friendsView) {
				friendsView = this._friendsView = new View({
					superview: this.getSuperview()
				});
				friendsView.on('InputSelect', bind(this, 'onSelectFriends', views, deltaX, deltaY));
			}

			i = len;
			while (i > 0) {
				friendsView.addSubview(views[--i]);
			}

			i = len;
			while (i > 0) {
				view = views[--i];
				view.updateOpts({
					x: x,
					y: y,
					zIndex: i
				});
				x += (padding * deltaX);
				y += (padding * deltaY);
			}

			friendsView.updateOpts({
				x: this.style.x + friends.x * tileSettings.tileWidth - friendsLeft + friendsRight,
				y: this.style.y + friends.y * tileSettings.tileHeight - friendsTop + friendsBottom,
				r: friends.r,
				anchorX: (top || bottom ? friendsWidth / 2 : (left ? friendsWidth : 0)),
				anchorY: (left || right ? friendsHeight / 2 : (top ? friendsHeight : 0)),
				width: friendsWidth,
				height: friendsHeight,
				visible: true
			});
		} else if (friendsView) {
			friendsView.hide();
		}

		this.style.visible = tile.node;
	};

	this.onSelectTag = function (tag, tile, itemView) {
		this._adventureMapView.emit('ClickTag', tag, tile, itemView);
	};

	this.onSelectNode = function (tile) {
		this._adventureMapView.emit('ClickNode', tile);
	};

	this.onSelectFriends = function (views, deltaX, deltaY) {
		if(this._ongoing) {
			return;
		}

		var sub = this._friendsView.getSubviews(),
			len = sub.length,
			i = len,
			tileSettings = this._tileSettings,
			valueX, valueY, view, x, y;

		this._ongoing = true;

		while (i > 0) {
			valueX = tileSettings.friendWidth * deltaX * (len - i);
			valueY = tileSettings.friendHeight * deltaY * (len - i);
			view = views[--i];
			x = view.style.x;
			y = view.style.y;

			animate(view, 'friends')
				.then({x: x + valueX, y: y + valueY})
				.then({}, 1000)
				.then({x: x, y: y})
				.then(bind(this, function() {
					this._ongoing = false;
				}));
		}
	};

	this.refreshLoc = function() {
		this.style.x = this.initial[0];
		this.style.y = this.initial[1];
		this._locSet = false;
	};

	this.onRelease = function () {
		this._addItemEmitter = true;
		this._idText.hide();
		this.refreshLoc();
		this._itemView.removeAllListeners('InputSelect');
	}
});
<commit_msg>fix for proper touch area<commit_after>import math.geom.Vec2D as Vec2D;

import ui.View as View;
import ui.ImageView as ImageView;
import ui.TextView as TextView;
import ui.ScoreView as ScoreView;
import animate;

import ..ViewPool;

exports = Class(ImageView, function (supr) {
	var invert = function(direction) {
		var ret,
			pos = {
				left: 'right',
				right: 'left'
			};

		if (direction !== '') {
			ret = pos[direction];
		}
		return ret;
	};

	this.init = function (opts) {
		opts.width = opts.tileSettings.tileWidth;
		opts.height = opts.tileSettings.tileHeight;

		supr(this, 'init', [opts]);

		this._adventureMapView = opts.adventureMapView;
		this._ongoing = false;

		this._itemView = null;

		this._tileX = 0;
		this._tileY = 0;

		this._editMode = opts.editMode;

		/*this._doodadView = new ImageView({
			superview: this
		});*/
		this._itemView = new ImageView({
			superview: this,
			zIndex: 1
		});

		this._idText = new ScoreView({
			superview: this._itemView,
			visible: false,
			blockEvents: true,
		});

		this._characterSettings = null;
		this._addItemEmitter = true;
		this._locSet = false;

		this._itemCtors = opts.nodeSettings.itemCtors;
		this._hideViews = {};

		this._tileSettings = opts.tileSettings;
		/*this._doodads = opts.tileSettings.doodads;*/
		this._nodes = opts.nodeSettings.nodes;

		this.canHandleEvents(false);
	};

	this.update = function (grid, tileX, tileY) {
		this._tileX = tileX;
		this._tileY = tileY;

		var tile = grid[tileY][tileX];
		if (tile && tile.node) {
			var node = this._nodes[tile.node - 1];
			var style = this._itemView.style;
			var x = this.style.width * tile.x;
		        var y = this.style.height * tile.y;

                        this.updateOpts({
                                width: node.width,
                                height: node.height
                        });
			if(!this._locSet)
			{
				this.initial = [this.style.x, this.style.y];
				style.x = x - node.width * 0.5;
				style.y = y - node.height * 0.5;
				this.style.x = this.style.x + style.x;
				this.style.y = this.style.y + style.y;
				style.x = 0;
			        style.y = 0;
			        style.width = node.width;
                          	style.height = node.height;
				this._locSet = true;
			}

			style.visible = true;
			this._itemView.setImage(node.image);

			this._hideViews = {};
			var itemViews = tile.itemViews;
			if (!itemViews) {
				itemViews = {};
				tile.itemViews = itemViews;
			}

			var hideViews = this._hideViews;
			for (var tag in itemViews) {
				var itemView = itemViews[tag];
				if (itemView.style.visible) {
					hideViews[tag] = itemView;
				}
			}

			for (var tag in tile.tags) {
				if (this._itemCtors[tag]) {
					var itemView = this._adventureMapView._playerView;
					if (!itemView) {
						itemView = new this._itemCtors[tag]({
							superview: this.getSuperview(),
							adventureMapView: this._adventureMapView,
							zIndex: 999999999,
							tag: tag,
							tile: tile
						});
						this._adventureMapView._playerView = itemView;
					}
					else {
						itemView.updateOpts({
							tile: tile
						});
						itemView.removeAllListeners('InputSelect');
					}
					itemView.on('InputSelect', bind(this, 'onSelectTag', tag, tile, itemView));

					if (!('centerTag' in this._tileSettings) || this._tileSettings.centerTag) {
						itemView.style.x = this.style.x + (this.style.width * 0.15);
						itemView.style.y = this.style.y - (itemView.style.height * 0.3 + this.style.height);
					} else {
						itemView.style.x = this.style.x + (this.style.width * 0.15);
						itemView.style.y = this.style.y - (itemView.style.height * 0.3 + this.style.height);
					}
					itemView.update && itemView.update(tile);

					hideViews[tag] = null;
				}
			}

			for (var tag in hideViews) {
				if (hideViews[tag]) {
					hideViews[tag].style.visible = false;
				}
			}

			if (tile.id && node.characterSettings && !tile.tags.locked) {
				this._idText.updateOpts({
					x: node.characterSettings.x || 0,
					y: node.characterSettings.y || 0,
					width: node.width,
					height: node.characterSettings.height || node.height,
					visible: true
				});
				this._idText.setCharacterData(node.characterSettings.data);
				this._idText.setText(tile.id);
				if (node.characterSettings !== this._characterSettings) {
					this._characterSettings = node.characterSettings.data;
				}
				this._idText._container.style.x = -10;
				this._idText._container.style.y = (node.height - node.characterSettings.height) * 0.5-30;
			}

			if (this._addItemEmitter) {
				this._addItemEmitter = false;
				this._itemView.on('InputSelect', bind(this, 'onSelectNode', tile));
			}
		} else {
			this._itemView.style.visible = false;
		}

		/*if (tile && tile.doodad) {
			var doodad = this._doodads[tile.doodad - 1];
			if (doodad) {
				var style = this._doodadView.style;

				this._doodadView.setImage(doodad.image);
				style.x = tile.doodadX * this._tileSettings.tileWidth - doodad.width * 0.5;
				style.y = tile.doodadY * this._tileSettings.tileHeight - doodad.height * 0.5;
				style.width = doodad.width;
				style.height = doodad.height;
				style.visible = true;
			} else {
				this._doodadView.style.visible = false;
			}
		} else {
			this._doodadView.style.visible = false;
		}*/

		var friendsView = this._friendsView;
		if (tile && tile.friends.views) {
			var friends = tile.friends,
				views = friends.views,
				tileSettings = this._tileSettings,
				position = friends.position || invert(tile.position) || 'right',
				left = (position === 'left'),
				right = (position === 'right'),
				top = (position === 'top'),
				bottom = (position === 'bottom'),
				deltaX = (left ? -1 : (right ? 1 : 0)),
				deltaY = (top ? -1 : (bottom ? 1 : 0)),
				// with and height of the container
				friendsWidth =  (left || right ? friends.width : friends.height),
				friendsHeight = (left || right ? friends.height : friends.width),
				// position of the container if it is after the milestone icon
				// if position is right, then x position should come after the node, on left it should be 0, before the node
				// otherwise (top and bottom) it should take x value from tile settings.
				friendsRight = (right && isNaN(parseFloat(friends.x)) && node ? node.width : (left ? 0 : tileSettings.friendsX)),
				// if position is bottom, then y position should come after the node, on top it should be 0, before the node
				// otherwise (left and right) it should take y value from tile settings.
				friendsBottom = (bottom && isNaN(parseFloat(friends.y)) && node ? node.height : (top ? 0 : tileSettings.friendsY)),
				// position of the container if it is before the milestone icon
				friendsLeft = (left ? friendsWidth : 0),
				friendsTop = (top ? friendsHeight : 0),
				// x and y value for inner views
				x = (deltaX === -1 ? friendsWidth - tileSettings.friendWidth : 0),
				y = (deltaY === -1 ? friendsHeight - tileSettings.friendHeight : 0),
				padding = 25,
				len = views.length,
				view, i;

			if (!friendsView) {
				friendsView = this._friendsView = new View({
					superview: this.getSuperview()
				});
				friendsView.on('InputSelect', bind(this, 'onSelectFriends', views, deltaX, deltaY));
			}

			i = len;
			while (i > 0) {
				friendsView.addSubview(views[--i]);
			}

			i = len;
			while (i > 0) {
				view = views[--i];
				view.updateOpts({
					x: x,
					y: y,
					zIndex: i
				});
				x += (padding * deltaX);
				y += (padding * deltaY);
			}

			friendsView.updateOpts({
				x: this.style.x + friends.x * tileSettings.tileWidth - friendsLeft + friendsRight,
				y: this.style.y + friends.y * tileSettings.tileHeight - friendsTop + friendsBottom,
				r: friends.r,
				anchorX: (top || bottom ? friendsWidth / 2 : (left ? friendsWidth : 0)),
				anchorY: (left || right ? friendsHeight / 2 : (top ? friendsHeight : 0)),
				width: friendsWidth,
				height: friendsHeight,
				visible: true
			});
		} else if (friendsView) {
			friendsView.hide();
		}

		this.style.visible = tile.node;
	};

	this.onSelectTag = function (tag, tile, itemView) {
		this._adventureMapView.emit('ClickTag', tag, tile, itemView);
	};

	this.onSelectNode = function (tile) {
		this._adventureMapView.emit('ClickNode', tile);
	};

	this.onSelectFriends = function (views, deltaX, deltaY) {
		if(this._ongoing) {
			return;
		}

		var sub = this._friendsView.getSubviews(),
			len = sub.length,
			i = len,
			tileSettings = this._tileSettings,
			valueX, valueY, view, x, y;

		this._ongoing = true;

		while (i > 0) {
			valueX = tileSettings.friendWidth * deltaX * (len - i);
			valueY = tileSettings.friendHeight * deltaY * (len - i);
			view = views[--i];
			x = view.style.x;
			y = view.style.y;

			animate(view, 'friends')
				.then({x: x + valueX, y: y + valueY})
				.then({}, 1000)
				.then({x: x, y: y})
				.then(bind(this, function() {
					this._ongoing = false;
				}));
		}
	};

	this.refreshLoc = function() {
		this.style.x = this.initial[0];
		this.style.y = this.initial[1];
		this._locSet = false;
	};

	this.onRelease = function () {
		this._addItemEmitter = true;
		this._idText.hide();
		this.refreshLoc();
		this._itemView.removeAllListeners('InputSelect');
	}
});
<|endoftext|>


<commit_before>import '@testing-library/cypress/add-commands';
import 'cypress-axe';
import 'cypress-plugin-tab';
import 'cypress-real-events/support';
import '@cypress/code-coverage/support';
import addContext from 'mochawesome/addContext';
import './commands';

Cypress.on('window:before:load', window => {
  // Workaround to allow Cypress to intercept requests made with the Fetch API.
  // This forces fetch to fall back to the polyfill, which can get intercepted.
  // https://github.com/cypress-io/cypress/issues/95
  delete window.fetch; // eslint-disable-line no-param-reassign

  // Hide Foresee overlay.
  const style = document.createElement('style');
  style.type = 'text/css';
  style.innerHTML = '.__acs { display: none !important; }';
  document.head.appendChild(style);
});

// Hack to allow the type command to accept and simulate an input with 0 delay.
// The default command ignores delays under 10 (seconds).
// https://github.com/cypress-io/cypress/issues/566#issuecomment-577763747
Cypress.Commands.overwrite('type', (originalFn, element, text, options) => {
  if (options?.delay === 0) {
    element.val(text);
    // Type and delete a character to trigger change events.
    // Use 0 because it's expected to pass most validations.
    return originalFn(element, '0{backspace}', options);
  }

  return originalFn(element, text, options);
});

Cypress.on('uncaught:exception', () => {
  return false;
});

// Default responses for common endpoints called by most apps.
// Stubbing these will save a few seconds of loading time in tests.
beforeEach(() => {
  cy.intercept('GET', '/v0/maintenance_windows', {
    data: [],
  });
});

// Assign the video path to the context property for failed tests
Cypress.on('test:after:run', test => {
  if (test.state === 'failed') {
    let videoName = Cypress.spec.name;
    videoName = videoName.replace('/.js.*', '.js');
    const videoPath = `${Cypress.config('videosFolder')}/${videoName}.mp4`;
    addContext(
      { test },
      {
        title: 'context',
        value: {
          video: videoPath,
          retries: test.currentRetry,
          testPath: Cypress.spec.relative,
          testTitle: test.title,
        },
      },
    );
  } else {
    addContext(
      { test },
      {
        title: 'context',
        value: {
          retries: test.currentRetry,
          testPath: Cypress.spec.relative,
          testTitle: test.title,
        },
      },
    );
  }
});
<commit_msg>Remove typing delay in Cypress tests (#20930)<commit_after>import '@testing-library/cypress/add-commands';
import 'cypress-axe';
import 'cypress-plugin-tab';
import 'cypress-real-events/support';
import '@cypress/code-coverage/support';
import addContext from 'mochawesome/addContext';
import './commands';

Cypress.on('window:before:load', window => {
  // Workaround to allow Cypress to intercept requests made with the Fetch API.
  // This forces fetch to fall back to the polyfill, which can get intercepted.
  // https://github.com/cypress-io/cypress/issues/95
  delete window.fetch; // eslint-disable-line no-param-reassign

  // Hide Foresee overlay.
  const style = document.createElement('style');
  style.type = 'text/css';
  style.innerHTML = '.__acs { display: none !important; }';
  document.head.appendChild(style);
});

// Hack to allow the type command to accept and simulate an input with 0 delay.
// The default command ignores delays under 10 (seconds).
// https://github.com/cypress-io/cypress/issues/566#issuecomment-577763747
Cypress.Commands.overwrite('type', (originalFn, element, text, options) => {
  if (options?.delay === 0) {
    element.val(text);
    // Type and delete a character to trigger change events.
    // Use 0 because it's expected to pass most validations.
    return originalFn(element, '0{backspace}', options);
  }
  let newOptions;
  if (options?.delay) {
    newOptions = options;
  } else {
    // This removes the default 10 ms delay in cy.type().
    newOptions = { ...options, delay: 0 };
  }
  return originalFn(element, text, newOptions);
});

// This removes the default 10 ms delay in cy.clear().
Cypress.Commands.overwrite('clear', (originalFn, element) => {
  return originalFn(element, { delay: 0 });
});

Cypress.on('uncaught:exception', () => {
  return false;
});

// Default responses for common endpoints called by most apps.
// Stubbing these will save a few seconds of loading time in tests.
beforeEach(() => {
  cy.intercept('GET', '/v0/maintenance_windows', {
    data: [],
  });
});

// Assign the video path to the context property for failed tests
Cypress.on('test:after:run', test => {
  if (test.state === 'failed') {
    let videoName = Cypress.spec.name;
    videoName = videoName.replace('/.js.*', '.js');
    const videoPath = `${Cypress.config('videosFolder')}/${videoName}.mp4`;
    addContext(
      { test },
      {
        title: 'context',
        value: {
          video: videoPath,
          retries: test.currentRetry,
          testPath: Cypress.spec.relative,
          testTitle: test.title,
        },
      },
    );
  } else {
    addContext(
      { test },
      {
        title: 'context',
        value: {
          retries: test.currentRetry,
          testPath: Cypress.spec.relative,
          testTitle: test.title,
        },
      },
    );
  }
});
<|endoftext|>


<commit_before>'use strict';

/**
 * @module static-bootstrap
 */
var path = require('path');
var bootstrapDefault = 'bootstrap.html';

/**
 * @param {String} staticRoot
 * @param {String} bootstrapFile
 * @param {String} jsonParam
 */
module.exports = function (staticRoot, bootstrapFile, jsonParam) {

	/**
	 * @param {ExpressServerRequest} req
	 * @param {ExpressServerResponse} res
	 * @param {Function} next
	 */
	return function (req, res, next) {
		if (req.query && req.query[jsonParam || 'json']) {
			next(null);
		} else {
			res.sendfile(path.join(staticRoot, bootstrapFile || bootstrapDefault), next);
		}
	};
};<commit_msg>Json query param could be empty<commit_after>'use strict';

/**
 * @module static-bootstrap
 */
var path = require('path');
var bootstrapDefault = 'bootstrap.html';

/**
 * @param {String} staticRoot
 * @param {String} bootstrapFile
 * @param {String} jsonParam
 */
module.exports = function (staticRoot, bootstrapFile, jsonParam) {

	/**
	 * @param {ExpressServerRequest} req
	 * @param {ExpressServerResponse} res
	 * @param {Function} next
	 */
	return function (req, res, next) {
		if (req.query && req.query[jsonParam || 'json'] !== undefined) {
			next(null);
		} else {
			res.sendfile(path.join(staticRoot, bootstrapFile || bootstrapDefault), next);
		}
	};
};<|endoftext|>


<commit_before>/**
* Generated by PluginGenerator from webgme on Mon Apr 07 2014 15:59:37 GMT-0500 (Central Daylight Time)
 * Run this with activeNode "/1023960100"
*/

define(['plugin/PluginConfig', 'plugin/PluginBase'], function (PluginConfig, PluginBase) {
    'use strict';

    /**
    * Initializes a new instance of CoreExamples.
    * @class
    * @augments {PluginBase}
    * @classdesc This class represents the plugin CoreExamples.
    * @constructor
    */
    var CoreExamples = function () {
        // Call base class' constructor.
        PluginBase.call(this);
    };

    // Prototypal inheritance from PluginBase.
    CoreExamples.prototype = Object.create(PluginBase.prototype);
    CoreExamples.prototype.constructor = CoreExamples;

    /**
    * Gets the name of the CoreExamples.
    * @returns {string} The name of the plugin.
    * @public
    */
    CoreExamples.prototype.getName = function () {
        return "Core Examples";
    };

    /**
    * Gets the description of the CoreExamples.
    * @returns {string} The description of the plugin.
    * @public
    */
    CoreExamples.prototype.getDescription = function () {
        return "Description for Core Examples";
    };

    /**
    * Gets the semantic version (semver.org) of the CoreExamples.
    * @returns {string} The version of the plugin.
    * @public
    */
    CoreExamples.prototype.getVersion = function () {
        return "0.1.0";
    };

    /**
    * Main function for the plugin to execute. This will perform the execution.
    * Notes:
    * - Always log with the provided logger.[error,warning,info,debug].
    * - Do NOT put any user interaction logic UI, etc. inside this method.
    * - callback always have to be called even if error happened.
    *
    * @param {function(string, plugin.PluginResult)} callback - the result callback
    */
    CoreExamples.prototype.main = function (callback) {
        // Use self to access core, project, result, logger etc from PluginBase.
        // These are all instantiated at this point.
        var self = this;

        if (self.core.getPath(self.activeNode) !== '/1023960100') {
            self.logger.error('Run this interpreter on "/1023960100" (models in the root) as activeNode.');
            self.logger.error('Current activeNode was : ' + self.core.getPath(self.activeNode));
            self.result.setSuccess(false);
            callback('Run this interpreter on "/1023960100" as activeNode.', self.result);
            return;
        }

        self.core.loadChildren(self.activeNode, function (err, children) {
            var i,
                runningExamples = children.length;

            if (runningExamples === 0) {
                self.result.setSuccess(false);
                callback('The active node does not have any children. Are you using the right model?', self.result);
                return;
            }

            for (i = 0; i < children.length; i += 1) {
                (function (element) {
                    // function is needed to get a reference for each element in the array
                    self.core.loadChildren(element, function (err1, children1) {
                        var name = self.core.getAttribute(element, 'name');
                        self.logger.debug(name);
                        if (name === 'ConnectionExample') {
                            self.connectionExample(self, children1, function (err) {
                                runningExamples -= 1;
                                if (runningExamples === 0) {
                                    self.result.setSuccess(true);
                                    callback(err, self.result);
                                }
                            });
                        } else if (name === 'ReferenceExample') {
                            self.logger.debug('ReferenceExample to be done...');
                            runningExamples -= 1;
                            if (runningExamples === 0) {
                                self.result.setSuccess(true);
                                callback(err, self.result);
                            }
                        } else if (name === 'ParentExample') {
                            self.logger.debug('ParentExample to be done...');
                            runningExamples -= 1;
                            if (runningExamples === 0) {
                                self.result.setSuccess(true);
                                callback(err, self.result);
                            }
                        } else {
                            self.logger.debug('Found unexpected child, ' + name + ', inside Models.');
                            runningExamples -= 1;
                            if (runningExamples === 0) {
                                self.result.setSuccess(true);
                                callback(err, self.result);
                            }
                        }
                    });
                })(children[i]);
            }
        });
    };

    CoreExamples.prototype.connectionExample = function (self, children, callback) {
        var i,
            childrenVisits = children.length,
            err = '';

        for (i = 0; i < children.length; i += 1) {
            (function (childNode) {
                if (self.isMetaTypeOf(self, childNode, self.META['PortElement'])) {

                    self.visitPorts(self, childNode, function (err) {
                        err += err;
                        childrenVisits -= 1;
                        if (childrenVisits === 0) {
                            callback(err);
                        }
                    });
                } else {
                    childrenVisits -= 1;
                    if (childrenVisits === 0) {
                        callback(err);
                    }
                }
            })(children[i]);
        }
        //callback(null, self.result);
    };

    CoreExamples.prototype.visitPorts = function (self, portNode, callback) {
        var j,
            collectionNames = self.core.getCollectionNames(portNode),
            err = '';

        if (collectionNames.indexOf('src') === -1) {
            callback(err);
        } else {
            self.core.loadCollection(portNode, 'src', function (err, connections) {
                var connectionVisits = connections.length;
                for (j = 0; j < connections.length; j += 1) {
                    (function (connection) {
                        if (self.core.hasPointer(connection, 'dst') === false) {
                            // TODO: This error does not seem to happen.
                            err += ' connection with src but without dst exists in model!';
                            connectionVisits -= 1;
                            if (connectionVisits === 0) {
                                callback(err);
                            }
                        } else {
                            self.core.loadPointer(connection, 'dst', function (err, dst) {
                                var srcName = self.core.getAttribute(portNode, 'name'),
                                    dstName = self.core.getAttribute(dst, 'name'),
                                    connName = self.core.getAttribute(connection, 'name');
                                self.logger.info(connName + ' connects "' + srcName + '" and "' + dstName + '".');
                                connectionVisits -= 1;
                                if (connectionVisits === 0) {
                                    callback(err);
                                }
                            });
                        }
                    })(connections[j]);
                }
            });
        }
    };

    CoreExamples.prototype.isMetaTypeOf = function (self, nodeObj, metaTypeObj) {
        while (nodeObj) {
            if (self.core.getGuid(nodeObj) === self.core.getGuid(metaTypeObj)) {
                return true;
            }
            nodeObj = self.core.getBase(nodeObj);
        }
        return false;
    };

    return CoreExamples;
});<commit_msg>GH-4 parentExample implemented.<commit_after>/**
* Generated by PluginGenerator from webgme on Mon Apr 07 2014 15:59:37 GMT-0500 (Central Daylight Time)
 * Run this with activeNode "/1023960100"
*/

define(['plugin/PluginConfig', 'plugin/PluginBase'], function (PluginConfig, PluginBase) {
    'use strict';

    /**
    * Initializes a new instance of CoreExamples.
    * @class
    * @augments {PluginBase}
    * @classdesc This class represents the plugin CoreExamples.
    * @constructor
    */
    var CoreExamples = function () {
        // Call base class' constructor.
        PluginBase.call(this);
    };

    // Prototypal inheritance from PluginBase.
    CoreExamples.prototype = Object.create(PluginBase.prototype);
    CoreExamples.prototype.constructor = CoreExamples;

    /**
    * Gets the name of the CoreExamples.
    * @returns {string} The name of the plugin.
    * @public
    */
    CoreExamples.prototype.getName = function () {
        return "Core Examples";
    };

    /**
    * Gets the description of the CoreExamples.
    * @returns {string} The description of the plugin.
    * @public
    */
    CoreExamples.prototype.getDescription = function () {
        return "Description for Core Examples";
    };

    /**
    * Gets the semantic version (semver.org) of the CoreExamples.
    * @returns {string} The version of the plugin.
    * @public
    */
    CoreExamples.prototype.getVersion = function () {
        return "0.1.0";
    };

    /**
    * Main function for the plugin to execute. This will perform the execution.
    * Notes:
    * - Always log with the provided logger.[error,warning,info,debug].
    * - Do NOT put any user interaction logic UI, etc. inside this method.
    * - callback always have to be called even if error happened.
    *
    * @param {function(string, plugin.PluginResult)} callback - the result callback
    */
    CoreExamples.prototype.main = function (callback) {
        // Use self to access core, project, result, logger etc from PluginBase.
        // These are all instantiated at this point.
        var self = this;

        if (self.core.getPath(self.activeNode) !== '/1023960100') {
            self.logger.error('Run this interpreter on "/1023960100" (models in the root) as activeNode.');
            self.logger.error('Current activeNode was : ' + self.core.getPath(self.activeNode));
            self.result.setSuccess(false);
            callback('Run this interpreter on "/1023960100" as activeNode.', self.result);
            return;
        }

        self.core.loadChildren(self.activeNode, function (err, children) {
            var i,
                runningExamples = children.length;

            if (runningExamples === 0) {
                self.result.setSuccess(false);
                callback('The active node does not have any children. Are you using the right model?', self.result);
                return;
            }

            for (i = 0; i < children.length; i += 1) {
                // function is needed to save the reference to the specific element i child.
                (function (element) {
                    self.core.loadChildren(element, function (err1, children1) {
                        var name = self.core.getAttribute(element, 'name');
                        self.logger.info('Starting work on ' + name + '...');
                        if (name === 'ConnectionExample') {
                            self.connectionExample(self, children1, function (err) {
                                self.logger.info('Done with ' + name + '!');
                                runningExamples -= 1;
                                if (runningExamples === 0) {
                                    self.result.setSuccess(true);
                                    callback(err, self.result);
                                }
                            });
                        } else if (name === 'ReferenceExample') {
                            self.logger.debug('ReferenceExample to be done...');
                            runningExamples -= 1;
                            if (runningExamples === 0) {
                                self.result.setSuccess(true);
                                callback(err, self.result);
                            }
                        } else if (name === 'ParentExample') {
                            self.parentExample(self, children1, function (err) {
                                self.logger.info('Done with ' + name + '!');
                                runningExamples -= 1;
                                if (runningExamples === 0) {
                                    self.result.setSuccess(true);
                                    callback(err, self.result);
                                }
                            });
                        } else {
                            self.logger.debug('Found unexpected child, ' + name + ', inside Models.');
                            runningExamples -= 1;
                            if (runningExamples === 0) {
                                self.result.setSuccess(true);
                                callback(err, self.result);
                            }
                        }
                    });
                })(children[i]);
            }
        });
    };

// --------------------------------- Parent Example -------------------------------------
    CoreExamples.prototype.parentExample = function (self, children, callback) {
        var i,
            childrenVisits = children.length,
            err;

        if (childrenVisits === 0) {
            callback('The starting node in ParentExample did not have any children!?');
        }

        for (i = 0; i < children.length; i += 1) {
            (function (childNode) {
                var name = self.core.getAttribute(childNode, 'name');
                if (name === 'm_parent') {
                    self.compareParentAndChildsParent(self, childNode, function (err) {
                        childrenVisits -= 1;
                        if (childrenVisits === 0) {
                            callback(err);
                        }
                    });
                } else {
                    childrenVisits -= 1;
                    if (childrenVisits === 0) {
                        callback(err);
                    }
                }
            })(children[i]);
        }
    };

    CoreExamples.prototype.compareParentAndChildsParent = function (self, parentNode, callback) {
        self.core.loadChildren(parentNode, function (err, children) {
            var returnedParent,
                guid1, guid2,
                error = '';
            if (children.length === 0) {
                callback('m_parent did not have any children!?');
            } else {
                returnedParent = self.core.getParent(children[0]);
                guid1 = self.core.getGuid(parentNode);
                guid2 = self.core.getGuid(returnedParent);
                if (guid1 === guid2) {
                    self.logger.info("Parent och its child's parent had the same GUID (as expected).");
                } else {
                    error += "Parent och its child's parent had the same GUID (very weird indeed).";
                }
                callback(error);
            }
        });
    };

// --------------------------------- Connection Example ---------------------------------
    CoreExamples.prototype.connectionExample = function (self, children, callback) {
        var i,
            childrenVisits = children.length,
            err = '';

        if (childrenVisits === 0) {
            callback('The starting node in ConnectionExample did not have any children!?');
        }
        for (i = 0; i < children.length; i += 1) {
            (function (childNode) {
                if (self.isMetaTypeOf(self, childNode, self.META['PortElement'])) {

                    self.visitPorts(self, childNode, function (err) {
                        err += err;
                        childrenVisits -= 1;
                        if (childrenVisits === 0) {
                            callback(err);
                        }
                    });
                } else {
                    childrenVisits -= 1;
                    if (childrenVisits === 0) {
                        callback(err);
                    }
                }
            })(children[i]);
        }
    };

    CoreExamples.prototype.visitPorts = function (self, portNode, callback) {
        var j,
            collectionNames = self.core.getCollectionNames(portNode),
            err = '';

        if (collectionNames.indexOf('src') === -1) {
            callback(err);
        } else {
            self.core.loadCollection(portNode, 'src', function (err, connections) {
                var connectionVisits = connections.length;
                for (j = 0; j < connections.length; j += 1) {
                    (function (connection) {
                        if (self.core.hasPointer(connection, 'dst') === false) {
                            // TODO: This error does not seem to happen.
                            err += ' connection with src but without dst exists in model!';
                            connectionVisits -= 1;
                            if (connectionVisits === 0) {
                                callback(err);
                            }
                        } else {
                            self.core.loadPointer(connection, 'dst', function (err, dst) {
                                var srcName = self.core.getAttribute(portNode, 'name'),
                                    dstName = self.core.getAttribute(dst, 'name'),
                                    connName = self.core.getAttribute(connection, 'name');
                                self.logger.info(connName + ' connects "' + srcName + '" and "' + dstName + '".');
                                connectionVisits -= 1;
                                if (connectionVisits === 0) {
                                    callback(err);
                                }
                            });
                        }
                    })(connections[j]);
                }
            });
        }
    };

    CoreExamples.prototype.isMetaTypeOf = function (self, nodeObj, metaTypeObj) {
        while (nodeObj) {
            if (self.core.getGuid(nodeObj) === self.core.getGuid(metaTypeObj)) {
                return true;
            }
            nodeObj = self.core.getBase(nodeObj);
        }
        return false;
    };

    return CoreExamples;
});<|endoftext|>


<commit_before>/*!
 * lunr.stopWordFilter
 * Copyright (C) @YEAR Oliver Nightingale
 */

/**
 * lunr.stopWordFilter is an English language stop word list filter, any words
 * contained in the list will not be passed through the filter.
 *
 * This is intended to be used in the Pipeline. If the token does not pass the
 * filter then undefined will be returned.
 *
 * @module
 * @param {String} token The token to pass through the filter
 * @returns {String}
 * @see lunr.Pipeline
 */
lunr.stopWordFilter = function (token) {
  if (lunr.stopWordFilter.stopWords.indexOf(token) === -1) return token
}

lunr.stopWordFilter.stopWords = new lunr.SortedSet
lunr.stopWordFilter.stopWords.length = 119
lunr.stopWordFilter.stopWords.elements = [
  "",
  "a",
  "able",
  "about",
  "across",
  "after",
  "all",
  "almost",
  "also",
  "am",
  "among",
  "an",
  "and",
  "any",
  "are",
  "as",
  "at",
  "be",
  "because",
  "been",
  "but",
  "by",
  "can",
  "cannot",
  "could",
  "dear",
  "did",
  "do",
  "does",
  "either",
  "else",
  "ever",
  "every",
  "for",
  "from",
  "get",
  "got",
  "had",
  "has",
  "have",
  "he",
  "her",
  "hers",
  "him",
  "his",
  "how",
  "however",
  "i",
  "if",
  "in",
  "into",
  "is",
  "it",
  "its",
  "just",
  "least",
  "let",
  "like",
  "likely",
  "may",
  "me",
  "might",
  "most",
  "must",
  "my",
  "neither",
  "no",
  "nor",
  "not",
  "of",
  "off",
  "often",
  "on",
  "only",
  "or",
  "other",
  "our",
  "own",
  "rather",
  "said",
  "say",
  "says",
  "she",
  "should",
  "since",
  "so",
  "some",
  "than",
  "that",
  "the",
  "their",
  "them",
  "then",
  "there",
  "these",
  "they",
  "this",
  "tis",
  "to",
  "too",
  "twas",
  "us",
  "wants",
  "was",
  "we",
  "were",
  "what",
  "when",
  "where",
  "which",
  "while",
  "who",
  "whom",
  "why",
  "will",
  "with",
  "would",
  "yet",
  "you",
  "your"
]

lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter')
<commit_msg>remove us from stopwords<commit_after>/*!
 * lunr.stopWordFilter
 * Copyright (C) @YEAR Oliver Nightingale
 */

/**
 * lunr.stopWordFilter is an English language stop word list filter, any words
 * contained in the list will not be passed through the filter.
 *
 * This is intended to be used in the Pipeline. If the token does not pass the
 * filter then undefined will be returned.
 *
 * @module
 * @param {String} token The token to pass through the filter
 * @returns {String}
 * @see lunr.Pipeline
 */
lunr.stopWordFilter = function (token) {
  if (lunr.stopWordFilter.stopWords.indexOf(token) === -1) return token
}

lunr.stopWordFilter.stopWords = new lunr.SortedSet
lunr.stopWordFilter.stopWords.length = 119
lunr.stopWordFilter.stopWords.elements = [
  "",
  "a",
  "able",
  "about",
  "across",
  "after",
  "all",
  "almost",
  "also",
  "am",
  "among",
  "an",
  "and",
  "any",
  "are",
  "as",
  "at",
  "be",
  "because",
  "been",
  "but",
  "by",
  "can",
  "cannot",
  "could",
  "dear",
  "did",
  "do",
  "does",
  "either",
  "else",
  "ever",
  "every",
  "for",
  "from",
  "get",
  "got",
  "had",
  "has",
  "have",
  "he",
  "her",
  "hers",
  "him",
  "his",
  "how",
  "however",
  "i",
  "if",
  "in",
  "into",
  "is",
  "it",
  "its",
  "just",
  "least",
  "let",
  "like",
  "likely",
  "may",
  "me",
  "might",
  "most",
  "must",
  "my",
  "neither",
  "no",
  "nor",
  "not",
  "of",
  "off",
  "often",
  "on",
  "only",
  "or",
  "other",
  "our",
  "own",
  "rather",
  "said",
  "say",
  "says",
  "she",
  "should",
  "since",
  "so",
  "some",
  "than",
  "that",
  "the",
  "their",
  "them",
  "then",
  "there",
  "these",
  "they",
  "this",
  "tis",
  "to",
  "too",
  "twas",
  "wants",
  "was",
  "we",
  "were",
  "what",
  "when",
  "where",
  "which",
  "while",
  "who",
  "whom",
  "why",
  "will",
  "with",
  "would",
  "yet",
  "you",
  "your"
]

lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter')
<|endoftext|>