<commit_before>//=========================================
// 类工厂模块 v11 by 司徒正美
//==========================================
define("class", ["lang"], function($) {
    var
    unextend = $.oneObject(["_super", "prototype", 'extend', 'implement']),
    //不能重写的类成员列表
    rconst = /constructor|_init|_super/,
    //不能重写的原型成员列表
    classOne = $.oneObject('Object,Array,Function');

    function expand(klass, props) {
        'extend,implement'.replace($.rword, function(name) {
            var modules = props[name];
            if(classOne[$.type(modules)]) {
                klass[name].apply(klass, [].concat(modules));
                delete props[name];
            }
        });
        return klass;
    }

    var hash = {
        inherit: function(parent, init) {
            //继承一个父类，并将它放进_init列表中，并添加setOptions原型方法
            var bridge = function() {}
            if(typeof parent == "function") {
                for(var i in parent) { //继承类成员
                    this[i] = parent[i];
                }
                bridge.prototype = parent.prototype;
                this.prototype = new bridge; //继承原型成员
                this._super = parent; //指定父类
                if(!this._init) {
                    this._init = [parent]
                }
            }
            this._init = (this._init || []).concat();
            if(init) {
                this._init.push(init);
            }
            this.toString = function() {
                return(init || bridge) + ""
            }
            var proto = this.prototype;
            proto.setOptions = function() {
                var first = arguments[0];
                if(typeof first === "string") {
                    first = this[first] || (this[first] = {});
                    [].splice.call(arguments, 0, 1, first);
                } else {
                    [].unshift.call(arguments, this);
                }
                $.Object.merge.apply(null, arguments);
                return this;
            }
            return proto.constructor = this;
        },
        implement: function() {
            //添加一组原型方法
            var target = this.prototype,
            reg = rconst;
            for(var i = 0, module; module = arguments[i++];) {
                module = typeof module === "function" ? new module : module;
                Object.keys(module).forEach(function(name) {
                    if(!reg.test(name)) {
                        target[name] = module[name];
                    }
                }, this);
            }
            return this;
        },
        extend: function() {
            //添加一组类成员
            var bridge = {};
            for(var i = 0, module; module = arguments[i++];) {
                $.mix(bridge, module);
            }
            for(var key in bridge) {
                if(!unextend[key]) {
                    this[key] = bridge[key]
                }
            }
            return this;
        }
    };
    $.factory = function(obj) {
        obj = obj || {}; //父类
        var parent = obj.inherit,
        init = obj.init; //构造器
        delete obj.inherit;
        delete obj.init;
        var klass = function() {
            for(var i = 0, init; init = klass._init[i++];) {
                init.apply(this, arguments);
            }
        };
        $.mix(klass, hash).inherit(parent, init); //添加更多类方法
        return expand(klass, obj).implement(obj);
    }
    $.mix($.factory, hash)
    return $
});
/**
 change log:
2011.7.11 将$["class"]改为$["@class"] v4
2011.7.25
继承链与方法链被重新实现。
在方法中调用父类的同名实例方法，由$super改为supermethod，保留父类的原型属性parent改为superclass v5
2011.8.6
在方法中调用父类的同名实例方法，由supermethod改为_super，保留父类的原型属性superclass改为_super v6
重新实现方法链
fix 子类实例不是父类的实例的bug
2011.8.14 更改隐藏namespace,增强setOptions
2011.10.7 include更名为implement 修复implement的BUG（能让人重写toString valueOf方法） v7
2012.1.29 修正setOptions中$.Object.merge方法的调用方式
2012.2.25 改进setOptions，可以指定在this上扩展还是在this.XXX上扩展
2012.2.26 重新实现方法链，抛弃arguments.callee.caller   v8
2012.7.22 v10 大幅简化,去掉defineProperty与方法链
2012.12.25 去掉mutators 对象，它的方法绑到$.factory上，并且它支持继续用户用其他方法定义的“类” v11
https://gist.github.com/2990054
*/<commit_msg>升级到v12<commit_after>//=========================================
// 类工厂模块 v12 by 司徒正美
//==========================================
define("class", ["lang"], function($) {

    function bridge() {
    }
    var fnTest = /mass/.test(function() {
        mass;
    }) ? /\b_super|_superApply\b/ : /.*/;

    var hash = {
        inherit: function(parent, init) {
            //继承一个父类，并将它放进_init列表中，并添加setOptions原型方法
            if (typeof parent == "function") {
                for (var i in parent) { //继承类成员
                    this[i] = parent[i];
                }
                bridge.prototype = parent.prototype;
                this.prototype = new bridge; //继承原型成员
                this._super = parent; //指定父类
                if (!this.__init__) {
                    this.__init__ = [parent]
                }
            }
            this.__init__ = (this.__init__ || []).concat();
            if (init) {
                this.__init__.push(init);
            }
            this.toString = function() {
                return(init || bridge) + "";
            }
            var proto = this.fn = this.prototype;
            proto.extend = hash.extend;
            proto.setOptions = function() {
                var first = arguments[0];
                if (typeof first === "string") {
                    first = this[first] || (this[first] = {});
                    [].splice.call(arguments, 0, 1, first);
                } else {
                    [].unshift.call(arguments, this);
                }
                $.Object.merge.apply(null, arguments);
                return this;
            }
            return proto.constructor = this;
        },
        extend: function(module) {
            //添加一组原型方法
            var target = this;
            Object.keys(module).forEach(function(name) {
                var fn = target[name], fn2 = module[name]
                if (typeof fn === "funciton" && typeof fn2 === "function" && fnTest.test(fn2)) {
                    var __super = function() { //创建方法链
                        return fn.apply(this, arguments);
                    };
                    var __superApply = function(args) {
                        return fn.apply(this, args);
                    };
                    target[name] = function() {
                        var t1 = this._super;
                        var t2 = this._superApply;
                        this._super = __super;
                        this._superApply = __superApply;
                        var ret = fn2.apply(this, arguments);
                        this._super = t1;
                        this._superApply = t2;
                        return ret;
                    };
                } else {
                    target[name] = fn2;
                }
            });
            return this;
        }
    };
    function getSubClass(obj) {
        return  $.factory(this, obj);
    }
    $.factory = function(parent, obj) {
        if (arguments.length === 1) {
            obj = parent;
            parent = null;
        }
        var statics = obj.statics;//静态成员扩展包
        var init = obj.init; //构造器
        delete obj.init;
        delete obj.statics;
        var klass = function() {
            for (var i = 0, init; init = klass.__init__[i++]; ) {
                init.apply(this, arguments);
            }
        };
        hash.inherit.call(klass, parent, init);//继承了父类原型成员与类成员
        var fn = klass.fn;
        var __init__ = klass.__init__;
        $.mix(klass, statics);//添加类成员
        klass.prototype = klass.fn = fn;
        klass.__init__ = __init__;
        klass.fn.extend(obj);
        klass.mix = $.mix;
        klass.extend = getSubClass;
        return klass;
    };
    $.mix($.factory, hash);
    return $
});
/**
 change log:
2011.7.11 将$["class"]改为$["@class"] v4
2011.7.25
继承链与方法链被重新实现。
在方法中调用父类的同名实例方法，由$super改为supermethod，保留父类的原型属性parent改为superclass v5
2011.8.6
在方法中调用父类的同名实例方法，由supermethod改为_super，保留父类的原型属性superclass改为_super v6
重新实现方法链
fix 子类实例不是父类的实例的bug
2011.8.14 更改隐藏namespace,增强setOptions
2011.10.7 include更名为implement 修复implement的BUG（能让人重写toString valueOf方法） v7
2012.1.29 修正setOptions中$.Object.merge方法的调用方式
2012.2.25 改进setOptions，可以指定在this上扩展还是在this.XXX上扩展
2012.2.26 重新实现方法链，抛弃arguments.callee.caller   v8
2012.7.22 v10 大幅简化,去掉defineProperty与方法链
2012.12.25 去掉mutators 对象，它的方法绑到$.factory上，并且它支持继续用户用其他方法定义的“类” v11
2013.2.23 支持方法链，可以添加静态成员，默认绑定fn为prototype, fn.extend用于扩展原型方法，extend为产生子类
https://gist.github.com/2990054
*/<|endoftext|>


<commit_before>/*#ifndef(UMD)*/
(function () { /* Begin of privacy scope */
    "use strict";
/*#endif*/

/*
 * Rewrote class management to be more compatible with other frameworks.
 * Especially, it should not be necessary to inherit from a give root class
 * (as previously with gpf.Class).
 *
 * Only one function is available to create a class but it is not mandatory:
 * gpf.define(name, baseClass, definition)
 *
 * definition is an object describing members of the class and its attributes.
 *
 * NEW: use private, protected, static and public to declare visibility.
 *
 * As a first step, this won't change the way the object is created but I plan
 * to add validations in the future.
 *
 * The constructor function is based on the constructor member of the definition
 *
 * for instance:
 * var Test = gpf.define("Test", {
 *
 *   private: {
 *     _member: 0
 *   },
 *
 *   reset: function () {
 *   },
 *
 *   static: {
 *     DEFAULT_VALUE: 0
 *   },
 *
 *   constructor: function (value) {
 *     if (undefined === value) {
 *       value = this.static.DEFAULT_VALUE;
 *     }
 *     this._member = value;
 *     this.reset();
 *   }
 * });
 *
 * Per JavaScript prototype model, this.constructor returns the initialisation
 * function. This object also receives these new members:
 * - static members
 * - Base member (the case for inheritance)
 *   Base.prototype is assigned to object prototype.super
 *   so that the following is possible:
 *   function myMethod(param) {
 *     this.constructor.Base.prototype.myMethod.apply(this, param)
 *   }
 * - _attributes (for attributes)
 *
 *
 * 2014-05-05 #14
 *  Found that the 'constructor' member is treated in a special way with
 *  cscript.exe. hasOwnProperty returns false with it.
 *
 * 2014-06-25
 *  Rewrote to consolidate everything in a single class that handles both
 *  definition and information
 *
 */

    var
        _visibilityKeywords     = "public|protected|private|static".split("|"),
        _VISIBILITY_PUBLIC      = 0,
//        _VISIBILITY_PROTECTED   = 1,
//        _VISIBILITY_PRIVATE     = 2,
        _VISIBILITY_STATIC      = 3,
        _initAllowed = true;

    /**
     * An helper to create class and store its information
     *
     * @class gpf.ClassDefinition
     * @constructor
     * @param {String|Function} name
     * @param {Function} Base
     * @param {Object} definition
     */
    gpf.ClassDefinition = function  (name, Base, definition) {
        this._Subs = [];
        if ("function" === typeof name) {
            // TODO to extract class info from there
            this._Constructor = name;
        } else {
            this._name = name;
            this._Base = Base;
            this._definition = definition;
            this._build();
        }
    };

    gpf.extend(gpf.ClassDefinition.prototype, {

        //region Members

        /**
         * Class name
         *
         * @type {String}
         * @private
         */
        _name: "",

        /**
         * Class name
         *
         * @return {String}
         */
        name: function () {
            return this._name;
        },

        /**
         * Base class
         *
         * @type {Function}
         * @private
         */
        _Base: Object,

        /**
         * Base class
         *
         * @return {Function}
         */
        Base: function () {
            return this._Base;
        },

        /**
         * Child classes
         *
         * @type {Function[}}
         * @private
         */
        _Subs: [],

        /**
         * Child classes
         *
         * @return {Function[}}
         */
        Subs: function () {
            return this._Subs;
        },

        /**
         * Attributes of this class
         *
         * NOTE: during definition, this member is used as a simple JavaScript
         *
         * @type {gpf.attributes.Map}
         * @private
         */
        _attributes: null,

        /**
         * Attributes of this class
         *
         * @return {gpf.attributes.Map}
         */
        attributes: function () {
            /*__begin__thread_safe__*/
            if (!this._attributes) {
                this._attributes = new gpf.attributes.Map();
            }
            /*__end_thread_safe__*/
            return this._attributes;
        },

        /**
         * Class constructor
         *
         * @type {Function}
         * @private
         */
        _Constructor: function () {},

        /**
         * Class 'definition' constructor
         *
         * @type {Function}
         * @private
         */
        _defConstructor: null,

        /**
         * Class constructor
         *
         * @return {Function}
         */
        Constructor: function () {
            return this._Constructor;
        },

        //endregion

        //region Class construction

        /**
         * Class definition
         *
         * @type {Object}
         * @private
         */
        _definition: null,

        /**
         * Defines a new member of the class
         *
         * @param {String} member Name of the member to define
         * @param {Number} visibility Visibility of the members
         * @private
         */
        _processMember: function (member, visibility) {
            // Don't know yet how I want to handle visibility
            var
                newPrototype = this._Constructor.prototype,
                defMember = this._definition[member],
                newType,
                baseMember,
                baseType,
                baseName;
            newType = typeof defMember;
            if (_VISIBILITY_STATIC === visibility) {
                // No inheritance can be applied here
                newPrototype.constructor[member] = defMember;
                return;
            }
            baseMember = this._Base.prototype[member];
            baseType = typeof baseMember;
            if ("undefined" !== baseType && newType !== baseType) {
                throw {
                    message: "You can't overload a member to change its type"
                };
            }
            if ("function" === newType && "undefined" !== baseType) {
                /*
                 * As it is a function overload, defines a new member that will
                 * give a quick access to the base function. This should answer
                 * 90% of the cases.
                 *
                 * TODO how do we handle possible conflict name
                 */
                baseName = member;
                if ("_" === baseName.charAt(0)) {
                    baseName = baseName.substr(1);
                }
                // Capitalize
                baseName = gpf.capitalize(baseName);
                newPrototype["_base" + baseName] = baseMember;
            }
            if ("constructor" === member) {
                this._defConstructor = defMember;
            } else {
                newPrototype[member] = defMember;
            }
        },

        /**
         * An attribute definition is found in the class definition, store it
         * into a temporary map: it will be processed later
         *
         * @param {String} key Attribute name of the member to associate the
         * attributes to ([name])
         * @private
         */
        _processAttribute: function (key) {
            var
                attributeArray,
                newAttributeArray = this._definition[key];
            key = key.substr(1, key.length - 2); // Extract member name
            if (!this._attributes) {
                this._attributes = {};
            }
            attributeArray = this._attributes[key];
            if (undefined === attributeArray) {
                attributeArray = [];
            }
            this._attributes[key] = attributeArray.concat(newAttributeArray);
        },

        /**
         * Process class definition including visibility
         *
         * NOTE: alters this._definition
         *
         * @param {Number} visibility Visibility of the members
         * @private
         */
        _processDefWithVisibility: function (visibility) {
            var
                initialDefinition = this._definition,
                definition,
                member;
            member = _visibilityKeywords[visibility];
            definition = initialDefinition[member];
            this._definition = definition;
            try {
                for (member in definition) {
                    if (definition.hasOwnProperty(member)) {

                        // Attribute
                        if ("[" === member.charAt(0)
                            && "]" === member.charAt(member.length - 1)) {

                            this._processAttribute(member);

                            // Visibility
                        } else if ("public" === member
                            || "private" === member
                            || "protected" === member
                            || "static" === member) {
                            throw {
                                message: "Invalid visibility keyword"
                            };

                            // Usual member
                        } else {
                            this._processMember(member, visibility);
                        }
                    }
                }
                // 2014-05-05 #14
                if ("wscript" === gpf.host()
                    && definition.constructor !== Object) {
                    this._processMember("constructor", visibility);
                }
            } catch (e) {
                throw e;
            } finally {
                this._definition = initialDefinition;
            }
        },

        /**
         * Process definition
         *
         * @private
         */
        _processDefinition: function () {
            var
                definition = this._definition,
                member,
                visibility;
            for (member in definition) {
                if (definition.hasOwnProperty(member)) {
                    if ("[" === member.charAt(0)
                        && "]" === member.charAt(member.length - 1)) {
                        // Attribute
                        this._processAttribute(member);
                    } else {
                        visibility = _visibilityKeywords
                            .indexOf(member);
                        if (-1 === visibility) {
                            // Usual member
                            this._processMember(member,
                                _VISIBILITY_PUBLIC);
                        } else {
                            // Visibility
                            this._processDefWithVisibility(visibility);
                        }
                    }
                }
            }
            // 2014-05-05 #14
            if ("wscript" === gpf.host() && definition.constructor !== Object) {
                this._processMember("constructor", _VISIBILITY_PUBLIC);
            }
        },

        /**
         * Process the attributes collected in the definition
         *
         * NOTE: gpf.attributes._add is defined in attributes.js
         *
         * @private
         */
        _processAttributes: function () {
            var
                attributes = this._attributes,
                Constructor,
                newPrototype,
                attributeName;
            if (attributes) {
                delete this._attributes;
                Constructor = this._Constructor;
                newPrototype = Constructor.prototype;
                for (attributeName in attributes) {
                    if (attributes.hasOwnProperty(attributeName)) {
                        if (attributeName in newPrototype
                            || attributeName === "Class") {
                            gpf.attributes.add(Constructor, attributeName,
                                attributes[attributeName]);
                        } else {
                            // 2013-12-15 ABZ Exceptional, trace it only
                            console.error("gpf.define: Invalid attribute name '"
                                + attributeName + "'");
                        }
                    }
                }
            }
        },

        /**
         * Create the new Class constructor
         *
         * @closure
         */
        _build: function () {
            var
                newClass,
                newPrototype,
                baseClassDef;

            // The new class constructor
            newClass = gpf._func(_getNewClassConstructorSrc(this._name))(gpf);
            this._Constructor = newClass;
            newClass._gpf = this;

            /*
             * Basic JavaScript inheritance mechanism:
             * Defines the newClass prototype as an instance of the base class
             * Do it in a critical section that prevents class initialization
             */
            /*__begin__thread_safe__*/
            _initAllowed = false;
            newPrototype = new this._Base();
            _initAllowed = true;
            /*__end_thread_safe__*/

            // Populate our constructed prototype object
            newClass.prototype = newPrototype;

            // Enforce the constructor to be what we expect
            newPrototype.constructor = newClass;

            /*
             * Defines the link between this class and its base one
             * (It is necessary to do it here because of the gpf.addAttributes
             * that will test the parent class)
             */
            baseClassDef = gpf.classDef(this._Base);
            baseClassDef.Subs().push(newClass);

            /*
             * 2014-04-28 ABZ Changed again from two passes on all members to
             * two passes in which the first one also collects attributes to
             * simplify the second pass.
             */
            this._processDefinition();
            this._processAttributes();
        }

        //endregion
    });

    //region Class related helpers

    /**
     * Retrieves (or allocate) the class definition object
     *
     * @param {Function} constructor Class constructor
     * @returns {gpf.ClassDefinition}
     */
    gpf.classDef = function (constructor) {
        if (undefined === constructor._gpf) {
            constructor._gpf = new gpf.ClassDefinition(constructor);
        }
        return constructor._gpf;
    };

    /**
     * Class initializer: it triggers the call to this._defConstructor only if
     * _classInitAllowed is true.
     *
     * NOTE: it must belong to gpf as the created closure will use gpf as an
     * anchor point.
     *
     * @param {Function} constructor Class constructor
     * @param {*[]} args Arguments
     * @private
     */
    gpf._classInit = function (constructor, args) {
        if (_initAllowed) {
            var classDef = gpf.classDef(constructor);
            // TODO resolve prototype if not yet done
            if (classDef._defConstructor) {
                classDef._defConstructor.apply(this, args);
            } else {
                classDef._Base.apply(this, args);
            }
        }
    };

    /**
     * Template for new class constructor (using name that includes namespace)
     * - Uses closure to keep track of gpf handle and constructor function
     * - _CONSTRUCTOR_ will be replaced with the actual class name
     *
     * @returns {Function}
     * @private
     * @closure
     */
    function _newClassConstructorFromFullName() {
        var
            gpf = arguments[0],
            /*global _CONSTRUCTOR_:true*/
            /*jshint -W120*/
            constructor = _CONSTRUCTOR_ = function () {
                gpf._classInit.apply(this, [constructor, arguments]);
            };
        return constructor;
    }

    /**
     * Template for new class constructor (using name without namespace)
     * - Uses closure to keep track of gpf handle and constructor function
     * - _CONSTRUCTOR_ will be replaced with the actual class name
     *
     * @returns {Function}
     * @private
     * @closure
     */
    function _newClassConstructorFromName() {
        var
            gpf = arguments[0],
            constructor = function _CONSTRUCTOR_ () {
                gpf._classInit.apply(this, [constructor, arguments]);
            };
        return constructor;
    }

    /**
     * Returns the source of _newClassConstructor with the appropriate class
     * name
     *
     * @param {String} name
     * @return {String}
     * @private
     */
    function _getNewClassConstructorSrc(name) {
        var
            constructorDef,
            src,
            start,
            end;
        if (-1 < name.indexOf(".")) {
            constructorDef = _newClassConstructorFromFullName;
        } else {
            constructorDef = _newClassConstructorFromName;
        }
        src = constructorDef.toString().replace("_CONSTRUCTOR_", name);
        start = src.indexOf("{") + 1;
        end = src.lastIndexOf("}") - 1;
        return src.substr(start, end - start + 1);
    }

    //endregion

    /**
     * Defines a new class by setting a contextual name
     *
     * @param {String} name New class contextual name
     * @param {String} [base=undefined] base Base class contextual name
     * @param {Object} [definition=undefined] definition Class definition
     * @return {Function}
     */
    gpf.define = function (name, base, definition) {
        var
            result,
            ns,
            path,
            classDef;
        if ("string" === typeof base) {
            // Convert base into the function
            base = gpf.context(base);

        } else if ("object" === typeof base) {
            definition = base;
            base = undefined;
        }
        if (undefined === base) {
            base = Object; // Root class
        }
        if (-1 < name.indexOf(".")) {
            path = name.split(".");
            path.pop();
            ns = gpf.context(path);
        }
        classDef = new gpf.ClassDefinition(name, base, definition || {});
        result = classDef.Constructor();
        if (undefined !== ns) {
            ns[name] = result;
        }
        return result;
    };

    /**
     * Allocate a new class handler that is specific to a class type
     * (used for interfaces & attributes)
     *
     * @param {String} ctxRoot Default context root
     * @param {String} defaultBase Default contextual root class
     * @private
     */
    gpf._genDefHandler = function (ctxRoot, defaultBase) {
        ctxRoot = ctxRoot + ".";
        return function (name, base, definition) {
            var result;
            if (undefined === definition && "object" === typeof base) {
                definition = base;
                base = ctxRoot + defaultBase;
            } else if (undefined === base) {
                base = ctxRoot + defaultBase;
            }
            if (-1 === name.indexOf(".")) {
                name = ctxRoot + name;
            }
            result = gpf.define(name, base, definition);
            return result;
        };
    };

/*#ifndef(UMD)*/
}()); /* End of privacy scope */
/*#endif*/<commit_msg>Bug fix on full class name handling<commit_after>/*#ifndef(UMD)*/
(function () { /* Begin of privacy scope */
    "use strict";
/*#endif*/

/*
 * Rewrote class management to be more compatible with other frameworks.
 * Especially, it should not be necessary to inherit from a give root class
 * (as previously with gpf.Class).
 *
 * Only one function is available to create a class but it is not mandatory:
 * gpf.define(name, baseClass, definition)
 *
 * definition is an object describing members of the class and its attributes.
 *
 * NEW: use private, protected, static and public to declare visibility.
 *
 * As a first step, this won't change the way the object is created but I plan
 * to add validations in the future.
 *
 * The constructor function is based on the constructor member of the definition
 *
 * for instance:
 * var Test = gpf.define("Test", {
 *
 *   private: {
 *     _member: 0
 *   },
 *
 *   reset: function () {
 *   },
 *
 *   static: {
 *     DEFAULT_VALUE: 0
 *   },
 *
 *   constructor: function (value) {
 *     if (undefined === value) {
 *       value = this.static.DEFAULT_VALUE;
 *     }
 *     this._member = value;
 *     this.reset();
 *   }
 * });
 *
 * Per JavaScript prototype model, this.constructor returns the initialisation
 * function. This object also receives these new members:
 * - static members
 * - Base member (the case for inheritance)
 *   Base.prototype is assigned to object prototype.super
 *   so that the following is possible:
 *   function myMethod(param) {
 *     this.constructor.Base.prototype.myMethod.apply(this, param)
 *   }
 * - _attributes (for attributes)
 *
 *
 * 2014-05-05 #14
 *  Found that the 'constructor' member is treated in a special way with
 *  cscript.exe. hasOwnProperty returns false with it.
 *
 * 2014-06-25
 *  Rewrote to consolidate everything in a single class that handles both
 *  definition and information
 *
 */

    var
        _visibilityKeywords     = "public|protected|private|static".split("|"),
        _VISIBILITY_PUBLIC      = 0,
//        _VISIBILITY_PROTECTED   = 1,
//        _VISIBILITY_PRIVATE     = 2,
        _VISIBILITY_STATIC      = 3,
        _initAllowed = true;

    /**
     * An helper to create class and store its information
     *
     * @class gpf.ClassDefinition
     * @constructor
     * @param {String|Function} name
     * @param {Function} Base
     * @param {Object} definition
     */
    gpf.ClassDefinition = function  (name, Base, definition) {
        this._Subs = [];
        if ("function" === typeof name) {
            // TODO to extract class info from there
            this._Constructor = name;
        } else {
            this._name = name;
            this._Base = Base;
            this._definition = definition;
            this._build();
        }
    };

    gpf.extend(gpf.ClassDefinition.prototype, {

        //region Members

        /**
         * Class name
         *
         * @type {String}
         * @private
         */
        _name: "",

        /**
         * Class name
         *
         * @return {String}
         */
        name: function () {
            return this._name;
        },

        /**
         * Base class
         *
         * @type {Function}
         * @private
         */
        _Base: Object,

        /**
         * Base class
         *
         * @return {Function}
         */
        Base: function () {
            return this._Base;
        },

        /**
         * Child classes
         *
         * @type {Function[}}
         * @private
         */
        _Subs: [],

        /**
         * Child classes
         *
         * @return {Function[}}
         */
        Subs: function () {
            return this._Subs;
        },

        /**
         * Attributes of this class
         *
         * NOTE: during definition, this member is used as a simple JavaScript
         *
         * @type {gpf.attributes.Map}
         * @private
         */
        _attributes: null,

        /**
         * Attributes of this class
         *
         * @return {gpf.attributes.Map}
         */
        attributes: function () {
            /*__begin__thread_safe__*/
            if (!this._attributes) {
                this._attributes = new gpf.attributes.Map();
            }
            /*__end_thread_safe__*/
            return this._attributes;
        },

        /**
         * Class constructor
         *
         * @type {Function}
         * @private
         */
        _Constructor: function () {},

        /**
         * Class 'definition' constructor
         *
         * @type {Function}
         * @private
         */
        _defConstructor: null,

        /**
         * Class constructor
         *
         * @return {Function}
         */
        Constructor: function () {
            return this._Constructor;
        },

        //endregion

        //region Class construction

        /**
         * Class definition
         *
         * @type {Object}
         * @private
         */
        _definition: null,

        /**
         * Defines a new member of the class
         *
         * @param {String} member Name of the member to define
         * @param {Number} visibility Visibility of the members
         * @private
         */
        _processMember: function (member, visibility) {
            // Don't know yet how I want to handle visibility
            var
                newPrototype = this._Constructor.prototype,
                defMember = this._definition[member],
                newType,
                baseMember,
                baseType,
                baseName;
            newType = typeof defMember;
            if (_VISIBILITY_STATIC === visibility) {
                // No inheritance can be applied here
                newPrototype.constructor[member] = defMember;
                return;
            }
            baseMember = this._Base.prototype[member];
            baseType = typeof baseMember;
            if ("undefined" !== baseType && newType !== baseType) {
                throw {
                    message: "You can't overload a member to change its type"
                };
            }
            if ("function" === newType && "undefined" !== baseType) {
                /*
                 * As it is a function overload, defines a new member that will
                 * give a quick access to the base function. This should answer
                 * 90% of the cases.
                 *
                 * TODO how do we handle possible conflict name
                 */
                baseName = member;
                if ("_" === baseName.charAt(0)) {
                    baseName = baseName.substr(1);
                }
                // Capitalize
                baseName = gpf.capitalize(baseName);
                newPrototype["_base" + baseName] = baseMember;
            }
            if ("constructor" === member) {
                this._defConstructor = defMember;
            } else {
                newPrototype[member] = defMember;
            }
        },

        /**
         * An attribute definition is found in the class definition, store it
         * into a temporary map: it will be processed later
         *
         * @param {String} key Attribute name of the member to associate the
         * attributes to ([name])
         * @private
         */
        _processAttribute: function (key) {
            var
                attributeArray,
                newAttributeArray = this._definition[key];
            key = key.substr(1, key.length - 2); // Extract member name
            if (!this._attributes) {
                this._attributes = {};
            }
            attributeArray = this._attributes[key];
            if (undefined === attributeArray) {
                attributeArray = [];
            }
            this._attributes[key] = attributeArray.concat(newAttributeArray);
        },

        /**
         * Process class definition including visibility
         *
         * NOTE: alters this._definition
         *
         * @param {Number} visibility Visibility of the members
         * @private
         */
        _processDefWithVisibility: function (visibility) {
            var
                initialDefinition = this._definition,
                definition,
                member;
            member = _visibilityKeywords[visibility];
            definition = initialDefinition[member];
            this._definition = definition;
            try {
                for (member in definition) {
                    if (definition.hasOwnProperty(member)) {

                        // Attribute
                        if ("[" === member.charAt(0)
                            && "]" === member.charAt(member.length - 1)) {

                            this._processAttribute(member);

                            // Visibility
                        } else if ("public" === member
                            || "private" === member
                            || "protected" === member
                            || "static" === member) {
                            throw {
                                message: "Invalid visibility keyword"
                            };

                            // Usual member
                        } else {
                            this._processMember(member, visibility);
                        }
                    }
                }
                // 2014-05-05 #14
                if ("wscript" === gpf.host()
                    && definition.constructor !== Object) {
                    this._processMember("constructor", visibility);
                }
            } catch (e) {
                throw e;
            } finally {
                this._definition = initialDefinition;
            }
        },

        /**
         * Process definition
         *
         * @private
         */
        _processDefinition: function () {
            var
                definition = this._definition,
                member,
                visibility;
            for (member in definition) {
                if (definition.hasOwnProperty(member)) {
                    if ("[" === member.charAt(0)
                        && "]" === member.charAt(member.length - 1)) {
                        // Attribute
                        this._processAttribute(member);
                    } else {
                        visibility = _visibilityKeywords
                            .indexOf(member);
                        if (-1 === visibility) {
                            // Usual member
                            this._processMember(member,
                                _VISIBILITY_PUBLIC);
                        } else {
                            // Visibility
                            this._processDefWithVisibility(visibility);
                        }
                    }
                }
            }
            // 2014-05-05 #14
            if ("wscript" === gpf.host() && definition.constructor !== Object) {
                this._processMember("constructor", _VISIBILITY_PUBLIC);
            }
        },

        /**
         * Process the attributes collected in the definition
         *
         * NOTE: gpf.attributes._add is defined in attributes.js
         *
         * @private
         */
        _processAttributes: function () {
            var
                attributes = this._attributes,
                Constructor,
                newPrototype,
                attributeName;
            if (attributes) {
                delete this._attributes;
                Constructor = this._Constructor;
                newPrototype = Constructor.prototype;
                for (attributeName in attributes) {
                    if (attributes.hasOwnProperty(attributeName)) {
                        if (attributeName in newPrototype
                            || attributeName === "Class") {
                            gpf.attributes.add(Constructor, attributeName,
                                attributes[attributeName]);
                        } else {
                            // 2013-12-15 ABZ Exceptional, trace it only
                            console.error("gpf.define: Invalid attribute name '"
                                + attributeName + "'");
                        }
                    }
                }
            }
        },

        /**
         * Create the new Class constructor
         *
         * @closure
         */
        _build: function () {
            var
                newClass,
                newPrototype,
                baseClassDef;

            // The new class constructor
            newClass = gpf._func(_getNewClassConstructorSrc(this._name))(gpf);
            this._Constructor = newClass;
            newClass._gpf = this;

            /*
             * Basic JavaScript inheritance mechanism:
             * Defines the newClass prototype as an instance of the base class
             * Do it in a critical section that prevents class initialization
             */
            /*__begin__thread_safe__*/
            _initAllowed = false;
            newPrototype = new this._Base();
            _initAllowed = true;
            /*__end_thread_safe__*/

            // Populate our constructed prototype object
            newClass.prototype = newPrototype;

            // Enforce the constructor to be what we expect
            newPrototype.constructor = newClass;

            /*
             * Defines the link between this class and its base one
             * (It is necessary to do it here because of the gpf.addAttributes
             * that will test the parent class)
             */
            baseClassDef = gpf.classDef(this._Base);
            baseClassDef.Subs().push(newClass);

            /*
             * 2014-04-28 ABZ Changed again from two passes on all members to
             * two passes in which the first one also collects attributes to
             * simplify the second pass.
             */
            this._processDefinition();
            this._processAttributes();
        }

        //endregion
    });

    //region Class related helpers

    /**
     * Retrieves (or allocate) the class definition object
     *
     * @param {Function} constructor Class constructor
     * @returns {gpf.ClassDefinition}
     */
    gpf.classDef = function (constructor) {
        if (undefined === constructor._gpf) {
            constructor._gpf = new gpf.ClassDefinition(constructor);
        }
        return constructor._gpf;
    };

    /**
     * Class initializer: it triggers the call to this._defConstructor only if
     * _classInitAllowed is true.
     *
     * NOTE: it must belong to gpf as the created closure will use gpf as an
     * anchor point.
     *
     * @param {Function} constructor Class constructor
     * @param {*[]} args Arguments
     * @private
     */
    gpf._classInit = function (constructor, args) {
        if (_initAllowed) {
            var classDef = gpf.classDef(constructor);
            // TODO resolve prototype if not yet done
            if (classDef._defConstructor) {
                classDef._defConstructor.apply(this, args);
            } else {
                classDef._Base.apply(this, args);
            }
        }
    };

    /*global _CONSTRUCTOR_:true*/
    /**
     * Template for new class constructor (using name that includes namespace)
     * - Uses closure to keep track of gpf handle and constructor function
     * - _CONSTRUCTOR_ will be replaced with the actual class name
     *
     * @returns {Function}
     * @private
     * @closure
     */
    function _newClassConstructorFromFullName() {
        var
            gpf = arguments[0],
            /*jshint -W120*/
            constructor = _CONSTRUCTOR_ = function () {
                gpf._classInit.apply(this, [constructor, arguments]);
            };
        return constructor;
    }

    /**
     * Template for new class constructor (using name without namespace)
     * - Uses closure to keep track of gpf handle and constructor function
     * - _CONSTRUCTOR_ will be replaced with the actual class name
     *
     * @returns {Function}
     * @private
     * @closure
     */
    function _newClassConstructorFromName() {
        var
            gpf = arguments[0],
            constructor = function _CONSTRUCTOR_ () {
                gpf._classInit.apply(this, [constructor, arguments]);
            };
        return constructor;
    }

    /**
     * Returns the source of _newClassConstructor with the appropriate class
     * name
     *
     * @param {String} name
     * @return {String}
     * @private
     */
    function _getNewClassConstructorSrc(name) {
        var
            constructorDef,
            src,
            start,
            end;
        if (-1 < name.indexOf(".")) {
            constructorDef = _newClassConstructorFromFullName;
        } else {
            constructorDef = _newClassConstructorFromName;
        }
        src = constructorDef.toString().replace("_CONSTRUCTOR_", name);
        start = src.indexOf("{") + 1;
        end = src.lastIndexOf("}") - 1;
        return src.substr(start, end - start + 1);
    }

    //endregion

    /**
     * Defines a new class by setting a contextual name
     *
     * @param {String} name New class contextual name
     * @param {String} [base=undefined] base Base class contextual name
     * @param {Object} [definition=undefined] definition Class definition
     * @return {Function}
     */
    gpf.define = function (name, base, definition) {
        var
            result,
            path,
            ns,
            leafName,
            classDef;
        if ("string" === typeof base) {
            // Convert base into the function
            base = gpf.context(base);

        } else if ("object" === typeof base) {
            definition = base;
            base = undefined;
        }
        if (undefined === base) {
            base = Object; // Root class
        }
        if (-1 < name.indexOf(".")) {
            path = name.split(".");
            leafName = path.pop();
            ns = gpf.context(path);
        }
        classDef = new gpf.ClassDefinition(name, base, definition || {});
        result = classDef.Constructor();
        if (undefined !== ns) {
            ns[leafName] = result;
        }
        return result;
    };

    /**
     * Allocate a new class handler that is specific to a class type
     * (used for interfaces & attributes)
     *
     * @param {String} ctxRoot Default context root
     * @param {String} defaultBase Default contextual root class
     * @private
     */
    gpf._genDefHandler = function (ctxRoot, defaultBase) {
        ctxRoot = ctxRoot + ".";
        return function (name, base, definition) {
            var result;
            if (undefined === definition && "object" === typeof base) {
                definition = base;
                base = ctxRoot + defaultBase;
            } else if (undefined === base) {
                base = ctxRoot + defaultBase;
            }
            if (-1 === name.indexOf(".")) {
                name = ctxRoot + name;
            }
            result = gpf.define(name, base, definition);
            return result;
        };
    };

/*#ifndef(UMD)*/
}()); /* End of privacy scope */
/*#endif*/<|endoftext|>


<commit_before>SKYVE.PF = function() {
	// block multiple load attempts of google maps JS libs.
	var loadingGMap = false;

	// public
	return {
		getById: function(id) {
			return $(PrimeFaces.escapeClientId(id));
		},

		getByIdEndsWith: function(id) {
			var result = SKYVE.PF.getById(id);
			if (result.length) { // 1 node found
				return result;
			}
			else {
				return $('[id$="' + PrimeFaces.escapeClientId(id) + '"]');
			}
		},

		contentOverlayOnShow: function(id, url) {
			SKYVE.PF.getById(id + '_iframe').attr('src', url);
		},

		contentOverlayOnHide: function(id) {
			SKYVE.PF.getById(id + '_iframe').attr('src','')
		},

		afterContentUpload: function(binding, contentId, modoc, fileName) {
			top.$('[id$="_' + binding + '"]').val(contentId);
			var url = 'content?_n=' + contentId + '&_doc=' + modoc + '&_b=' + binding.replace(/\_/g, '.');
			top.$('[id$="_' + binding + '_link"]').attr('href', url).text(fileName);
			top.$('[id$="_' + binding + '_image"]').attr('src', url);
			top.PF(binding + 'Overlay').hide();
		},

		clearContentImage: function(binding) {
			$('[id$="_' + binding + '"]').val('');
			$('[id$="_' + binding + '_image"]').attr('src','images/blank.gif');
		},

		clearContentLink: function(binding) {
			$('[id$="_' + binding + '"]').val('');
			$('[id$="_' + binding + '_link"]').attr('href','javascript:void(0)').text('<Empty>');
		},

		getTextElement: function(id) {
			return SKYVE.PF.getById(id);
		},

		getTextValue: function(id) {
			return SKYVE.PF.getTextElement(id).val();
		},

		setTextValue: function(id, value) {
			SKYVE.PF.getTextElement(id).val(value);
		},

		getPasswordElement: function(id) {
			return SKYVE.PF.getById(id + 'password');
		},

		getPasswordValue: function(id) {
			return SKYVE.PF.getPasswordElement(id).val();
		},

		setPasswordValue: function(id, value) {
			SKYVE.PF.getPasswordElement(id).val(value);
		},

		// for selecting values and getting the selected value, use the PF SelectOneMenu API through widgetVar
		getComboElement: function(id) {
			return SKYVE.PF.getById(id);
		},

		// to perform a lookup, use the AutoComplete API through widgetVar
		getLookupElement: function(id) {
			return SKYVE.PF.getById(id);
		},

		getLookupValue: function(id) {
			return SKYVE.PF.getById(id + '_hinput').val();
		},

		setLookupValue: function(id, value) {
			SKYVE.PF.getById(id + '_hinput').val(value);
		},

		getLookupDescription: function(id) {
			return SKYVE.PF.getById(id + '_input').val();
		},

		setLookupDescription: function(id, value) {
			SKYVE.PF.getById(id + '_input').val(value);
		},

		getCheckboxElement: function(id) {
			return SKYVE.PF.getById(id);
		},

		getCheckboxValue: function(id) {
			var value = SKYVE.PF.getById(id + '_input').val();
			if (value == '0') {
				return null;
			}
			else if (value == '1') {
				return true;
			}
			else if (value == '2') {
				return false;
			}
			else {
				return SKYVE.PF.getById(id + '_input').is(":checked");
			}
		},

		setCheckboxValue: function(id, trueOrFalse) {
			SKYVE.PF.getById(id + '_input').prop('checked', trueOrFalse);

			var outerDiv = SKYVE.PF.getById(id);
			var innerDiv = outerDiv.find('.ui-chkbox-box');
			var innerSpan = innerDiv.find('.ui-chkbox-icon')
			if (trueOrFalse) {
				innerDiv.addClass('ui-state-active');
				innerSpan.addClass('ui-icon ui-icon-check')
			}
			else {
				innerDiv.removeClass('ui-state-active');
				innerSpan.removeClass('ui-icon ui-icon-check')
			}
		},

        toggleFilters: function(dataTableId) {
            var hiddenClass = 'hiddenFilter';
            // test for element that ends with the dataTableId as it may be in a naming container
            var dataTable = $('[id$="' + dataTableId + '"]');
			if (dataTable != null) {
				var toggleClass = function() {
                    var filter = $(this);
                    if (filter.hasClass(hiddenClass)) {
                        filter.removeClass(hiddenClass);
                    } else {
                        filter.addClass(hiddenClass);
                    }
				};
				dataTable.find('.ui-filter-column').each(toggleClass);
				dataTable.find('.ui-column-customfilter').each(toggleClass);
			}
		},

		onPushMessage: function(pushMessage) {
			var growls = [];

			for (var i = 0, l = pushMessage.length; i < l; i++) {
				var m = pushMessage[i];
				if (m.type == 'g') {
					growls.push({severity: m.severity, summary: m.message});
				}
				else if (m.type == 'm') {
					alert(m.message);
				}
				else if (m.type == 'r') {
					pushRerender();
				}
				else if (m.type == 'j') {
					window[m.method](m.argument);
				}
			}

			if (growls.length > 0) {
				PrimeFaces.cw('Growl', 'pushGrowl', {
					id: 'pushGrowl',
					widgetVar: 'pushGrowl',
					life: 6000,
					sticky: false,
					msgs: growls
				});
			}
		},

		gmap: function(options) {
			if (loadingGMap) {
				setTimeout(function() {SKYVE.PF.gmap(options)}, 100);
			}
			else if (window.google && window.google.maps && window.SKYVE.BizMapPicker) {
				if (options.queryName || options.modelName) {
					return SKYVE.BizMap.create(options);
				}
				return SKYVE.BizMapPicker.create(options);
			}
			else {
				loadingGMap = true;

				SKYVE.Util.loadJS('wicket/wicket.js?v=' + SKYVE.Util.v, function() {
					SKYVE.Util.loadJS('wicket/wicket-gmap3.js?v=' + SKYVE.Util.v, function() {
						var url = 'https://maps.googleapis.com/maps/api/js?v=3&libraries=drawing';
						if (SKYVE.Util.googleMapsV3ApiKey) {
							url += '&key=' + SKYVE.Util.googleMapsV3ApiKey;
						}
						SKYVE.Util.loadJS(url, function() {
							SKYVE.Util.loadJS('prime/skyve-gmap-min.js?v=' + SKYVE.Util.v, function() {
								loadingGMap = false;
								if (options.queryName || options.modelName) {
									return SKYVE.BizMap.create(options);
								}
								return SKYVE.BizMapPicker.create(options);
							});
						});
					});
				});
			}
		}
	};
}();
<commit_msg>Get maps to take within PF naming containers.<commit_after>SKYVE.PF = function() {
	// block multiple load attempts of google maps JS libs.
	var loadingGMap = false;

	// public
	return {
		getById: function(id) {
			return $(PrimeFaces.escapeClientId(id));
		},

		getByIdEndsWith: function(id) {
			return $('[id$="' + id + '"]');
		},

		contentOverlayOnShow: function(id, url) {
			SKYVE.PF.getById(id + '_iframe').attr('src', url);
		},

		contentOverlayOnHide: function(id) {
			SKYVE.PF.getById(id + '_iframe').attr('src','')
		},

		afterContentUpload: function(binding, contentId, modoc, fileName) {
			top.$('[id$="_' + binding + '"]').val(contentId);
			var url = 'content?_n=' + contentId + '&_doc=' + modoc + '&_b=' + binding.replace(/\_/g, '.');
			top.$('[id$="_' + binding + '_link"]').attr('href', url).text(fileName);
			top.$('[id$="_' + binding + '_image"]').attr('src', url);
			top.PF(binding + 'Overlay').hide();
		},

		clearContentImage: function(binding) {
			$('[id$="_' + binding + '"]').val('');
			$('[id$="_' + binding + '_image"]').attr('src','images/blank.gif');
		},

		clearContentLink: function(binding) {
			$('[id$="_' + binding + '"]').val('');
			$('[id$="_' + binding + '_link"]').attr('href','javascript:void(0)').text('<Empty>');
		},

		getTextElement: function(id) {
			return SKYVE.PF.getById(id);
		},

		getTextValue: function(id) {
			return SKYVE.PF.getTextElement(id).val();
		},

		setTextValue: function(id, value) {
			SKYVE.PF.getTextElement(id).val(value);
		},

		getPasswordElement: function(id) {
			return SKYVE.PF.getById(id + 'password');
		},

		getPasswordValue: function(id) {
			return SKYVE.PF.getPasswordElement(id).val();
		},

		setPasswordValue: function(id, value) {
			SKYVE.PF.getPasswordElement(id).val(value);
		},

		// for selecting values and getting the selected value, use the PF SelectOneMenu API through widgetVar
		getComboElement: function(id) {
			return SKYVE.PF.getById(id);
		},

		// to perform a lookup, use the AutoComplete API through widgetVar
		getLookupElement: function(id) {
			return SKYVE.PF.getById(id);
		},

		getLookupValue: function(id) {
			return SKYVE.PF.getById(id + '_hinput').val();
		},

		setLookupValue: function(id, value) {
			SKYVE.PF.getById(id + '_hinput').val(value);
		},

		getLookupDescription: function(id) {
			return SKYVE.PF.getById(id + '_input').val();
		},

		setLookupDescription: function(id, value) {
			SKYVE.PF.getById(id + '_input').val(value);
		},

		getCheckboxElement: function(id) {
			return SKYVE.PF.getById(id);
		},

		getCheckboxValue: function(id) {
			var value = SKYVE.PF.getById(id + '_input').val();
			if (value == '0') {
				return null;
			}
			else if (value == '1') {
				return true;
			}
			else if (value == '2') {
				return false;
			}
			else {
				return SKYVE.PF.getById(id + '_input').is(":checked");
			}
		},

		setCheckboxValue: function(id, trueOrFalse) {
			SKYVE.PF.getById(id + '_input').prop('checked', trueOrFalse);

			var outerDiv = SKYVE.PF.getById(id);
			var innerDiv = outerDiv.find('.ui-chkbox-box');
			var innerSpan = innerDiv.find('.ui-chkbox-icon')
			if (trueOrFalse) {
				innerDiv.addClass('ui-state-active');
				innerSpan.addClass('ui-icon ui-icon-check')
			}
			else {
				innerDiv.removeClass('ui-state-active');
				innerSpan.removeClass('ui-icon ui-icon-check')
			}
		},

        toggleFilters: function(dataTableId) {
            var hiddenClass = 'hiddenFilter';
            // test for element that ends with the dataTableId as it may be in a naming container
            var dataTable = $('[id$="' + dataTableId + '"]');
			if (dataTable != null) {
				var toggleClass = function() {
                    var filter = $(this);
                    if (filter.hasClass(hiddenClass)) {
                        filter.removeClass(hiddenClass);
                    } else {
                        filter.addClass(hiddenClass);
                    }
				};
				dataTable.find('.ui-filter-column').each(toggleClass);
				dataTable.find('.ui-column-customfilter').each(toggleClass);
			}
		},

		onPushMessage: function(pushMessage) {
			var growls = [];

			for (var i = 0, l = pushMessage.length; i < l; i++) {
				var m = pushMessage[i];
				if (m.type == 'g') {
					growls.push({severity: m.severity, summary: m.message});
				}
				else if (m.type == 'm') {
					alert(m.message);
				}
				else if (m.type == 'r') {
					pushRerender();
				}
				else if (m.type == 'j') {
					window[m.method](m.argument);
				}
			}

			if (growls.length > 0) {
				PrimeFaces.cw('Growl', 'pushGrowl', {
					id: 'pushGrowl',
					widgetVar: 'pushGrowl',
					life: 6000,
					sticky: false,
					msgs: growls
				});
			}
		},

		gmap: function(options) {
			if (loadingGMap) {
				setTimeout(function() {SKYVE.PF.gmap(options)}, 100);
			}
			else if (window.google && window.google.maps && window.SKYVE.BizMapPicker) {
				if (options.queryName || options.modelName) {
					return SKYVE.BizMap.create(options);
				}
				return SKYVE.BizMapPicker.create(options);
			}
			else {
				loadingGMap = true;

				SKYVE.Util.loadJS('wicket/wicket.js?v=' + SKYVE.Util.v, function() {
					SKYVE.Util.loadJS('wicket/wicket-gmap3.js?v=' + SKYVE.Util.v, function() {
						var url = 'https://maps.googleapis.com/maps/api/js?v=3&libraries=drawing';
						if (SKYVE.Util.googleMapsV3ApiKey) {
							url += '&key=' + SKYVE.Util.googleMapsV3ApiKey;
						}
						SKYVE.Util.loadJS(url, function() {
							SKYVE.Util.loadJS('prime/skyve-gmap-min.js?v=' + SKYVE.Util.v, function() {
								loadingGMap = false;
								if (options.queryName || options.modelName) {
									return SKYVE.BizMap.create(options);
								}
								return SKYVE.BizMapPicker.create(options);
							});
						});
					});
				});
			}
		}
	};
}();
<|endoftext|>


<commit_before>$(document).ready(function () {
  initialize();
  getLocation();
  getmap();
  NProgress.configure({ showSpinner: false });

$("#customval").focus();

$("#submit").click(function(event) {
	event.preventDefault();
	enableCustomLocation();
});
$("#customval").keypress(function(event) {
	if(event.which == 13) {
		event.preventDefault();
		enableCustomLocation();
	}
});
$("a#customlocation").click(function() {
	disableCustomLocation();
});

});

// HTML5 Geolocation : Find Current Location
var current_lat;
var current_long;

var city;
var state;

var amount_checks = 0;
var latlng;
var geocoder;
var check_time = new Date();
var check_initial = false;
var update_delay = 20000; // milliseconds

var custom = false;
var zipcode = "12180";
var the_zipcoder;
var watchID;

function getLocation() {
  if (navigator.geolocation) {
    watchID = navigator.geolocation.watchPosition(currentPosition, handleError, {
      'enableHighAccuracy': true,
      'maximumAge': 30000
    });
  } else {
    $('#msg').html("Your browser does not support geolocation.");
  }
}

function handleError(error) {
  switch (error.code) {
  case error.PERMISSION_DENIED:
    $('#msg').html("Geolocation data not shared.");
    break;
  case error.POSITION_UNAVAILABLE:
    $('#msg').html("Could not detect current position.");
    break;
  case error.TIMEOUT:
    $('#msg').html("Retrieving position timed out.");
    break;
  default:
    $('#msg').html("Unknown Error.");
    break;
  }
}

function updateCoords(latitude, longitude) {
  current_lat = latitude;
  current_long = longitude;
}

function currentPosition(position) {
  current_lat = position.coords.latitude;
  current_long = position.coords.longitude;
  updateCoords(position.coords.latitude, position.coords.longitude);
  $('#lat').html('Latitude: ' + current_lat);
  $('#long').html('Longitude: ' + current_long);
  $('#msg').html(position.coords.accuracy + " meters of accuracy.");
  var now = new Date();
  var diff = now - check_time;
  if (!check_initial) {
    codeLatLng();
    check_initial = true;
	getZipCode();
    getmap();
    getData();
    NProgress.start();
  }
  if ((diff > update_delay) && (custom == false)) {
    codeLatLng();
    check_time = now;
	getZipCode();
    getmap();
    getData();
  }
  amount_checks += 1;
  $('#checks').html('Checks: ' + amount_checks);
}

// Google Maps API : Show Current Location & Get Info

var infowindow = new google.maps.InfoWindow();

function initialize() {
  geocoder = new google.maps.Geocoder();
  latlng = new google.maps.LatLng(40.75, -74);
  zipcoder = new google.maps.LatLng(40.75, -74);
}

function codeLatLng() {
  var lat = parseFloat(current_lat);
  var lng = parseFloat(current_long);

  latlng = new google.maps.LatLng(lat, lng);
  geocoder.geocode({
    'latLng': latlng
  }, function (results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      if (results[1]) {
        $('#name').html(results[1].formatted_address);
        city = findCity(results[0].address_components);
        state = findState(results[0].address_components);
		  $.ajax({
		    url: 'get_census.php',
		    type: 'POST',
		    data: {
		      city: findCity(results[0].address_components),
			  state: findState(results[0].address_components)
		    },
		    success: function (msg) {
		      $("ul#population").html(msg);
		  	  NProgress.done();
		    },
			beforeSend: function() {
				$("ul#population").html("
Loading Census data...
");
			}
		  });
        $("#citystate").html(city + ", " + state);
      } else {
        $('#msg').html('Google Maps: No results found for current location.');
      }
    } else {
      $('#msg').html('Google Maps Geocoder failed due to: ' + status);
    }
  });
}

function findCity(results) {
  for (var i in results) {
    if (results[i].types[0] == "locality") {
      $("#city").html(results[i].long_name);
      return results[i].long_name;
    }
  }
  return 0;
}

function findState(results) {
  for (var i in results) {
    if (results[i].types[0] == "administrative_area_level_1") {
      $("#state").html(results[i].short_name);
      return results[i].short_name;
    }
  }
  return 0;
}

function getmap() {
  $("#mastHead").css('background-image', 'linear-gradient(to right, rgba(0, 0, 0, 0.65),  rgba(0, 0, 0, 0.1)), url("https://maps.googleapis.com/maps/api/staticmap?center=' + current_lat + ',' + current_long + '&zoom=12&size=640x320&scale=2")');
}

function getData() {
  $.ajax({
    url: 'get_IG.php',
    type: 'POST',
    data: {
      latitude: current_lat,
      longitude: current_long
    },
    success: function (msg) {
      $("#instagram ul").html(msg);
  	  NProgress.inc(0.15);
    },
	beforeSend: function() {
		$("#instagram ul").html("
Loading Instagram...
");
	}
  });

  $.ajax({
    url: 'get_yelp.php',
    type: 'POST',
    data: {
      latitude: current_lat,
      longitude: current_long
    },
    success: function (msg) {
      data = JSON.parse(msg);
      var return_data = "
";
      var businesses = data["businesses"];
      for (var i in businesses) {
        var business = businesses[i];
        return_data += "
" + "
" + "" + '' + business["name"] + '' + "" + "" + '" + "
" + "
";
      }
      return_data += "
";
      $("#restaurants").html(return_data);
  	  NProgress.inc(0.25);
    },
	beforeSend: function() {
		$("#restaurants").html("
Loading Yelp data...
");
	}
  });

  $.ajax ({
    url: 'get_trulia.php',
    type: 'POST',
    data: {zipcode : zipcode},
    success: function(msg) {
      result = JSON.parse(msg);
      //console.log(result);

      var return_data = "
";
      var j = 1;
      for (var i in result) {
        var avg_input = result[i].toString();
        //console.log(avg_input);
        var avg = avg_input.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");

        if (j == 1) {
          	if (avg < 1) {
				return_data += "
" + "
" + j + " bedroom: No data available.
" + "
";
			}
			else return_data += "
" + "
" + j + " bedroom: $" + avg + "
" + "
";
        }
        else {
			if (avg < 1) {
				return_data += "
" + "
" + j + " bedrooms: No data available.
" + "
";
			}
			else return_data += "
" + "
" + j + " bedrooms: $" + avg + "
" + "
";
        }
        j += 1;
      }

      return_data += "
";

      $('#truliaData').html(return_data);
	NProgress.inc(0.15);
    },
	beforeSend: function() {
		$("#truliaData").html("
Loading Trulia housing information...
");
	}
  });
}

function getZipCode() {
	var lat = parseFloat(current_lat);
	var lng = parseFloat(current_long);

	  zipcoder = new google.maps.LatLng(lat, lng);
	  geocoder.geocode({
	    'latLng': zipcoder
	  }, function (results, status) {
	    if (status == google.maps.GeocoderStatus.OK) {
	      if (results[1]) {
			zipcode = findZip(results[0].address_components);
	      } else {
	        $('#msg').html('Google Maps: No results found for current location.');
	      }
	    } else {
	      $('#msg').html('Google Maps Geocoder failed due to: ' + status);
	    }
	  });
}

function findZip(results) {
	for (var i in results) {
		if (results[i].types[0] == "postal_code") {
			return results[i].long_name;
		}
	}
	return 0;
}

function enableCustomLocation() {
	if (custom != true) {
		custom = true;
	}
	// Turn off glowing
	$("#customlocationform a i ").addClass("noglow");

	// Turn off HTML5 geolocation
	navigator.geolocation.clearWatch(watchID);

	input_zipcode = $("#customval").val();
	zipcode = input_zipcode;
	NProgress.start();
  $.ajax({
	url: 'latlongfromzip.php',
	type: 'POST',
	data: {
		zipcode: zipcode
	},
	dataType: "JSON",
	success: function(msg) {
		current_lat = msg.latitude;
		current_long = msg.longitude;
		codeLatLng();
		getZipCode();
		getmap();
		getData();
	}
  });

	NProgress.done();
}

function disableCustomLocation() {
	if (custom == true) {
		custom = false;
	}
	// Turn glowing back on
	$("#customlocationform a i").removeClass("noglow");
	NProgress.start();
	// Reload everything
	location.reload();

	NProgress.done();
}

<commit_msg>Deleted instagram refresh visual for UX benefit<commit_after>$(document).ready(function () {
  initialize();
  getLocation();
  getmap();
  NProgress.configure({ showSpinner: false });

$("#customval").focus();

$("#submit").click(function(event) {
	event.preventDefault();
	enableCustomLocation();
});
$("#customval").keypress(function(event) {
	if(event.which == 13) {
		event.preventDefault();
		enableCustomLocation();
	}
});
$("a#customlocation").click(function() {
	disableCustomLocation();
});

});

// HTML5 Geolocation : Find Current Location
var current_lat;
var current_long;

var city;
var state;

var amount_checks = 0;
var latlng;
var geocoder;
var check_time = new Date();
var check_initial = false;
var update_delay = 20000; // milliseconds

var custom = false;
var zipcode = "12180";
var the_zipcoder;
var watchID;

function getLocation() {
  if (navigator.geolocation) {
    watchID = navigator.geolocation.watchPosition(currentPosition, handleError, {
      'enableHighAccuracy': true,
      'maximumAge': 30000
    });
  } else {
    $('#msg').html("Your browser does not support geolocation.");
  }
}

function handleError(error) {
  switch (error.code) {
  case error.PERMISSION_DENIED:
    $('#msg').html("Geolocation data not shared.");
    break;
  case error.POSITION_UNAVAILABLE:
    $('#msg').html("Could not detect current position.");
    break;
  case error.TIMEOUT:
    $('#msg').html("Retrieving position timed out.");
    break;
  default:
    $('#msg').html("Unknown Error.");
    break;
  }
}

function updateCoords(latitude, longitude) {
  current_lat = latitude;
  current_long = longitude;
}

function currentPosition(position) {
  current_lat = position.coords.latitude;
  current_long = position.coords.longitude;
  updateCoords(position.coords.latitude, position.coords.longitude);
  $('#lat').html('Latitude: ' + current_lat);
  $('#long').html('Longitude: ' + current_long);
  $('#msg').html(position.coords.accuracy + " meters of accuracy.");
  var now = new Date();
  var diff = now - check_time;
  if (!check_initial) {
    codeLatLng();
    check_initial = true;
	getZipCode();
    getmap();
    getData();
    NProgress.start();
  }
  if ((diff > update_delay) && (custom == false)) {
    codeLatLng();
    check_time = now;
	getZipCode();
    getmap();
    getData();
  }
  amount_checks += 1;
  $('#checks').html('Checks: ' + amount_checks);
}

// Google Maps API : Show Current Location & Get Info

var infowindow = new google.maps.InfoWindow();

function initialize() {
  geocoder = new google.maps.Geocoder();
  latlng = new google.maps.LatLng(40.75, -74);
  zipcoder = new google.maps.LatLng(40.75, -74);
}

function codeLatLng() {
  var lat = parseFloat(current_lat);
  var lng = parseFloat(current_long);

  latlng = new google.maps.LatLng(lat, lng);
  geocoder.geocode({
    'latLng': latlng
  }, function (results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      if (results[1]) {
        $('#name').html(results[1].formatted_address);
        city = findCity(results[0].address_components);
        state = findState(results[0].address_components);
		  $.ajax({
		    url: 'get_census.php',
		    type: 'POST',
		    data: {
		      city: findCity(results[0].address_components),
			  state: findState(results[0].address_components)
		    },
		    success: function (msg) {
		      $("ul#population").html(msg);
		  	  NProgress.done();
		    },
			beforeSend: function() {
				$("ul#population").html("
Loading Census data...
");
			}
		  });
        $("#citystate").html(city + ", " + state);
      } else {
        $('#msg').html('Google Maps: No results found for current location.');
      }
    } else {
      $('#msg').html('Google Maps Geocoder failed due to: ' + status);
    }
  });
}

function findCity(results) {
  for (var i in results) {
    if (results[i].types[0] == "locality") {
      $("#city").html(results[i].long_name);
      return results[i].long_name;
    }
  }
  return 0;
}

function findState(results) {
  for (var i in results) {
    if (results[i].types[0] == "administrative_area_level_1") {
      $("#state").html(results[i].short_name);
      return results[i].short_name;
    }
  }
  return 0;
}

function getmap() {
  $("#mastHead").css('background-image', 'linear-gradient(to right, rgba(0, 0, 0, 0.65),  rgba(0, 0, 0, 0.1)), url("https://maps.googleapis.com/maps/api/staticmap?center=' + current_lat + ',' + current_long + '&zoom=12&size=640x320&scale=2")');
}

function getData() {
  $.ajax({
    url: 'get_IG.php',
    type: 'POST',
    data: {
      latitude: current_lat,
      longitude: current_long
    },
    success: function (msg) {
      $("#instagram ul").html(msg);
  	  NProgress.inc(0.15);
    },
	beforeSend: function() {
		// $("#instagram ul").html("
Loading Instagram...
");
	}
  });

  $.ajax({
    url: 'get_yelp.php',
    type: 'POST',
    data: {
      latitude: current_lat,
      longitude: current_long
    },
    success: function (msg) {
      data = JSON.parse(msg);
      var return_data = "
";
      var businesses = data["businesses"];
      for (var i in businesses) {
        var business = businesses[i];
        return_data += "
" + "
" + "" + '' + business["name"] + '' + "" + "" + '" + "
" + "
";
      }
      return_data += "
";
      $("#restaurants").html(return_data);
  	  NProgress.inc(0.25);
    },
	beforeSend: function() {
		$("#restaurants").html("
Loading Yelp data...
");
	}
  });

  $.ajax ({
    url: 'get_trulia.php',
    type: 'POST',
    data: {zipcode : zipcode},
    success: function(msg) {
      result = JSON.parse(msg);
      //console.log(result);

      var return_data = "
";
      var j = 1;
      for (var i in result) {
        var avg_input = result[i].toString();
        //console.log(avg_input);
        var avg = avg_input.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");

        if (j == 1) {
          	if (avg < 1) {
				return_data += "
" + "
" + j + " bedroom: No data available.
" + "
";
			}
			else return_data += "
" + "
" + j + " bedroom: $" + avg + "
" + "
";
        }
        else {
			if (avg < 1) {
				return_data += "
" + "
" + j + " bedrooms: No data available.
" + "
";
			}
			else return_data += "
" + "
" + j + " bedrooms: $" + avg + "
" + "
";
        }
        j += 1;
      }

      return_data += "
";

      $('#truliaData').html(return_data);
	NProgress.inc(0.15);
    },
	beforeSend: function() {
		$("#truliaData").html("
Loading Trulia housing information...
");
	}
  });
}

function getZipCode() {
	var lat = parseFloat(current_lat);
	var lng = parseFloat(current_long);

	  zipcoder = new google.maps.LatLng(lat, lng);
	  geocoder.geocode({
	    'latLng': zipcoder
	  }, function (results, status) {
	    if (status == google.maps.GeocoderStatus.OK) {
	      if (results[1]) {
			zipcode = findZip(results[0].address_components);
	      } else {
	        $('#msg').html('Google Maps: No results found for current location.');
	      }
	    } else {
	      $('#msg').html('Google Maps Geocoder failed due to: ' + status);
	    }
	  });
}

function findZip(results) {
	for (var i in results) {
		if (results[i].types[0] == "postal_code") {
			return results[i].long_name;
		}
	}
	return 0;
}

function enableCustomLocation() {
	if (custom != true) {
		custom = true;
	}
	// Turn off glowing
	$("#customlocationform a i ").addClass("noglow");

	// Turn off HTML5 geolocation
	navigator.geolocation.clearWatch(watchID);

	input_zipcode = $("#customval").val();
	zipcode = input_zipcode;
	NProgress.start();
  $.ajax({
	url: 'latlongfromzip.php',
	type: 'POST',
	data: {
		zipcode: zipcode
	},
	dataType: "JSON",
	success: function(msg) {
		current_lat = msg.latitude;
		current_long = msg.longitude;
		codeLatLng();
		getZipCode();
		getmap();
		getData();
	}
  });

	NProgress.done();
}

function disableCustomLocation() {
	if (custom == true) {
		custom = false;
	}
	// Turn glowing back on
	$("#customlocationform a i").removeClass("noglow");
	NProgress.start();
	// Reload everything
	location.reload();

	NProgress.done();
}

<|endoftext|>


<commit_before>var Client = require('node-rest-client').Client,
    clientOptions = {
      connection: {
        rejectUnauthorized: false,
        requestCert: true,
      }
    },
    client = new Client(clientOptions),
    tokenArgs = {
      'data': {
        'grant_type':'client_credentials',
        'client_id':'foo',
        'client_secret':'bar',
        'scope':'*'
      },
      headers: {
        'Content-Type':'application/json'
      }
    };

client.post('https://api.fronter.com/oauth/token', tokenArgs, function (data, response) {
    console.log(data);

    var clientArgs = {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': data['token_type'] + ' ' + data['access_token']
      }
    };

    client.get('https://api.fronter.com/planning/users/12345', clientArgs, function (data, response) {
      console.log(data);
    }).on('error', function (err) {
      console.log('err: ', err);
    });

}).on('error', function (err) {
  console.log('err: ', err);
});
<commit_msg>Use cli parameter for token.<commit_after>var Client = require('node-rest-client').Client,
    clientOptions = {
      connection: {
        rejectUnauthorized: true,
        requestCert: true,
      }
    },
    client = new Client(clientOptions),

    token = process.argv[2],

    params = {
      headers: {
        'Content-Type' : 'application/json',
        'Authorization' : 'bearer ' + token
      }
    };

client.get('https://api.fronter.com/planning/users/12345', params, function (data, response) {
  console.log(data);
}).on('error', function (err) {
  console.log('err: ', err);
});

client.on('error', function (err) {
 console.error(' client error : ', err);
});
<|endoftext|>


<commit_before>/*!
 * API для работы с Jade-Like синтаксисом
 */

(() => {
	var alb = ADV_LEFT_BLOCK,
		lb = LEFT_BLOCK,
		rb = RIGHT_BLOCK;

	var commandRgxp = /([^\s]+).*/,
		nonBlockCommentRgxp = /([^\\])\/\/\/(\s?)(.*)/,
		rightPartRgxp = new RegExp(`(?:${alb}?${lb}__&-__${rb}|)\\s*$`),
		rightWSRgxp = /\s*$/,
		lastSymbolRgxp = new RegExp(`(${alb}|\\\\)$`);

	var endDirInit,
		needSpace,
		nl;

	/**
	 * Вернуть объект-описание преобразованной части шаблона из
	 * Jade-Like синтаксиса в стандартный
	 *
	 * @param {string} str - исходная строка
	 * @param {number} i - номер начальной итерации
	 * @return {{str: string, length: number, error: (boolean|null|undefined)}}
	 */
	DirObj.prototype.toBaseSyntax = function (str, i) {
		needSpace = !this.tolerateWhitespace;
		nl = this.lineSeparator;
		endDirInit = false;

		var clrL = 0,
			init = true,
			spaces = 0,
			space = '';

		var struct,
			res = '';

		var length = 0,
			tSpace = 0;

		function f(struct, obj) {
			if (struct.block) {
				if (chains[struct.name] && chains[struct.name][obj.name]) {
					obj.block = true;
					obj.name = struct.name;

				} else if (ends[struct.name] && ends[struct.name][obj.name]) {
					obj.block = false;

				} else {
					let rightSpace = rightWSRgxp.exec(res)[0];
					res = res.replace(rightPartRgxp, '') +
						genEndDir(struct, struct.space);

					if (rightSpace && needSpace) {
						res += `${struct.adv}${lb}__&-__${rb}`;
					}

					res += rightSpace;
				}

			} else {
				endDirInit = false;
			}
		}

		for (let j = i - 1; ++j < str.length;) {
			length++;

			let el = str.charAt(j),
				next = str.charAt(j + 1);

			let next2str = str.substr(j, 2),
				diff2str = str.substr(j + 1, 2);

			if (nextLineRgxp.test(el)) {
				tSpace++;

				if (next2str === '\r\n') {
					continue;
				}

				if (clrL) {
					if (clrL === 1 && needSpace) {
						res += `${alb}${lb}__&-__${rb}`;
					}

					res += el;
				}

				clrL++;
				init = true;

				spaces = 0;
				space = nl;

			} else if (init) {
				if (whiteSpaceRgxp.test(el)) {
					spaces++;
					space += el;
					tSpace++;

				} else {
					let nextSpace = false;

					init = false;
					clrL = 0;

					if (el === alb) {
						if (shortMap[diff2str]) {
							let tmp = str.charAt(j + 3);
							nextSpace = !tmp || whiteSpaceRgxp.test(tmp);

						} else if (shortMap[next]) {
							let tmp = str.charAt(j + 2);
							nextSpace = !tmp || whiteSpaceRgxp.test(tmp);

						} else {
							nextSpace = !next || whiteSpaceRgxp.test(next);
						}

					} else {
						if (shortMap[next2str]) {
							let tmp = str.charAt(j + 2);
							nextSpace = !tmp || whiteSpaceRgxp.test(tmp);

						} else {
							nextSpace = !next || whiteSpaceRgxp.test(next);
						}
					}

					let dir = (shortMap[el] || shortMap[next2str]) && nextSpace,
						decl = getLineDesc(
							str,
							nextSpace && baseShortMap[el] || el === IGNORE_COMMAND ? j + 1 : j,
							Boolean(dir),
							next2str === MULT_COMMENT_START
						);

					if (!decl) {
						this.error('invalid syntax');
						return {
							str: '',
							length: 0,
							error: true
						};
					}

					let replacer;

					if (el === alb) {
						replacer = replacers[diff2str] ||
							replacers[next] ||
							replacers[next2str] ||
							replacers[el];

					} else {
						replacer = replacers[next2str] ||
							replacers[el];
					}

					if (replacer) {
						decl.name = replacer(decl.name).replace(commandRgxp, '$1');
					}

					let adv = el === alb ?
						alb : '';

					let s = dir ? adv + lb : '',
						e = dir ? rb : '';

					let obj = {
						dir: dir,
						name: decl.name,
						spaces: spaces,
						space: space,
						parent: null,
						block: dir && block[decl.name],
						text: !dir || text[decl.name],
						adv: adv
					};

					if (struct) {
						if (struct.spaces < spaces && struct.block) {
							obj.parent = struct;

							if (!obj.adv && struct.adv) {
								obj.block = false;
								adv = alb;
							}

						} else if (struct.spaces === spaces || struct.spaces < spaces && !struct.block) {
							obj.parent = struct.parent;

							if (!obj.adv && struct.parent && struct.parent.adv) {
								obj.block = false;
								adv = alb;
							}

							f(struct, obj);
							if (!struct.parent) {
								return {
									str: res,
									length: length - tSpace - 1
								};
							}

						} else {
							while (struct.spaces >= spaces) {
								f(struct, obj);
								struct = struct
									.parent;

								if (!struct) {
									return {
										str: res,
										length: length - tSpace - 1
									};
								}
							}

							obj.parent = struct;
						}
					}

					let parts,
						txt;

					decl.command = decl.command.replace(lastSymbolRgxp, '\\$1');

					if (dir) {
						if (decl.sComment) {
							parts = [decl.command];

						} else {
							parts = this.replaceDangerBlocks(decl.command).split(INLINE_COMMAND);

							for (let z = -1; ++z < parts.length;) {
								parts[z] = this.pasteDangerBlocks(parts[z]);
							}
						}

						txt = parts.slice(1).join(INLINE_COMMAND);
						txt = txt && txt.trim();
					}

					struct = obj;
					res += space;

					if (needSpace && (obj.text || !Snakeskin.Directions[obj.name])) {
						res += `${adv}${lb}__&-__${rb}`;
					}

					res += s + (dir ? parts[0] : decl.command).replace(nonBlockCommentRgxp, '$1/*$2$3$2*/') + e;
					endDirInit = false;

					let tmp = decl.length - 1;
					tSpace = 0;

					length += tmp;
					j += tmp;

					if (dir && txt) {
						let inline = {
							dir: false,
							spaces: spaces + 1,
							space: '',
							parent: obj,
							block: false,
							adv: ''
						};

						inline.parent = obj;
						struct = inline;
						res += txt;
					}
				}
			}
		}

		while (struct) {
			if (struct.block) {
				res += genEndDir(struct, struct.space);
			}

			struct = struct
				.parent;
		}

		return {
			str: res,
			length: length
		};
	};

	/**
	 * Вернуть строку окончания блоковой директивы
	 *
	 * @param {!Object} dir - объект-описание директивы
	 * @param {string} space - доступное свободное пространство
	 * @return {string}
	 */
	function genEndDir(dir, space) {
		var s = dir.adv + lb,
			tmp;

		if (needSpace) {
			tmp = `${endDirInit ? '' : `${s}__&+__${rb}`}${nl}`;

		} else {
			tmp = nl + (space || '').substring(1);
		}

		endDirInit = true;
		return `${tmp}${s}__end__${rb}${s}__cutLine__${rb}`;
	}

	/**
	 * Вернуть объект описание строки в Jade-Like синтаксисе
	 *
	 * @param {string} str - исходная строка
	 * @param {number} i - номер начальной итерации
	 * @param {boolean} dir - если true, то идёт декларация директивы
	 * @param {boolean} comment - если true, то идёт декларация мультистрочного комментария
	 * @return {{command: string, length: number, name: string, lastEl: string, sComment: boolean}}
	 */
	function getLineDesc(str, i, dir, comment) {
		var res = '',
			name = '';

		var lastEl = '',
			lastElI = 0,
			length = -1;

		var escape = false;
		var sComment = false,
			inline = false;

		var bOpen = false,
			bEnd = true,
			bEscape = false;

		var part = '',
			rPart = '';

		var concatLine = false,
			nmBrk = null;

		for (let j = i - 1; ++j < str.length;) {
			let currentEscape = escape,
				el = str.charAt(j);

			if (!bOpen && (el === '\\' || escape)) {
				escape = !escape;
			}

			length++;
			if (nextLineRgxp.test(el)) {
				if (!comment && !bOpen) {
					rPart = sComment ?
						'' : part;

					part = '';
				}

				let prevEl = lastEl,
					brk = false;

				lastEl = '';
				if (comment || (sComment && concatLine)) {
					res += el;

				} else if (!sComment && dir) {
					let dirStart = whiteSpaceRgxp.test(
						str.charAt(j - 2)
					);

					let literal;
					brk = dirStart &&
						prevEl === CONCAT_END;

					if (dirStart && (prevEl === CONCAT_COMMAND && res !== CONCAT_COMMAND || brk)) {
						literal = prevEl;
						res = res.substring(0, lastElI - 1) +
							res.substring(lastElI + 1);

					} else if (concatLine && !bOpen) {
						res += el;
					}

					if (concatLine && !brk) {
						continue;
					}

					if (literal === CONCAT_COMMAND) {
						concatLine = true;

						if (!bOpen) {
							res += el;
						}

						continue;
					}
				}

				if (comment || concatLine && !brk) {
					sComment = false;
					continue;
				}

				return {
					command: res,
					length: length,
					name: name,
					lastEl: lastEl,
					sComment: !inline && sComment
				};

			} else {
				if (!bOpen && !currentEscape) {
					let commentType = returnComment(str, j);

					if (comment) {
						comment = commentType !== MULT_COMMENT_END;

					} else if (!sComment) {
						comment = commentType === MULT_COMMENT_START;

						if (!comment) {
							sComment = commentType === SINGLE_COMMENT;
						}
					}
				}

				if (!comment && !sComment) {
					if (!bOpen) {
						if (escapeEndMap[el] || escapeEndWords[rPart]) {
							bEnd = true;

						} else if (bEndRgxp.test(el)) {
							bEnd = false;
						}

						if (escapeEndMap[el] || escapeEndWords[rPart]) {
							bEnd = true;

						} else if (bEndRgxp.test(el)) {
							bEnd = false;
						}

						if (partRgxp.test(el)) {
							part += el;

						} else {
							rPart = part;
							part = '';
						}

						if (dir && !inline) {
							inline = str.substr(j, INLINE_COMMAND.length) === INLINE_COMMAND;
						}
					}

					if (escapeMap[el] && (el !== '/' || bEnd) && !bOpen) {
						bOpen = el;

					} else if (bOpen && (el === '\\' || bEscape)) {
						bEscape = !bEscape;

					} else if (escapeMap[el] && bOpen === el && !bEscape) {
						bOpen = false;
						bEnd = false;
					}
				}

				let needSpace = lineWhiteSpaceRgxp.test(el);

				if (needSpace) {
					if (nmBrk === false) {
						nmBrk = true;
					}

				} else {
					lastEl = el;
					lastElI = res.length;
				}

				if (!nmBrk && !needSpace) {
					if (nmBrk === null) {
						nmBrk = false;
					}

					name += el;
				}

				if (nmBrk !== null) {
					res += el;
				}
			}
		}

		if (dir && lastEl === CONCAT_END && whiteSpaceRgxp.test(res.charAt(lastElI - 1))) {
			res = res.substring(0, lastElI) + res.substring(lastElI + 1);
		}

		return {
			command: res,
			length: length,
			name: name,
			lastEl: lastEl,
			sComment: !inline && sComment
		};
	}
})();
<commit_msg>Рефакторинг<commit_after>/*!
 * API для работы с Jade-Like синтаксисом
 */

(() => {
	var alb = ADV_LEFT_BLOCK,
		lb = LEFT_BLOCK,
		rb = RIGHT_BLOCK;

	var commandRgxp = /([^\s]+).*/,
		nonBlockCommentRgxp = /([^\\])\/\/\/(\s?)(.*)/,
		rightPartRgxp = new RegExp(`(?:${alb}?${lb}__&-__${rb}|)\\s*$`),
		rightWSRgxp = /\s*$/,
		lastSymbolRgxp = new RegExp(`(${alb}|\\\\)$`);

	var endDirInit,
		needSpace,
		nl;

	/**
	 * Вернуть объект-описание преобразованной части шаблона из
	 * Jade-Like синтаксиса в стандартный
	 *
	 * @param {string} str - исходная строка
	 * @param {number} i - номер начальной итерации
	 * @return {{str: string, length: number, error: (boolean|null|undefined)}}
	 */
	DirObj.prototype.toBaseSyntax = function (str, i) {
		needSpace = !this.tolerateWhitespace;
		nl = this.lineSeparator;
		endDirInit = false;

		var clrL = 0,
			init = true,
			spaces = 0,
			space = '';

		var struct,
			res = '';

		var length = 0,
			tSpace = 0;

		function f(struct, obj) {
			if (struct.block) {
				if (chains[struct.name] && chains[struct.name][obj.name]) {
					obj.block = true;
					obj.name = struct.name;

				} else if (ends[struct.name] && ends[struct.name][obj.name]) {
					obj.block = false;

				} else {
					let rightSpace = rightWSRgxp.exec(res)[0];
					res = res.replace(rightPartRgxp, '') +
						genEndDir(struct, struct.space);

					if (rightSpace && needSpace) {
						res += `${struct.adv}${lb}__&-__${rb}`;
					}

					res += rightSpace;
				}

			} else {
				endDirInit = false;
			}
		}

		for (let j = i - 1; ++j < str.length;) {
			length++;

			let el = str.charAt(j),
				next = str.charAt(j + 1);

			let next2str = str.substr(j, 2),
				diff2str = str.substr(j + 1, 2);

			if (nextLineRgxp.test(el)) {
				tSpace++;

				if (next2str === '\r\n') {
					continue;
				}

				if (clrL) {
					if (clrL === 1 && needSpace) {
						res += `${alb}${lb}__&-__${rb}`;
					}

					res += el;
				}

				clrL++;
				init = true;

				spaces = 0;
				space = nl;

			} else if (init) {
				if (whiteSpaceRgxp.test(el)) {
					spaces++;
					space += el;
					tSpace++;

				} else {
					let nextSpace = false,
						diff;

					init = false;
					clrL = 0;

					if (el === alb) {
						diff = shortMap[diff2str] ?
							3 : shortMap[next] ? 2 : 1;

					} else {
						diff = shortMap[next2str] ? 2 : 1;
					}

					let char = str.charAt(j + diff);
					nextSpace = !char || whiteSpaceRgxp.test(char);

					let dir = (shortMap[el] || shortMap[next2str]) && nextSpace,
						decl = getLineDesc(
							str,
							nextSpace && baseShortMap[el] || el === IGNORE_COMMAND ? j + 1 : j,
							Boolean(dir),
							next2str === MULT_COMMENT_START
						);

					if (!decl) {
						this.error('invalid syntax');
						return {
							str: '',
							length: 0,
							error: true
						};
					}

					let replacer;

					if (el === alb) {
						replacer = replacers[diff2str] ||
							replacers[next] ||
							replacers[next2str] ||
							replacers[el];

					} else {
						replacer = replacers[next2str] ||
							replacers[el];
					}

					if (replacer) {
						decl.name = replacer(decl.name).replace(commandRgxp, '$1');
					}

					let adv = el === alb ?
						alb : '';

					let s = dir ? adv + lb : '',
						e = dir ? rb : '';

					let obj = {
						dir: dir,
						name: decl.name,
						spaces: spaces,
						space: space,
						parent: null,
						block: dir && block[decl.name],
						text: !dir || text[decl.name],
						adv: adv
					};

					if (struct) {
						if (struct.spaces < spaces && struct.block) {
							obj.parent = struct;

							if (!obj.adv && struct.adv) {
								obj.block = false;
								adv = alb;
							}

						} else if (struct.spaces === spaces || struct.spaces < spaces && !struct.block) {
							obj.parent = struct.parent;

							if (!obj.adv && struct.parent && struct.parent.adv) {
								obj.block = false;
								adv = alb;
							}

							f(struct, obj);
							if (!struct.parent) {
								return {
									str: res,
									length: length - tSpace - 1
								};
							}

						} else {
							while (struct.spaces >= spaces) {
								f(struct, obj);
								struct = struct
									.parent;

								if (!struct) {
									return {
										str: res,
										length: length - tSpace - 1
									};
								}
							}

							obj.parent = struct;
						}
					}

					let parts,
						txt;

					decl.command = decl.command.replace(lastSymbolRgxp, '\\$1');

					if (dir) {
						if (decl.sComment) {
							parts = [decl.command];

						} else {
							parts = this.replaceDangerBlocks(decl.command).split(INLINE_COMMAND);

							for (let z = -1; ++z < parts.length;) {
								parts[z] = this.pasteDangerBlocks(parts[z]);
							}
						}

						txt = parts.slice(1).join(INLINE_COMMAND);
						txt = txt && txt.trim();
					}

					struct = obj;
					res += space;

					if (needSpace && (obj.text || !Snakeskin.Directions[obj.name])) {
						res += `${adv}${lb}__&-__${rb}`;
					}

					res += s + (dir ? parts[0] : decl.command).replace(nonBlockCommentRgxp, '$1/*$2$3$2*/') + e;
					endDirInit = false;

					let tmp = decl.length - 1;
					tSpace = 0;

					length += tmp;
					j += tmp;

					if (dir && txt) {
						let inline = {
							dir: false,
							spaces: spaces + 1,
							space: '',
							parent: obj,
							block: false,
							adv: ''
						};

						inline.parent = obj;
						struct = inline;
						res += txt;
					}
				}
			}
		}

		while (struct) {
			if (struct.block) {
				res += genEndDir(struct, struct.space);
			}

			struct = struct
				.parent;
		}

		return {
			str: res,
			length: length
		};
	};

	/**
	 * Вернуть строку окончания блоковой директивы
	 *
	 * @param {!Object} dir - объект-описание директивы
	 * @param {string} space - доступное свободное пространство
	 * @return {string}
	 */
	function genEndDir(dir, space) {
		var s = dir.adv + lb,
			tmp;

		if (needSpace) {
			tmp = `${endDirInit ? '' : `${s}__&+__${rb}`}${nl}`;

		} else {
			tmp = nl + (space || '').substring(1);
		}

		endDirInit = true;
		return `${tmp}${s}__end__${rb}${s}__cutLine__${rb}`;
	}

	/**
	 * Вернуть объект описание строки в Jade-Like синтаксисе
	 *
	 * @param {string} str - исходная строка
	 * @param {number} i - номер начальной итерации
	 * @param {boolean} dir - если true, то идёт декларация директивы
	 * @param {boolean} comment - если true, то идёт декларация мультистрочного комментария
	 * @return {{command: string, length: number, name: string, lastEl: string, sComment: boolean}}
	 */
	function getLineDesc(str, i, dir, comment) {
		var res = '',
			name = '';

		var lastEl = '',
			lastElI = 0,
			length = -1;

		var escape = false;
		var sComment = false,
			inline = false;

		var bOpen = false,
			bEnd = true,
			bEscape = false;

		var part = '',
			rPart = '';

		var concatLine = false,
			nmBrk = null;

		for (let j = i - 1; ++j < str.length;) {
			let currentEscape = escape,
				el = str.charAt(j);

			if (!bOpen && (el === '\\' || escape)) {
				escape = !escape;
			}

			length++;
			if (nextLineRgxp.test(el)) {
				if (!comment && !bOpen) {
					rPart = sComment ?
						'' : part;

					part = '';
				}

				let prevEl = lastEl,
					brk = false;

				lastEl = '';
				if (comment || (sComment && concatLine)) {
					res += el;

				} else if (!sComment && dir) {
					let dirStart = whiteSpaceRgxp.test(
						str.charAt(j - 2)
					);

					let literal;
					brk = dirStart &&
						prevEl === CONCAT_END;

					if (dirStart && (prevEl === CONCAT_COMMAND && res !== CONCAT_COMMAND || brk)) {
						literal = prevEl;
						res = res.substring(0, lastElI - 1) +
							res.substring(lastElI + 1);

					} else if (concatLine && !bOpen) {
						res += el;
					}

					if (concatLine && !brk) {
						continue;
					}

					if (literal === CONCAT_COMMAND) {
						concatLine = true;

						if (!bOpen) {
							res += el;
						}

						continue;
					}
				}

				if (comment || concatLine && !brk) {
					sComment = false;
					continue;
				}

				return {
					command: res,
					length: length,
					name: name,
					lastEl: lastEl,
					sComment: !inline && sComment
				};

			} else {
				if (!bOpen && !currentEscape) {
					let commentType = returnComment(str, j);

					if (comment) {
						comment = commentType !== MULT_COMMENT_END;

					} else if (!sComment) {
						comment = commentType === MULT_COMMENT_START;

						if (!comment) {
							sComment = commentType === SINGLE_COMMENT;
						}
					}
				}

				if (!comment && !sComment) {
					if (!bOpen) {
						if (escapeEndMap[el] || escapeEndWords[rPart]) {
							bEnd = true;

						} else if (bEndRgxp.test(el)) {
							bEnd = false;
						}

						if (escapeEndMap[el] || escapeEndWords[rPart]) {
							bEnd = true;

						} else if (bEndRgxp.test(el)) {
							bEnd = false;
						}

						if (partRgxp.test(el)) {
							part += el;

						} else {
							rPart = part;
							part = '';
						}

						if (dir && !inline) {
							inline = str.substr(j, INLINE_COMMAND.length) === INLINE_COMMAND;
						}
					}

					if (escapeMap[el] && (el !== '/' || bEnd) && !bOpen) {
						bOpen = el;

					} else if (bOpen && (el === '\\' || bEscape)) {
						bEscape = !bEscape;

					} else if (escapeMap[el] && bOpen === el && !bEscape) {
						bOpen = false;
						bEnd = false;
					}
				}

				let needSpace = lineWhiteSpaceRgxp.test(el);

				if (needSpace) {
					if (nmBrk === false) {
						nmBrk = true;
					}

				} else {
					lastEl = el;
					lastElI = res.length;
				}

				if (!nmBrk && !needSpace) {
					if (nmBrk === null) {
						nmBrk = false;
					}

					name += el;
				}

				if (nmBrk !== null) {
					res += el;
				}
			}
		}

		if (dir && lastEl === CONCAT_END && whiteSpaceRgxp.test(res.charAt(lastElI - 1))) {
			res = res.substring(0, lastElI) + res.substring(lastElI + 1);
		}

		return {
			command: res,
			length: length,
			name: name,
			lastEl: lastEl,
			sComment: !inline && sComment
		};
	}
})();
<|endoftext|>