<commit_before>window.jermaine.util.namespace("window.ide", function (ns) {
    var Button = ns.Button;
    var Project = ns.Project;

    //////////////// IDE MODEL /////////////////////////
    var IDE = new window.jermaine.Model (function () {
        this.hasAn("editor").which.isImmutable();
        this.hasA("directory").which.isA("string");

        this.hasA("project").which.validatesWith(function (project) {
            return project instanceof Project;
        });

        this.hasA("changedFlag").which.isA("boolean").and.defaultsTo(false);

        this.hasMany("messages").eachOfWhich.isA("string");
        this.hasMany("buttons").which.validateWith(function (button) {
            return button instanceof Button;
        });

        this.hasA("view");

        this.isBuiltWith("directory", function () {
            var that = this;

            //initialize editor as ace editor
            this.editor(ace.edit("IDE-editor"));
            this.editor().setTheme("ace/theme/eclipse");
            this.editor().setHighlightActiveLine(false);
            this.editor().renderer.setShowPrintMargin(false);

            this.editor().getSession().on("change", function () {
                that.changedFlag(true);
            });

            this.view(new IDEView(this));
        });
    });
    //////////////// IDE MODEL /////////////////////////

    //////////////// IDE VIEW //////////////////////////
    var IDEView = new window.jermaine.View (function () {
        var messageTimer,
            messageTimeout = 5000,
            toggleEditorAndDirectory;

        this.respondsTo("deleteSketch", function (name) {
            var that = this;
            var instance = this.instance();
            if(confirm("Are you sure you want to delete '"+name+"'?"))  {
                $.post("sketches/"+name+"/delete", function (response) {
                    if ($("#"+name).hasClass("active")) {
                        if ($("#"+name).next("div.directory_listing").size() > 0) {
                            $("#"+name).next("div.directory_listing").trigger("click");
                        } else if ($("#"+name).prev("div.directory_listing").size() > 0) {
                            $("#"+name).prev("div.inactive").trigger("click");
                        } else {
                            that.setUpEmptyDirectory();
                        }
                    }
                    $("#"+name).fadeOut(function () {
                        $("#"+name).remove();
                    });
                });
            }
        });

        this.respondsTo("createNewSketch", function (name) {
            var that = this,
                instance = this.instance(),
                directoryEntryTemplate = Handlebars.compile($("#directory-entry-partial").html());

            $.post("sketches/new", {"title":name}, function (sketch) {
                var p = {"name":sketch.title,
                         "directory":"sketches",
                         "url":sketch.slug+".json"
                         };

                //because this is returning strings on error :(
                if (typeof (sketch) === "object") {
                    var menuEntry = $(directoryEntryTemplate(p));
                    menuEntry.hide();
                    menuEntry.insertAfter("#new_sketch_div");

                    if ($("#empty_directory").size() > 0) {
                        $("#empty_directory").remove();
                        $("#IDE-title").click(function () {
                            that.toggleEditorAndDirectory();
                        });
                    };

                    //duplicate code
                    menuEntry.children("span").click(function () {
                        that.deleteSketch($(this).parent("div").attr("id"));
                        return false;
                    });

                    menuEntry.click(function () {
                        if (instance.project() !== undefined) {
                            $("#"+instance.project().url().match(/\/(.*)\.json/)[1]).removeClass("active").addClass("inactive");
                        }
                        $(this).addClass("active").removeClass("inactive");
                        instance.project(new Project($(this).find("a").attr("href")));
                        //that.toggleEditorAndDirectory();
                        return false;
                    });

                    $("#new_sketch_div").fadeOut(function () {
                        $("#new_sketch_input").val("");
                        menuEntry.fadeIn(function () {
                            menuEntry.trigger("click");
                        });
                    });
                } else {
                    console.log(sketch);
                }
            });

        });

        this.respondsTo("toggleEditorAndDirectory", function () {
            var that = this;
            var direction = $("#ide").is(":visible")?"lr":"rl";
            var elementA = $("#ide").is(":visible")?$("#ide"):$("#IDE-directory");
            var elementB = $("#ide").is(":visible")?$("#IDE-directory"):$("#ide");

            elementA.flip({
                speed: 200,
                direction:direction,
                color:"#fff",
                onBefore: function () {
                    elementA.hide();
                    $("#IDE-title").unbind("click");
                },
                onEnd: function () {
                    elementB.show();
                    if ($("#empty_directory").size() === 0) {
                        $("#IDE-title").click(function () {
                            that.toggleEditorAndDirectory();
                        });
                    }
                    //this is a hack to force Ace to update when the editor
                    //becomes visible again
                    if ($("#ide").is(":visible")) {
                        that.instance().editor().setValue(that.instance().editor().getValue());
                        that.instance().editor().gotoLine(0,0);
                    }

                }
            });
        });

        this.respondsTo("setUpProcessingRunner", function () {
            var p;  //processing object
            var error;  //processing error
            var that = this;

            $("#IDE-run_button").colorbox({
                'title' : this.instance().project().title(),
                'inline' : true,
                'scrolling' : false,
                'href':"#canvas",
                'onLoad' : function()  {
                    var width, height;
                    var code = that.instance().editor().getSession().getValue();
                    var canvas = document.getElementById("processing_canvas");
                    error = null;

                    try  {

                        var dimensions = code.match(/\s+size\((\d+),(\d+)\)/);
                        if (dimensions !== null) {
                            width = parseInt(dimensions[1]);
                            height = parseInt(dimensions[2]);
                        } else {
                            width = 200;
                            height = 200;
                        }
                        $("#processing_canvas").css('width',width);
                        $("#processing_canvas").css('height',height);
                        p = new Processing(canvas, code);
                    }
                    catch(err)  {
                        error = err;
                        Processing.logger.log(err);
                        if(p)  {
                            p.exit();
                        }
                    }
                },

                'onComplete' : function()  {
                    if(error)  {
                        console.log(error);
                        $.colorbox.close();
                    } else  {
                        $("#processing_canvas").focus();
                    }
                },
                'onCleanup' : function()  {
                    if(p)  {
                        p.exit();
                    }
                }
            });
        });

        this.respondsTo("setUpEmptyDirectory", function () {
            $("#IDE-title").unbind("click");
            $("#IDE-title").html(" ");
            $("#directory").append("

you have no sketches :(

click the button above to add one :)

");
        });

        this.respondsTo("addServerButtons", function () {
            var that = this;

            this.instance().buttons().add(new Button("save", "images/icons/save.png", function () {
                var saveURL;

                if (that.instance().changedFlag() === false) {
                    that.instance().messages().add("no changes need to be saved");
                } else {
                    that.instance().project().source(that.instance().editor().getSession().getValue());
                    that.instance().project().save(function (response) {
                        that.instance().messages().add(response);
                        that.instance().changedFlag(false);
                    });
                }
            }));
        });

        this.initializesWith(function () {
            var that = this;

            //add run button
            this.instance().buttons().add(new Button("run", "images/icons/run.png", function () {
                that.instance().messages().add("running program");
                return false;
            }));

            //set up the click responder on the title
            $("#IDE-title").click(function () {
                that.toggleEditorAndDirectory();
            });

            if ($("#ide").hasClass("server")) {
                this.addServerButtons();
            }
        });

        this.watches("messages", function (newMessage) {
            if (messageTimer !== null) {
                clearTimeout(messageTimer);
            }

            $("#IDE-message").css("display", "none");
            $("#IDE-message").text(newMessage);
            $("#IDE-message").fadeIn();

            messageTimer = setTimeout(function()  {
                $("#IDE-message").fadeOut();
            }, messageTimeout);
        });

        this.watches("project", function (newProject) {
            $("#IDE-directory #" + this.instance().project().url().match(/\/(.*)\.json/)[1]).addClass("active").removeClass("inactive");
            this.setUpProcessingRunner();
        });

        this.watches("project.title", function (newTitle) {
            $("#IDE-title").text(newTitle);
        });

        this.watches("project.source", function (newSource) {
            this.instance().editor().getSession().setValue(newSource);
            this.instance().changedFlag(false);
        });

        this.watches("buttons", function (newButton) {
            var button = $($.parseHTML(newButton.view().render()));
            //add click function
            button.click(function () {
                newButton.handler()();
            });
            $("#IDE-buttons").append(button);
        });

        this.watches("directory", function (newDirectory) {
            var instance = this.instance(),
                that = this;

            $.getJSON(newDirectory, function (result) {
                var directoryTemplate = Handlebars.compile($("#directory-template").html());
                Handlebars.registerPartial("directory-entry", $("#directory-entry-partial").html());
                for (i = 0; i < result.length; ++i) {
                    result[i]["directory"] = "sketches";
                    result[i]["name"] = result[i]["url"].match(/(.*).json/)[1];
                }
                $("#IDE-directory").append(directoryTemplate({project:result}));

                $(".directory_listing").each(function (i, elt) {
                    $(elt).click(function () {
                        $("#"+instance.project().url().match(/\/(.*)\.json/)[1]).removeClass("active").addClass("inactive");
                        $(elt).addClass("active").removeClass("inactive");
                        instance.project(new Project($(elt).find("a").attr("href")));
                        //that.toggleEditorAndDirectory();
                        return false;
                    });
                });

                if (result.length > 0) {
                    instance.project(new Project(result[0]["directory"] + "/" + result[0].url));
                } else {
                    //show directory
                    that.toggleEditorAndDirectory();
                    that.setUpEmptyDirectory();
                }

                if ($("#ide").hasClass("server")) {
                    $("#new_sketch_button").click(function () {
                        if ($("#new_sketch_div").is(":visible")) {
                            $("#new_sketch_div").slideUp(function () {
                                $("#new_sketch_input").val("");
                            });
                        } else {
                            $("#new_sketch_div").slideDown();
                        }
                    });

                    $("#new_sketch_input").keypress(function (e) {
                        if (e.keyCode === 13 && $(this).val() !== "" ) {
                            that.createNewSketch($(this).val());
                        }
                    });

                    $(".delete_sketch_button").click(function () {
                        that.deleteSketch($(this).parent("div").attr("id"));
                        return false;
                    });
                }
            });
        });
    });
    //////////////// IDE VIEW //////////////////////////

    ns.IDE = IDE;
});
<commit_msg>fix error with directory entry templates<commit_after>window.jermaine.util.namespace("window.ide", function (ns) {
    var Button = ns.Button;
    var Project = ns.Project;

    //////////////// IDE MODEL /////////////////////////
    var IDE = new window.jermaine.Model (function () {
        this.hasAn("editor").which.isImmutable();
        this.hasA("directory").which.isA("string");

        this.hasA("project").which.validatesWith(function (project) {
            return project instanceof Project;
        });

        this.hasA("changedFlag").which.isA("boolean").and.defaultsTo(false);

        this.hasMany("messages").eachOfWhich.isA("string");
        this.hasMany("buttons").which.validateWith(function (button) {
            return button instanceof Button;
        });

        this.hasA("view");

        this.isBuiltWith("directory", function () {
            var that = this;

            //initialize editor as ace editor
            this.editor(ace.edit("IDE-editor"));
            this.editor().setTheme("ace/theme/eclipse");
            this.editor().setHighlightActiveLine(false);
            this.editor().renderer.setShowPrintMargin(false);

            this.editor().getSession().on("change", function () {
                that.changedFlag(true);
            });

            this.view(new IDEView(this));
        });
    });
    //////////////// IDE MODEL /////////////////////////

    //////////////// IDE VIEW //////////////////////////
    var IDEView = new window.jermaine.View (function () {
        var messageTimer,
            messageTimeout = 5000,
            toggleEditorAndDirectory;

        this.respondsTo("deleteSketch", function (name) {
            var that = this;
            var instance = this.instance();
            if(confirm("Are you sure you want to delete '"+name+"'?"))  {
                $.post("sketches/"+name+"/delete", function (response) {
                    if ($("#"+name).hasClass("active")) {
                        if ($("#"+name).next("div.directory_listing").size() > 0) {
                            $("#"+name).next("div.directory_listing").trigger("click");
                        } else if ($("#"+name).prev("div.directory_listing").size() > 0) {
                            $("#"+name).prev("div.inactive").trigger("click");
                        } else {
                            that.setUpEmptyDirectory();
                        }
                    }
                    $("#"+name).fadeOut(function () {
                        $("#"+name).remove();
                    });
                });
            }
        });

        this.respondsTo("createNewSketch", function (name) {
            var that = this,
                instance = this.instance(),
                directoryEntryTemplate = Handlebars.compile($("#directory-entry-partial").html());

            $.post("sketches/new", {"title":name}, function (sketch) {
                var p = {"title":sketch.title,
                         "directory":"sketches",
                         "url":sketch.slug+".json"
                         };

                //because this is returning strings on error :(
                if (typeof (sketch) === "object") {
                    var menuEntry = $($.trim(directoryEntryTemplate(p)));
                    menuEntry.hide();
                    menuEntry.insertAfter("#new_sketch_div");

                    if ($("#empty_directory").size() > 0) {
                        $("#empty_directory").remove();
                        $("#IDE-title").click(function () {
                            that.toggleEditorAndDirectory();
                        });
                    };

                    //duplicate code
                    menuEntry.children("span").click(function () {
                        that.deleteSketch($(this).parent("div").attr("id"));
                        return false;
                    });

                    menuEntry.click(function () {
                        if (instance.project() !== undefined) {
                            $("#"+instance.project().url().match(/\/(.*)\.json/)[1]).removeClass("active").addClass("inactive");
                        }
                        $(this).addClass("active").removeClass("inactive");
                        instance.project(new Project($(this).find("a").attr("href")));
                        //that.toggleEditorAndDirectory();
                        return false;
                    });

                    $("#new_sketch_div").fadeOut(function () {
                        $("#new_sketch_input").val("");
                        menuEntry.fadeIn(function () {
                            menuEntry.trigger("click");
                        });
                    });
                } else {
                    console.log(sketch);
                }
            });

        });

        this.respondsTo("toggleEditorAndDirectory", function () {
            var that = this;
            var direction = $("#ide").is(":visible")?"lr":"rl";
            var elementA = $("#ide").is(":visible")?$("#ide"):$("#IDE-directory");
            var elementB = $("#ide").is(":visible")?$("#IDE-directory"):$("#ide");

            elementA.flip({
                speed: 200,
                direction:direction,
                color:"#fff",
                onBefore: function () {
                    elementA.hide();
                    $("#IDE-title").unbind("click");
                },
                onEnd: function () {
                    elementB.show();
                    if ($("#empty_directory").size() === 0) {
                        $("#IDE-title").click(function () {
                            that.toggleEditorAndDirectory();
                        });
                    }
                    //this is a hack to force Ace to update when the editor
                    //becomes visible again
                    if ($("#ide").is(":visible")) {
                        that.instance().editor().setValue(that.instance().editor().getValue());
                        that.instance().editor().gotoLine(0,0);
                    }

                }
            });
        });

        this.respondsTo("setUpProcessingRunner", function () {
            var p;  //processing object
            var error;  //processing error
            var that = this;

            $("#IDE-run_button").colorbox({
                'title' : this.instance().project().title(),
                'inline' : true,
                'scrolling' : false,
                'href':"#canvas",
                'onLoad' : function()  {
                    var width, height;
                    var code = that.instance().editor().getSession().getValue();
                    var canvas = document.getElementById("processing_canvas");
                    error = null;

                    try  {

                        var dimensions = code.match(/\s+size\((\d+),(\d+)\)/);
                        if (dimensions !== null) {
                            width = parseInt(dimensions[1]);
                            height = parseInt(dimensions[2]);
                        } else {
                            width = 200;
                            height = 200;
                        }
                        $("#processing_canvas").css('width',width);
                        $("#processing_canvas").css('height',height);
                        p = new Processing(canvas, code);
                    }
                    catch(err)  {
                        error = err;
                        Processing.logger.log(err);
                        if(p)  {
                            p.exit();
                        }
                    }
                },

                'onComplete' : function()  {
                    if(error)  {
                        console.log(error);
                        $.colorbox.close();
                    } else  {
                        $("#processing_canvas").focus();
                    }
                },
                'onCleanup' : function()  {
                    if(p)  {
                        p.exit();
                    }
                }
            });
        });

        this.respondsTo("setUpEmptyDirectory", function () {
            $("#IDE-title").unbind("click");
            $("#IDE-title").html(" ");
            $("#directory").append("

you have no sketches :(

click the button above to add one :)

");
        });

        this.respondsTo("addServerButtons", function () {
            var that = this;

            this.instance().buttons().add(new Button("save", "images/icons/save.png", function () {
                var saveURL;

                if (that.instance().changedFlag() === false) {
                    that.instance().messages().add("no changes need to be saved");
                } else {
                    that.instance().project().source(that.instance().editor().getSession().getValue());
                    that.instance().project().save(function (response) {
                        that.instance().messages().add(response);
                        that.instance().changedFlag(false);
                    });
                }
            }));
        });

        this.initializesWith(function () {
            var that = this;

            //add run button
            this.instance().buttons().add(new Button("run", "images/icons/run.png", function () {
                that.instance().messages().add("running program");
                return false;
            }));

            //set up the click responder on the title
            $("#IDE-title").click(function () {
                that.toggleEditorAndDirectory();
            });

            if ($("#ide").hasClass("server")) {
                this.addServerButtons();
            }
        });

        this.watches("messages", function (newMessage) {
            if (messageTimer !== null) {
                clearTimeout(messageTimer);
            }

            $("#IDE-message").css("display", "none");
            $("#IDE-message").text(newMessage);
            $("#IDE-message").fadeIn();

            messageTimer = setTimeout(function()  {
                $("#IDE-message").fadeOut();
            }, messageTimeout);
        });

        this.watches("project", function (newProject) {
            $("#IDE-directory #" + this.instance().project().url().match(/\/(.*)\.json/)[1]).addClass("active").removeClass("inactive");
            this.setUpProcessingRunner();
        });

        this.watches("project.title", function (newTitle) {
            $("#IDE-title").text(newTitle);
        });

        this.watches("project.source", function (newSource) {
            this.instance().editor().getSession().setValue(newSource);
            this.instance().changedFlag(false);
        });

        this.watches("buttons", function (newButton) {
            var button = $($.parseHTML(newButton.view().render()));
            //add click function
            button.click(function () {
                newButton.handler()();
            });
            $("#IDE-buttons").append(button);
        });

        this.watches("directory", function (newDirectory) {
            var instance = this.instance(),
                that = this;

            $.getJSON(newDirectory, function (result) {
                var directoryTemplate = Handlebars.compile($("#directory-template").html());
                Handlebars.registerPartial("directory-entry", $("#directory-entry-partial").html());
                for (i = 0; i < result.length; ++i) {
                    result[i]["directory"] = "sketches";
                    result[i]["name"] = result[i]["url"].match(/(.*).json/)[1];
                }
                $("#IDE-directory").append(directoryTemplate({project:result}));

                $(".directory_listing").each(function (i, elt) {
                    $(elt).click(function () {
                        $("#"+instance.project().url().match(/\/(.*)\.json/)[1]).removeClass("active").addClass("inactive");
                        $(elt).addClass("active").removeClass("inactive");
                        instance.project(new Project($(elt).find("a").attr("href")));
                        //that.toggleEditorAndDirectory();
                        return false;
                    });
                });

                if (result.length > 0) {
                    instance.project(new Project(result[0]["directory"] + "/" + result[0].url));
                } else {
                    //show directory
                    that.toggleEditorAndDirectory();
                    that.setUpEmptyDirectory();
                }

                if ($("#ide").hasClass("server")) {
                    $("#new_sketch_button").click(function () {
                        if ($("#new_sketch_div").is(":visible")) {
                            $("#new_sketch_div").slideUp(function () {
                                $("#new_sketch_input").val("");
                            });
                        } else {
                            $("#new_sketch_div").slideDown();
                        }
                    });

                    $("#new_sketch_input").keypress(function (e) {
                        if (e.keyCode === 13 && $(this).val() !== "" ) {
                            that.createNewSketch($(this).val());
                        }
                    });

                    $(".delete_sketch_button").click(function () {
                        that.deleteSketch($(this).parent("div").attr("id"));
                        return false;
                    });
                }
            });
        });
    });
    //////////////// IDE VIEW //////////////////////////

    ns.IDE = IDE;
});
<|endoftext|>


<commit_before>/*
* Copyright (c) 2012-2015 S-Core Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
 * Constructor
 * Workbench
 *
 * @see Page, EventEmitter, PartContainer, Part, Perspective
 * @since: 2015.07.12
 * @author: hw.shim
 */

// @formatter:off
define([
    'external/eventEmitter/EventEmitter',
    'webida-lib/util/genetic',
    'webida-lib/util/logger/logger-client',
    './CompatibleLayoutPane',
    './DataSourceRegistry',
    './LayoutPane',
    './Page',
    './WorkspaceModel'
], function(
    EventEmitter,
    genetic,
    Logger,
    CompatibleLayoutPane,
    DataSourceRegistry,
    LayoutPane,
    Page,
    WorkspaceModel
) {
    'use strict';
// @formatter:on

    /**
     * @typedef {Object.<Object, Object>} Map
     * @typedef {Object} DataSourceRegistry
     * @typedef {Object} Page
     * @typedef {Object} WorkbenchModel
     * @typedef {Object} WorkspaceModel
     */

    var logger = new Logger();
    //logger.setConfig('level', Logger.LEVELS.log);
    //logger.off();

    function Workbench() {
        logger.info('new Workbench()');
        /** @type {Page} */
        this.currentPage = null;
        /** @type {Map.<string, Page>} */
        this.pages = [];
        /** @type {DataSourceRegistry} */
        this.dataSourceRegistry = new DataSourceRegistry();
        /** @type {WorkspaceModel} */
        this.workspaceModel = new WorkspaceModel();
    }

    genetic.inherits(Workbench, EventEmitter, {

        /**
         * @param {Page} page
         */
        addPage: function(page) {
            this.pages.push(page);
            page.setParent(this);
        },

        /**
         * @param {Page} page
         */
        removePage: function(page) {
            var index = this.pages.indexOf(page);
            if (index >= 0) {
                page.setParent(null);
                this.pages.splice(index, 1);
            }
        },

        /**
         * @return {Page[]}
         */
        getPages: function() {
            return this.pages;
        },

        /**
         * @param {Page} page
         */
        setCurrentPage: function(page) {
            this.currentPage = page;
        },

        /**
         * @return {Page}
         */
        getCurrentPage: function() {
            return this.currentPage;
        },

        /**
         * @return {DataSourceRegistry}
         */
        getDataSourceRegistry: function() {
            return this.dataSourceRegistry;
        },

        /**
         * Return true if specified dataSource is used
         * @return {boolean}
         */
        isDataSourceUsed: function(dataSource) {
            var reg, parts;
            var pages = this.getPages();
            for (var i in pages) {
                reg = pages[i].getPartRegistry();
                parts = reg.getPartsByDataSource(dataSource);
                if (parts.length > 0) {
                    return true;
                }
            }
            return false;
        },

        /**
         * @param {Object} dataSourceId
         * @param {Function} callback
         */
        createDataSource: function(dataSourceId, callback) {
            logger.info('createDataSource(' + dataSourceId + ', callback)');
            var dsRegistry = this.getDataSourceRegistry();
            var wsModel = this.getWorkspaceModel();
            var factoryId = wsModel.getDataSourceFactory(dataSourceId);
            require([factoryId], function(DataSourceFactory) {
                var factory = new DataSourceFactory();
                var dataSource = factory.create(dataSourceId);
                dsRegistry.registerDataSource(dataSource);
                callback(dataSource);
            });
        },

        /**
         * @param {WorkspaceModel}
         */
        getWorkspaceModel: function() {
            return this.workspaceModel;
        },

        /**
         * @param {WorkbenchModel} model
         */
        parseModel: function(workbenchModel) {

            //TODO : if(!(model instanceof WorkbenchModel)){return;}

            function getLayoutTree(model) {
                var LayoutClass = {
                    'Page': Page,
                    'LayoutPane': LayoutPane,
                    'CompatibleLayoutPane': CompatibleLayoutPane
                }
                var layoutTree, split, children, child;
                if ('type' in model) {
                    layoutTree = new LayoutClass[model.type](model.id, model.name);
                    if ('split' in model) {
                        split = model.split;
                        layoutTree.setOrientation(split.orientation);
                        layoutTree.setRatio(split.ratio);
                    }
                    if ('children' in model) {
                        children = model.children;
                        for (var i in children) {
                            child = getLayoutTree(children[i]);
                            layoutTree.insertChild(child, i);
                        }
                    }
                    return layoutTree;
                }
                return null;
            }

            if ('pages' in workbenchModel) {
                var page = [], pages = workbenchModel.pages;
                for (var i in pages) {
                    page[i] = getLayoutTree(pages[i]);
                    this.addPage(page[i]);
                }
                this.setCurrentPage(page[0]);
            }
        }
    });

    Workbench.CREATE_DATA_SOURCE = 'createDataSource';

    return Workbench;
});
<commit_msg>[TASK] Workbench : Solves async creation of DataSource<commit_after>/*
* Copyright (c) 2012-2015 S-Core Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
 * Constructor
 * Workbench
 *
 * @see Page, EventEmitter, PartContainer, Part, Perspective
 * @since: 2015.07.12
 * @author: hw.shim
 */

// @formatter:off
define([
    'external/eventEmitter/EventEmitter',
    'webida-lib/util/genetic',
    'webida-lib/util/logger/logger-client',
    './CompatibleLayoutPane',
    './DataSourceRegistry',
    './LayoutPane',
    './Page',
    './WorkspaceModel'
], function(
    EventEmitter,
    genetic,
    Logger,
    CompatibleLayoutPane,
    DataSourceRegistry,
    LayoutPane,
    Page,
    WorkspaceModel
) {
    'use strict';
// @formatter:on

    /**
     * @typedef {Object.<Object, Object>} Map
     * @typedef {Object} DataSourceRegistry
     * @typedef {Object} Page
     * @typedef {Object} WorkbenchModel
     * @typedef {Object} WorkspaceModel
     */

    var logger = new Logger();
    //logger.setConfig('level', Logger.LEVELS.log);
    //logger.off();

    function Workbench() {
        logger.info('new Workbench()');
        /** @type {Page} */
        this.currentPage = null;
        /** @type {Map.<string, Page>} */
        this.pages = [];
        /** @type {DataSourceRegistry} */
        this.dataSourceRegistry = new DataSourceRegistry();
        /** @type {WorkspaceModel} */
        this.workspaceModel = new WorkspaceModel();
    }

    genetic.inherits(Workbench, EventEmitter, {

        /**
         * @param {Page} page
         */
        addPage: function(page) {
            this.pages.push(page);
            page.setParent(this);
        },

        /**
         * @param {Page} page
         */
        removePage: function(page) {
            var index = this.pages.indexOf(page);
            if (index >= 0) {
                page.setParent(null);
                this.pages.splice(index, 1);
            }
        },

        /**
         * @return {Page[]}
         */
        getPages: function() {
            return this.pages;
        },

        /**
         * @param {Page} page
         */
        setCurrentPage: function(page) {
            this.currentPage = page;
        },

        /**
         * @return {Page}
         */
        getCurrentPage: function() {
            return this.currentPage;
        },

        /**
         * @return {DataSourceRegistry}
         */
        getDataSourceRegistry: function() {
            return this.dataSourceRegistry;
        },

        /**
         * Return true if specified dataSource is used
         * @return {boolean}
         */
        isDataSourceUsed: function(dataSource) {
            var reg, parts;
            var pages = this.getPages();
            for (var i in pages) {
                reg = pages[i].getPartRegistry();
                parts = reg.getPartsByDataSource(dataSource);
                if (parts.length > 0) {
                    return true;
                }
            }
            return false;
        },

        /**
         * @param {Object} dataSourceId
         * @param {Function} callback
         */
        createDataSource: function(dataSourceId, callback) {
            logger.info('createDataSource(' + dataSourceId + ', callback)');
            var dsRegistry = this.getDataSourceRegistry();
            var wsModel = this.getWorkspaceModel();
            var factoryId = wsModel.getDataSourceFactory(dataSourceId);
            require([factoryId], function(DataSourceFactory) {
                var dataSource;
                var existingDs = dsRegistry.getDataSourceById(dataSourceId);
                //To solve async creation of DataSource check exists again
                if (existingDs) {
                    dataSource = existingDs;
                } else {
                    var factory = new DataSourceFactory();
                    dataSource = factory.create(dataSourceId);
                    dsRegistry.registerDataSource(dataSource);
                }
                callback(dataSource);
            });
        },

        /**
         * @param {WorkspaceModel}
         */
        getWorkspaceModel: function() {
            return this.workspaceModel;
        },

        /**
         * @param {WorkbenchModel} model
         */
        parseModel: function(workbenchModel) {

            //TODO : if(!(model instanceof WorkbenchModel)){return;}

            function getLayoutTree(model) {
                var LayoutClass = {
                    'Page': Page,
                    'LayoutPane': LayoutPane,
                    'CompatibleLayoutPane': CompatibleLayoutPane
                }
                var layoutTree, split, children, child;
                if ('type' in model) {
                    layoutTree = new LayoutClass[model.type](model.id, model.name);
                    if ('split' in model) {
                        split = model.split;
                        layoutTree.setOrientation(split.orientation);
                        layoutTree.setRatio(split.ratio);
                    }
                    if ('children' in model) {
                        children = model.children;
                        for (var i in children) {
                            child = getLayoutTree(children[i]);
                            layoutTree.insertChild(child, i);
                        }
                    }
                    return layoutTree;
                }
                return null;
            }

            if ('pages' in workbenchModel) {
                var page = [], pages = workbenchModel.pages;
                for (var i in pages) {
                    page[i] = getLayoutTree(pages[i]);
                    this.addPage(page[i]);
                }
                this.setCurrentPage(page[0]);
            }
        }
    });

    Workbench.CREATE_DATA_SOURCE = 'createDataSource';

    return Workbench;
});
<|endoftext|>


<commit_before>var lastTs = 0;
var goalX = -1;
var goalY = -1;
var direction = 0;
var velocityX = 0;
var velocityY = 0;

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
window.addEventListener("resize", resizeCanvas);
window.addEventListener("click", resizeCanvas);

function resizeCanvas() {
    canvas.width = document.body.scrollWidth;
    canvas.height = document.body.scrollHeight;
    drawStudyTree();
}

function point(x, y, canvas){
    canvas.beginPath();
    canvas.arc(x, y, 2, 0, 2 * Math.PI, true);
    canvas.fill();
  }

function drawAnimations(ts){
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    if (player.dilation.tachyonParticles.gte(1)) {
        if ((goalX > canvas.width || goalX < 0) || (goalY > canvas.height || goalY < 0)) {
            goalX = Math.ceil(Math.random() * canvas.width);
            goalY = Math.ceil(Math.random() * canvas.height);
            direction = Math.ceil(Math.random() * 8);
            velocityX = Math.ceil((Math.random() - 0.5) * 25)
            velocityY = Math.ceil((Math.random() - 0.5) * 25)
            if (velocityX < 0) velocityX -= 5
            else velocityX += 5
            if (velocityY < 0) velocityY -= 5
            else velocityY += 5
        }
        point(goalX, goalY, ctx)
        goalX += velocityX
        goalY += velocityY
    }
    delta = (ts - lastTs) / 1000;
    lastTs = ts;
    requestAnimationFrame(drawAnimations);
}

function drawTreeBranch(num1, num2) {
    if (document.getElementById("timestudies").style.display === "none") return
    var name1 = parseInt(num1);
    var isECname = false;
    if (isNaN(parseInt(num2))) {
        var a = num2.split("c")[1];
        var name2 = parseInt(a.split("u")[0]);
        var isECname = true;
    } else {
        var name2 = parseInt(num2)
    }
    var start = document.getElementById(num1).getBoundingClientRect();
    var end = document.getElementById(num2).getBoundingClientRect();
    var x1 = start.left + (start.width / 2) + (document.documentElement.scrollLeft || document.body.scrollLeft);
    var y1 = start.top + (start.height / 2) + (document.documentElement.scrollTop || document.body.scrollTop);
    var x2 = end.left + (start.width / 2) + (document.documentElement.scrollLeft || document.body.scrollLeft);
    var y2 = end.top + (start.height / 2) + (document.documentElement.scrollTop || document.body.scrollTop);
    ctx.lineWidth=15;
    ctx.beginPath();
    if ((player.timestudy.studies.includes(name1) && player.timestudy.studies.includes(name2) && !isECname) || (player.timestudy.studies.includes(name1) && player.eternityChallUnlocked === name2)) {
        if (name2 < 20) {
            ctx.strokeStyle="#490066";
        } else if (name2 == 71 || name2 == 81 || name2 == 91 || name2 == 101 || name1 == 101) {
            ctx.strokeStyle="#22aa48";
        } else if (name2 == 72 || name2 == 82 || name2 == 92 || name2 == 102 || name1 == 102) {
            ctx.strokeStyle="#B67F33";
        } else if (name2 == 73 || name2 == 83 || name2 == 93 || name2 == 103 || name1 == 103) {
            ctx.strokeStyle="#B241E3";
        } else if (name2 == 121 || name2 == 131 || name2 == 141 || name1 == 141) {
            ctx.strokeStyle="#FF0100";
        } else if (name2 == 122 || name2 == 132 || name2 == 142 || name1 == 142) {
            ctx.strokeStyle="#5E33B6";
        } else if (name2 == 123 || name2 == 133 || name2 == 143 || name1 == 143) {
            ctx.strokeStyle="#0080ff";
        } else {
            ctx.strokeStyle="#000000";
        }
    } else {
        if (name2 < 20) {
            ctx.strokeStyle="#4b3753";
        } else if (name2 == 71 || name2 == 81 || name2 == 91 || name2 == 101 || name1 == 101) {
            ctx.strokeStyle="#37533f";
        } else if (name2 == 72 || name2 == 82 || name2 == 92 || name2 == 102 || name1 == 102) {
            ctx.strokeStyle="#534737";
        } else if (name2 == 73 || name2 == 83 || name2 == 93 || name2 == 103 || name1 == 103) {
            ctx.strokeStyle="#4a3753";
        } else if (name2 == 121 || name2 == 131 || name2 == 141 || name1 == 141) {
            ctx.strokeStyle="#533737";
        } else if (name2 == 122 || name2 == 132 || name2 == 142 || name1 == 142) {
            ctx.strokeStyle="#403753";
        } else if (name2 == 123 || name2 == 133 || name2 == 143 || name1 == 143) {
            ctx.strokeStyle="#374553";
        } else {
            ctx.strokeStyle="#444";
        }
    }
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
}

function drawStudyTree() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawTreeBranch("11", "21");
    drawTreeBranch("11", "22");
    drawTreeBranch("21", "31");
    drawTreeBranch("21", "33");
    drawTreeBranch("22", "32");
    drawTreeBranch("31", "41");
    drawTreeBranch("32", "42");
    drawTreeBranch("41", "51");
    drawTreeBranch("42", "51");
    drawTreeBranch("51", "61");
    drawTreeBranch("ec5unl", "62")
    drawTreeBranch("61", "71");
    drawTreeBranch("61", "72");
    drawTreeBranch("61", "73");
    drawTreeBranch("71", "81");
    drawTreeBranch("72", "82");
    drawTreeBranch("73", "83");
    drawTreeBranch("81", "91");
    drawTreeBranch("82", "92");
    drawTreeBranch("83", "93");
    drawTreeBranch("91", "101");
    drawTreeBranch("92", "102");
    drawTreeBranch("93", "103");
    drawTreeBranch("101", "111");
    drawTreeBranch("102", "111");
    drawTreeBranch("103", "111");
    drawTreeBranch("111", "121");
    drawTreeBranch("111", "122");
    drawTreeBranch("111", "123");
    drawTreeBranch("121", "131");
    drawTreeBranch("122", "132");
    drawTreeBranch("123", "133");
    drawTreeBranch("131", "141");
    drawTreeBranch("132", "142");
    drawTreeBranch("133", "143");
    drawTreeBranch("141", "151");
    drawTreeBranch("142", "151");
    drawTreeBranch("143", "151");
    drawTreeBranch("151", "161");
    drawTreeBranch("151", "162");
    drawTreeBranch("161", "171");
    drawTreeBranch("162", "171");
    drawTreeBranch("171", "ec1unl")
    drawTreeBranch("171", "ec2unl")
    drawTreeBranch("171", "ec3unl")
    drawTreeBranch("143", "ec4unl")
    drawTreeBranch("42", "ec5unl")
    drawTreeBranch("121", "ec6unl")
    drawTreeBranch("111", "ec7unl")
    drawTreeBranch("123", "ec8unl")
    drawTreeBranch("151", "ec9unl")
    drawTreeBranch("ec1unl", "181")
    drawTreeBranch("ec2unl", "181")
    drawTreeBranch("ec3unl", "181")
    drawTreeBranch("181", "ec10unl")
    drawTreeBranch("ec10unl", "191")
    drawTreeBranch("ec10unl", "192")
    drawTreeBranch("ec10unl", "193")
    drawTreeBranch("191", "211")
    drawTreeBranch("191", "212")
    drawTreeBranch("192", "201")
    drawTreeBranch("193", "213")
    drawTreeBranch("193", "214")
    drawTreeBranch("211", "221")
    drawTreeBranch("211", "222")
    drawTreeBranch("212", "223")
    drawTreeBranch("212", "224")
    drawTreeBranch("213", "225")
    drawTreeBranch("213", "226")
    drawTreeBranch("214", "227")
    drawTreeBranch("214", "228")
    drawTreeBranch("221", "231")
    drawTreeBranch("222", "231")
    drawTreeBranch("223", "232")
    drawTreeBranch("224", "232")
    drawTreeBranch("225", "233")
    drawTreeBranch("226", "233")
    drawTreeBranch("227", "234")
    drawTreeBranch("228", "234")
    drawTreeBranch("231", "ec11unl")
    drawTreeBranch("232", "ec11unl")
    drawTreeBranch("233", "ec12unl")
    drawTreeBranch("234", "ec12unl")
    drawTreeBranch("ec11unl", "dilationunlock")
    drawTreeBranch("ec12unl", "dilationunlock")
    if (shiftDown && document.getElementById("eternitystore").style.display !== "none" && document.getElementById("timestudies").style.display !== "none") {
        for (i=0; i<all.length; i++) {
            var start = document.getElementById(all[i]).getBoundingClientRect();
            var x1 = start.left + (start.width / 2) + (document.documentElement.scrollLeft || document.body.scrollLeft);
            var y1 = start.top + (start.height / 2) + (document.documentElement.scrollTop || document.body.scrollTop);
            ctx.fillStyle = 'white';
            ctx.strokeStyle = 'black';
            ctx.lineWidth = 3;
            ctx.font = "15px Typewriter";
            ctx.strokeText(all[i], x1 - start.width / 2, y1 - start.height / 2 - 1);
            ctx.fillText(all[i], x1 - start.width / 2, y1 - start.height / 2 - 1);
        }
    }
}<commit_msg>edge sucks<commit_after>var lastTs = 0;
var goalX = -1;
var goalY = -1;
var direction = 0;
var velocityX = 0;
var velocityY = 0;

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
window.addEventListener("resize", resizeCanvas);
window.addEventListener("click", resizeCanvas);

function resizeCanvas() {
    canvas.width = document.body.scrollWidth;
    canvas.height = document.body.scrollHeight;
    drawStudyTree();
}

function point(x, y, canvas){
    canvas.beginPath();
    canvas.arc(x, y, 2, 0, 2 * Math.PI, true);
    canvas.fill();
  }

function drawAnimations(ts){
    if (player.dilation.tachyonParticles.gte(1)) {
        if ((goalX > canvas.width || goalX < 0) || (goalY > canvas.height || goalY < 0)) {
            goalX = Math.ceil(Math.random() * canvas.width);
            goalY = Math.ceil(Math.random() * canvas.height);
            direction = Math.ceil(Math.random() * 8);
            velocityX = Math.ceil((Math.random() - 0.5) * 25)
            velocityY = Math.ceil((Math.random() - 0.5) * 25)
            if (velocityX < 0) velocityX -= 5
            else velocityX += 5
            if (velocityY < 0) velocityY -= 5
            else velocityY += 5
        }
        point(goalX, goalY, ctx)
        goalX += velocityX
        goalY += velocityY
    }
    delta = (ts - lastTs) / 1000;
    lastTs = ts;
    requestAnimationFrame(drawAnimations);
}

function drawTreeBranch(num1, num2) {
    if (document.getElementById("timestudies").style.display === "none") return
    var name1 = parseInt(num1);
    var isECname = false;
    if (isNaN(parseInt(num2))) {
        var a = num2.split("c")[1];
        var name2 = parseInt(a.split("u")[0]);
        var isECname = true;
    } else {
        var name2 = parseInt(num2)
    }
    var start = document.getElementById(num1).getBoundingClientRect();
    var end = document.getElementById(num2).getBoundingClientRect();
    var x1 = start.left + (start.width / 2) + (document.documentElement.scrollLeft || document.body.scrollLeft);
    var y1 = start.top + (start.height / 2) + (document.documentElement.scrollTop || document.body.scrollTop);
    var x2 = end.left + (start.width / 2) + (document.documentElement.scrollLeft || document.body.scrollLeft);
    var y2 = end.top + (start.height / 2) + (document.documentElement.scrollTop || document.body.scrollTop);
    ctx.lineWidth=15;
    ctx.beginPath();
    if ((player.timestudy.studies.includes(name1) && player.timestudy.studies.includes(name2) && !isECname) || (player.timestudy.studies.includes(name1) && player.eternityChallUnlocked === name2)) {
        if (name2 < 20) {
            ctx.strokeStyle="#490066";
        } else if (name2 == 71 || name2 == 81 || name2 == 91 || name2 == 101 || name1 == 101) {
            ctx.strokeStyle="#22aa48";
        } else if (name2 == 72 || name2 == 82 || name2 == 92 || name2 == 102 || name1 == 102) {
            ctx.strokeStyle="#B67F33";
        } else if (name2 == 73 || name2 == 83 || name2 == 93 || name2 == 103 || name1 == 103) {
            ctx.strokeStyle="#B241E3";
        } else if (name2 == 121 || name2 == 131 || name2 == 141 || name1 == 141) {
            ctx.strokeStyle="#FF0100";
        } else if (name2 == 122 || name2 == 132 || name2 == 142 || name1 == 142) {
            ctx.strokeStyle="#5E33B6";
        } else if (name2 == 123 || name2 == 133 || name2 == 143 || name1 == 143) {
            ctx.strokeStyle="#0080ff";
        } else {
            ctx.strokeStyle="#000000";
        }
    } else {
        if (name2 < 20) {
            ctx.strokeStyle="#4b3753";
        } else if (name2 == 71 || name2 == 81 || name2 == 91 || name2 == 101 || name1 == 101) {
            ctx.strokeStyle="#37533f";
        } else if (name2 == 72 || name2 == 82 || name2 == 92 || name2 == 102 || name1 == 102) {
            ctx.strokeStyle="#534737";
        } else if (name2 == 73 || name2 == 83 || name2 == 93 || name2 == 103 || name1 == 103) {
            ctx.strokeStyle="#4a3753";
        } else if (name2 == 121 || name2 == 131 || name2 == 141 || name1 == 141) {
            ctx.strokeStyle="#533737";
        } else if (name2 == 122 || name2 == 132 || name2 == 142 || name1 == 142) {
            ctx.strokeStyle="#403753";
        } else if (name2 == 123 || name2 == 133 || name2 == 143 || name1 == 143) {
            ctx.strokeStyle="#374553";
        } else {
            ctx.strokeStyle="#444";
        }
    }
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
}

function drawStudyTree() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawTreeBranch("11", "21");
    drawTreeBranch("11", "22");
    drawTreeBranch("21", "31");
    drawTreeBranch("21", "33");
    drawTreeBranch("22", "32");
    drawTreeBranch("31", "41");
    drawTreeBranch("32", "42");
    drawTreeBranch("41", "51");
    drawTreeBranch("42", "51");
    drawTreeBranch("51", "61");
    drawTreeBranch("ec5unl", "62")
    drawTreeBranch("61", "71");
    drawTreeBranch("61", "72");
    drawTreeBranch("61", "73");
    drawTreeBranch("71", "81");
    drawTreeBranch("72", "82");
    drawTreeBranch("73", "83");
    drawTreeBranch("81", "91");
    drawTreeBranch("82", "92");
    drawTreeBranch("83", "93");
    drawTreeBranch("91", "101");
    drawTreeBranch("92", "102");
    drawTreeBranch("93", "103");
    drawTreeBranch("101", "111");
    drawTreeBranch("102", "111");
    drawTreeBranch("103", "111");
    drawTreeBranch("111", "121");
    drawTreeBranch("111", "122");
    drawTreeBranch("111", "123");
    drawTreeBranch("121", "131");
    drawTreeBranch("122", "132");
    drawTreeBranch("123", "133");
    drawTreeBranch("131", "141");
    drawTreeBranch("132", "142");
    drawTreeBranch("133", "143");
    drawTreeBranch("141", "151");
    drawTreeBranch("142", "151");
    drawTreeBranch("143", "151");
    drawTreeBranch("151", "161");
    drawTreeBranch("151", "162");
    drawTreeBranch("161", "171");
    drawTreeBranch("162", "171");
    drawTreeBranch("171", "ec1unl")
    drawTreeBranch("171", "ec2unl")
    drawTreeBranch("171", "ec3unl")
    drawTreeBranch("143", "ec4unl")
    drawTreeBranch("42", "ec5unl")
    drawTreeBranch("121", "ec6unl")
    drawTreeBranch("111", "ec7unl")
    drawTreeBranch("123", "ec8unl")
    drawTreeBranch("151", "ec9unl")
    drawTreeBranch("ec1unl", "181")
    drawTreeBranch("ec2unl", "181")
    drawTreeBranch("ec3unl", "181")
    drawTreeBranch("181", "ec10unl")
    drawTreeBranch("ec10unl", "191")
    drawTreeBranch("ec10unl", "192")
    drawTreeBranch("ec10unl", "193")
    drawTreeBranch("191", "211")
    drawTreeBranch("191", "212")
    drawTreeBranch("192", "201")
    drawTreeBranch("193", "213")
    drawTreeBranch("193", "214")
    drawTreeBranch("211", "221")
    drawTreeBranch("211", "222")
    drawTreeBranch("212", "223")
    drawTreeBranch("212", "224")
    drawTreeBranch("213", "225")
    drawTreeBranch("213", "226")
    drawTreeBranch("214", "227")
    drawTreeBranch("214", "228")
    drawTreeBranch("221", "231")
    drawTreeBranch("222", "231")
    drawTreeBranch("223", "232")
    drawTreeBranch("224", "232")
    drawTreeBranch("225", "233")
    drawTreeBranch("226", "233")
    drawTreeBranch("227", "234")
    drawTreeBranch("228", "234")
    drawTreeBranch("231", "ec11unl")
    drawTreeBranch("232", "ec11unl")
    drawTreeBranch("233", "ec12unl")
    drawTreeBranch("234", "ec12unl")
    drawTreeBranch("ec11unl", "dilationunlock")
    drawTreeBranch("ec12unl", "dilationunlock")
    if (shiftDown && document.getElementById("eternitystore").style.display !== "none" && document.getElementById("timestudies").style.display !== "none") {
        for (i=0; i<all.length; i++) {
            var start = document.getElementById(all[i]).getBoundingClientRect();
            var x1 = start.left + (start.width / 2) + (document.documentElement.scrollLeft || document.body.scrollLeft);
            var y1 = start.top + (start.height / 2) + (document.documentElement.scrollTop || document.body.scrollTop);
            ctx.fillStyle = 'white';
            ctx.strokeStyle = 'black';
            ctx.lineWidth = 3;
            ctx.font = "15px Typewriter";
            ctx.strokeText(all[i], x1 - start.width / 2, y1 - start.height / 2 - 1);
            ctx.fillText(all[i], x1 - start.width / 2, y1 - start.height / 2 - 1);
        }
    }
}<|endoftext|>


<commit_before>/* eslint-env mocha, browser*/
/* global proclaim, it */

describe('Basic functionality', function () {
	var
	object = {},
	property = 'foo',
	value = 'bar';

	it('Returns the object being defined', function () {
		proclaim.deepEqual(Object.defineProperty(object, property, {
			configurable: true,
			enumerable: true,
			writable: true
		}), object);
	});

	it('Assigns a property', function () {
		Object.defineProperty(object, property, {
			configurable: true,
			enumerable: true,
			writable: true
		});
		proclaim.equal(property in object, true);
	});

	it('Assigns a property with a value', function () {
		Object.defineProperty(object, property, {
			configurable: true,
			enumerable: true,
			value: value,
			writable: true
		});

		proclaim.equal(object[property], value);
	});

	it('Assigns a property with a getter if getters are supported by the engine, else throws', function () {
		try {
			Object.defineProperty(object, property, {
				configurable: true,
				enumerable: true,
				get: function () {
					return value;
				}
			});
		} catch (e) {
			if (e.message !== "Getters & setters cannot be defined on this javascript engine") {
				throw e;
			}
		}

		proclaim.equal(object[property], value);
	});
});

describe('Error handling', function () {
	var
	object = {},
	property = 'foo',
	value = 'bar';

	it('Throws an error when called on a non-object', function() {
		proclaim.throws(function () {
			Object.defineProperty();
		});

		proclaim.throws(function () {
			Object.defineProperty(undefined);
		});

		proclaim.throws(function () {
			Object.defineProperty(null);
		});

		proclaim.throws(function () {
			Object.defineProperty('');
		});
	});

	it('Throws an error when descriptor is a non-object', function() {
		proclaim.throws(function () {
			Object.defineProperty(object, property);
		});

		proclaim.throws(function () {
			Object.defineProperty(object, property, undefined);
		});

		// Crashes Edge 14 on Sauce Labs, works on BrowserStack
		proclaim.throws(function () {
			Object.defineProperty(object, property, null);
		});

		proclaim.throws(function () {
			Object.defineProperty(object, property, '');
		});

		proclaim.throws(function () {
			Object.defineProperty(object, property);
		}, /^Property description must be an object/);
	});

	it('Throws an error when both an accessor and a value are specified', function () {
		proclaim.throws(function () {
			Object.defineProperty(object, property, {
				value: value,
				writable: true,
				enumerable: true,
				configurable: true,
				get: function () {}
			});
		});

		proclaim.throws(function () {
			Object.defineProperty(object, property, {
				value: value,
				writable: true,
				enumerable: true,
				configurable: true,
				set: function () {}
			});
		});
	});

	it('Throws an error when an accessor is specified and writable is set', function () {
		proclaim.throws(function () {
			Object.defineProperty(object, property, {
				get: function () {},
				writable: false
			});
		});

		proclaim.throws(function () {
			Object.defineProperty(object, property, {
				get: function () {},
				writable: true
			});
		});

		proclaim.throws(function () {
			Object.defineProperty(object, property, {
				set: function () {},
				writable: false
			});
		});

		proclaim.throws(function () {
			Object.defineProperty(object, property, {
				set: function () {},
				writable: true
			});
		});
	});
});
<commit_msg>Skip tests which crashes Edge 14 browsers<commit_after>/* eslint-env mocha, browser*/
/* global proclaim, it */

describe('Basic functionality', function () {
	var
	object = {},
	property = 'foo',
	value = 'bar';

	it('Returns the object being defined', function () {
		proclaim.deepEqual(Object.defineProperty(object, property, {
			configurable: true,
			enumerable: true,
			writable: true
		}), object);
	});

	it('Assigns a property', function () {
		Object.defineProperty(object, property, {
			configurable: true,
			enumerable: true,
			writable: true
		});
		proclaim.equal(property in object, true);
	});

	it('Assigns a property with a value', function () {
		Object.defineProperty(object, property, {
			configurable: true,
			enumerable: true,
			value: value,
			writable: true
		});

		proclaim.equal(object[property], value);
	});

	it('Assigns a property with a getter if getters are supported by the engine, else throws', function () {
		try {
			Object.defineProperty(object, property, {
				configurable: true,
				enumerable: true,
				get: function () {
					return value;
				}
			});
		} catch (e) {
			if (e.message !== "Getters & setters cannot be defined on this javascript engine") {
				throw e;
			}
		}

		proclaim.equal(object[property], value);
	});
});

describe('Error handling', function () {
	var
	object = {},
	property = 'foo',
	value = 'bar';

	it('Throws an error when called on a non-object', function() {
		proclaim.throws(function () {
			Object.defineProperty();
		});

		proclaim.throws(function () {
			Object.defineProperty(undefined);
		});

		proclaim.throws(function () {
			Object.defineProperty(null);
		});

		proclaim.throws(function () {
			Object.defineProperty('');
		});
	});

	it('Throws an error when descriptor is a non-object', function() {
		proclaim.throws(function () {
			Object.defineProperty(object, property);
		});

		proclaim.throws(function () {
			Object.defineProperty(object, property, undefined);
		});

		// Crashes Edge 14 - https://twitter.com/JakeDChampion/status/839442848948838401
		//proclaim.throws(function () {
		//	Object.defineProperty(object, property, null);
		//});

		proclaim.throws(function () {
			Object.defineProperty(object, property, '');
		});

		proclaim.throws(function () {
			Object.defineProperty(object, property);
		}, /^Property description must be an object/);
	});

	it('Throws an error when both an accessor and a value are specified', function () {
		proclaim.throws(function () {
			Object.defineProperty(object, property, {
				value: value,
				writable: true,
				enumerable: true,
				configurable: true,
				get: function () {}
			});
		});

		proclaim.throws(function () {
			Object.defineProperty(object, property, {
				value: value,
				writable: true,
				enumerable: true,
				configurable: true,
				set: function () {}
			});
		});
	});

	it('Throws an error when an accessor is specified and writable is set', function () {
		proclaim.throws(function () {
			Object.defineProperty(object, property, {
				get: function () {},
				writable: false
			});
		});

		proclaim.throws(function () {
			Object.defineProperty(object, property, {
				get: function () {},
				writable: true
			});
		});

		proclaim.throws(function () {
			Object.defineProperty(object, property, {
				set: function () {},
				writable: false
			});
		});

		proclaim.throws(function () {
			Object.defineProperty(object, property, {
				set: function () {},
				writable: true
			});
		});
	});
});
<|endoftext|>


<commit_before>var lastTs = 0;
var goalX = -1;
var goalY = -1;
var direction = 0;
var velocityX = 0;
var velocityY = 0;

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
window.addEventListener("resize", resizeCanvas);
window.addEventListener("click", resizeCanvas);

function resizeCanvas() {
    canvas.width = document.body.scrollWidth;
    canvas.height = document.body.scrollHeight;
    drawStudyTree();
}

function point(x, y, canvas){
    canvas.beginPath();
    canvas.arc(x, y, 2, 0, 2 * Math.PI, true);
    canvas.fill();
  }

function drawAnimations(ts){
    ctx.clearRect(0, 0, ctx.width, ctx.height)
    if (player.dilation.tachyonParticles.gte(1)) {
        if ((goalX > canvas.width || goalX < 0) || (goalY > canvas.height || goalY < 0)) {
            goalX = Math.ceil(Math.random() * canvas.width);
            goalY = Math.ceil(Math.random() * canvas.height);
            direction = Math.ceil(Math.random() * 8);
            velocityX = Math.ceil((Math.random() - 0.5) * 25)
            velocityY = Math.ceil((Math.random() - 0.5) * 25)
            if (velocityX < 0) velocityX -= 5
            else velocityX += 5
            if (velocityY < 0) velocityY -= 5
            else velocityY += 5
        }
        point(goalX, goalY, ctx)
        goalX += velocityX
        goalY += velocityY
    }
    delta = (ts - lastTs) / 1000;
    lastTs = ts;
    requestAnimationFrame(drawAnimations);
}

function drawTreeBranch(num1, num2) {
    if (document.getElementById("timestudies").style.display === "none") return
    var name1 = parseInt(num1);
    var isECname = false;
    if (isNaN(parseInt(num2))) {
        var a = num2.split("c")[1];
        var name2 = parseInt(a.split("u")[0]);
        var isECname = true;
    } else {
        var name2 = parseInt(num2)
    }
    var start = document.getElementById(num1).getBoundingClientRect();
    var end = document.getElementById(num2).getBoundingClientRect();
    var x1 = start.left + (start.width / 2) + (document.documentElement.scrollLeft || document.body.scrollLeft);
    var y1 = start.top + (start.height / 2) + (document.documentElement.scrollTop || document.body.scrollTop);
    var x2 = end.left + (start.width / 2) + (document.documentElement.scrollLeft || document.body.scrollLeft);
    var y2 = end.top + (start.height / 2) + (document.documentElement.scrollTop || document.body.scrollTop);
    ctx.lineWidth=15;
    ctx.beginPath();
    if ((player.timestudy.studies.includes(name1) && player.timestudy.studies.includes(name2) && !isECname) || (player.timestudy.studies.includes(name1) && player.eternityChallUnlocked === name2)) {
        if (name2 < 20) {
            ctx.strokeStyle="#490066";
        } else if (name2 == 71 || name2 == 81 || name2 == 91 || name2 == 101 || name1 == 101) {
            ctx.strokeStyle="#22aa48";
        } else if (name2 == 72 || name2 == 82 || name2 == 92 || name2 == 102 || name1 == 102) {
            ctx.strokeStyle="#B67F33";
        } else if (name2 == 73 || name2 == 83 || name2 == 93 || name2 == 103 || name1 == 103) {
            ctx.strokeStyle="#B241E3";
        } else if (name2 == 121 || name2 == 131 || name2 == 141 || name1 == 141) {
            ctx.strokeStyle="#FF0100";
        } else if (name2 == 122 || name2 == 132 || name2 == 142 || name1 == 142) {
            ctx.strokeStyle="#5E33B6";
        } else if (name2 == 123 || name2 == 133 || name2 == 143 || name1 == 143) {
            ctx.strokeStyle="#0080ff";
        } else {
            ctx.strokeStyle="#000000";
        }
    } else {
        if (name2 < 20) {
            ctx.strokeStyle="#4b3753";
        } else if (name2 == 71 || name2 == 81 || name2 == 91 || name2 == 101 || name1 == 101) {
            ctx.strokeStyle="#37533f";
        } else if (name2 == 72 || name2 == 82 || name2 == 92 || name2 == 102 || name1 == 102) {
            ctx.strokeStyle="#534737";
        } else if (name2 == 73 || name2 == 83 || name2 == 93 || name2 == 103 || name1 == 103) {
            ctx.strokeStyle="#4a3753";
        } else if (name2 == 121 || name2 == 131 || name2 == 141 || name1 == 141) {
            ctx.strokeStyle="#533737";
        } else if (name2 == 122 || name2 == 132 || name2 == 142 || name1 == 142) {
            ctx.strokeStyle="#403753";
        } else if (name2 == 123 || name2 == 133 || name2 == 143 || name1 == 143) {
            ctx.strokeStyle="#374553";
        } else {
            ctx.strokeStyle="#444";
        }
    }
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
}

function drawStudyTree() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawTreeBranch("11", "21");
    drawTreeBranch("11", "22");
    drawTreeBranch("21", "31");
    drawTreeBranch("21", "33");
    drawTreeBranch("22", "32");
    drawTreeBranch("31", "41");
    drawTreeBranch("32", "42");
    drawTreeBranch("41", "51");
    drawTreeBranch("42", "51");
    drawTreeBranch("51", "61");
    drawTreeBranch("ec5unl", "62")
    drawTreeBranch("61", "71");
    drawTreeBranch("61", "72");
    drawTreeBranch("61", "73");
    drawTreeBranch("71", "81");
    drawTreeBranch("72", "82");
    drawTreeBranch("73", "83");
    drawTreeBranch("81", "91");
    drawTreeBranch("82", "92");
    drawTreeBranch("83", "93");
    drawTreeBranch("91", "101");
    drawTreeBranch("92", "102");
    drawTreeBranch("93", "103");
    drawTreeBranch("101", "111");
    drawTreeBranch("102", "111");
    drawTreeBranch("103", "111");
    drawTreeBranch("111", "121");
    drawTreeBranch("111", "122");
    drawTreeBranch("111", "123");
    drawTreeBranch("121", "131");
    drawTreeBranch("122", "132");
    drawTreeBranch("123", "133");
    drawTreeBranch("131", "141");
    drawTreeBranch("132", "142");
    drawTreeBranch("133", "143");
    drawTreeBranch("141", "151");
    drawTreeBranch("142", "151");
    drawTreeBranch("143", "151");
    drawTreeBranch("151", "161");
    drawTreeBranch("151", "162");
    drawTreeBranch("161", "171");
    drawTreeBranch("162", "171");
    drawTreeBranch("171", "ec1unl")
    drawTreeBranch("171", "ec2unl")
    drawTreeBranch("171", "ec3unl")
    drawTreeBranch("143", "ec4unl")
    drawTreeBranch("42", "ec5unl")
    drawTreeBranch("121", "ec6unl")
    drawTreeBranch("111", "ec7unl")
    drawTreeBranch("123", "ec8unl")
    drawTreeBranch("151", "ec9unl")
    drawTreeBranch("ec1unl", "181")
    drawTreeBranch("ec2unl", "181")
    drawTreeBranch("ec3unl", "181")
    drawTreeBranch("181", "ec10unl")
    drawTreeBranch("ec10unl", "191")
    drawTreeBranch("ec10unl", "192")
    drawTreeBranch("ec10unl", "193")
    drawTreeBranch("191", "211")
    drawTreeBranch("191", "212")
    drawTreeBranch("192", "201")
    drawTreeBranch("193", "213")
    drawTreeBranch("193", "214")
    drawTreeBranch("211", "221")
    drawTreeBranch("211", "222")
    drawTreeBranch("212", "223")
    drawTreeBranch("212", "224")
    drawTreeBranch("213", "225")
    drawTreeBranch("213", "226")
    drawTreeBranch("214", "227")
    drawTreeBranch("214", "228")
    drawTreeBranch("221", "231")
    drawTreeBranch("222", "231")
    drawTreeBranch("223", "232")
    drawTreeBranch("224", "232")
    drawTreeBranch("225", "233")
    drawTreeBranch("226", "233")
    drawTreeBranch("227", "234")
    drawTreeBranch("228", "234")
    drawTreeBranch("231", "ec11unl")
    drawTreeBranch("232", "ec11unl")
    drawTreeBranch("233", "ec12unl")
    drawTreeBranch("234", "ec12unl")
    drawTreeBranch("ec11unl", "dilationunlock")
    drawTreeBranch("ec12unl", "dilationunlock")
    if (shiftDown && document.getElementById("eternitystore").style.display !== "none" && document.getElementById("timestudies").style.display !== "none") {
        for (i=0; i<all.length; i++) {
            var start = document.getElementById(all[i]).getBoundingClientRect();
            var x1 = start.left + (start.width / 2) + (document.documentElement.scrollLeft || document.body.scrollLeft);
            var y1 = start.top + (start.height / 2) + (document.documentElement.scrollTop || document.body.scrollTop);
            ctx.fillStyle = 'white';
            ctx.strokeStyle = 'black';
            ctx.lineWidth = 3;
            ctx.font = "15px Typewriter";
            ctx.strokeText(all[i], x1 - start.width / 2, y1 - start.height / 2 - 1);
            ctx.fillText(all[i], x1 - start.width / 2, y1 - start.height / 2 - 1);
        }
    }
}<commit_msg>attempting to fix an edge bug<commit_after>var lastTs = 0;
var goalX = -1;
var goalY = -1;
var direction = 0;
var velocityX = 0;
var velocityY = 0;

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
window.addEventListener("resize", resizeCanvas);
window.addEventListener("click", resizeCanvas);

function resizeCanvas() {
    canvas.width = document.body.scrollWidth;
    canvas.height = document.body.scrollHeight;
    drawStudyTree();
}

function point(x, y, canvas){
    canvas.beginPath();
    canvas.arc(x, y, 2, 0, 2 * Math.PI, true);
    canvas.fill();
  }

function drawAnimations(ts){
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    if (player.dilation.tachyonParticles.gte(1)) {
        if ((goalX > canvas.width || goalX < 0) || (goalY > canvas.height || goalY < 0)) {
            goalX = Math.ceil(Math.random() * canvas.width);
            goalY = Math.ceil(Math.random() * canvas.height);
            direction = Math.ceil(Math.random() * 8);
            velocityX = Math.ceil((Math.random() - 0.5) * 25)
            velocityY = Math.ceil((Math.random() - 0.5) * 25)
            if (velocityX < 0) velocityX -= 5
            else velocityX += 5
            if (velocityY < 0) velocityY -= 5
            else velocityY += 5
        }
        point(goalX, goalY, ctx)
        goalX += velocityX
        goalY += velocityY
    }
    delta = (ts - lastTs) / 1000;
    lastTs = ts;
    requestAnimationFrame(drawAnimations);
}

function drawTreeBranch(num1, num2) {
    if (document.getElementById("timestudies").style.display === "none") return
    var name1 = parseInt(num1);
    var isECname = false;
    if (isNaN(parseInt(num2))) {
        var a = num2.split("c")[1];
        var name2 = parseInt(a.split("u")[0]);
        var isECname = true;
    } else {
        var name2 = parseInt(num2)
    }
    var start = document.getElementById(num1).getBoundingClientRect();
    var end = document.getElementById(num2).getBoundingClientRect();
    var x1 = start.left + (start.width / 2) + (document.documentElement.scrollLeft || document.body.scrollLeft);
    var y1 = start.top + (start.height / 2) + (document.documentElement.scrollTop || document.body.scrollTop);
    var x2 = end.left + (start.width / 2) + (document.documentElement.scrollLeft || document.body.scrollLeft);
    var y2 = end.top + (start.height / 2) + (document.documentElement.scrollTop || document.body.scrollTop);
    ctx.lineWidth=15;
    ctx.beginPath();
    if ((player.timestudy.studies.includes(name1) && player.timestudy.studies.includes(name2) && !isECname) || (player.timestudy.studies.includes(name1) && player.eternityChallUnlocked === name2)) {
        if (name2 < 20) {
            ctx.strokeStyle="#490066";
        } else if (name2 == 71 || name2 == 81 || name2 == 91 || name2 == 101 || name1 == 101) {
            ctx.strokeStyle="#22aa48";
        } else if (name2 == 72 || name2 == 82 || name2 == 92 || name2 == 102 || name1 == 102) {
            ctx.strokeStyle="#B67F33";
        } else if (name2 == 73 || name2 == 83 || name2 == 93 || name2 == 103 || name1 == 103) {
            ctx.strokeStyle="#B241E3";
        } else if (name2 == 121 || name2 == 131 || name2 == 141 || name1 == 141) {
            ctx.strokeStyle="#FF0100";
        } else if (name2 == 122 || name2 == 132 || name2 == 142 || name1 == 142) {
            ctx.strokeStyle="#5E33B6";
        } else if (name2 == 123 || name2 == 133 || name2 == 143 || name1 == 143) {
            ctx.strokeStyle="#0080ff";
        } else {
            ctx.strokeStyle="#000000";
        }
    } else {
        if (name2 < 20) {
            ctx.strokeStyle="#4b3753";
        } else if (name2 == 71 || name2 == 81 || name2 == 91 || name2 == 101 || name1 == 101) {
            ctx.strokeStyle="#37533f";
        } else if (name2 == 72 || name2 == 82 || name2 == 92 || name2 == 102 || name1 == 102) {
            ctx.strokeStyle="#534737";
        } else if (name2 == 73 || name2 == 83 || name2 == 93 || name2 == 103 || name1 == 103) {
            ctx.strokeStyle="#4a3753";
        } else if (name2 == 121 || name2 == 131 || name2 == 141 || name1 == 141) {
            ctx.strokeStyle="#533737";
        } else if (name2 == 122 || name2 == 132 || name2 == 142 || name1 == 142) {
            ctx.strokeStyle="#403753";
        } else if (name2 == 123 || name2 == 133 || name2 == 143 || name1 == 143) {
            ctx.strokeStyle="#374553";
        } else {
            ctx.strokeStyle="#444";
        }
    }
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
}

function drawStudyTree() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawTreeBranch("11", "21");
    drawTreeBranch("11", "22");
    drawTreeBranch("21", "31");
    drawTreeBranch("21", "33");
    drawTreeBranch("22", "32");
    drawTreeBranch("31", "41");
    drawTreeBranch("32", "42");
    drawTreeBranch("41", "51");
    drawTreeBranch("42", "51");
    drawTreeBranch("51", "61");
    drawTreeBranch("ec5unl", "62")
    drawTreeBranch("61", "71");
    drawTreeBranch("61", "72");
    drawTreeBranch("61", "73");
    drawTreeBranch("71", "81");
    drawTreeBranch("72", "82");
    drawTreeBranch("73", "83");
    drawTreeBranch("81", "91");
    drawTreeBranch("82", "92");
    drawTreeBranch("83", "93");
    drawTreeBranch("91", "101");
    drawTreeBranch("92", "102");
    drawTreeBranch("93", "103");
    drawTreeBranch("101", "111");
    drawTreeBranch("102", "111");
    drawTreeBranch("103", "111");
    drawTreeBranch("111", "121");
    drawTreeBranch("111", "122");
    drawTreeBranch("111", "123");
    drawTreeBranch("121", "131");
    drawTreeBranch("122", "132");
    drawTreeBranch("123", "133");
    drawTreeBranch("131", "141");
    drawTreeBranch("132", "142");
    drawTreeBranch("133", "143");
    drawTreeBranch("141", "151");
    drawTreeBranch("142", "151");
    drawTreeBranch("143", "151");
    drawTreeBranch("151", "161");
    drawTreeBranch("151", "162");
    drawTreeBranch("161", "171");
    drawTreeBranch("162", "171");
    drawTreeBranch("171", "ec1unl")
    drawTreeBranch("171", "ec2unl")
    drawTreeBranch("171", "ec3unl")
    drawTreeBranch("143", "ec4unl")
    drawTreeBranch("42", "ec5unl")
    drawTreeBranch("121", "ec6unl")
    drawTreeBranch("111", "ec7unl")
    drawTreeBranch("123", "ec8unl")
    drawTreeBranch("151", "ec9unl")
    drawTreeBranch("ec1unl", "181")
    drawTreeBranch("ec2unl", "181")
    drawTreeBranch("ec3unl", "181")
    drawTreeBranch("181", "ec10unl")
    drawTreeBranch("ec10unl", "191")
    drawTreeBranch("ec10unl", "192")
    drawTreeBranch("ec10unl", "193")
    drawTreeBranch("191", "211")
    drawTreeBranch("191", "212")
    drawTreeBranch("192", "201")
    drawTreeBranch("193", "213")
    drawTreeBranch("193", "214")
    drawTreeBranch("211", "221")
    drawTreeBranch("211", "222")
    drawTreeBranch("212", "223")
    drawTreeBranch("212", "224")
    drawTreeBranch("213", "225")
    drawTreeBranch("213", "226")
    drawTreeBranch("214", "227")
    drawTreeBranch("214", "228")
    drawTreeBranch("221", "231")
    drawTreeBranch("222", "231")
    drawTreeBranch("223", "232")
    drawTreeBranch("224", "232")
    drawTreeBranch("225", "233")
    drawTreeBranch("226", "233")
    drawTreeBranch("227", "234")
    drawTreeBranch("228", "234")
    drawTreeBranch("231", "ec11unl")
    drawTreeBranch("232", "ec11unl")
    drawTreeBranch("233", "ec12unl")
    drawTreeBranch("234", "ec12unl")
    drawTreeBranch("ec11unl", "dilationunlock")
    drawTreeBranch("ec12unl", "dilationunlock")
    if (shiftDown && document.getElementById("eternitystore").style.display !== "none" && document.getElementById("timestudies").style.display !== "none") {
        for (i=0; i<all.length; i++) {
            var start = document.getElementById(all[i]).getBoundingClientRect();
            var x1 = start.left + (start.width / 2) + (document.documentElement.scrollLeft || document.body.scrollLeft);
            var y1 = start.top + (start.height / 2) + (document.documentElement.scrollTop || document.body.scrollTop);
            ctx.fillStyle = 'white';
            ctx.strokeStyle = 'black';
            ctx.lineWidth = 3;
            ctx.font = "15px Typewriter";
            ctx.strokeText(all[i], x1 - start.width / 2, y1 - start.height / 2 - 1);
            ctx.fillText(all[i], x1 - start.width / 2, y1 - start.height / 2 - 1);
        }
    }
}<|endoftext|>