<commit_before>(function(){

    // underscore simulation.

    var _ = {};

    _.map = function(ary, f) {
      var ret = [];
      for (var i = 0; i < ary.length; i++) {
        ret.push(f(ary[i]));
      }
      return ret;
    };

    _.filter = function(ary, f) {
      var ret = [];
      for (var i = 0; i < ary.length; i++) {
        if ( f(ary[i]) ) ret.push(ary[i]);
      }
      return ret;
    };

    _.find = function(ary, f) {
      for (var i = 0; i < ary.length; i++) {
        if ( f(ary[i]) ) return ary[i];
      }
      return null;
    };

    // Variables and functions go here.
    var root = this;
    var cubes = { };

    cubes.Server = function(ajaxHandler){

        // Represents Cubes Slicer Server connection.
        //
        // Attributes:
        //
        // * `ajaxHandler`: a function accepting jquery-style settings object as in $.ajax(settings)
        //

        this.ajaxRequest = ajaxHandler;
    }

    cubes.Server.prototype.ajaxRequest = function(settings) {
        throw "Must implement ajaxRequest for server to process jquery-style $.ajax settings object";
    };

    cubes.Server.prototype.query = function(query, cube, args, callback) {
        var params = {dataType : 'json', type : "GET"};

        if(cube.hasOwnProperty("name"))
            cube_name = cube.name
        else
            cube_name = cube

        params.url = this.url + "cube/" + cube_name + "/" + query
        params.data = args

        if(args && args.cut)
            params.data.cut = params.data.cut.toString()

        params.success = function(obj) {
            console.log("browser query ok", obj)
            callback(obj)
        }
        params.error = function(obj) {
            console.log("browser query error", obj)
            // FIXME: Some error handler here
        }

        console.log("cubes query: ", path, params.data)
        return this.ajaxRequest(params)
    };

    cubes.Server.prototype.connect = function(url, callback) {
        var self = this;

        self.url = self._normalize_url(url);

        var options = {dataType : 'json', type : "GET", error: self._onError};

        options.url = self.url + 'version';

        options.success = function(resp, status, xhr) {
            console.log(resp);
            self.server_version = resp.server_version;
            self.api_version = resp.api_version;
            console.log("slicer connected: version=" + self.server_version +
                            " API=" + self.api_version)
            self.load_model(callback);
        };

        this.ajaxRequest(options);
    };

    cubes.Server.prototype._normalize_url = function(url) {
        if(url[url.length-1] != '/')
            return url + '/';
        return url;
    };

    cubes.Server.prototype.load_model = function(callback) {
        var self = this;

        var options = {dataType : 'json', type : "GET", error: self._onError};

        options.url = self.url + 'model';

        options.success = function(resp, status, xhr) {
            self.model = new cubes.Model(resp);

            // FIXME: handle model parse failure

            if (callback)
                callback(self.model);
        };

        return this.ajaxRequest(options);
    };

    cubes.Model = function(obj){
        // obj - model description
        this.parse(obj)
    }

    cubes.Model.prototype.parse = function(desc) {
        var model = this;

        !desc.name        || (model.name = desc.name);
        !desc.label       || (model.label = desc.label);
        !desc.description || (model.description = desc.description);
        !desc.locale      || (model.locale = desc.locale);
        model.locales = desc.locales;

        model.dimensions = []

        if(desc.dimensions) {
            for(i in desc.dimensions) {
                var dim = new cubes.Dimension(desc.dimensions[i])
                model.dimensions.push(dim)
            }
        }

        model.cubes = []

        if(desc.cubes) {
            for(i in desc.cubes) {
                var cube = new cubes.Cube(desc.cubes[i], this)
                model.cubes.push(cube)
            }
        }

    };

    cubes.Model.prototype.dimension = function(name) {
        // Return a dimension with given name
        return _.find(this.dimensions, function(dim){return dim.name == name;})
    };

    cubes.Model.prototype.cube = function(name) {
        // Return a dimension with given name
        return _.find(this.cubes, function(obj){return obj.name == name;})
    };

    cubes.Cube = function(obj, model){
        this.url = null;
        this.parse(obj, model)
    };

    cubes.Cube.prototype.parse = function(desc, model) {
        this.name = desc.name;
        !desc.label || (this.label = desc.label);
        !desc.description || (this.description = desc.description);
        !desc.key || (this.key = desc.key);

        this.measures = []

        for(i in desc.measures) {
            var obj = new cubes.Attribute(desc.measures[i])
            this.measures.push(obj)
        }

        this.details = []

        for(i in desc.details) {
            var obj = new cubes.Attribute(desc.details[i])
            this.details.push(obj)
        }

        this.dimensions = _.map(desc.dimensions, function(name) {return model.dimension(name)} )
    };

    cubes.Cube.prototype.dimension = function(name) {
        // Return a dimension with given name
        return _.find(this.dimensions, function(obj){return obj.name == obj;})
    };

    cubes.Dimension = function(obj){
        this.parse(obj)
    };

    cubes.Dimension.prototype.parse = function(desc) {
        var dim = this;
        dim.name = desc.name;
        !desc.label || (dim.label = desc.label);
        !desc.description || (dim.description = desc.description);
        !desc.default_hierarchy_name || (dim.default_hierarchy_name = desc.default_hierarchy_name);

        dim.levels = {};

        if(desc.levels) {
            for(i in desc.levels) {
                var level = new cubes.Level(desc.levels[i])
                dim.levels[level.name] = level
            }
        };

        this.hierarchies = {};

        if(desc.hierarchies) {
            for(i in desc.hierarchies) {
                var hier = new cubes.Hierarchy(desc.hierarchies[i], this)
                dim.hierarchies[hier.name] = hier
            }
        }

    };

    cubes.Dimension.prototype.level = function(name) {
        // Return a level with given name
        return _.find(this.levels, function(obj){return obj.name == obj;})
    };

    cubes.Dimension.prototype.toString = function(desc) {
        return this.name;
    };

    cubes.Dimension.prototype.display_label = function() {
        return this.label || this.name;
    };

    cubes.Dimension.prototype.hierarchy = function(name) {
        if(name)
            return this.hierarchies[name]
        else
            return this.hierarchies[default_hierarchy_name]
    };

    cubes.Hierarchy = function(obj, dim){
        this.parse(obj, dim)
    };

    cubes.Hierarchy.prototype.parse = function(desc, dim) {
        var hier = this;
        hier.name = desc.name
        !desc.label || (hier.label = desc.label)
        !desc.description || (hier.description = desc.description)

        hier._level_names = []

        for(i in desc.levels) {
            hier._level_names.push(desc.levels[i])
        }

        hier.levels = _.map(hier._level_names, function(name) {return dim.level(name)} )
    };

    cubes.Hierarchy.prototype.toString = function(desc) {
        return cubes.HIERARCHY_PREFIX_CHAR + this.name;
    };

    cubes.Hierarchy.prototype.display_label = function() {
        return this.label || this.name;
    };

    cubes.Level = function(obj){
        this.parse(obj)
    };

    cubes.Level.prototype.parse = function(desc) {
        var level = this;
        level.name = desc.name
        !desc.label || (level.label = desc.label)
        !desc.description || (level.description = desc.description)
        level._key = desc.key
        level._label_attribute = desc.label_attribute

        level.attributes = []

        if(desc.attributes) {
            for(i in desc.attributes) {
                var attr = new cubes.Attribute(desc.attributes[i])
                level.attributes.push(attr)
            }
        }
    };

    cubes.Level.prototype.key = function(desc) {
        // Key attribute is either explicitly specified or it is first attribute in the list
        return level._key || level.attributes[0];
    };

    cubes.Level.prototype.label_attribute = function(desc) {
        // Label attribute is either explicitly specified or it is second attribute if there are more
        // than one, otherwise it is first
        return level._label_attribute || level.attributes[1] || level.attributes[0];
    };

    cubes.Level.prototype.toString = function(desc) {
        return this.name;
    };

    cubes.Level.prototype.full_name = function(dimension) {
        return dimension + "." + this.name
    };

    cubes.Attribute = function(obj){
        this.name = obj.name;
        this.label = obj.label;
        this.order = obj.order;
        this.locales = obj.locales;
    };

    cubes.Browser = function(server, cube){
        this.cube = cube
        this.server = server
    };

    cubes.Browser.prototype.full_cube = function(dimension) {
        return new cubes.Cell(self.cube)
    };

    cubes.Browser.prototype.aggregate = function(cell, drilldown, callback) {
        var args = {}

        if (cell) args.cut = cell
        if (drilldown) args.drilldown = drilldown

        this.server.query("aggregate", this.cube, args, callback)
    };

    cubes.Cell = function(cube){
        this.cube = cube;
        this.cuts = [];
    };

    cubes.Cell.prototype.slice = function(dimension, path) {
        var cuts = _.filter(this.cuts, function(cut) {cut.dimension != dimension} )
        if(path) {
            cut = cubes.PointCut(dimension, path)
            cuts.push(cut)
        }
        var cell = cubes.Cell(self.cube);
        cell.cuts = cuts;
        return cell;
    };

    cubes.Cell.prototype.toString = function() {
        return _.map(this.cuts || [], function(cut) { return cut.toString(); }).join(cubes.CUT_STRING_SEPARATOR_CHAR);
    };

    cubes.Cell.prototype.cut_for_dimension = function(name) {
        return _.find(this.cuts, function(cut){
            return cut.dimension.name == name
        })
    };

    cubes.PointCut = function(dimension, hierarchy, path, invert){
        this.dimension = dimension;
        this.hierarchy = hierarchy;
        this.path = path;
        this.invert = !!invert;
    };

    cubes.PointCut.prototype.toString = function() {
        var path_str = cubes.string_from_path(this.path);
        return (this.invert ? cubes.CUT_INVERSION_CHAR : "")
            + this.dimension
            + this.hierarchy
            + cubes.DIMENSION_STRING_SEPARATOR_CHAR
            + path_str;
    };

    cubes.SetCut = function(dimension, hierarchy, paths){
        this.dimension = dimension;
        this.hierarchy = hierarchy;
        this.paths = paths;
        this.invert = !!invert;
    };

    cubes.SetCut.prototype.toString = function() {
        var path_str = _.map(this.paths, cubes.string_from_path).join(cubes.SET_CUT_SEPARATOR_CHAR);
        return (this.invert ? cubes.CUT_INVERSION_CHAR : "")
            + this.dimension
            + this.hierarchy
            + cubes.DIMENSION_STRING_SEPARATOR_CHAR
            + path_str;
    };

    cubes.RangeCut = function(dimension, hierarchy, from_path, to_path, invert){
        this.dimension = dimension;
        this.hierarchy = hierarchy;
        if ( from_path == null && to_path == null ) {
            throw "Either from_path or to_path must be defined for RangeCut";
        }
        this.from_path = from_path;
        this.to_path = to_path;
        this.invert = !!invert;
    };

    cubes.RangeCut.prototype.toString = function() {
        var path_str = cubes.string_from_path(this.from_path) + cubes.RANGE_CUT_SEPARATOR_CHAR + cubes.string_from_path(this.to_path);
        return (this.invert ? cubes.CUT_INVERSION_CHAR : "")
            + this.dimension
            + this.hierarchy
            + cubes.DIMENSION_STRING_SEPARATOR_CHAR
            + path_str;
    };

    cubes.CUT_INVERSION_CHAR = "!";
    cubes.CUT_STRING_SEPARATOR_CHAR = "|";
    cubes.DIMENSION_STRING_SEPARATOR_CHAR = ":";
    cubes.HIERARCHY_PREFIX_CHAR = "@";
    cubes.PATH_STRING_SEPARATOR_CHAR = ",";
    cubes.RANGE_CUT_SEPARATOR_CHAR = "-";
    cubes.SET_CUT_SEPARATOR_CHAR = ";";

    cubes.CUT_STRING_SEPARATOR = /(?!\\)\|/;
    cubes.DIMENSION_STRING_SEPARATOR = /(?!\\):/;
    cubes.PATH_STRING_SEPARATOR = /(?!\\),/;
    cubes.RANGE_CUT_SEPARATOR = /(?!\\)-/;
    cubes.SET_CUT_SEPARATOR = /(?!\\);/;

    cubes.PATH_PART_ESCAPE_PATTERN = /([\\!|:;,-])/g;
    cubes.PATH_PART_UNESCAPE_PATTERN = /\\([\\!|;,-])/g;

    cubes._escape_path_part = function(part) {
        return part.replace(cubes.PATH_PART_ESCAPE_PATTERN, function(match, b1) { return "\\" + b1; });
    };

    cubes._unescape_path_part = function(part) {
        return part.replace(cubes.PATH_PART_UNESCAPE_PATTERN, function(match, b1) { return b1; });
    };

    cubes.string_from_path = function(path){
        var fixed_path = _.map(path || [], function(element) {return cubes._escape_path_part(element || "");})
        return fixed_path.join(cubes.PATH_STRING_SEPARATOR_CHAR);
        return string;
    };

    root['cubes'] = cubes;
}).call(this);
<commit_msg>linting fixes<commit_after>(function(){

    // underscore simulation.

    var _ = {};

    _.map = function(ary, f) {
      var ret = [];
      for (var i = 0; i < ary.length; i++) {
        ret.push(f(ary[i]));
      }
      return ret;
    };

    _.filter = function(ary, f) {
      var ret = [];
      for (var i = 0; i < ary.length; i++) {
        if ( f(ary[i]) ) ret.push(ary[i]);
      }
      return ret;
    };

    _.find = function(ary, f) {
      for (var i = 0; i < ary.length; i++) {
        if ( f(ary[i]) ) return ary[i];
      }
      return null;
    };

    // Variables and functions go here.
    var root = this;
    var cubes = { };

    cubes.Server = function(ajaxHandler){
        // Represents Cubes Slicer Server connection.
        //
        // Attributes:
        //
        // * `ajaxHandler`: a function accepting jquery-style settings object as in $.ajax(settings)
        //

        this.ajaxRequest = ajaxHandler;
    };

    cubes.Server.prototype.ajaxRequest = function(settings) {
        throw "Must implement ajaxRequest for server to process jquery-style $.ajax settings object";
    };

    cubes.Server.prototype.query = function(query, cube, args, callback) {
        var params = {dataType : 'json', type : "GET"};

        if(cube.hasOwnProperty("name"))
            cube_name = cube.name;
        else
            cube_name = cube;

        params.url = this.url + "cube/" + cube_name + "/" + query;
        params.data = args;

        if(args && args.cut)
            params.data.cut = params.data.cut.toString();

        params.success = function(obj) {
            console.log("browser query ok", obj);
            callback(obj);
        };
        params.error = function(obj) {
            console.log("browser query error", obj);
            // FIXME: Some error handler here
        };

        console.log("cubes query: ", path, params.data);
        return this.ajaxRequest(params);
    };

    cubes.Server.prototype.connect = function(url, callback) {
        var self = this;

        self.url = self._normalize_url(url);

        var options = {dataType : 'json', type : "GET", error: self._onError};

        options.url = self.url + 'version';

        options.success = function(resp, status, xhr) {
            console.log(resp);
            self.server_version = resp.server_version;
            self.api_version = resp.api_version;
            console.log("slicer connected: version=" + self.server_version +
                            " API=" + self.api_version);
            self.load_model(callback);
        };

        this.ajaxRequest(options);
    };

    cubes.Server.prototype._normalize_url = function(url) {
        if(url[url.length-1] != '/')
            return url + '/';
        return url;
    };

    cubes.Server.prototype.load_model = function(callback) {
        var self = this;

        var options = {dataType : 'json', type : "GET", error: self._onError};

        options.url = self.url + 'model';

        options.success = function(resp, status, xhr) {
            self.model = new cubes.Model(resp);

            // FIXME: handle model parse failure

            if (callback)
                callback(self.model);
        };

        return this.ajaxRequest(options);
    };

    cubes.Model = function(obj){
        // obj - model description
        this.parse(obj);
    };

    cubes.Model.prototype.parse = function(desc) {
        var model = this;
        var i;

        !desc.name        || (model.name = desc.name);
        !desc.label       || (model.label = desc.label);
        !desc.description || (model.description = desc.description);
        !desc.locale      || (model.locale = desc.locale);
        model.locales = desc.locales;

        model.dimensions = [];

        if(desc.dimensions) {
            for(i in desc.dimensions) {
                var dim = new cubes.Dimension(desc.dimensions[i]);
                model.dimensions.push(dim);
            }
        }

        model.cubes = [];

        if(desc.cubes) {
            for(i in desc.cubes) {
                var cube = new cubes.Cube(desc.cubes[i], this);
                model.cubes.push(cube);
            }
        }

    };

    cubes.Model.prototype.dimension = function(name) {
        // Return a dimension with given name
        return _.find(this.dimensions, function(dim){return dim.name == name;});
    };

    cubes.Model.prototype.cube = function(name) {
        // Return a dimension with given name
        return _.find(this.cubes, function(obj){return obj.name == name;});
    };

    cubes.Cube = function(obj, model) {
        this.url = null;
        this.parse(obj, model);
    };

    cubes.Cube.prototype.parse = function(desc, model) {
        var i, obj;

        this.name = desc.name;
        !desc.label || (this.label = desc.label);
        !desc.description || (this.description = desc.description);
        !desc.key || (this.key = desc.key);

        this.measures = [];

        for(i in desc.measures) {
            obj = new cubes.Attribute(desc.measures[i]);
            this.measures.push(obj);
        }

        this.details = [];

        for(i in desc.details) {
            obj = new cubes.Attribute(desc.details[i]);
            this.details.push(obj);
        }

        this.dimensions = _.map(desc.dimensions, function(name) {return model.dimension(name);} );
    };

    cubes.Cube.prototype.dimension = function(name) {
        // Return a dimension with given name
        return _.find(this.dimensions, function(obj){return obj.name == obj;});
    };

    cubes.Dimension = function(obj){
        this.parse(obj);
    };

    cubes.Dimension.prototype.parse = function(desc) {
        var dim = this;
        var i;

        dim.name = desc.name;
        !desc.label || (dim.label = desc.label);
        !desc.description || (dim.description = desc.description);
        !desc.default_hierarchy_name || (dim.default_hierarchy_name = desc.default_hierarchy_name);

        dim.levels = {};

        if(desc.levels) {
            for(i in desc.levels) {
                var level = new cubes.Level(desc.levels[i]);
                dim.levels[level.name] = level;
            }
        }

        this.hierarchies = {};

        if(desc.hierarchies) {
            for(i in desc.hierarchies) {
                var hier = new cubes.Hierarchy(desc.hierarchies[i], this);
                dim.hierarchies[hier.name] = hier;
            }
        }
    };

    cubes.Dimension.prototype.level = function(name) {
        // Return a level with given name
        return _.find(this.levels, function(obj){return obj.name == obj;});
    };

    cubes.Dimension.prototype.toString = function(desc) {
        return this.name;
    };

    cubes.Dimension.prototype.display_label = function() {
        return this.label || this.name;
    };

    cubes.Dimension.prototype.hierarchy = function(name) {
        if(name)
            return this.hierarchies[name];
        else
            return this.hierarchies[default_hierarchy_name];
    };

    cubes.Hierarchy = function(obj, dim){
        this.parse(obj, dim);
    };

    cubes.Hierarchy.prototype.parse = function(desc, dim) {
        var hier = this;
        var i;

        hier.name = desc.name
        !desc.label || (hier.label = desc.label)
        !desc.description || (hier.description = desc.description)

        hier._level_names = [];

        for(i in desc.levels) {
            hier._level_names.push(desc.levels[i]);
        }

        hier.levels = _.map(hier._level_names, function(name) {return dim.level(name);} );
    };

    cubes.Hierarchy.prototype.toString = function(desc) {
        return cubes.HIERARCHY_PREFIX_CHAR + this.name;
    };

    cubes.Hierarchy.prototype.display_label = function() {
        return this.label || this.name;
    };

    cubes.Level = function(obj){
        this.parse(obj);
    };

    cubes.Level.prototype.parse = function(desc) {
        var level = this;
        var i;

        level.name = desc.name
        !desc.label || (level.label = desc.label)
        !desc.description || (level.description = desc.description)
        level._key = desc.key
        level._label_attribute = desc.label_attribute

        level.attributes = [];

        if(desc.attributes) {
            for(i in desc.attributes) {
                var attr = new cubes.Attribute(desc.attributes[i]);
                level.attributes.push(attr);
            }
        }
    };

    cubes.Level.prototype.key = function(desc) {
        // Key attribute is either explicitly specified or it is first attribute in the list
        return level._key || level.attributes[0];
    };

    cubes.Level.prototype.label_attribute = function(desc) {
        // Label attribute is either explicitly specified or it is second attribute if there are more
        // than one, otherwise it is first
        return level._label_attribute || level.attributes[1] || level.attributes[0];
    };

    cubes.Level.prototype.toString = function(desc) {
        return this.name;
    };

    cubes.Level.prototype.full_name = function(dimension) {
        return dimension + "." + this.name;
    };

    cubes.Attribute = function(obj){
        this.name = obj.name;
        this.label = obj.label;
        this.order = obj.order;
        this.locales = obj.locales;
    };

    cubes.Browser = function(server, cube){
        this.cube = cube;
        this.server = server;
    };

    cubes.Browser.prototype.full_cube = function(dimension) {
        return new cubes.Cell(self.cube);
    };

    cubes.Browser.prototype.aggregate = function(cell, drilldown, callback) {
        var args = {};

        if (cell) args.cut = cell;
        if (drilldown) args.drilldown = drilldown;

        this.server.query("aggregate", this.cube, args, callback);
    };

    cubes.Cell = function(cube){
        this.cube = cube;
        this.cuts = [];
    };

    cubes.Cell.prototype.slice = function(dimension, path) {
        var cuts = _.filter(this.cuts, function(cut) {cut.dimension != dimension} );
        if(path) {
            cut = cubes.PointCut(dimension, path);
            cuts.push(cut);
        }
        var cell = cubes.Cell(self.cube);
        cell.cuts = cuts;
        return cell;
    };

    cubes.Cell.prototype.toString = function() {
        return _.map(this.cuts || [], function(cut) { return cut.toString(); }).join(cubes.CUT_STRING_SEPARATOR_CHAR);
    };

    cubes.Cell.prototype.cut_for_dimension = function(name) {
        return _.find(this.cuts, function(cut) {
            return cut.dimension.name == name;
        });
    };

    cubes.PointCut = function(dimension, hierarchy, path, invert){
        this.dimension = dimension;
        this.hierarchy = hierarchy;
        this.path = path;
        this.invert = !!invert;
    };

    cubes.PointCut.prototype.toString = function() {
        var path_str = cubes.string_from_path(this.path);
        return (this.invert ? cubes.CUT_INVERSION_CHAR : "") +
            this.dimension +
            this.hierarchy +
            cubes.DIMENSION_STRING_SEPARATOR_CHAR +
            path_str;
    };

    cubes.SetCut = function(dimension, hierarchy, paths){
        this.dimension = dimension;
        this.hierarchy = hierarchy;
        this.paths = paths;
        this.invert = !!invert;
    };

    cubes.SetCut.prototype.toString = function() {
        var path_str = _.map(this.paths, cubes.string_from_path).join(cubes.SET_CUT_SEPARATOR_CHAR);
        return (this.invert ? cubes.CUT_INVERSION_CHAR : "") +
            this.dimension +
            this.hierarchy +
            cubes.DIMENSION_STRING_SEPARATOR_CHAR +
            path_str;
    };

    cubes.RangeCut = function(dimension, hierarchy, from_path, to_path, invert){
        this.dimension = dimension;
        this.hierarchy = hierarchy;
        if ( from_path === null && to_path === null ) {
            throw "Either from_path or to_path must be defined for RangeCut";
        }
        this.from_path = from_path;
        this.to_path = to_path;
        this.invert = !!invert;
    };

    cubes.RangeCut.prototype.toString = function() {
        var path_str = cubes.string_from_path(this.from_path) + cubes.RANGE_CUT_SEPARATOR_CHAR + cubes.string_from_path(this.to_path);
        return (this.invert ? cubes.CUT_INVERSION_CHAR : "") +
            this.dimension +
            this.hierarchy +
            cubes.DIMENSION_STRING_SEPARATOR_CHAR +
            path_str;
    };

    cubes.CUT_INVERSION_CHAR = "!";
    cubes.CUT_STRING_SEPARATOR_CHAR = "|";
    cubes.DIMENSION_STRING_SEPARATOR_CHAR = ":";
    cubes.HIERARCHY_PREFIX_CHAR = "@";
    cubes.PATH_STRING_SEPARATOR_CHAR = ",";
    cubes.RANGE_CUT_SEPARATOR_CHAR = "-";
    cubes.SET_CUT_SEPARATOR_CHAR = ";";

    cubes.CUT_STRING_SEPARATOR = /(?!\\)\|/;
    cubes.DIMENSION_STRING_SEPARATOR = /(?!\\):/;
    cubes.PATH_STRING_SEPARATOR = /(?!\\),/;
    cubes.RANGE_CUT_SEPARATOR = /(?!\\)-/;
    cubes.SET_CUT_SEPARATOR = /(?!\\);/;

    cubes.PATH_PART_ESCAPE_PATTERN = /([\\!|:;,-])/g;
    cubes.PATH_PART_UNESCAPE_PATTERN = /\\([\\!|;,-])/g;

    cubes._escape_path_part = function(part) {
        return part.replace(cubes.PATH_PART_ESCAPE_PATTERN, function(match, b1) { return "\\" + b1; });
    };

    cubes._unescape_path_part = function(part) {
        return part.replace(cubes.PATH_PART_UNESCAPE_PATTERN, function(match, b1) { return b1; });
    };

    cubes.string_from_path = function(path){
        var fixed_path = _.map(path || [], function(element) {return cubes._escape_path_part(element || "");});
        return fixed_path.join(cubes.PATH_STRING_SEPARATOR_CHAR);
    };

    root['cubes'] = cubes;
}).call(this);
<|endoftext|>


<commit_before>function createTestObject() {
  return [
    {
      "id": 1,
      "name": "Leanne Graham",
      "username": "Bret",
      "email": "Sincere@april.biz",
      "address": {
        "street": "Kulas Light",
        "suite": "Apt. 556",
        "city": "Gwenborough",
        "zipcode": 92998,
        "geo": {
          "lat": -37.3159,
          "lng": 81.1496
        }
      },
      "website": null,
      "company": {
        "active": false,
        "name": "Romaguera-Crona",
        "catchPhrase": "Multi-layered client-server neural-net",
        "bs": "harness real-time e-markets"
      }
    },
    {
      "id": 2,
      "name": "Ervin Howell",
      "username": "Antonette",
      "email": "Shanna@melissa.tv",
      "address": {
        "street": "Victor Plains",
        "suite": "Suite 879",
        "city": "Wisokyburgh",
        "zipcode": 90566,
        "geo": {
          "lat": -43.9509,
          "lng": -34.4618
        }
      },
      "website": null,
      "company": {
        "active": true,
        "name": "Deckow-Crist",
        "catchPhrase": "Proactive didactic contingency",
        "bs": "synergize scalable supply-chains"
      }
    }
  ];
}
var testObjects = {};
testObjects["Multidimensional Acyclic"] = createTestObject();
testObjects["Linear Acyclic"] = ["one", "two", "three"];
// Fourth element is a cycle
testObjects["Linear Cyclic"] = ["one", "two", "three"];
testObjects["Linear Cyclic"][3] = testObjects["Linear Cyclic"];
// `otherUser` properties are a cycle
testObjects["Multidimensional Cyclic"] = createTestObject();
testObjects["Multidimensional Cyclic"][0].otherUser = testObjects["Multidimensional Cyclic"][1];
testObjects["Multidimensional Cyclic"][1].otherUser = testObjects["Multidimensional Cyclic"][0];

function createKeyCounter() {
  var testObject = testObjects["Multidimensional Cyclic"];
  var keyCounts = {};
  for (var key in testObject) {
    keyCounts[key] = 0;
  }
  for (var key in testObject[0]) {
    keyCounts[key] = 0;
  }
  for (var key in testObject[0]["address"]) {
    keyCounts[key] = 0;
  }
  for (var key in testObject[0]["address"]["geo"]) {
    keyCounts[key] = 0;
  }
  for (var key in testObject[0]["company"]) {
    keyCounts[key] = 0;
  }
  return keyCounts;
}

describe("isContainer", function () {
  var array = [];
  var object = {};
  it("should return true if the input is an Object or Array", function () {
    expect(differentia.isContainer(array)).toBe(true);
    expect(differentia.isContainer(object)).toBe(true);
  });
  it("should return false if the input is not an Object or Array", function () {
    expect(differentia.isContainer(12345)).toBe(false);
    expect(differentia.isContainer("Hello World")).toBe(false);
    expect(differentia.isContainer(true)).toBe(false);
    expect(differentia.isContainer(false)).toBe(false);
  });
});

describe("getContainerLength", function () {
  var array = [1, 2, 3, 4, 5];
  var object = { 1: 1, 2: 2, 3: 3, 4: 4, 5: 5 };
  it("should count 5 items in each container", function () {
    expect(differentia.getContainerLength(array)).toBe(5);
    expect(differentia.getContainerLength(object)).toBe(5);
  });
});

describe("Iterative Deepening Depth-First Search", function () {
  it("should throw a TypeError when no arguments are given", function () {
    expect(() => differentia.iddfs().next()).toThrow(new TypeError("Argument 1 must be an Object or Array"));
  });
  it("should throw a TypeError when argument 2 is not given", function () {
    expect(() => differentia.iddfs({}).next()).toThrow(new TypeError("Argument 2 must be a non-empty Object or Array"));
  });
  it("should throw a TypeError when any arguments are the wrong type", function () {
    expect(() => differentia.iddfs(123).next()).toThrow(new TypeError("Argument 1 must be an Object or Array"));
    expect(() => differentia.iddfs("test").next()).toThrow(new TypeError("Argument 1 must be an Object or Array"));
    expect(() => differentia.iddfs({}, 123).next()).toThrow(new TypeError("Argument 2 must be a non-empty Object or Array"));
    expect(() => differentia.iddfs({}, "test").next()).toThrow(new TypeError("Argument 2 must be a non-empty Object or Array"));
  });
  it("should iterate all nodes and properties", function () {
    var keyCounts = createKeyCounter();
    var testObject = testObjects["Multidimensional Cyclic"];
    var iterator = differentia.iddfs(testObject, testObject);
    var iteration = iterator.next();
    while (!iteration.done) {
      keyCounts[iteration.value.accessor]++;
      iteration = iterator.next();
    }
    console.group("IDDFS Traversal & Iteration Results:");
    for (var accessor in keyCounts) {
      console.info("Accessor \"" + accessor + "\" was visited " + keyCounts[accessor] + " time(s).");
      expect(keyCounts[accessor] > 0).toBe(true);
    }
    console.groupEnd();
  });
});

describe("forEach", function () {
  it("should iterate all nodes and properties", function () {
    var keyCounts = createKeyCounter();
    var testObject = testObjects["Multidimensional Cyclic"];
    differentia.forEach(testObject, function (value, accessor, object) {
      keyCounts[accessor]++;
    });
    console.group("forEach Traversal & Iteration Results:");
    for (var accessor in keyCounts) {
      console.info("Accessor \"" + accessor + "\" was visited " + keyCounts[accessor] + " time(s).");
      expect(keyCounts[accessor] > 0).toBe(true);
    }
    console.groupEnd();
  });
});

describe("Diff", function () {
  it("should return true when two objects differ", function () {
    expect(differentia.diff(testObjects["Linear Acyclic"], testObjects["Linear Cyclic"])).toBe(true);
    expect(differentia.diff(testObjects["Multidimensional Cyclic"], testObjects["Multidimensional Acyclic"])).toBe(true);
    expect(differentia.diff(testObjects["Linear Cyclic"], testObjects["Multidimensional Acyclic"])).toBe(true);
  });
  it("should return false when two objects are the same", function () {
    expect(differentia.diff(testObjects["Linear Acyclic"], testObjects["Linear Acyclic"])).toBe(false);
    expect(differentia.diff(testObjects["Linear Cyclic"], testObjects["Linear Cyclic"])).toBe(false);
    expect(differentia.diff(testObjects["Multidimensional Acyclic"], testObjects["Multidimensional Acyclic"])).toBe(false);
    expect(differentia.diff(testObjects["Multidimensional Cyclic"], testObjects["Multidimensional Cyclic"])).toBe(false);
  });
  it("should return true when two objects differ using the search index", function () {
    expect(differentia.diff(testObjects["Linear Acyclic"], testObjects["Linear Cyclic"], { 3: null })).toBe(true);
  });
  it("should return false when two objects are the same using the search index", function () {
    expect(differentia.diff(testObjects["Linear Acyclic"], testObjects["Linear Cyclic"], { 1: null })).toBe(false);
  });
});

describe("Clone", function () {
  it("should make an exact copy of the subject", function () {
    var clone = differentia.clone(testObjects["Linear Acyclic"]);
    expect(differentia.diff(clone, testObjects["Linear Acyclic"])).toBe(false);
    clone = differentia.clone(testObjects["Linear Cyclic"]);
    expect(differentia.diff(clone, testObjects["Linear Cyclic"])).toBe(false);
    clone = differentia.clone(testObjects["Multidimensional Cyclic"]);
    expect(differentia.diff(clone, testObjects["Multidimensional Cyclic"])).toBe(false);
  });
  it("should clone properties using the search index", function () {
    var clone = differentia.clone(testObjects["Linear Acyclic"], { 2: null });
    var search = { 2: Number };
    expect(differentia.diff(clone, testObjects["Linear Acyclic"], search)).toBe(false);
    search = [{
      address: {
        geo: {
          lat: null
        }
      }
    }];
    clone = differentia.clone(testObjects["Multidimensional Cyclic"], search);
    expect(differentia.diff(clone, testObjects["Multidimensional Cyclic"], search)).toBe(false);
  });
});

describe("Diff Clone", function () {
  var subject = { "hello": "world", "how": "are you?", "have a": "good day" };
  var compare = { "hello": "world", "whats": "up?", "have a": "good night" };
  it("should clone properties that differ", function () {
    var clone = differentia.diffClone(subject, compare);
    expect(differentia.diff(clone, { "how": "are you?", "have a": "good day" })).toBe(false);
  });
  it("should clone properties that differ using the search index", function () {
    var clone = differentia.diffClone(subject, compare, { "how": null });
    expect(differentia.diff(clone, { "how": "are you?" })).toBe(false);
  });
});

describe("find", function () {
  it("should return a value if it passes the test", function () {
    expect(differentia.find(testObjects["Multidimensional Cyclic"], function (value, accessor, object) {
      return value === -37.3159;
    })).toBe(-37.3159);
  });
  it("should return undefined if no values pass the test", function () {
    expect(differentia.find(testObjects["Multidimensional Cyclic"], function (value, accessor, object) {
      return value === "This string does not exist in the test object!";
    })).toBeUndefined();
  });
});

describe("every", function () {
  var testObject = [10, 11, 12, 13, 14, 15];
  it("should return true if all values pass the test", function () {
    expect(differentia.every(testObject, function (value, accessor, object) {
      return typeof value === "number" && value >= 10;
    })).toBe(true);
  });
  it("should return false if one value fails the test", function () {
    expect(differentia.every(testObject, function (value, accessor, object) {
      return typeof value === "number" && value < 13;
    })).toBe(false);
  });
});

describe("some", function () {
  var testObject = [10, 11, 12, 13, 14, 15];
  it("should return true if one value passes the test", function () {
    expect(differentia.some(testObject, function (value, accessor, object) {
      return typeof value === "number" && value === 13;
    })).toBe(true);
  });
  it("should return false if no values pass the test", function () {
    expect(differentia.some(testObject, function (value, accessor, object) {
      return typeof value === "number" && value < 10;
    })).toBe(false);
  });
});

describe("deepFreeze", function () {
  it("should freeze all nodes and properties", function () {
    var frozenObject = differentia.deepFreeze(differentia.clone(testObjects["Multidimensional Cyclic"]));
    expect(differentia.every(frozenObject, function (value, accessor, object) {
      return Object.isFrozen(object) && differentia.isContainer(value) ? Object.isFrozen(value) : true;
    })).toBe(true);
  });
});

describe("deepSeal", function () {
  it("should seal all nodes and properties", function () {
    var sealedObject = differentia.deepSeal(differentia.clone(testObjects["Multidimensional Cyclic"]));
    expect(differentia.every(sealedObject, function (value, accessor, object) {
      return Object.isSealed(object) && differentia.isContainer(value) ? Object.isSealed(value) : true;
    })).toBe(true);
  });
});<commit_msg>Added basic diff function to tests to make other tests less reliant on the library diff<commit_after>function createTestObject() {
  return [
    {
      "id": 1,
      "name": "Leanne Graham",
      "username": "Bret",
      "email": "Sincere@april.biz",
      "address": {
        "street": "Kulas Light",
        "suite": "Apt. 556",
        "city": "Gwenborough",
        "zipcode": 92998,
        "geo": {
          "lat": -37.3159,
          "lng": 81.1496
        }
      },
      "website": null,
      "company": {
        "active": false,
        "name": "Romaguera-Crona",
        "catchPhrase": "Multi-layered client-server neural-net",
        "bs": "harness real-time e-markets"
      }
    },
    {
      "id": 2,
      "name": "Ervin Howell",
      "username": "Antonette",
      "email": "Shanna@melissa.tv",
      "address": {
        "street": "Victor Plains",
        "suite": "Suite 879",
        "city": "Wisokyburgh",
        "zipcode": 90566,
        "geo": {
          "lat": -43.9509,
          "lng": -34.4618
        }
      },
      "website": null,
      "company": {
        "active": true,
        "name": "Deckow-Crist",
        "catchPhrase": "Proactive didactic contingency",
        "bs": "synergize scalable supply-chains"
      }
    }
  ];
}
var testObjects = {};
testObjects["Multidimensional Acyclic"] = createTestObject();
testObjects["Linear Acyclic"] = ["one", "two", "three"];
// Fourth element is a cycle
testObjects["Linear Cyclic"] = ["one", "two", "three"];
testObjects["Linear Cyclic"][3] = testObjects["Linear Cyclic"];
// `otherUser` properties are a cycle
testObjects["Multidimensional Cyclic"] = createTestObject();
testObjects["Multidimensional Cyclic"][0].otherUser = testObjects["Multidimensional Cyclic"][1];
testObjects["Multidimensional Cyclic"][1].otherUser = testObjects["Multidimensional Cyclic"][0];

function createKeyCounter() {
  var testObject = testObjects["Multidimensional Cyclic"];
  var keyCounts = {};
  for (var key in testObject) {
    keyCounts[key] = 0;
  }
  for (var key in testObject[0]) {
    keyCounts[key] = 0;
  }
  for (var key in testObject[0]["address"]) {
    keyCounts[key] = 0;
  }
  for (var key in testObject[0]["address"]["geo"]) {
    keyCounts[key] = 0;
  }
  for (var key in testObject[0]["company"]) {
    keyCounts[key] = 0;
  }
  return keyCounts;
}

function testLength(obj) {
  if (Array.isArray(obj)) {
    return obj.legth;
  }
  if (typeof obj === "object") {
    return Object.keys(obj).length;
  }
  throw new TypeError("The given parameter must be an Object or Array");
}

function diff(subject, compare) {
  var map = new Map();
  for (var accessor in subject) {
    if (testDiff(subject, compare, accessor, map)) {
      return true;
    }
  }
  return false;
}

function testDiff(subject, compare, accessor, map) {
  if (!(accessor in compare)) {
    return true;
  }
  if (map.has(subject[accessor])) {
    return;
  }
  var subjectProp = subject[accessor];
  var compareProp = compare[accessor];
  if (typeof subjectProp === "object") {
    map.set(subjectProp, compareProp);
  }
  if ((Array.isArray(subjectProp) && Array.isArray(compareProp))
    || (typeof subjectProp === "object" && typeof subjectProp === "object")) {
    // Object type does not match.
    if (testLength(subjectProp) !== testLength(subjectProp)) {
      // Object index/property count does not match, they are different.
      return true;
    }
    for (var accessor in subjectProp) {
      return testDiff(subjectProp, compareProp, accessor, map);
    }
  } else if (subjectProp !== compareProp) {
    return true;
  }
}

describe("isContainer", function () {
  var array = [];
  var object = {};
  it("should return true if the input is an Object or Array", function () {
    expect(differentia.isContainer(array)).toBe(true);
    expect(differentia.isContainer(object)).toBe(true);
  });
  it("should return false if the input is not an Object or Array", function () {
    expect(differentia.isContainer(12345)).toBe(false);
    expect(differentia.isContainer("Hello World")).toBe(false);
    expect(differentia.isContainer(true)).toBe(false);
    expect(differentia.isContainer(false)).toBe(false);
  });
});

describe("getContainerLength", function () {
  var array = [1, 2, 3, 4, 5];
  var object = { 1: 1, 2: 2, 3: 3, 4: 4, 5: 5 };
  it("should count 5 items in each container", function () {
    expect(differentia.getContainerLength(array)).toBe(5);
    expect(differentia.getContainerLength(object)).toBe(5);
  });
});

describe("Iterative Deepening Depth-First Search", function () {
  it("should throw a TypeError when no arguments are given", function () {
    expect(() => differentia.iddfs().next()).toThrow(new TypeError("Argument 1 must be an Object or Array"));
  });
  it("should throw a TypeError when argument 2 is not given", function () {
    expect(() => differentia.iddfs({}).next()).toThrow(new TypeError("Argument 2 must be a non-empty Object or Array"));
  });
  it("should throw a TypeError when any arguments are the wrong type", function () {
    expect(() => differentia.iddfs(123).next()).toThrow(new TypeError("Argument 1 must be an Object or Array"));
    expect(() => differentia.iddfs("test").next()).toThrow(new TypeError("Argument 1 must be an Object or Array"));
    expect(() => differentia.iddfs({}, 123).next()).toThrow(new TypeError("Argument 2 must be a non-empty Object or Array"));
    expect(() => differentia.iddfs({}, "test").next()).toThrow(new TypeError("Argument 2 must be a non-empty Object or Array"));
  });
  it("should iterate all nodes and properties", function () {
    var keyCounts = createKeyCounter();
    var testObject = testObjects["Multidimensional Cyclic"];
    var iterator = differentia.iddfs(testObject, testObject);
    var iteration = iterator.next();
    while (!iteration.done) {
      keyCounts[iteration.value.accessor]++;
      iteration = iterator.next();
    }
    console.group("IDDFS Traversal & Iteration Results:");
    for (var accessor in keyCounts) {
      console.info("Accessor \"" + accessor + "\" was visited " + keyCounts[accessor] + " time(s).");
      expect(keyCounts[accessor] > 0).toBe(true);
    }
    console.groupEnd();
  });
});

describe("forEach", function () {
  it("should iterate all nodes and properties", function () {
    var keyCounts = createKeyCounter();
    var testObject = testObjects["Multidimensional Cyclic"];
    differentia.forEach(testObject, function (value, accessor, object) {
      keyCounts[accessor]++;
    });
    console.group("forEach Traversal & Iteration Results:");
    for (var accessor in keyCounts) {
      console.info("Accessor \"" + accessor + "\" was visited " + keyCounts[accessor] + " time(s).");
      expect(keyCounts[accessor] > 0).toBe(true);
    }
    console.groupEnd();
  });
});

describe("Diff", function () {
  it("should return true when two objects differ", function () {
    expect(differentia.diff(testObjects["Linear Acyclic"], testObjects["Linear Cyclic"])).toBe(true);
    expect(differentia.diff(testObjects["Multidimensional Cyclic"], testObjects["Multidimensional Acyclic"])).toBe(true);
    expect(differentia.diff(testObjects["Linear Cyclic"], testObjects["Multidimensional Acyclic"])).toBe(true);
  });
  it("should return false when two objects are the same", function () {
    expect(differentia.diff(testObjects["Linear Acyclic"], testObjects["Linear Acyclic"])).toBe(false);
    expect(differentia.diff(testObjects["Linear Cyclic"], testObjects["Linear Cyclic"])).toBe(false);
    expect(differentia.diff(testObjects["Multidimensional Acyclic"], testObjects["Multidimensional Acyclic"])).toBe(false);
    expect(differentia.diff(testObjects["Multidimensional Cyclic"], testObjects["Multidimensional Cyclic"])).toBe(false);
  });
  it("should return true when two objects differ using the search index", function () {
    expect(differentia.diff(testObjects["Linear Acyclic"], testObjects["Linear Cyclic"], { 3: null })).toBe(true);
  });
  it("should return false when two objects are the same using the search index", function () {
    expect(differentia.diff(testObjects["Linear Acyclic"], testObjects["Linear Cyclic"], { 1: null })).toBe(false);
  });
});

describe("Clone", function () {
  it("should make an exact copy of the subject", function () {
    var clone = differentia.clone(testObjects["Linear Acyclic"]);
    expect(diff(clone, testObjects["Linear Acyclic"])).toBe(false);
    clone = differentia.clone(testObjects["Linear Cyclic"]);
    expect(diff(clone, testObjects["Linear Cyclic"])).toBe(false);
    clone = differentia.clone(testObjects["Multidimensional Cyclic"]);
    expect(diff(clone, testObjects["Multidimensional Cyclic"])).toBe(false);
  });
  it("should clone properties using the search index", function () {
    var clone = differentia.clone(testObjects["Linear Acyclic"], { 2: null });
    var search = { 2: Number };
    expect(diff(clone, testObjects["Linear Acyclic"], search)).toBe(false);
    search = [{
      address: {
        geo: {
          lat: null
        }
      }
    }];
    clone = differentia.clone(testObjects["Multidimensional Cyclic"], search);
    expect(diff(clone, testObjects["Multidimensional Cyclic"], search)).toBe(false);
  });
});

describe("Diff Clone", function () {
  var subject = { "hello": "world", "how": "are you?", "have a": "good day" };
  var compare = { "hello": "world", "whats": "up?", "have a": "good night" };
  it("should clone properties that differ", function () {
    var clone = differentia.diffClone(subject, compare);
    expect(diff(clone, { "how": "are you?", "have a": "good day" })).toBe(false);
  });
  it("should clone properties that differ using the search index", function () {
    var clone = differentia.diffClone(subject, compare, { "how": null });
    expect(diff(clone, { "how": "are you?" })).toBe(false);
  });
});

describe("find", function () {
  it("should return a value if it passes the test", function () {
    expect(differentia.find(testObjects["Multidimensional Cyclic"], function (value, accessor, object) {
      return value === -37.3159;
    })).toBe(-37.3159);
  });
  it("should return undefined if no values pass the test", function () {
    expect(differentia.find(testObjects["Multidimensional Cyclic"], function (value, accessor, object) {
      return value === "This string does not exist in the test object!";
    })).toBeUndefined();
  });
});

describe("every", function () {
  var testObject = [10, 11, 12, 13, 14, 15];
  it("should return true if all values pass the test", function () {
    expect(differentia.every(testObject, function (value, accessor, object) {
      return typeof value === "number" && value >= 10;
    })).toBe(true);
  });
  it("should return false if one value fails the test", function () {
    expect(differentia.every(testObject, function (value, accessor, object) {
      return typeof value === "number" && value < 13;
    })).toBe(false);
  });
});

describe("some", function () {
  var testObject = [10, 11, 12, 13, 14, 15];
  it("should return true if one value passes the test", function () {
    expect(differentia.some(testObject, function (value, accessor, object) {
      return typeof value === "number" && value === 13;
    })).toBe(true);
  });
  it("should return false if no values pass the test", function () {
    expect(differentia.some(testObject, function (value, accessor, object) {
      return typeof value === "number" && value < 10;
    })).toBe(false);
  });
});

describe("deepFreeze", function () {
  it("should freeze all nodes and properties", function () {
    var frozenObject = differentia.deepFreeze(differentia.clone(testObjects["Multidimensional Cyclic"]));
    expect(differentia.every(frozenObject, function (value, accessor, object) {
      return Object.isFrozen(object) && differentia.isContainer(value) ? Object.isFrozen(value) : true;
    })).toBe(true);
  });
});

describe("deepSeal", function () {
  it("should seal all nodes and properties", function () {
    var sealedObject = differentia.deepSeal(differentia.clone(testObjects["Multidimensional Cyclic"]));
    expect(differentia.every(sealedObject, function (value, accessor, object) {
      return Object.isSealed(object) && differentia.isContainer(value) ? Object.isSealed(value) : true;
    })).toBe(true);
  });
});<|endoftext|>


<commit_before>/* Copyright 2009-2011 Hewlett-Packard Development Company, L.P. All rights reserved. */

enyo.kind({
	name: "EditorPanel",
	kind: enyo.HFlexBox,
	components: [
		{name: "slidingPane", kind: "HSlidingPane", flex: 1, multiViewMinHeight: 0,
			onSlideComplete: "barMoved",
			components: [
			{name: "top", kind:"HSlidingView",
				components: [
					{kind: "HFlexBox", pack: "center", components: [
						{className: "editor-left", flex: 1, overflow: "hidden" },
						{kind: "BasicScroller",
							name:"editorScroller",
							height: "760px",
							width: "760px",
							autoHorizontal: false,
							horizontal: false,
							className: "editor-scroller",
							onmouseup: "scrollerClicked",
							components: [
								{kind: "RichText",
									name: "editor",
									richContent: true,
									className: "editor-input",
									onblur: "syncViews",
									onfocus: "editorFocussed",
									onmouseup: "syncViews",
									hint: "",
									spellcheck: true,
									autocorrect: false,
									autoCapitalize: false,
									styled: false
								}
							]
						},
						{className: "editor-right", flex: 1, overflow: "hidden" }
					]}
			]},
			{name: "bottom", kind:"HSlidingView", height: "100px", fixedHeight: true, pack:"end", style:"overflow: hidden;",
				applySlideToNode: function(inSlide) {
					if (inSlide != this.slidePosition && this.index) {
						inSlide = Math.min(0,inSlide);
						this.lastSlidePosition = this.slidePosition;
						this.slidePosition = inSlide;
						if (this.hasNode()) {
							//this.log(this.id, inSlide);
							var t = inSlide !== null ? "translate3d(0," + inSlide + "px,0)" : "";
							this.domStyles["-webkit-transform"] = this.node.style.webkitTransform = t;
							var s = inSlide !== null ? "translate3d(0,"+ (-enyo.fetchControlSize(this).h-inSlide+55) + "px,0)" : "";
							this.$.client.children[1].node.style.webkitTransform = s;
						}
					}
				},
				resizeHandler: function() {
					//var s = "translate3d(0,1px,0)";
					var s = "translate3d(0," + (55-enyo.fetchControlSize(this).h) + "px,0)";
					this.node.style.webkitTransform = s;
				},
				components: [
					{kind: "Header", name: "header", height: "55px",className: "enyo-toolbar fake-toolbar", style:"z-index: 1000;",
						onmousedown: "sliderclicked",
						onmouseup: "sliderreleased",
						components: [
						{kind: "GrabButton", className: "HGrabButton"},
						{kind: "Spacer", style:"width: 1px;"},
						{content: "", name:"filename"},
						//{kind: "Image", src:"images/title.png", style:"margin-top: 4px;"},
						{kind: "Spacer", flex: 25},
						//{content: "Typewriter"},
						{kind: "Spacer", style:"width: 1px;"},
						{kind: "GrabButton", className: "HGrabButton Right"}
					]},
					{kind: "VFlexBox", flex: 1,
						components: [
						{kind: "HFlexBox", flex: 1, pack: "center", components: [
							{className: "preview-left", flex: 1, overflow: "hidden" },
							{kind: "BasicScroller",
								name:"previewScroller",
								width: "760px",
								autoHorizontal: false,
								horizontal: false,
								className: "output-scroller",
								components: [
									{kind: "HtmlContent",
										name: "preview",
										className: "output-preview",
										onLinkClick: "htmlContentLinkClick",
										onmouseup: "syncViews"
									}
								]
							},
							{className: "preview-right", flex: 1, overflow: "hidden" }
						]}
					]}
			]}
		]},
		{name:'filePicker', kind: "FilePicker", fileType:["image"], allowMultiSelect:false, onPickFile: "handleFile"},
		{kind: "PrintDialog",
			duplexOption: true,
			frameToPrint: {name:"preview", landscape:false},
			appName: "Typewriter"
		}
	],

	/* PREVIEW HANDLING */
	synccount: 0,

	barBeingDragged: false,

	sliderclicked: function() {
		this.barBeingDragged = true;
	},

	sliderreleased: function() {
		this.barBeingDragged = false;
	},

	barMoved: function(event) {
		if(event.view == this.$.top) {
			this.position = "down";
			//enyo.keyboard.show();
		}
		else {
			this.position = "up";
			//enyo.keyboard.hide();
		}

		//this.generateMarkdown();
	},
	htmlContentLinkClick: function(sender, url) {
		var splits = url.split(/#/).slice(-1).pop();
		switch(splits) {
			case "clear":
				this.$.editor.setValue("");
			case "editor":
				this.$.slidingPane.selectView(this.$.top);
				return false;
				break;
			case "preview":
				this.$.slidingPane.selectView(this.$.bottom);
				return false;
				break;
			default:
				var r = new enyo.PalmService();
				r.service = "palm://com.palm.applicationManager/";
				r.method = "open";
				r.call({target: url});
		}
	},

	/* PRINT HANDLING */

	printDocument: function() {
		this.$.slidingPane.selectViewByIndex(1);
		this.$.printDialog.openAtCenter();
	},
	/* EDITOR CALLBACKS */
	editorFocussed: function() {
		enyo.keyboard.show();
	},

	scrollerClicked: function() {
		this.$.editor.forceFocus();
	},

	syncViews: function(inSender, inEvent) {

		var eb = this.$.editorScroller.getBoundaries().bottom;
		var et = this.$.editorScroller.getBoundaries().top;
		var ec = this.$.editorScroller.scrollTop;
		var ep = eb!=0 ? ec/eb : 0;
		ep = Math.max(0,ep);
		ep = Math.min(1,ep);

		if(this.position == "up")
			var pb = this.$.previewScroller.getBoundaries().bottom;
		else // weirdly enough the preview box appears to be bigger if the bar is down. we'll simply substract the height added here.
			var pb = this.$.previewScroller.getBoundaries().bottom - enyo.fetchControlSize(this).h+55;
		var pt = this.$.previewScroller.getBoundaries().top;
		var pc = this.$.previewScroller.scrollTop;
		var pp = pb!=0 ? pc/pb : 0;
		pp = Math.max(0,pp);
		pp = Math.min(1,pp);

		if(!this.barBeingDragged && (this.$.bottom.slidePosition == 0 || -enyo.fetchControlSize(this).h == this.$.bottom.slidePosition-55)) {
			if(this.position == "up") {
				//enyo.keyboard.hide();
				//this.$.editorScroller.setScrollTop(pp * eb); // TODO: das kann sau nervig sein
			}
			else {
				//enyo.keyboard.show();
				this.$.previewScroller.setScrollTop(ep * pb);
				//this.$.editor.forceFocus(); // buggy with on screen keyboard
			}
		}

		//console.log(pp + " " + ep);

		if(this.synccount == 0 || inSender.name != "schedule") {
			this.makePreview();
		}
		this.synccount++;
		this.synccount = this.synccount % 3;
	},

	makePreview: function() {
		//console.log("generating Markdown");
		var converter = new Showdown.converter();
		var value = this.$.editor.getText();
		this.$.preview.setContent(converter.makeHtml(value));
	},

	setSchedule: function() {
		this.scheduleID = setInterval(enyo.bind(this,function() {
			this.syncViews({name:"schedule"});
		}), 5000);
	},
	clearSchedule: function() {
		clearInterval(this.scheduleID);
	},

	/* CONSTRUCTOR */

	ready: function() {
		this.position = "down";
		enyo.keyboard.setManualMode(true);
		//enyo.keyboard.setResizesWindow(false);
		enyo.keyboard.show();

		this.syncViews({name:"startup"});
	},

	rendered: function() {
		this.inherited(arguments);
		this.adjustSlidingSize();
		this.setSchedule();
	},
	resizeHandler: function() {
		this.adjustSlidingSize();
		var v = this.$.slidingPane.view;
		if (v && v.resizeHandler) {
			v.resizeHandler();
		}
	},
	adjustSlidingSize: function() {
		var s = enyo.fetchControlSize(this);
		var pcs = enyo.fetchControlSize(this.$.bottom.$.client);
		var kh = enyo.keyboard.isShowing() ? enyo.keyboard.height : 0;

		this.$.editorScroller.node.style.height = (s.h - 55 - kh) + "px";

		this.$.top.node.style.height = (s.h - 55 - kh) + "px";
		this.$.bottom.node.style.height = (s.h - kh) + "px";
		this.$.bottom.setPeekHeight(s.h - pcs.h);

		if(this.position == "up")
			this.$.bottom.slidePosition = this.$.bottom.lastSlidePosition = -(enyo.fetchControlSize(this.$.bottom).h-56);
	},

	getContent: function() {
		return this.$.editor.getText();
	},

	setContent: function(inContent, inFilename) {
		var inFilename = inFilename || "";
		this.$.editor.setValue(inContent);
		this.$.filename.setContent(inFilename.basename(".md"));
	},

	setActive: function(inToggle) {
		if(inToggle == true) {
			this.$.editorScroller.removeClass("disabled");
			this.$.editor.setDisabled(false);
		}
		else {
			this.$.editorScroller.addClass("disabled");
			this.$.editor.setDisabled(true);
		}
	}
});
<commit_msg>sync ohne focus problem geloest<commit_after>/* Copyright 2009-2011 Hewlett-Packard Development Company, L.P. All rights reserved. */

enyo.kind({
	name: "EditorPanel",
	kind: enyo.HFlexBox,
	components: [
		{name: "slidingPane", kind: "HSlidingPane", flex: 1, multiViewMinHeight: 0,
			onSlideComplete: "barMoved",
			components: [
			{name: "top", kind:"HSlidingView",
				components: [
					{kind: "HFlexBox", pack: "center", components: [
						{className: "editor-left", flex: 1, overflow: "hidden" },
						{kind: "BasicScroller",
							name:"editorScroller",
							height: "760px",
							width: "760px",
							autoHorizontal: false,
							horizontal: false,
							className: "editor-scroller",
							onmouseup: "scrollerClicked",
							components: [
								{kind: "RichText",
									name: "editor",
									richContent: true,
									className: "editor-input",
									onblur: "syncViews",
									onfocus: "editorFocussed",
									onmouseup: "syncViews",
									hint: "",
									spellcheck: true,
									autocorrect: false,
									autoCapitalize: false,
									styled: false
								}
							]
						},
						{className: "editor-right", flex: 1, overflow: "hidden" }
					]}
			]},
			{name: "bottom", kind:"HSlidingView", height: "100px", fixedHeight: true, pack:"end", style:"overflow: hidden;",
				applySlideToNode: function(inSlide) {
					if (inSlide != this.slidePosition && this.index) {
						inSlide = Math.min(0,inSlide);
						this.lastSlidePosition = this.slidePosition;
						this.slidePosition = inSlide;
						if (this.hasNode()) {
							//this.log(this.id, inSlide);
							var t = inSlide !== null ? "translate3d(0," + inSlide + "px,0)" : "";
							this.domStyles["-webkit-transform"] = this.node.style.webkitTransform = t;
							var s = inSlide !== null ? "translate3d(0,"+ (-enyo.fetchControlSize(this).h-inSlide+55) + "px,0)" : "";
							this.$.client.children[1].node.style.webkitTransform = s;
						}
					}
				},
				resizeHandler: function() {
					//var s = "translate3d(0,1px,0)";
					var s = "translate3d(0," + (55-enyo.fetchControlSize(this).h) + "px,0)";
					this.node.style.webkitTransform = s;
				},
				components: [
					{kind: "Header", name: "header", height: "55px",className: "enyo-toolbar fake-toolbar", style:"z-index: 1000;",
						onmousedown: "sliderclicked",
						onmouseup: "sliderreleased",
						components: [
						{kind: "GrabButton", className: "HGrabButton"},
						{kind: "Spacer", style:"width: 1px;"},
						{content: "", name:"filename"},
						//{kind: "Image", src:"images/title.png", style:"margin-top: 4px;"},
						{kind: "Spacer", flex: 25},
						//{content: "Typewriter"},
						{kind: "Spacer", style:"width: 1px;"},
						{kind: "GrabButton", className: "HGrabButton Right"}
					]},
					{kind: "VFlexBox", flex: 1,
						components: [
						{kind: "HFlexBox", flex: 1, pack: "center", components: [
							{className: "preview-left", flex: 1, overflow: "hidden" },
							{kind: "BasicScroller",
								name:"previewScroller",
								width: "760px",
								autoHorizontal: false,
								horizontal: false,
								className: "output-scroller",
								components: [
									{kind: "HtmlContent",
										name: "preview",
										className: "output-preview",
										onLinkClick: "htmlContentLinkClick",
										onmouseup: "syncViews"
									}
								]
							},
							{className: "preview-right", flex: 1, overflow: "hidden" }
						]}
					]}
			]}
		]},
		{name:'filePicker', kind: "FilePicker", fileType:["image"], allowMultiSelect:false, onPickFile: "handleFile"},
		{kind: "PrintDialog",
			duplexOption: true,
			frameToPrint: {name:"preview", landscape:false},
			appName: "Typewriter"
		}
	],

	/* PREVIEW HANDLING */
	synccount: 0,

	barBeingDragged: false,

	sliderclicked: function() {
		this.barBeingDragged = true;
	},

	sliderreleased: function() {
		this.barBeingDragged = false;
	},

	barMoved: function(event) {
		if(event.view == this.$.top) {
			this.position = "down";
			//enyo.keyboard.show();
		}
		else {
			this.position = "up";
			//enyo.keyboard.hide();
		}

		//this.generateMarkdown();
	},
	htmlContentLinkClick: function(sender, url) {
		var splits = url.split(/#/).slice(-1).pop();
		switch(splits) {
			case "clear":
				this.$.editor.setValue("");
			case "editor":
				this.$.slidingPane.selectView(this.$.top);
				return false;
				break;
			case "preview":
				this.$.slidingPane.selectView(this.$.bottom);
				return false;
				break;
			default:
				var r = new enyo.PalmService();
				r.service = "palm://com.palm.applicationManager/";
				r.method = "open";
				r.call({target: url});
		}
	},

	/* PRINT HANDLING */

	printDocument: function() {
		this.$.slidingPane.selectViewByIndex(1);
		this.$.printDialog.openAtCenter();
	},
	/* EDITOR CALLBACKS */
	editorFocussed: function() {
		enyo.keyboard.show();
	},

	scrollerClicked: function() {
		this.$.editor.forceFocus();
	},

	syncViews: function(inSender, inEvent) {

		var eb = this.$.editorScroller.getBoundaries().bottom;
		var et = this.$.editorScroller.getBoundaries().top;
		var ec = this.$.editorScroller.scrollTop;
		var ep = eb!=0 ? ec/eb : 0;
		ep = Math.max(0,ep);
		ep = Math.min(1,ep);

		if(this.position == "up")
			var pb = this.$.previewScroller.getBoundaries().bottom;
		else // weirdly enough the preview box appears to be bigger if the bar is down. we'll simply substract the height added here.
			var pb = this.$.previewScroller.getBoundaries().bottom - enyo.fetchControlSize(this).h+55;
		var pt = this.$.previewScroller.getBoundaries().top;
		var pc = this.$.previewScroller.scrollTop;
		var pp = pb!=0 ? pc/pb : 0;
		pp = Math.max(0,pp);
		pp = Math.min(1,pp);

		if(!this.barBeingDragged && (this.$.bottom.slidePosition == 0 || -enyo.fetchControlSize(this).h == this.$.bottom.slidePosition-55)) {
			if(this.position == "up") {
				//enyo.keyboard.hide();
				//this.$.editorScroller.setScrollTop(pp * eb); // TODO: das kann sau nervig sein
			}
			else {
				//enyo.keyboard.show();
				this.$.previewScroller.setScrollTop(ep * pb);
				//this.$.editor.forceFocus(); // buggy with on screen keyboard
			}
		}

		//console.log(pp + " " + ep);

		if(this.synccount == 0 || inSender.name != "schedule") {
			this.makePreview();
		}
		this.synccount++;
		this.synccount = this.synccount % 3;
	},

	makePreview: function() {
		//console.log("generating Markdown");
		var converter = new Showdown.converter();
		var value = this.$.editor.getText();
		this.$.preview.setContent(converter.makeHtml(value));
	},

	setSchedule: function() {
		this.scheduleID = setInterval(enyo.bind(this,function() {
			this.syncViews({name:"schedule"});
		}), 5000);
	},
	clearSchedule: function() {
		clearInterval(this.scheduleID);
	},

	/* CONSTRUCTOR */

	ready: function() {
		this.position = "down";
		enyo.keyboard.setManualMode(true);
		//enyo.keyboard.setResizesWindow(false);
		enyo.keyboard.show();

		this.syncViews({name:"startup"});
	},

	rendered: function() {
		this.inherited(arguments);
		this.adjustSlidingSize();
		this.setSchedule();
	},
	resizeHandler: function() {
		this.adjustSlidingSize();
		var v = this.$.slidingPane.view;
		if (v && v.resizeHandler) {
			v.resizeHandler();
		}
	},
	adjustSlidingSize: function() {
		var s = enyo.fetchControlSize(this);
		var pcs = enyo.fetchControlSize(this.$.bottom.$.client);
		var kh = enyo.keyboard.isShowing() ? enyo.keyboard.height : 0;

		this.$.editorScroller.node.style.height = (s.h - 55 - kh) + "px";

		this.$.top.node.style.height = (s.h - 55 - kh) + "px";
		this.$.bottom.node.style.height = (s.h - kh) + "px";
		this.$.bottom.setPeekHeight(s.h - pcs.h);

		if(this.position == "up")
			this.$.bottom.slidePosition = this.$.bottom.lastSlidePosition = -(enyo.fetchControlSize(this.$.bottom).h-56);
	},

	getContent: function() {
		return this.$.editor.getText();
	},

	setContent: function(inContent, inFilename) {
		var inFilename = inFilename || "";
		this.$.editor.setValue(inContent);
		this.$.filename.setContent(inFilename.basename(".md"));
		this.syncViews({name:"setcontent"});
	},

	setActive: function(inToggle) {
		if(inToggle == true) {
			this.$.editorScroller.removeClass("disabled");
			this.$.editor.setDisabled(false);
		}
		else {
			this.$.editorScroller.addClass("disabled");
			this.$.editor.setDisabled(true);
		}
	}
});
<|endoftext|>


<commit_before>import {Rect, Grid} from '../src'

describe('Rect', () => {

    let rect

    beforeEach(() => {

        rect = new Rect({
            top: 100,
            left: 300,
            right: 500,
            bottom: 600
        })

    })

    describe('width', () => {

        it('returns the width of the rect', () => {

            expect(rect.width()).to.equal(200)

        })

    })

    describe('height', () => {

        it('returns the height of the rect', () => {

            expect(rect.height()).to.equal(500)

        })

    })

    describe('scaleTop', () => {

        it('scales the top side with the given scale', () => {

            const scaled = rect.scaleTop(2)

            expect(scaled.top).to.equal(-400)
            expect(scaled.left).to.equal(300)
            expect(scaled.right).to.equal(500)
            expect(scaled.bottom).to.equal(600)

        })

    })

    describe('scaleLeft', () => {

        it('scales the left side with the given scale', () => {

            const scaled = rect.scaleLeft(2)

            expect(scaled.top).to.equal(100)
            expect(scaled.left).to.equal(100)
            expect(scaled.right).to.equal(500)
            expect(scaled.bottom).to.equal(600)

        })

    })

    describe('scaleRight', () => {

        it('scales the right side with the given scale', () => {

            const scaled = rect.scaleRight(2)

            expect(scaled.top).to.equal(100)
            expect(scaled.left).to.equal(300)
            expect(scaled.right).to.equal(700)
            expect(scaled.bottom).to.equal(600)

        })

    })

    describe('scaleBottom', () => {

        it('scales the bottom side with the given scale', () => {

            const scaled = rect.scaleBottom(2)

            expect(scaled.top).to.equal(100)
            expect(scaled.left).to.equal(300)
            expect(scaled.right).to.equal(500)
            expect(scaled.bottom).to.equal(1100)

        })

    })

    describe('shiftUp', () => {

        it('shifts the rect upward the given units long', () => {

            const shifted = rect.shiftUp(2)

            expect(shifted.top).to.equal(-900)
            expect(shifted.left).to.equal(300)
            expect(shifted.right).to.equal(500)
            expect(shifted.bottom).to.equal(-400)

        })

        it('shifts the rect upward a unit long if called without argument', () => {

            const shifted = rect.shiftUp()

            expect(shifted.top).to.equal(-400)
            expect(shifted.left).to.equal(300)
            expect(shifted.right).to.equal(500)
            expect(shifted.bottom).to.equal(100)

        })

    })

    describe('shiftLeft', () => {

        it('shifts the rect leftward the given units long', () => {

            const shifted = rect.shiftLeft(2)

            expect(shifted.top).to.equal(100)
            expect(shifted.left).to.equal(-100)
            expect(shifted.right).to.equal(100)
            expect(shifted.bottom).to.equal(600)

        })

        it('shifts the rect leftward a unit long if called without argument', () => {

            const shifted = rect.shiftLeft()

            expect(shifted.top).to.equal(100)
            expect(shifted.left).to.equal(100)
            expect(shifted.right).to.equal(300)
            expect(shifted.bottom).to.equal(600)

        })

    })

    describe('shiftRight', () => {

        it('shifts the rect rightward the given units long', () => {

            const shifted = rect.shiftRight(2)

            expect(shifted.top).to.equal(100)
            expect(shifted.left).to.equal(700)
            expect(shifted.right).to.equal(900)
            expect(shifted.bottom).to.equal(600)

        })

        it('shifts the rect rightward a unit long if called without argument', () => {

            const shifted = rect.shiftRight()

            expect(shifted.top).to.equal(100)
            expect(shifted.left).to.equal(500)
            expect(shifted.right).to.equal(700)
            expect(shifted.bottom).to.equal(600)

        })

    })

    describe('shiftDown', () => {

        it('shifts the rect downward the given units long', () => {

            const shifted = rect.shiftDown(2)

            expect(shifted.top).to.equal(1100)
            expect(shifted.left).to.equal(300)
            expect(shifted.right).to.equal(500)
            expect(shifted.bottom).to.equal(1600)

        })

        it('shifts the rect downward a unit long if called without argument', () => {

            const shifted = rect.shiftDown()

            expect(shifted.top).to.equal(600)
            expect(shifted.left).to.equal(300)
            expect(shifted.right).to.equal(500)
            expect(shifted.bottom).to.equal(1100)

        })

    })

    describe('cutTop', () => {

        it('cuts the top part of the given height', () => {

            const cut = rect.cutTop(100)

            expect(cut.top).to.equal(100)
            expect(cut.left).to.equal(300)
            expect(cut.right).to.equal(500)
            expect(cut.bottom).to.equal(200)

        })

    })

    describe('cutLeft', () => {

        it('cuts the left part of the given width', () => {

            const cut = rect.cutLeft(100)

            expect(cut.top).to.equal(100)
            expect(cut.left).to.equal(300)
            expect(cut.right).to.equal(400)
            expect(cut.bottom).to.equal(600)

        })

    })

    describe('cutRight', () => {

        it('cuts the right part of the given width', () => {

            const cut = rect.cutRight(100)

            expect(cut.top).to.equal(100)
            expect(cut.left).to.equal(400)
            expect(cut.right).to.equal(500)
            expect(cut.bottom).to.equal(600)

        })

    })

    describe('cutBottom', () => {

        it('cuts the bottom part of the given height', () => {

            const cut = rect.cutBottom(100)

            expect(cut.top).to.equal(500)
            expect(cut.left).to.equal(300)
            expect(cut.right).to.equal(500)
            expect(cut.bottom).to.equal(600)

        })

    })

    describe('extCutTop', () => {

        it('cuts out the next area of the top side of the rect with the given height', () => {

            const cut = rect.extCutTop(50)

            expect(cut.top).to.equal(50)
            expect(cut.left).to.equal(300)
            expect(cut.right).to.equal(500)
            expect(cut.bottom).to.equal(100)

        })

    })

    describe('extCutLeft', () => {

        it('cuts out the next area of the left side of the rect with the given width', () => {

            const cut = rect.extCutLeft(50)

            expect(cut.top).to.equal(100)
            expect(cut.left).to.equal(250)
            expect(cut.right).to.equal(300)
            expect(cut.bottom).to.equal(600)

        })

    })

    describe('extCutRight', () => {

        it('cuts out the next area of the right side of the rect with the given width', () => {

            const cut = rect.extCutRight(50)

            expect(cut.top).to.equal(100)
            expect(cut.left).to.equal(500)
            expect(cut.right).to.equal(550)
            expect(cut.bottom).to.equal(600)

        })

    })

    describe('extCutBottom', () => {

        it('cuts out the next area of the bottom side of the rect with the given height', () => {

            const cut = rect.extCutBottom(50)

            expect(cut.top).to.equal(600)
            expect(cut.left).to.equal(300)
            expect(cut.right).to.equal(500)
            expect(cut.bottom).to.equal(650)

        })

    })

    describe('similarInnerTangent', () => {

        it('returns a similar rect which is an inner tangent of the given rect', () => {

            const tangent = rect.similarInnerTangent(new Rect({
                top: 0,
                left: 0,
                right: 100,
                bottom: 50
            }))

            expect(tangent.top).to.equal(0)
            expect(tangent.left).to.equal(40)
            expect(tangent.right).to.equal(60)
            expect(tangent.bottom).to.equal(50)

            const tangent0 = rect.similarInnerTangent(new Rect({
                top: 0,
                left: 0,
                right: 2000,
                bottom: 10000
            }))

            expect(tangent0.top).to.equal(2500)
            expect(tangent0.left).to.equal(0)
            expect(tangent0.right).to.equal(2000)
            expect(tangent0.bottom).to.equal(7500)

        })
    })

    describe('margin', () => {

        it('returns a new rect with the given margins added', () => {

            const margined = rect.margin({
                top: 10,
                left: 10,
                right: 10,
                bottom: 10
            })

            expect(margined.top).to.equal(110)
            expect(margined.left).to.equal(310)
            expect(margined.right).to.equal(490)
            expect(margined.bottom).to.equal(590)

        })

    })

    describe('windowAsRect', () => {

        it('returns a rect of the size of the current window', () => {

            const rect = Rect.windowAsRect()

            expect(rect.top).to.equal(0)
            expect(rect.left).to.equal(0)
            expect(rect.right).to.equal($(window).width())
            expect(rect.bottom).to.equal($(window).height())

        })

    })

    describe('getBestRect', () => {

        it('gets the best available rect inside it with the given horizontal and vertical ratios', () => {

            const best = rect.getBestRect({horizontal: 1, vertical: 2})

            expect(best.top).to.equal(150)
            expect(best.left).to.equal(300)
            expect(best.right).to.equal(500)
            expect(best.bottom).to.equal(550)

            const best0 = rect.getBestRect({horizontal: 1, vertical: 5})

            expect(best0.top).to.equal(100)
            expect(best0.left).to.equal(350)
            expect(best0.right).to.equal(450)
            expect(best0.bottom).to.equal(600)

        })
    })

    describe('toGrid', () => {

        it('returns a grid which has origin at the center of the rect', () => {

            const grid = rect.toGrid()

            expect(grid.x).to.equal(rect.centerX())
            expect(grid.y).to.equal(rect.centerY())

        })

        it('returns a grid which has unit width and height as the width and rect of the rect', () => {

            const grid = rect.toGrid()

            expect(grid.unitWidth).to.equal(rect.width())
            expect(grid.unitHeight).to.equal(rect.height())

        })

    })

    describe('dual', () => {

        it('returns a dual grid', () => {

            const dual = rect.dual()

            expect(dual).to.be.instanceof(Grid)
            expect(dual.x).to.equal(rect.centerX())
            expect(dual.y).to.equal(rect.centerY())
            expect(dual.unitWidth).to.equal(rect.width())
            expect(dual.unitHeight).to.equal(rect.height())

        })

        it('returns a dual grid and its dual is the same as the original', () => {

            const dualDual = rect.dual().dual()

            expect(dualDual).to.be.instanceof(Rect)
            expect(dualDual.top).to.equal(rect.top)
            expect(dualDual.left).to.equal(rect.left)
            expect(dualDual.right).to.equal(rect.right)
            expect(dualDual.bottom).to.equal(rect.bottom)

        })

    })

})
<commit_msg>Fix lint<commit_after>import {Rect, Grid} from '../src'

describe('Rect', () => {

    let rect

    beforeEach(() => {

        rect = new Rect({
            top: 100,
            left: 300,
            right: 500,
            bottom: 600
        })

    })

    describe('width', () => {

        it('returns the width of the rect', () => {

            expect(rect.width()).to.equal(200)

        })

    })

    describe('height', () => {

        it('returns the height of the rect', () => {

            expect(rect.height()).to.equal(500)

        })

    })

    describe('scaleTop', () => {

        it('scales the top side with the given scale', () => {

            const scaled = rect.scaleTop(2)

            expect(scaled.top).to.equal(-400)
            expect(scaled.left).to.equal(300)
            expect(scaled.right).to.equal(500)
            expect(scaled.bottom).to.equal(600)

        })

    })

    describe('scaleLeft', () => {

        it('scales the left side with the given scale', () => {

            const scaled = rect.scaleLeft(2)

            expect(scaled.top).to.equal(100)
            expect(scaled.left).to.equal(100)
            expect(scaled.right).to.equal(500)
            expect(scaled.bottom).to.equal(600)

        })

    })

    describe('scaleRight', () => {

        it('scales the right side with the given scale', () => {

            const scaled = rect.scaleRight(2)

            expect(scaled.top).to.equal(100)
            expect(scaled.left).to.equal(300)
            expect(scaled.right).to.equal(700)
            expect(scaled.bottom).to.equal(600)

        })

    })

    describe('scaleBottom', () => {

        it('scales the bottom side with the given scale', () => {

            const scaled = rect.scaleBottom(2)

            expect(scaled.top).to.equal(100)
            expect(scaled.left).to.equal(300)
            expect(scaled.right).to.equal(500)
            expect(scaled.bottom).to.equal(1100)

        })

    })

    describe('shiftUp', () => {

        it('shifts the rect upward the given units long', () => {

            const shifted = rect.shiftUp(2)

            expect(shifted.top).to.equal(-900)
            expect(shifted.left).to.equal(300)
            expect(shifted.right).to.equal(500)
            expect(shifted.bottom).to.equal(-400)

        })

        it('shifts the rect upward a unit long if called without argument', () => {

            const shifted = rect.shiftUp()

            expect(shifted.top).to.equal(-400)
            expect(shifted.left).to.equal(300)
            expect(shifted.right).to.equal(500)
            expect(shifted.bottom).to.equal(100)

        })

    })

    describe('shiftLeft', () => {

        it('shifts the rect leftward the given units long', () => {

            const shifted = rect.shiftLeft(2)

            expect(shifted.top).to.equal(100)
            expect(shifted.left).to.equal(-100)
            expect(shifted.right).to.equal(100)
            expect(shifted.bottom).to.equal(600)

        })

        it('shifts the rect leftward a unit long if called without argument', () => {

            const shifted = rect.shiftLeft()

            expect(shifted.top).to.equal(100)
            expect(shifted.left).to.equal(100)
            expect(shifted.right).to.equal(300)
            expect(shifted.bottom).to.equal(600)

        })

    })

    describe('shiftRight', () => {

        it('shifts the rect rightward the given units long', () => {

            const shifted = rect.shiftRight(2)

            expect(shifted.top).to.equal(100)
            expect(shifted.left).to.equal(700)
            expect(shifted.right).to.equal(900)
            expect(shifted.bottom).to.equal(600)

        })

        it('shifts the rect rightward a unit long if called without argument', () => {

            const shifted = rect.shiftRight()

            expect(shifted.top).to.equal(100)
            expect(shifted.left).to.equal(500)
            expect(shifted.right).to.equal(700)
            expect(shifted.bottom).to.equal(600)

        })

    })

    describe('shiftDown', () => {

        it('shifts the rect downward the given units long', () => {

            const shifted = rect.shiftDown(2)

            expect(shifted.top).to.equal(1100)
            expect(shifted.left).to.equal(300)
            expect(shifted.right).to.equal(500)
            expect(shifted.bottom).to.equal(1600)

        })

        it('shifts the rect downward a unit long if called without argument', () => {

            const shifted = rect.shiftDown()

            expect(shifted.top).to.equal(600)
            expect(shifted.left).to.equal(300)
            expect(shifted.right).to.equal(500)
            expect(shifted.bottom).to.equal(1100)

        })

    })

    describe('cutTop', () => {

        it('cuts the top part of the given height', () => {

            const cut = rect.cutTop(100)

            expect(cut.top).to.equal(100)
            expect(cut.left).to.equal(300)
            expect(cut.right).to.equal(500)
            expect(cut.bottom).to.equal(200)

        })

    })

    describe('cutLeft', () => {

        it('cuts the left part of the given width', () => {

            const cut = rect.cutLeft(100)

            expect(cut.top).to.equal(100)
            expect(cut.left).to.equal(300)
            expect(cut.right).to.equal(400)
            expect(cut.bottom).to.equal(600)

        })

    })

    describe('cutRight', () => {

        it('cuts the right part of the given width', () => {

            const cut = rect.cutRight(100)

            expect(cut.top).to.equal(100)
            expect(cut.left).to.equal(400)
            expect(cut.right).to.equal(500)
            expect(cut.bottom).to.equal(600)

        })

    })

    describe('cutBottom', () => {

        it('cuts the bottom part of the given height', () => {

            const cut = rect.cutBottom(100)

            expect(cut.top).to.equal(500)
            expect(cut.left).to.equal(300)
            expect(cut.right).to.equal(500)
            expect(cut.bottom).to.equal(600)

        })

    })

    describe('extCutTop', () => {

        it('cuts out the next area of the top side of the rect with the given height', () => {

            const cut = rect.extCutTop(50)

            expect(cut.top).to.equal(50)
            expect(cut.left).to.equal(300)
            expect(cut.right).to.equal(500)
            expect(cut.bottom).to.equal(100)

        })

    })

    describe('extCutLeft', () => {

        it('cuts out the next area of the left side of the rect with the given width', () => {

            const cut = rect.extCutLeft(50)

            expect(cut.top).to.equal(100)
            expect(cut.left).to.equal(250)
            expect(cut.right).to.equal(300)
            expect(cut.bottom).to.equal(600)

        })

    })

    describe('extCutRight', () => {

        it('cuts out the next area of the right side of the rect with the given width', () => {

            const cut = rect.extCutRight(50)

            expect(cut.top).to.equal(100)
            expect(cut.left).to.equal(500)
            expect(cut.right).to.equal(550)
            expect(cut.bottom).to.equal(600)

        })

    })

    describe('extCutBottom', () => {

        it('cuts out the next area of the bottom side of the rect with the given height', () => {

            const cut = rect.extCutBottom(50)

            expect(cut.top).to.equal(600)
            expect(cut.left).to.equal(300)
            expect(cut.right).to.equal(500)
            expect(cut.bottom).to.equal(650)

        })

    })

    describe('similarInnerTangent', () => {

        it('returns a similar rect which is an inner tangent of the given rect', () => {

            const tangent = rect.similarInnerTangent(new Rect({
                top: 0,
                left: 0,
                right: 100,
                bottom: 50
            }))

            expect(tangent.top).to.equal(0)
            expect(tangent.left).to.equal(40)
            expect(tangent.right).to.equal(60)
            expect(tangent.bottom).to.equal(50)

            const tangent0 = rect.similarInnerTangent(new Rect({
                top: 0,
                left: 0,
                right: 2000,
                bottom: 10000
            }))

            expect(tangent0.top).to.equal(2500)
            expect(tangent0.left).to.equal(0)
            expect(tangent0.right).to.equal(2000)
            expect(tangent0.bottom).to.equal(7500)

        })
    })

    describe('margin', () => {

        it('returns a new rect with the given margins added', () => {

            const margined = rect.margin({
                top: 10,
                left: 10,
                right: 10,
                bottom: 10
            })

            expect(margined.top).to.equal(110)
            expect(margined.left).to.equal(310)
            expect(margined.right).to.equal(490)
            expect(margined.bottom).to.equal(590)

        })

    })

    describe('windowAsRect', () => {

        it('returns a rect of the size of the current window', () => {

            const rect = Rect.windowAsRect()

            expect(rect.top).to.equal(0)
            expect(rect.left).to.equal(0)
            expect(rect.right).to.equal($(window).width())
            expect(rect.bottom).to.equal($(window).height())

        })

    })

    describe('getBestRect', () => {

        it('gets the best available rect inside it with the given horizontal and vertical ratios', () => {

            const best = rect.getBestRect({horizontal: 1, vertical: 2})

            expect(best.top).to.equal(150)
            expect(best.left).to.equal(300)
            expect(best.right).to.equal(500)
            expect(best.bottom).to.equal(550)

            const best0 = rect.getBestRect({horizontal: 1, vertical: 5})

            expect(best0.top).to.equal(100)
            expect(best0.left).to.equal(350)
            expect(best0.right).to.equal(450)
            expect(best0.bottom).to.equal(600)

        })
    })

    describe('toGrid', () => {

        it('returns a grid which has origin at the center of the rect', () => {

            const grid = rect.toGrid()

            expect(grid.x).to.equal(rect.centerX())
            expect(grid.y).to.equal(rect.centerY())

        })

        it('returns a grid which has unit width and height as the width and rect of the rect', () => {

            const grid = rect.toGrid()

            expect(grid.unitWidth).to.equal(rect.width())
            expect(grid.unitHeight).to.equal(rect.height())

        })

    })

    describe('dual', () => {

        it('returns a dual grid', () => {

            const dual = rect.dual()

            expect(dual).to.be.instanceof(Grid)
            expect(dual.x).to.equal(rect.centerX())
            expect(dual.y).to.equal(rect.centerY())
            expect(dual.unitWidth).to.equal(rect.width())
            expect(dual.unitHeight).to.equal(rect.height())

        })

        it('returns a dual grid and its dual is the same as the original', () => {

            const dualDual = rect.dual().dual()

            expect(dualDual).to.be.instanceof(Rect)
            expect(dualDual.top).to.equal(rect.top)
            expect(dualDual.left).to.equal(rect.left)
            expect(dualDual.right).to.equal(rect.right)
            expect(dualDual.bottom).to.equal(rect.bottom)

        })

    })

})
<|endoftext|>


<commit_before>#!/usr/bin/env node
var child_process = require('child_process');

function log(msg) {
	process.stdout.write(msg + '\n');
}

module.exports = function(context) {
	var fs = context.requireCordovaModule('fs');
	var path = context.requireCordovaModule('path');
	var deferral = context.requireCordovaModule('q').defer();

	var make_platform_dir = function(base) {
		return path.join(base, 'platforms', 'ios');
	}
	var pluginDir = path.join(context.opts.projectRoot, 'plugins', context.opts.plugin.id);
	var hooksDir = path.join(make_platform_dir(pluginDir), 'hooks');

	var addHook = function() {
		var XmlHelpers = context.requireCordovaModule("cordova-lib/src/util/xml-helpers");
		var et = context.requireCordovaModule('elementtree');

		var configFile = path.join(context.opts.projectRoot, 'config.xml');
		var xml = XmlHelpers.parseElementtreeSync(configFile);
		log('Processing XML: ' + JSON.stringify(xml, null, '\t'));

		var getParent = function(tag, name) {
			log('getParent: ' + tag + '(name=' + name + ')');
			var list = xml.findall('/' + tag);
			log('Finding ios in: ' + list);
			var ios = list.find(function(e) {
				return e.get('name') === name;
			});
			log('Found platform(name=ios): ' + ios);
			if (!ios) {
				log('Creating tag: ' + tag + '(name=' + name + ')');
				ios = el.makeelement(tag, {name: name});
				xml.append(ios);
			}
			return ios;
		}
		var child = et.XML('<hook type="after_plugin_add" src="' + path.join(hooksDir, 'add-bridging_header.sh') + '" />');
		getParent('platform', 'ios').append(child);

		fs.writeFileSync(configFile, xml.write({indent: 4}), 'utf-8');
	}

	var main = function() {
		log("################################ Start preparing\n");
		addHook();

		var script = path.join(hooksDir, 'after_plugin_install.sh');
		var child = child_process.execFile(script, [ context.opts.plugin.id ], {
			cwd : make_platform_dir(context.opts.projectRoot)
		}, function(error) {
			if (error) {
				deferral.reject(error);
			} else {
				log("################################ Finish preparing\n\n");
				deferral.resolve();
			}
		});
		child.stdout.on('data', function(data) {
			log(data);
		});
		child.stderr.on('data', function(data) {
			process.stderr.write(data);
		});
	}
	main();
	return deferral.promise;
};
<commit_msg>findall ではなく getchildren に変更<commit_after>#!/usr/bin/env node
var child_process = require('child_process');

function log(msg) {
	process.stdout.write(msg + '\n');
}

module.exports = function(context) {
	var fs = context.requireCordovaModule('fs');
	var path = context.requireCordovaModule('path');
	var deferral = context.requireCordovaModule('q').defer();

	var make_platform_dir = function(base) {
		return path.join(base, 'platforms', 'ios');
	}
	var pluginDir = path.join(context.opts.projectRoot, 'plugins', context.opts.plugin.id);
	var hooksDir = path.join(make_platform_dir(pluginDir), 'hooks');

	var addHook = function() {
		var XmlHelpers = context.requireCordovaModule("cordova-lib/src/util/xml-helpers");
		var et = context.requireCordovaModule('elementtree');

		var configFile = path.join(context.opts.projectRoot, 'config.xml');
		var xml = XmlHelpers.parseElementtreeSync(configFile);
		log('Processing XML: ' + JSON.stringify(xml, null, '\t'));

		var getParent = function(tag, name) {
			log('getParent: ' + tag + '(name=' + name + ')');
			var list = xml.getchildren('/' + tag);
			log('Finding ios in: ' + list);
			var ios = list.find(function(e) {
				return e.tag === tag && e.get('name') === name;
			});
			log('Found platform(name=ios): ' + ios);
			if (!ios) {
				log('Creating tag: ' + tag + '(name=' + name + ')');
				ios = el.makeelement(tag, {name: name});
				xml.append(ios);
			}
			return ios;
		}
		var child = et.XML('<hook type="after_plugin_add" src="' + path.join(hooksDir, 'add-bridging_header.sh') + '" />');
		getParent('platform', 'ios').append(child);

		fs.writeFileSync(configFile, xml.write({indent: 4}), 'utf-8');
	}

	var main = function() {
		log("################################ Start preparing\n");
		addHook();

		var script = path.join(hooksDir, 'after_plugin_install.sh');
		var child = child_process.execFile(script, [ context.opts.plugin.id ], {
			cwd : make_platform_dir(context.opts.projectRoot)
		}, function(error) {
			if (error) {
				deferral.reject(error);
			} else {
				log("################################ Finish preparing\n\n");
				deferral.resolve();
			}
		});
		child.stdout.on('data', function(data) {
			log(data);
		});
		child.stderr.on('data', function(data) {
			process.stderr.write(data);
		});
	}
	main();
	return deferral.promise;
};
<|endoftext|>


<commit_before>let fs = require('fs')
let path = require('path')
let tildify = require('tildify')
let mkdirp = require('mkdirp')
let common = require('../common')
let conf = require('../conf')

module.exports = {
  add,
  rm,
  ls
}

let serversDir = common.serversDir

mkdirp.sync(serversDir)

function getId (name) {
  return name || path.basename(process.cwd())
}

function getServerFile (id) {
  return `${serversDir}/${id}.json`
}

function add (cmd, opts) {
  let id = getId(opts.n)
  let file = getServerFile(id)
  let obj = {
    cwd: process.cwd(),
    cmd: cmd
  }

  if (opts.o) obj.out = opts.o

  obj.env = {}

  // By default, save PATH env for version managers users
  obj.env.PATH = process.env.PATH

  if (opts.e && process.env[opts.e]) {
    obj.env[opts.e] = process.env[opts.e]
  }

  let data = JSON.stringify(obj, null, 2)

  console.log(`  Create ${tildify(file)}`)
  fs.writeFileSync(file, data)

  if (obj.out) {
    let logFile = tildify(path.resolve(obj.out))
    console.log(`  Output ${logFile}`)
  } else {
    console.log('  Output No log file specified (use \'-o app.log\')')
  }

  console.log(`  Added  http://localhost:${conf.port}/${id}`)
}

function rm (name) {
  let id = getId(name)
  let file = getServerFile(id)

  console.log(`  Remove  ${tildify(file)}`)
  if (fs.existsSync(file)) {
    fs.unlinkSync(file)
    console.log('  Removed')
  } else {
    console.log('  No such file')
  }
}

function ls () {
  let list = fs
    .readdirSync(serversDir)
    .map(file => {
      let id = path.basename(file, '.json')
      let serverFile = getServerFile(id)
      let server = JSON.parse(fs.readFileSync(serverFile))
      return `  ${tildify(server.cwd)}$ ${server.cmd}\n` +
        `  http://localhost:${conf.port}/${id}`
    })
    .join('\n\n')

  console.log(list)
}
<commit_msg>Small refactor<commit_after>let fs = require('fs')
let path = require('path')
let tildify = require('tildify')
let mkdirp = require('mkdirp')
let common = require('../common')
let conf = require('../conf')

module.exports = {
  add,
  rm,
  ls
}

let serversDir = common.serversDir

mkdirp.sync(serversDir)

function getId (name) {
  return name || path.basename(process.cwd())
}

function getServerFile (id) {
  return `${serversDir}/${id}.json`
}

function add (cmd, opts) {
  let id = getId(opts.n)
  let file = getServerFile(id)
  let cwd = process.cwd()
  let obj = { cwd, cmd }

  if (opts.o) obj.out = opts.o

  obj.env = {}

  // By default, save PATH env for version managers users
  obj.env.PATH = process.env.PATH

  if (opts.e && process.env[opts.e]) {
    obj.env[opts.e] = process.env[opts.e]
  }

  let data = JSON.stringify(obj, null, 2)

  console.log(`  Create ${tildify(file)}`)
  fs.writeFileSync(file, data)

  if (obj.out) {
    let logFile = tildify(path.resolve(obj.out))
    console.log(`  Output ${logFile}`)
  } else {
    console.log('  Output No log file specified (use \'-o app.log\')')
  }

  console.log(`  Added  http://localhost:${conf.port}/${id}`)
}

function rm (name) {
  let id = getId(name)
  let file = getServerFile(id)

  console.log(`  Remove  ${tildify(file)}`)
  if (fs.existsSync(file)) {
    fs.unlinkSync(file)
    console.log('  Removed')
  } else {
    console.log('  No such file')
  }
}

function ls () {
  let list = fs
    .readdirSync(serversDir)
    .map(file => {
      let id = path.basename(file, '.json')
      let serverFile = getServerFile(id)
      let server = JSON.parse(fs.readFileSync(serverFile))
      return `  ${tildify(server.cwd)}$ ${server.cmd}\n` +
        `  http://localhost:${conf.port}/${id}`
    })
    .join('\n\n')

  console.log(list)
}
<|endoftext|>