<commit_before>(function(fin) {
    'use strict';
    const poolSize = 3;

    class FreeWindowPool {
        constructor($q, configService) {
            this.pool = [];
            this.$q = $q;
            this.configService = configService;

            for (var i = 0; i < poolSize; i++) {
                this._fillPool();
            }
        }

        _fillPool() {
            var deferred = this.$q.defer();
            this.pool.push({ promise: deferred.promise, window: new fin.desktop.Window(
                    this.configService.getWindowConfig(),
                    () => { deferred.resolve(); }
                )
            });
        }

        fetch() {
            var pooledWindow = this.pool.shift();
            this._fillPool();

            return pooledWindow;
        }
    }

    class WindowTracker {
        constructor() {
            this.openWindows = {};
            this.mainWindowsCache = [];
            this.windowsOpen = 0;
        }

        add(_window) {
            this.mainWindowsCache.push(_window);
            this.windowsOpen++;
        }

        addTearout(name, _window) {
            if (!this.openWindows[name]) {
                this.openWindows[name] = [].concat(_window);
            } else {
                this.openWindows[name].push(_window);
            }
        }

        dispose(_window, closedCb) {
            var parent = this.openWindows[_window.name];
            if (parent) {
                // Close all the OpenFin tearout windows associated with the closing parent.
                parent.forEach((child) => child.close());
            }

            if (this.windowsOpen !== 1) {
                closedCb();
            }

            var index = this.mainWindowsCache.indexOf(_window);
            this.mainWindowsCache.slice(index, 1);

            this.windowsOpen--;

            if (this.windowsOpen === 0) {
                // This was the last open window; close the application.
                window.close();
            }
        }

        getMainWindows() {
            return this.mainWindowsCache;
        }
    }

    class DragService {
        constructor(storeService, geometryService, windowTracker, tearoutWindow, $q) {
            this.storeService = storeService;
            this.geometryService = geometryService;
            this.windowTracker = windowTracker;
            this.tearoutWindow = tearoutWindow;
            this.$q = $q;
            this.otherInstance = null;
        }

        overAnotherInstance(cb) {
            var mainWindows = this.windowTracker.getMainWindows(),
                result = false,
                promises = [];

            mainWindows.forEach((mainWindow) => {
                var deferred = this.$q.defer();
                promises.push(deferred.promise);
                mainWindow.getState((state) => {
                    if (state !== 'minimized' && this.geometryService.windowsIntersect(this.tearoutWindow, mainWindow.getNativeWindow())) {
                        this.otherInstance = mainWindow;
                        result = true;
                    }

                    deferred.resolve();
                });
            });

            this.$q.all(promises).then(() => cb(result));
        }

        moveToOtherInstance(stock) {
            this.storeService.open(this.otherInstance.name).add(stock);
            this.otherInstance.bringToFront();
        }
    }

    class WindowCreationService {
        constructor(storeService, geometryService, $q, configService) {
            this.storeService = storeService;
            this.geometryService = geometryService;
            this.$q = $q;
            this.configService = configService;
            this.windowTracker = new WindowTracker();
            this.firstName = true;
            this.pool = null;

            this.ready(() => { this.pool = new FreeWindowPool($q, configService); });
        }

        createMainWindow(name, isCompact, successCb) {
            var windowCreatedCb = (newWindow) => {
                // TODO
                // Begin super hack
                newWindow.getNativeWindow().windowService = this;
                newWindow.getNativeWindow().storeService = this.storeService;
                // End super hack

                this.windowTracker.add(newWindow);

                if (successCb) {
                    successCb(newWindow);
                }

                newWindow.show();
                newWindow.bringToFront();
            };

            var mainWindow;
            if (name) {
                var config;
                if (isCompact) {
                    config = this.configService.getCompactConfig(name);
                } else {
                    config = this.configService.getWindowConfig(name);
                }
                mainWindow = new fin.desktop.Window(config, () => {
                    windowCreatedCb(mainWindow);
                });
            } else {
                var poolWindow = this.pool.fetch();
                mainWindow = poolWindow.window;
                if (isCompact) {
                    this.updateOptions(poolWindow.window, true);
                    this.window.resizeTo(230, 500, 'top-right');
                }

                poolWindow.promise.then(() => {
                    windowCreatedCb(mainWindow);
                });
            }

            mainWindow.addEventListener('closed', (e) => {
                this.windowTracker.dispose(mainWindow, () => {
                    this.storeService.open(mainWindow.name).closeWindow();
                });
            });
        }

        createTearoutWindow(parentName) {
            var tearoutWindow = new fin.desktop.Window(this.configService.getTearoutConfig());

            this.windowTracker.addTearout(parentName, tearoutWindow);

            return tearoutWindow;
        }

        updateOptions(_window, isCompact) {
            if (isCompact) {
                _window.updateOptions({
                    resizable: false,
                    minHeight: 500,
                    minWidth: 230,
                    maximizable: false
                });
            } else {
                _window.updateOptions({
                    resizable: true,
                    minHeight: 510,
                    minWidth: 918,
                    maximizable: true
                });
            }
        }

        updateOptions(_window, isCompact) {
            if (isCompact) {
                _window.updateOptions({
                    resizable: false,
                    minHeight: 500,
                    minWidth: 230,
                    maximizable: false
                });
            } else {
                _window.updateOptions({
                    resizable: true,
                    minHeight: 510,
                    minWidth: 918,
                    maximizable: true
                });
            }
        }

        ready(cb) {
            fin.desktop.main(cb);
        }

        getWindows() {
            return this.windowTracker.getMainWindows();
        }

        registerDrag(tearoutWindow) {
            return new DragService(this.storeService, this.geometryService, this.windowTracker, tearoutWindow, this.$q);
        }
    }
    WindowCreationService.$inject = ['storeService', 'geometryService', '$q', 'configService'];

    angular.module('openfin.window')
        .service('windowCreationService', WindowCreationService);
}(fin));
<commit_msg>Make ternary<commit_after>(function(fin) {
    'use strict';
    const poolSize = 3;

    class FreeWindowPool {
        constructor($q, configService) {
            this.pool = [];
            this.$q = $q;
            this.configService = configService;

            for (var i = 0; i < poolSize; i++) {
                this._fillPool();
            }
        }

        _fillPool() {
            var deferred = this.$q.defer();
            this.pool.push({ promise: deferred.promise, window: new fin.desktop.Window(
                    this.configService.getWindowConfig(),
                    () => { deferred.resolve(); }
                )
            });
        }

        fetch() {
            var pooledWindow = this.pool.shift();
            this._fillPool();

            return pooledWindow;
        }
    }

    class WindowTracker {
        constructor() {
            this.openWindows = {};
            this.mainWindowsCache = [];
            this.windowsOpen = 0;
        }

        add(_window) {
            this.mainWindowsCache.push(_window);
            this.windowsOpen++;
        }

        addTearout(name, _window) {
            if (!this.openWindows[name]) {
                this.openWindows[name] = [].concat(_window);
            } else {
                this.openWindows[name].push(_window);
            }
        }

        dispose(_window, closedCb) {
            var parent = this.openWindows[_window.name];
            if (parent) {
                // Close all the OpenFin tearout windows associated with the closing parent.
                parent.forEach((child) => child.close());
            }

            if (this.windowsOpen !== 1) {
                closedCb();
            }

            var index = this.mainWindowsCache.indexOf(_window);
            this.mainWindowsCache.slice(index, 1);

            this.windowsOpen--;

            if (this.windowsOpen === 0) {
                // This was the last open window; close the application.
                window.close();
            }
        }

        getMainWindows() {
            return this.mainWindowsCache;
        }
    }

    class DragService {
        constructor(storeService, geometryService, windowTracker, tearoutWindow, $q) {
            this.storeService = storeService;
            this.geometryService = geometryService;
            this.windowTracker = windowTracker;
            this.tearoutWindow = tearoutWindow;
            this.$q = $q;
            this.otherInstance = null;
        }

        overAnotherInstance(cb) {
            var mainWindows = this.windowTracker.getMainWindows(),
                result = false,
                promises = [];

            mainWindows.forEach((mainWindow) => {
                var deferred = this.$q.defer();
                promises.push(deferred.promise);
                mainWindow.getState((state) => {
                    if (state !== 'minimized' && this.geometryService.windowsIntersect(this.tearoutWindow, mainWindow.getNativeWindow())) {
                        this.otherInstance = mainWindow;
                        result = true;
                    }

                    deferred.resolve();
                });
            });

            this.$q.all(promises).then(() => cb(result));
        }

        moveToOtherInstance(stock) {
            this.storeService.open(this.otherInstance.name).add(stock);
            this.otherInstance.bringToFront();
        }
    }

    class WindowCreationService {
        constructor(storeService, geometryService, $q, configService) {
            this.storeService = storeService;
            this.geometryService = geometryService;
            this.$q = $q;
            this.configService = configService;
            this.windowTracker = new WindowTracker();
            this.firstName = true;
            this.pool = null;

            this.ready(() => { this.pool = new FreeWindowPool($q, configService); });
        }

        createMainWindow(name, isCompact, successCb) {
            var windowCreatedCb = (newWindow) => {
                // TODO
                // Begin super hack
                newWindow.getNativeWindow().windowService = this;
                newWindow.getNativeWindow().storeService = this.storeService;
                // End super hack

                this.windowTracker.add(newWindow);

                if (successCb) {
                    successCb(newWindow);
                }

                newWindow.show();
                newWindow.bringToFront();
            };

            var mainWindow;
            if (name) {
                mainWindow = new fin.desktop.Window(
                    isCompact ?
                        this.configService.getCompactConfig(name) :
                        this.configService.getWindowConfig(name),
                    () => {
                        windowCreatedCb(mainWindow);
                    }
                );
            } else {
                var poolWindow = this.pool.fetch();
                mainWindow = poolWindow.window;
                if (isCompact) {
                    this.updateOptions(poolWindow.window, true);
                    this.window.resizeTo(230, 500, 'top-right');
                }

                poolWindow.promise.then(() => {
                    windowCreatedCb(mainWindow);
                });
            }

            mainWindow.addEventListener('closed', (e) => {
                this.windowTracker.dispose(mainWindow, () => {
                    this.storeService.open(mainWindow.name).closeWindow();
                });
            });
        }

        createTearoutWindow(parentName) {
            var tearoutWindow = new fin.desktop.Window(this.configService.getTearoutConfig());

            this.windowTracker.addTearout(parentName, tearoutWindow);

            return tearoutWindow;
        }

        updateOptions(_window, isCompact) {
            if (isCompact) {
                _window.updateOptions({
                    resizable: false,
                    minHeight: 500,
                    minWidth: 230,
                    maximizable: false
                });
            } else {
                _window.updateOptions({
                    resizable: true,
                    minHeight: 510,
                    minWidth: 918,
                    maximizable: true
                });
            }
        }

        updateOptions(_window, isCompact) {
            if (isCompact) {
                _window.updateOptions({
                    resizable: false,
                    minHeight: 500,
                    minWidth: 230,
                    maximizable: false
                });
            } else {
                _window.updateOptions({
                    resizable: true,
                    minHeight: 510,
                    minWidth: 918,
                    maximizable: true
                });
            }
        }

        ready(cb) {
            fin.desktop.main(cb);
        }

        getWindows() {
            return this.windowTracker.getMainWindows();
        }

        registerDrag(tearoutWindow) {
            return new DragService(this.storeService, this.geometryService, this.windowTracker, tearoutWindow, this.$q);
        }
    }
    WindowCreationService.$inject = ['storeService', 'geometryService', '$q', 'configService'];

    angular.module('openfin.window')
        .service('windowCreationService', WindowCreationService);
}(fin));
<|endoftext|>


<commit_before>var MemoryHandler = function() {
    this.UIElement=null;
    this.JUIElement=null;
    this.rowCount = 0;
    this.n = 20;
    this.m = 10;
    this.selected = {st:0, dr:-1};
    this.adresses = [];
}

MemoryHandler.prototype.init = function(UIElement) {
    this.UIElement = UIElement;
    this.JUIElement = $(this.UIElement);
    this.invalidate();
}

MemoryHandler.prototype.resize = function(height, width) {
    this.n = height;
    this.m = width;
    this.invalidate();
}

MemoryHandler.prototype.addRow = function() {
    var i = this.rowCount;
    var tr = this.UIElement.insertRow();
    for(var j = 0; j < this.m; j++){
        var td = tr.insertCell();
        $(td).addClass("memory_cell");
        td.appendChild(document.createTextNode(i*this.m + j));
        td.style.border = '1px solid black';
        td.style.width = '30px';
    }
    this.rowCount++;
    return tr;
}

MemoryHandler.prototype.invalidate = function() {
    this.JUIElement.empty();
    //this.UIElement.style.width  = '210px';
    this.UIElement.style.border = '1px solid black';
    this.selected = {st:0, dr:-1};
    for(var i = 0; i < this.n; i++){
        this.addRow();
    }
    var self = this;
    // this.JUIElement.endlessScroll({
    //     pagesToKeep: 10,
    //     fireOnce: false,
    //     insertBefore: ".memory_table_class div:first",
    //     insertAfter: ".memory_table_class div:last",
    //     content: function(i, p) {
    //         //alert(i + " si " + p);
    //         return self.addRow(i);
    //     },
    //     ceaseFire: function(i) {
    //       if (i >= 10) {
    //         return true;
    //       }
    //     },
    //     intervalFrequency: 5
    // });
    this.JUIElement.on('scroll', function() {
        if($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight) {
            self.JUIElement.stop(true);
            self.addRow();
            /// smooth debounce :)
            var offTop = $(this).scrollTop() - 1;
            $(this).scrollTop(offTop);
        }
    })
    this.gatherVarData();
}

function uniq(a) {
    return a.sort().filter(function(item, pos, ary) {
        return !pos || item != ary[pos - 1];
    })
}

MemoryHandler.prototype.gatherVarData = function() {
    if (!simpleVar || !pointerVar)
        return;
    var a = simpleVar.getEntries();
    var b = pointerVar.getEntries();
    for (var i = 0; i < b.length; i++) {
        a.push(b[i]);
    }
    this.adresses = uniq(a);
    console.log("gatherVarData adresses " + this.adresses);
}

MemoryHandler.prototype.reColor = function() {
    this.highlight(3, 7);
}

MemoryHandler.prototype.highlight = function(lo, hi) {
    this.colorRange(this.selected.st, this.selected.dr);
    this.selected = {st: lo, dr: hi};
    this.colorRange(lo, hi);
}

MemoryHandler.prototype.colorRange = function(lo, hi) {
    // var filteredCells = $('.memory_cell').filter(function(i){
    //     console.log(JSON.stringify($(this)));
    //     var num = parseInt(this.html(), 10);
    //     return num >= lo && num <= hi;
    // });
    var cells = $('.memory_cell');
    for (var index = 0; index < cells.length; index++){
        var num = parseInt($(cells[index]).text(), 10);
        if (num >= lo && num <= hi) {
            $(cells[index]).toggleClass("colored_cell");
        }
    };
    //console.log(filteredCells);
    //filteredCells.css('color', 'red');
}

/* Old version, to be removed

MemoryHandler.prototype.select = function(str, size) {
    console.log("looking for " + str + " with size " + size) ;
    var ind = findIndex(this.adresses, str);
    console.log("Selected index is " + ind);
    if (ind === -1) return;
    ++ind;
    this.highlight(ind, ind+size-1);
}*/

MemoryHandler.prototype.select = function(str, size) {
    console.log("looking for " + str + " with size " + size) ;
    var nr = parseInt(str, 16), ind = -1;
    if (nr == 0)
        ind = 0;
    else {
        var orig = parseInt(this.adresses[0], 16);
        if (orig == 0)
            ind = nr - parseInt(this.adresses[1], 16);
        else
            ind = nr - orig;
        if (ind < 0) return;
        ++ind;
    }
    console.log("Selected index is " + ind);
    this.highlight(ind, ind+size-1);
}

function findIndex(array, elem) {
    for (var i = 0; i < array.length; i++)
        if (array[i] === elem)
            return i;
    return -1;
}

var memoryHandler = new MemoryHandler();

function refresh() {
    var height = parseInt($('#htext').val(), 10);
    var width = parseInt($('#wtext').val(), 10);
    memoryHandler.resize(height, width);
}

function initLeftPart() {
	$("#left_content").html("
Memory status
");
    var body = document.getElementById("left_content");
    function tableCreate(){
        var tbl  = document.createElement('table');
        $(tbl).addClass("memory_table_class");
        memoryHandler.init(tbl);
        body.appendChild(tbl);
    }
    var x = $("

Height: 	<input type='text' id='htext'>

Width:	<input type='text' id='wtext'>

");
    $(body).append(x);
	x = $("<button  onclick='refresh()' class='pure-button'> Refresh </button>

");
    $(body).append(x);
    tableCreate();
}
<commit_msg>Fixed memomap coloring while debuging large sized variables<commit_after>var MemoryHandler = function() {
    this.UIElement=null;
    this.JUIElement=null;
    this.rowCount = 0;
    this.n = 20;
    this.m = 10;
    this.selected = {st:0, dr:-1};
    this.adresses = [];
}

MemoryHandler.prototype.init = function(UIElement) {
    this.UIElement = UIElement;
    this.JUIElement = $(this.UIElement);
    this.invalidate();
}

MemoryHandler.prototype.resize = function(height, width) {
    this.n = height;
    this.m = width;
    this.invalidate();
}

MemoryHandler.prototype.addRow = function() {
    var i = this.rowCount;
    var tr = this.UIElement.insertRow();
    for(var j = 0; j < this.m; j++){
        var td = tr.insertCell();
        $(td).addClass("memory_cell");
        td.appendChild(document.createTextNode(i*this.m + j));
        td.style.border = '1px solid black';
        td.style.width = '30px';
    }
    this.colorRange(Math.max(this.select.st, i*this.m), this.selected.dr);
    this.rowCount++;
    return tr;
}

MemoryHandler.prototype.invalidate = function() {
    this.JUIElement.empty();
    //this.UIElement.style.width  = '210px';
    this.rowCount = 0;
    this.UIElement.style.border = '1px solid black';
    this.selected = {st:0, dr:-1};
    for(var i = 0; i < this.n; i++){
        this.addRow();
    }
    var self = this;
    // this.JUIElement.endlessScroll({
    //     pagesToKeep: 10,
    //     fireOnce: false,
    //     insertBefore: ".memory_table_class div:first",
    //     insertAfter: ".memory_table_class div:last",
    //     content: function(i, p) {
    //         //alert(i + " si " + p);
    //         return self.addRow(i);
    //     },
    //     ceaseFire: function(i) {
    //       if (i >= 10) {
    //         return true;
    //       }
    //     },
    //     intervalFrequency: 5
    // });
    this.JUIElement.on('scroll', function() {
        if($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight) {
            self.JUIElement.stop(true);
            self.addRow();
            /// smooth debounce :)
            var offTop = $(this).scrollTop() - 1;
            $(this).scrollTop(offTop);
        }
    })
    this.gatherVarData();
}

function uniq(a) {
    return a.sort().filter(function(item, pos, ary) {
        return !pos || item != ary[pos - 1];
    })
}

MemoryHandler.prototype.gatherVarData = function() {
    if (!simpleVar || !pointerVar)
        return;
    var a = simpleVar.getEntries();
    var b = pointerVar.getEntries();
    for (var i = 0; i < b.length; i++) {
        a.push(b[i]);
    }
    this.adresses = uniq(a);
    console.log("gatherVarData adresses " + this.adresses);
}

// Not used, to be removed

// MemoryHandler.prototype.reColor = function() {
//     this.highlight(3, 7);
// }

MemoryHandler.prototype.highlight = function(lo, hi) {
    this.clearRange(this.selected.st, this.selected.dr);
    this.selected = {st: lo, dr: hi};
    this.colorRange(lo, hi);
}

MemoryHandler.prototype.colorRange = function(lo, hi) {
    // var filteredCells = $('.memory_cell').filter(function(i){
    //     console.log(JSON.stringify($(this)));
    //     var num = parseInt(this.html(), 10);
    //     return num >= lo && num <= hi;
    // });
    var cells = $('.memory_cell');
    if (lo > hi) return;
    for (var index = 0; index < cells.length; index++){
        var num = parseInt($(cells[index]).text(), 10);
        if (num >= lo && num <= hi) {
            $(cells[index]).addClass("colored_cell");
        }
    };
    //console.log(filteredCells);
    //filteredCells.css('color', 'red');
}

MemoryHandler.prototype.clearRange = function(lo, hi) {
    var cells = $('.memory_cell');
    if (lo > hi) return;
    for (var index = 0; index < cells.length; index++){
        var num = parseInt($(cells[index]).text(), 10);
        if (num >= lo && num <= hi) {
            $(cells[index]).removeClass("colored_cell");
        }
    };
}

/* Old version, to be removed

MemoryHandler.prototype.select = function(str, size) {
    console.log("looking for " + str + " with size " + size) ;
    var ind = findIndex(this.adresses, str);
    console.log("Selected index is " + ind);
    if (ind === -1) return;
    ++ind;
    this.highlight(ind, ind+size-1);
}*/

MemoryHandler.prototype.select = function(str, size) {
    console.log("looking for " + str + " with size " + size) ;
    var nr = parseInt(str, 16), ind = -1;
    if (nr == 0)
        ind = 0;
    else {
        var orig = parseInt(this.adresses[0], 16);
        if (orig == 0)
            ind = nr - parseInt(this.adresses[1], 16);
        else
            ind = nr - orig;
        if (ind < 0) return;
        ++ind;
    }
    console.log("Selected index is " + ind);
    this.highlight(ind, ind+size-1);
}

function findIndex(array, elem) {
    for (var i = 0; i < array.length; i++)
        if (array[i] === elem)
            return i;
    return -1;
}

var memoryHandler = new MemoryHandler();

function refresh() {
    var height = parseInt($('#htext').val(), 10);
    var width = parseInt($('#wtext').val(), 10);
    memoryHandler.resize(height, width);
}

function initLeftPart() {
	$("#left_content").html("
Memory status
");
    var body = document.getElementById("left_content");
    function tableCreate(){
        var tbl  = document.createElement('table');
        $(tbl).addClass("memory_table_class");
        memoryHandler.init(tbl);
        body.appendChild(tbl);
    }
    var x = $("

Height: 	<input type='text' id='htext'>

Width:	<input type='text' id='wtext'>

");
    $(body).append(x);
	x = $("<button  onclick='refresh()' class='pure-button'> Refresh </button>

");
    $(body).append(x);
    tableCreate();
}
<|endoftext|>


<commit_before>/*
 * islamicDate.js - Represent a date in the Islamic calendar
 *
 * Copyright © 2012-2015, JEDLSoft
 *
 * 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.
 */

/* !depends
ilib.js
Locale.js
LocaleInfo.js
TimeZone.js
IDate.js
MathUtils.js
SearchUtils.js
Calendar.js
IslamicCal.js
IslamicRataDie.js
*/

var ilib = require("./ilib.js");
var SearchUtils = require("./SearchUtils.js");
var MathUtils = require("./MathUtils.js");

var Locale = require("./Locale.js");
var LocaleInfo = require("./LocaleInfo.js");
var TimeZone = require("./TimeZone.js");
var IDate = require("./IDate.js");
var Calendar = require("./Calendar.js");

var IslamicRataDie = require("./IslamicRataDie.js");
var IslamicCal = require("./IslamicCal.js");

/**
 * @class
 * Construct a new civil Islamic date object. The constructor can be called
 * with a params object that can contain the following properties:

 *
 *

 *
julianday - the Julian Day to set into this date
 *
year - any integer except 0. Years go from -1 (BCE) to 1 (CE), skipping the zero year
 *
month - 1 to 12, where 1 means Muharram, 2 means Saffar, etc.
 *
day - 1 to 30
 *
hour - 0 to 23. A formatter is used to display 12 hour clocks, but this representation
 * is always done with an unambiguous 24 hour representation
 *
minute - 0 to 59
 *
second - 0 to 59
 *
millisecond - 0 to 999
 *
locale - the TimeZone instance or time zone name as a string
 * of this julian date. The date/time is kept in the local time. The time zone
 * is used later if this date is formatted according to a different time zone and
 * the difference has to be calculated, or when the date format has a time zone
 * component in it.
 *
timezone - the time zone of this instance. If the time zone is not
 * given, it can be inferred from this locale. For locales that span multiple
 * time zones, the one with the largest population is chosen as the one that
 * represents the locale.
 *
 *
date - use the given intrinsic Javascript date to initialize this one.
 *

 *
 * If called with another Islamic date argument, the date components of the given
 * date are copied into the current one.

 *
 * If the constructor is called with no arguments at all or if none of the
 * properties listed above
 * from julianday through millisecond are present, then the date
 * components are
 * filled in with the current date at the time of instantiation. Note that if
 * you do not give the time zone when defaulting to the current time and the
 * time zone for all of ilib was not set with ilib.setTimeZone(), then the
 * time zone will default to UTC ("Universal Time, Coordinated" or "Greenwich
 * Mean Time").

 *
 *
 * @constructor
 * @extends IDate
 * @param {Object=} params parameters that govern the settings and behaviour of this Islamic date
 */
var IslamicDate = function(params) {
	this.cal = new IslamicCal();

	if (params) {
		if (params.locale) {
			this.locale = (typeof(params.locale) === 'string') ? new Locale(params.locale) : params.locale;
			var li = new LocaleInfo(this.locale);
			this.timezone = li.getTimeZone();
		}
		if (params.timezone) {
			this.timezone = params.timezone;
		}

		if (params.year || params.month || params.day || params.hour ||
				params.minute || params.second || params.millisecond ) {
			/**
			 * Year in the Islamic calendar.
			 * @type number
			 */
			this.year = parseInt(params.year, 10) || 0;

			/**
			 * The month number, ranging from 1 to 12 (December).
			 * @type number
			 */
			this.month = parseInt(params.month, 10) || 1;

			/**
			 * The day of the month. This ranges from 1 to 30.
			 * @type number
			 */
			this.day = parseInt(params.day, 10) || 1;

			/**
			 * The hour of the day. This can be a number from 0 to 23, as times are
			 * stored unambiguously in the 24-hour clock.
			 * @type number
			 */
			this.hour = parseInt(params.hour, 10) || 0;

			/**
			 * The minute of the hours. Ranges from 0 to 59.
			 * @type number
			 */
			this.minute = parseInt(params.minute, 10) || 0;

			/**
			 * The second of the minute. Ranges from 0 to 59.
			 * @type number
			 */
			this.second = parseInt(params.second, 10) || 0;

			/**
			 * The millisecond of the second. Ranges from 0 to 999.
			 * @type number
			 */
			this.millisecond = parseInt(params.millisecond, 10) || 0;

			/**
			 * The day of the year. Ranges from 1 to 355.
			 * @type number
			 */
			this.dayOfYear = parseInt(params.dayOfYear, 10);

			if (typeof(params.dst) === 'boolean') {
				this.dst = params.dst;
			}

			this.rd = this.newRd(this);

			// add the time zone offset to the rd to convert to UTC
			if (!this.tz) {
				this.tz = new TimeZone({id: this.timezone});
			}
			// getOffsetMillis requires that this.year, this.rd, and this.dst
			// are set in order to figure out which time zone rules apply and
			// what the offset is at that point in the year
			this.offset = this.tz._getOffsetMillisWallTime(this) / 86400000;
			if (this.offset !== 0) {
				this.rd = this.newRd({
					rd: this.rd.getRataDie() - this.offset
				});
			}
		}
	}

	if (!this.rd) {
		this.rd = this.newRd(params);
		this._calcDateComponents();
	}
};

IslamicDate.prototype = new IDate({noinstance: true});
IslamicDate.prototype.parent = IDate;
IslamicDate.prototype.constructor = IslamicDate;

/**
 * the cumulative lengths of each month, for a non-leap year
 * @private
 * @const
 * @type Array.<number>
 */
IslamicDate.cumMonthLengths = [
	0,  /* Muharram */
	30,  /* Saffar */
	59,  /* Rabi'I */
	89,  /* Rabi'II */
	118,  /* Jumada I */
	148,  /* Jumada II */
	177,  /* Rajab */
	207,  /* Sha'ban */
	236,  /* Ramadan */
	266,  /* Shawwal */
	295,  /* Dhu al-Qa'da */
	325,  /* Dhu al-Hijja */
	354
];

/**
 * Number of days difference between RD 0 of the Gregorian calendar and
 * RD 0 of the Islamic calendar.
 * @private
 * @const
 * @type number
 */
IslamicDate.GregorianDiff = 227015;

/**
 * Return a new RD for this date type using the given params.
 * @protected
 * @param {Object=} params the parameters used to create this rata die instance
 * @returns {RataDie} the new RD instance for the given params
 */
IslamicDate.prototype.newRd = function (params) {
	return new IslamicRataDie(params);
};

/**
 * Return the year for the given RD
 * @protected
 * @param {number} rd RD to calculate from
 * @returns {number} the year for the RD
 */
IslamicDate.prototype._calcYear = function(rd) {
	return Math.floor((30 * rd + 10646) / 10631);
};

/**
 * Calculate date components for the given RD date.
 * @protected
 */
IslamicDate.prototype._calcDateComponents = function () {
	var remainder,
		rd = this.rd.getRataDie();

	this.year = this._calcYear(rd);

	if (typeof(this.offset) === "undefined") {
		this.year = this._calcYear(rd);

		// now offset the RD by the time zone, then recalculate in case we were
		// near the year boundary
		if (!this.tz) {
			this.tz = new TimeZone({id: this.timezone});
		}
		this.offset = this.tz.getOffsetMillis(this) / 86400000;
	}

	if (this.offset !== 0) {
		rd += this.offset;
		this.year = this._calcYear(rd);
	}

	//console.log("IslamicDate.calcComponent: calculating for rd " + rd);
	//console.log("IslamicDate.calcComponent: year is " + ret.year);
	var yearStart = this.newRd({
		year: this.year,
		month: 1,
		day: 1,
		hour: 0,
		minute: 0,
		second: 0,
		millisecond: 0
	});
	remainder = rd - yearStart.getRataDie() + 1;

	this.dayOfYear = remainder;

	//console.log("IslamicDate.calcComponent: remainder is " + remainder);

	this.month = SearchUtils.bsearch(remainder, IslamicDate.cumMonthLengths);
	remainder -= IslamicDate.cumMonthLengths[this.month-1];

	//console.log("IslamicDate.calcComponent: month is " + this.month + " and remainder is " + remainder);

	this.day = Math.floor(remainder);
	remainder -= this.day;

	//console.log("IslamicDate.calcComponent: day is " + this.day + " and remainder is " + remainder);

	// now convert to milliseconds for the rest of the calculation
	remainder = Math.round(remainder * 86400000);

	this.hour = Math.floor(remainder/3600000);
	remainder -= this.hour * 3600000;

	this.minute = Math.floor(remainder/60000);
	remainder -= this.minute * 60000;

	this.second = Math.floor(remainder/1000);
	remainder -= this.second * 1000;

	this.millisecond = remainder;
};

/**
 * Return the day of the week of this date. The day of the week is encoded
 * as number from 0 to 6, with 0=Sunday, 1=Monday, etc., until 6=Saturday.
 *
 * @return {number} the day of the week
 */
IslamicDate.prototype.getDayOfWeek = function() {
	var rd = Math.floor(this.rd.getRataDie() + (this.offset || 0));
	return MathUtils.mod(rd-2, 7);
};

/**
 * Return the ordinal day of the year. Days are counted from 1 and proceed linearly up to
 * 354 or 355, regardless of months or weeks, etc. That is, Muharran 1st is day 1, and
 * Dhu al-Hijja 29 is 354.
 * @return {number} the ordinal day of the year
 */
IslamicDate.prototype.getDayOfYear = function() {
	return IslamicDate.cumMonthLengths[this.month-1] + this.day;
};

/**
 * Return the era for this date as a number. The value for the era for Islamic
 * calendars is -1 for "before the Islamic era" and 1 for "the Islamic era".
 * Islamic era dates are any date after Muharran 1, 1, which is the same as
 * July 16, 622 CE in the Gregorian calendar.
 *
 * @return {number} 1 if this date is in the common era, -1 if it is before the
 * common era
 */
IslamicDate.prototype.getEra = function() {
	return (this.year < 1) ? -1 : 1;
};

/**
 * Return the name of the calendar that governs this date.
 *
 * @return {string} a string giving the name of the calendar
 */
IslamicDate.prototype.getCalendar = function() {
	return "islamic";
};

//register with the factory method
IDate._constructors["islamic"] = IslamicDate;

module.exports = IslamicDate;<commit_msg>Made the IslamicDate class be async capable<commit_after>/*
 * islamicDate.js - Represent a date in the Islamic calendar
 *
 * Copyright © 2012-2015, JEDLSoft
 *
 * 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.
 */

/* !depends
ilib.js
Locale.js
LocaleInfo.js
TimeZone.js
IDate.js
MathUtils.js
SearchUtils.js
Calendar.js
IslamicCal.js
IslamicRataDie.js
*/

var ilib = require("./ilib.js");
var SearchUtils = require("./SearchUtils.js");
var MathUtils = require("./MathUtils.js");

var Locale = require("./Locale.js");
var LocaleInfo = require("./LocaleInfo.js");
var TimeZone = require("./TimeZone.js");
var IDate = require("./IDate.js");
var Calendar = require("./Calendar.js");

var IslamicRataDie = require("./IslamicRataDie.js");
var IslamicCal = require("./IslamicCal.js");

/**
 * @class
 * Construct a new civil Islamic date object. The constructor can be called
 * with a params object that can contain the following properties:

 *
 *

 *
julianday - the Julian Day to set into this date
 *
year - any integer except 0. Years go from -1 (BCE) to 1 (CE), skipping the zero year
 *
month - 1 to 12, where 1 means Muharram, 2 means Saffar, etc.
 *
day - 1 to 30
 *
hour - 0 to 23. A formatter is used to display 12 hour clocks, but this representation
 * is always done with an unambiguous 24 hour representation
 *
minute - 0 to 59
 *
second - 0 to 59
 *
millisecond - 0 to 999
 *
locale - the TimeZone instance or time zone name as a string
 * of this julian date. The date/time is kept in the local time. The time zone
 * is used later if this date is formatted according to a different time zone and
 * the difference has to be calculated, or when the date format has a time zone
 * component in it.
 *
timezone - the time zone of this instance. If the time zone is not
 * given, it can be inferred from this locale. For locales that span multiple
 * time zones, the one with the largest population is chosen as the one that
 * represents the locale.
 *
 *
date - use the given intrinsic Javascript date to initialize this one.
 *

 *
 * If called with another Islamic date argument, the date components of the given
 * date are copied into the current one.

 *
 * If the constructor is called with no arguments at all or if none of the
 * properties listed above
 * from julianday through millisecond are present, then the date
 * components are
 * filled in with the current date at the time of instantiation. Note that if
 * you do not give the time zone when defaulting to the current time and the
 * time zone for all of ilib was not set with ilib.setTimeZone(), then the
 * time zone will default to UTC ("Universal Time, Coordinated" or "Greenwich
 * Mean Time").

 *
 *
 * @constructor
 * @extends IDate
 * @param {Object=} params parameters that govern the settings and behaviour of this Islamic date
 */
var IslamicDate = function(params) {
    this.cal = new IslamicCal();

    params = params || {};

    if (params.timezone) {
        this.timezone = params.timezone;
    }
    if (params.locale) {
        this.locale = (typeof(params.locale) === 'string') ? new Locale(params.locale) : params.locale;
    }

    if (!this.timezone) {
        if (this.locale) {
            new LocaleInfo(this.locale, {
                sync: params.sync,
                loadParams: params.loadParams,
                onLoad: ilib.bind(this, function(li) {
                    this.li = li;
                    this.timezone = li.getTimeZone();
                    this._init(params);
                })
            });
        } else {
            this.timezone = "local";
            this._init(params);
        }
    } else {
        this._init(params);
    }
};

IslamicDate.prototype = new IDate({noinstance: true});
IslamicDate.prototype.parent = IDate;
IslamicDate.prototype.constructor = IslamicDate;

/**
 * Initialize the date
 * @private
 */
IslamicDate.prototype._init = function (params) {
    if (params.year || params.month || params.day || params.hour ||
        params.minute || params.second || params.millisecond ) {
        /**
         * Year in the Islamic calendar.
         * @type number
         */
        this.year = parseInt(params.year, 10) || 0;

        /**
         * The month number, ranging from 1 to 12 (December).
         * @type number
         */
        this.month = parseInt(params.month, 10) || 1;

        /**
         * The day of the month. This ranges from 1 to 30.
         * @type number
         */
        this.day = parseInt(params.day, 10) || 1;

        /**
         * The hour of the day. This can be a number from 0 to 23, as times are
         * stored unambiguously in the 24-hour clock.
         * @type number
         */
        this.hour = parseInt(params.hour, 10) || 0;

        /**
         * The minute of the hours. Ranges from 0 to 59.
         * @type number
         */
        this.minute = parseInt(params.minute, 10) || 0;

        /**
         * The second of the minute. Ranges from 0 to 59.
         * @type number
         */
        this.second = parseInt(params.second, 10) || 0;

        /**
         * The millisecond of the second. Ranges from 0 to 999.
         * @type number
         */
        this.millisecond = parseInt(params.millisecond, 10) || 0;

        /**
         * The day of the year. Ranges from 1 to 355.
         * @type number
         */
        this.dayOfYear = parseInt(params.dayOfYear, 10);

        if (typeof(params.dst) === 'boolean') {
            this.dst = params.dst;
        }

        this.rd = this.newRd(this);

        new TimeZone({
            id: this.timezone,
            sync: params.sync,
            loadParams: params.loadParams,
            onLoad: ilib.bind(this, function(tz) {
                this.tz = tz;
                // add the time zone offset to the rd to convert to UTC
                // getOffsetMillis requires that this.year, this.rd, and this.dst
                // are set in order to figure out which time zone rules apply and
                // what the offset is at that point in the year
                this.offset = this.tz._getOffsetMillisWallTime(this) / 86400000;
                if (this.offset !== 0) {
                    this.rd = this.newRd({
                        rd: this.rd.getRataDie() - this.offset
                    });
                }
                this._init2(params);
            })
        });
    } else {
        this._init2(params);
    }
};

/**
 * @private
 * Finish initializing this date object
 */
IslamicDate.prototype._init2 = function (params) {
    if (!this.rd) {
        this.rd = this.newRd(params);
        this._calcDateComponents();
    }

    if (typeof(params.onLoad) === "function") {
        params.onLoad(this);
    }
};

/**
 * the cumulative lengths of each month, for a non-leap year
 * @private
 * @const
 * @type Array.<number>
 */
IslamicDate.cumMonthLengths = [
	0,  /* Muharram */
	30,  /* Saffar */
	59,  /* Rabi'I */
	89,  /* Rabi'II */
	118,  /* Jumada I */
	148,  /* Jumada II */
	177,  /* Rajab */
	207,  /* Sha'ban */
	236,  /* Ramadan */
	266,  /* Shawwal */
	295,  /* Dhu al-Qa'da */
	325,  /* Dhu al-Hijja */
	354
];

/**
 * Number of days difference between RD 0 of the Gregorian calendar and
 * RD 0 of the Islamic calendar.
 * @private
 * @const
 * @type number
 */
IslamicDate.GregorianDiff = 227015;

/**
 * Return a new RD for this date type using the given params.
 * @protected
 * @param {Object=} params the parameters used to create this rata die instance
 * @returns {RataDie} the new RD instance for the given params
 */
IslamicDate.prototype.newRd = function (params) {
	return new IslamicRataDie(params);
};

/**
 * Return the year for the given RD
 * @protected
 * @param {number} rd RD to calculate from
 * @returns {number} the year for the RD
 */
IslamicDate.prototype._calcYear = function(rd) {
	return Math.floor((30 * rd + 10646) / 10631);
};

/**
 * Calculate date components for the given RD date.
 * @protected
 */
IslamicDate.prototype._calcDateComponents = function () {
	var remainder,
		rd = this.rd.getRataDie();

	this.year = this._calcYear(rd);

	if (typeof(this.offset) === "undefined") {
		this.year = this._calcYear(rd);

		// now offset the RD by the time zone, then recalculate in case we were
		// near the year boundary
		if (!this.tz) {
			this.tz = new TimeZone({id: this.timezone});
		}
		this.offset = this.tz.getOffsetMillis(this) / 86400000;
	}

	if (this.offset !== 0) {
		rd += this.offset;
		this.year = this._calcYear(rd);
	}

	//console.log("IslamicDate.calcComponent: calculating for rd " + rd);
	//console.log("IslamicDate.calcComponent: year is " + ret.year);
	var yearStart = this.newRd({
		year: this.year,
		month: 1,
		day: 1,
		hour: 0,
		minute: 0,
		second: 0,
		millisecond: 0
	});
	remainder = rd - yearStart.getRataDie() + 1;

	this.dayOfYear = remainder;

	//console.log("IslamicDate.calcComponent: remainder is " + remainder);

	this.month = SearchUtils.bsearch(remainder, IslamicDate.cumMonthLengths);
	remainder -= IslamicDate.cumMonthLengths[this.month-1];

	//console.log("IslamicDate.calcComponent: month is " + this.month + " and remainder is " + remainder);

	this.day = Math.floor(remainder);
	remainder -= this.day;

	//console.log("IslamicDate.calcComponent: day is " + this.day + " and remainder is " + remainder);

	// now convert to milliseconds for the rest of the calculation
	remainder = Math.round(remainder * 86400000);

	this.hour = Math.floor(remainder/3600000);
	remainder -= this.hour * 3600000;

	this.minute = Math.floor(remainder/60000);
	remainder -= this.minute * 60000;

	this.second = Math.floor(remainder/1000);
	remainder -= this.second * 1000;

	this.millisecond = remainder;
};

/**
 * Return the day of the week of this date. The day of the week is encoded
 * as number from 0 to 6, with 0=Sunday, 1=Monday, etc., until 6=Saturday.
 *
 * @return {number} the day of the week
 */
IslamicDate.prototype.getDayOfWeek = function() {
	var rd = Math.floor(this.rd.getRataDie() + (this.offset || 0));
	return MathUtils.mod(rd-2, 7);
};

/**
 * Return the ordinal day of the year. Days are counted from 1 and proceed linearly up to
 * 354 or 355, regardless of months or weeks, etc. That is, Muharran 1st is day 1, and
 * Dhu al-Hijja 29 is 354.
 * @return {number} the ordinal day of the year
 */
IslamicDate.prototype.getDayOfYear = function() {
	return IslamicDate.cumMonthLengths[this.month-1] + this.day;
};

/**
 * Return the era for this date as a number. The value for the era for Islamic
 * calendars is -1 for "before the Islamic era" and 1 for "the Islamic era".
 * Islamic era dates are any date after Muharran 1, 1, which is the same as
 * July 16, 622 CE in the Gregorian calendar.
 *
 * @return {number} 1 if this date is in the common era, -1 if it is before the
 * common era
 */
IslamicDate.prototype.getEra = function() {
	return (this.year < 1) ? -1 : 1;
};

/**
 * Return the name of the calendar that governs this date.
 *
 * @return {string} a string giving the name of the calendar
 */
IslamicDate.prototype.getCalendar = function() {
	return "islamic";
};

//register with the factory method
IDate._constructors["islamic"] = IslamicDate;

module.exports = IslamicDate;<|endoftext|>


<commit_before>'use strict'

let logger = require('tracer').colorConsole()
let connection = require('../db/connection')

module.exports = function status(id, status, table) {
  let data = {
    status: status,
    updated_at: new Date()
  }

  switch (status) {
    case 'running':
      data.started_at = new Date()
      break
    case 'failed':
    case 'succeeded':
      data.finished_at = new Date()
      break
  }

  // Returns a promise
  return connection
    .table(table)
    .where('id', id)
    .update(data)
    .catch(err => logger.error(err))
}
<commit_msg>Documenting<commit_after>'use strict'

let logger = require('tracer').colorConsole()
let connection = require('../db/connection')

/**
 * Handles updating statuses for pipeline executions and stage executions
 * @param id
 * @param status
 * @param table
 * @returns {Promise}
 */
module.exports = function status(id, status, table) {
  let data = {
    status: status,
    updated_at: new Date()
  }

  switch (status) {
    case 'running':
      data.started_at = new Date()
      break
    case 'failed':
    case 'succeeded':
      data.finished_at = new Date()
      break
  }

  // Returns a promise
  return connection
    .table(table)
    .where('id', id)
    .update(data)
    .catch(err => logger.error(err))
}
<|endoftext|>


<commit_before>/**
 ******************************************************************************
 * @file    js/lib/interpreter.js
 * @author  David Middlecamp (david@spark.io)
 * @company Spark ( https://www.spark.io/ )
 * @source https://github.com/spark/spark-cli
 * @version V1.0.0
 * @date    14-February-2014
 * @brief   CLI Interpreter module
 ******************************************************************************
 Copyright (c) 2014 Spark Labs, Inc.  All rights reserved.

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation, either
 version 3 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this program; if not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************
 */

var fs = require('fs');
var path = require('path');
var settings = require('../settings.js');

var Interpreter = function () {

};
Interpreter.prototype = {
    _commands: null,
    commandsByName: null,
    _commandsMap: null,

    startup: function () {
        this.loadCommands();

        if (settings.commandMappings) {
            this.loadMappings(settings.commandMappings);
        }
    },
    handle: function (args) {
        if (!args || args.length == 2) {
            return this.runCommand("help");
        }
        else if (args.length >= 2) {
            return this.runCommand(args[2], args.slice(3));
        }
    },

    runCommand: function (name, args) {
        //console.log('looking for command ' + name);

        var c = null;
        if (this.hasMappings()) {
            c = this.getMappedCommand(name, args);
            args = this.addMappedArgs(name, args);
        }

        //allowing passthrough for things not mapped
        if (!c) {
            c = this.commandsByName[name];
        }

        if (c) {
            return c.runCommand(args);
        }
        else {
            console.log("Spark-CLI: Unknown command: \"" + name + "\"");
            return -1;
        }

    },

    getCommands: function () {
        return this._commands;
    },

    /**
     * ignores mappings, just uses the name in the original classfile,
     * so we can cross-reference commands internally
     * @param name
     * @returns {*}
     */
    getCommandModule: function (name) {
        var commands = this._commands;
        for (var i = 0; i < commands.length; i++) {
            try {
                var c = commands[i];
                if (c.name == name) {
                    return c;
                }
            }
            catch (ex) {
                console.error("Error loading command " + ex);
            }
        }
    },

    /**
     * finds a command using the mapped name, or the friendly name in the module
     * @param name
     * @returns {*}
     */
    findCommand: function (name) {
        if (!name) {
            name = "help";
        }

        var cmd;
        if (this.hasMappings()) {
             cmd = this._commandsMap[name];
        }

        if (!cmd && (name != "help")) {
            return this.getCommandModule(name);
        }

        return cmd;
    },

    /**
     * We could make this more efficient, but this is good for a small number
     * of commands with lots of functionality
     */
    loadCommands: function () {
        this._commands = [];
        this.commandsByName = {};

        var files = fs.readdirSync(settings.commandPath).filter(function (file) {
            return file.indexOf('.') !== 0; // Ignore hidden files (Such as .swp files)
        });

        for (var i = 0; i < files.length; i++) {
            var cmdPath = path.join(settings.commandPath, files[i]);
            try {
                var Cmd = require(cmdPath);
                var c = new Cmd(this);

                if (c.name != null) {
                    this._commands.push(c);
                    this.commandsByName[c.name] = c;
                }
            }
            catch (ex) {
                console.error("Error loading command " + cmdPath + " " + ex);
            }
        }
    },

    tryReadMappings: function (filename) {
        if (!filename || (filename == "")) {
            return null;
        }

        try {
            var contents = fs.readFileSync(filename);
            return JSON.parse(contents);
        }
        catch (ex) {
            console.error("Error parsing mappings file " + filename, ex);
        }

        return null;
    },

    /**
     * open our command mappings file, and override our stock commands
     * @param filename
     */
    loadMappings: function (filename) {
        var data = this.tryReadMappings(filename);
        if (!data || !data._commands) {
            console.log("Mappings filename was " + filename + " but no mappings were present");
            return;
        }

        this._commandsMap = data;

        //tree recursive
//        this.addMappedList(data._commands, data, this._commandsMap);

        //TODO: DAVE HERE
        //optional?
        //make a list of all overridden / mapped commands, so we know not to list them?

        //
        //[ ] we should show a list of all missed commands under common commands, so that they can be found.
        //[ ] help should work for mappings containing children
        //e.g. core

    },
//
//    /**
//     * recur down the command tree, building our structure
//     * @param arr
//     * @param tree
//     * @param commands
//     */
//    addMappedList: function (arr, tree, commands) {
//        var names = [];
//        for (var i = 0; i < arr.length; i++) {
//            var name = arr[i];
//            var node = tree[name];
//
//            names.push(name);
//            this.addMapping(name, node, commands);
//            commands._commands = names;
//        }
//    },
//
//
//    addMapping: function (name, node, commands) {
//        if (!node) {
//            return;
//        }
//
//        node.name = name;
//        commands[name] = node;
//
//        if (node._commands) {
//            var subcommands = { };
//            this.addMappedList(node._commands, node, subcommands);
//            commands[name]._commands = subcommands;
//        }
//    },

    getMappedCommand: function (name, args) {
        var node = this._commandsMap[name];
        if (!node) {
            return null;
        }

        //we don't map to anything, but there are more args?
        //maybe we're a root element.
        if (!node.maps && args && (args.length > 0)) {
            var subCmd = args[0];       //e.g. core add

            //does this root item have a subcommand with that name?
            if (node[subCmd]) {
                //what does that subcommand map to?
                var maps = node[subCmd].maps;

                var cmd = this.commandsByName[maps[0]];

                //cut off the alias from the args, and inject the true command
                if (maps.length > 1) {
                    args.splice(0, 1, maps[1]);
                }

                return cmd;
            }
        }

        if (!node.maps) {
            //doesn't map exactly to one command, so lets call help.
            //updating the maps property will let it trim the arguments later so we get the proper help command
            node.maps = [ "help", name ];
        }

        var cmdName = (node.maps) ? node.maps[0] : null;

        //grab the command we're mapped to
        return this.commandsByName[cmdName];
    },
    addMappedArgs: function (name, args) {
        var node = this._commandsMap[name];
        if (!node) {
            return null;
        }

        //append any remaining chunks of the mapping to the arguments list
        if (node.maps && (node.maps.length > 1)) {
            var arr = node.maps.slice(1);
            args = arr.concat(args);
        }
        return args;
    },

    hasMappings: function() {
        return !!this._commandsMap;
    },

    getUnmappedTopLevelCommands: function() {
        var results = [];

        var orig = this.commandsByName;
        for(var key in orig) {
            var obj = orig[key];

            var name = obj.name;
            if (!this._commandsMap[name]) {
                results.push(name);
            }
        }

        return results;
    },

//    getUnmappedCommands: function() {
//        var results = [];
//
//        var orig = this.cli.commandsByName;
//        for(var i=0;i<orig.length;i++) {
//            var name = orig[i].name;
//
//            if (!this._commandsMap[name]) {
//                results.push(name);
//            }
//        }
//
//        //what do I do about nested commands?
//
//        return results;
//    },

    _: null
};
module.exports = Interpreter;

<commit_msg>fixing passthrough command args<commit_after>/**
 ******************************************************************************
 * @file    js/lib/interpreter.js
 * @author  David Middlecamp (david@spark.io)
 * @company Spark ( https://www.spark.io/ )
 * @source https://github.com/spark/spark-cli
 * @version V1.0.0
 * @date    14-February-2014
 * @brief   CLI Interpreter module
 ******************************************************************************
 Copyright (c) 2014 Spark Labs, Inc.  All rights reserved.

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation, either
 version 3 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this program; if not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************
 */

var fs = require('fs');
var path = require('path');
var settings = require('../settings.js');

var Interpreter = function () {

};
Interpreter.prototype = {
    _commands: null,
    commandsByName: null,
    _commandsMap: null,

    startup: function () {
        this.loadCommands();

        if (settings.commandMappings) {
            this.loadMappings(settings.commandMappings);
        }
    },
    handle: function (args) {
        if (!args || args.length == 2) {
            return this.runCommand("help");
        }
        else if (args.length >= 2) {
            return this.runCommand(args[2], args.slice(3));
        }
    },

    runCommand: function (name, args) {
        //console.log('looking for command ' + name);

        var c = null;
        if (this.hasMappings()) {
            c = this.getMappedCommand(name, args);
            var newargs = this.addMappedArgs(name, args);
            if (c) {
                args = newargs;
            }
        }

        //allowing passthrough for things not mapped
        if (!c) {
            c = this.commandsByName[name];
        }

        if (c) {
            return c.runCommand(args);
        }
        else {
            console.log("Spark-CLI: Unknown command: \"" + name + "\"");
            return -1;
        }

    },

    getCommands: function () {
        return this._commands;
    },

    /**
     * ignores mappings, just uses the name in the original classfile,
     * so we can cross-reference commands internally
     * @param name
     * @returns {*}
     */
    getCommandModule: function (name) {
        var commands = this._commands;
        for (var i = 0; i < commands.length; i++) {
            try {
                var c = commands[i];
                if (c.name == name) {
                    return c;
                }
            }
            catch (ex) {
                console.error("Error loading command " + ex);
            }
        }
    },

    /**
     * finds a command using the mapped name, or the friendly name in the module
     * @param name
     * @returns {*}
     */
    findCommand: function (name) {
        if (!name) {
            name = "help";
        }

        var cmd;
        if (this.hasMappings()) {
             cmd = this._commandsMap[name];
        }

        if (!cmd && (name != "help")) {
            return this.getCommandModule(name);
        }

        return cmd;
    },

    /**
     * We could make this more efficient, but this is good for a small number
     * of commands with lots of functionality
     */
    loadCommands: function () {
        this._commands = [];
        this.commandsByName = {};

        var files = fs.readdirSync(settings.commandPath).filter(function (file) {
            return file.indexOf('.') !== 0; // Ignore hidden files (Such as .swp files)
        });

        for (var i = 0; i < files.length; i++) {
            var cmdPath = path.join(settings.commandPath, files[i]);
            try {
                var Cmd = require(cmdPath);
                var c = new Cmd(this);

                if (c.name != null) {
                    this._commands.push(c);
                    this.commandsByName[c.name] = c;
                }
            }
            catch (ex) {
                console.error("Error loading command " + cmdPath + " " + ex);
            }
        }
    },

    tryReadMappings: function (filename) {
        if (!filename || (filename == "")) {
            return null;
        }

        try {
            var contents = fs.readFileSync(filename);
            return JSON.parse(contents);
        }
        catch (ex) {
            console.error("Error parsing mappings file " + filename, ex);
        }

        return null;
    },

    /**
     * open our command mappings file, and override our stock commands
     * @param filename
     */
    loadMappings: function (filename) {
        var data = this.tryReadMappings(filename);
        if (!data || !data._commands) {
            console.log("Mappings filename was " + filename + " but no mappings were present");
            return;
        }

        this._commandsMap = data;

        //tree recursive
//        this.addMappedList(data._commands, data, this._commandsMap);

        //TODO: DAVE HERE
        //optional?
        //make a list of all overridden / mapped commands, so we know not to list them?

        //
        //[ ] we should show a list of all missed commands under common commands, so that they can be found.
        //[ ] help should work for mappings containing children
        //e.g. core

    },
//
//    /**
//     * recur down the command tree, building our structure
//     * @param arr
//     * @param tree
//     * @param commands
//     */
//    addMappedList: function (arr, tree, commands) {
//        var names = [];
//        for (var i = 0; i < arr.length; i++) {
//            var name = arr[i];
//            var node = tree[name];
//
//            names.push(name);
//            this.addMapping(name, node, commands);
//            commands._commands = names;
//        }
//    },
//
//
//    addMapping: function (name, node, commands) {
//        if (!node) {
//            return;
//        }
//
//        node.name = name;
//        commands[name] = node;
//
//        if (node._commands) {
//            var subcommands = { };
//            this.addMappedList(node._commands, node, subcommands);
//            commands[name]._commands = subcommands;
//        }
//    },

    getMappedCommand: function (name, args) {
        var node = this._commandsMap[name];
        if (!node) {
            return null;
        }

        //we don't map to anything, but there are more args?
        //maybe we're a root element.
        if (!node.maps && args && (args.length > 0)) {
            var subCmd = args[0];       //e.g. core add

            //does this root item have a subcommand with that name?
            if (node[subCmd]) {
                //what does that subcommand map to?
                var maps = node[subCmd].maps;

                var cmd = this.commandsByName[maps[0]];

                //cut off the alias from the args, and inject the true command
                if (maps.length > 1) {
                    args.splice(0, 1, maps[1]);
                }

                return cmd;
            }
        }

        if (!node.maps) {
            //doesn't map exactly to one command, so lets call help.
            //updating the maps property will let it trim the arguments later so we get the proper help command
            node.maps = [ "help", name ];
        }

        var cmdName = (node.maps) ? node.maps[0] : null;

        //grab the command we're mapped to
        return this.commandsByName[cmdName];
    },
    addMappedArgs: function (name, args) {
        var node = this._commandsMap[name];
        if (!node) {
            return null;
        }

        //append any remaining chunks of the mapping to the arguments list
        if (node.maps && (node.maps.length > 1)) {
            var arr = node.maps.slice(1);
            args = arr.concat(args);
        }
        return args;
    },

    hasMappings: function() {
        return !!this._commandsMap;
    },

    getUnmappedTopLevelCommands: function() {
        var results = [];

        var orig = this.commandsByName;
        for(var key in orig) {
            var obj = orig[key];

            var name = obj.name;
            if (!this._commandsMap[name]) {
                results.push(name);
            }
        }

        return results;
    },

//    getUnmappedCommands: function() {
//        var results = [];
//
//        var orig = this.cli.commandsByName;
//        for(var i=0;i<orig.length;i++) {
//            var name = orig[i].name;
//
//            if (!this._commandsMap[name]) {
//                results.push(name);
//            }
//        }
//
//        //what do I do about nested commands?
//
//        return results;
//    },

    _: null
};
module.exports = Interpreter;

<|endoftext|>


<commit_before>// Copyright 2013-2015, University of Colorado Boulder

/**
 * General constants for Fraction Matcher.  While constants, they are extended by MixedNumberConstants, so they should be instantiated
 * like instance objects.  See https://github.com/phetsims/fraction-matcher/issues/43
 *
 * @author Andrey Zelenkov (Mlearner)
 */
define( function( require ) {
  'use strict';

  // modules
  var fractionMatcher = require( 'FRACTION_MATCHER/fractionMatcher' );
  var FillType = require( 'FRACTION_MATCHER/model/FillType' );
  var Fraction = require( 'PHETCOMMON/model/Fraction' );
  var PhetColorScheme = require( 'SCENERY_PHET/PhetColorScheme' );

  //colors
  var COLORS = {
    LIGHT_GREEN: 'rgb(140,198,63)',
    LIGHT_BLUE: '#6acef5',//to match the PhET Logo
    LIGHT_RED: 'rgb(233,69,69)',
    LIGHT_PINK: 'rgb(255,175,175)',
    ORANGE: 'rgb(255,200,0)',
    YELLOW: PhetColorScheme.PHET_LOGO_YELLOW,//to match the PhET Logo
    GREEN: 'rgb(0,255,0)',
    PINK: 'rgb(255,0,255)'
  };
  COLORS.CIRCLE_COLOR = COLORS.LIGHT_GREEN;
  COLORS.HORIZONTAL_SLICE_COLOR = COLORS.LIGHT_RED;
  COLORS.VERTICAL_SLICE_COLOR = COLORS.LIGHT_BLUE;
  COLORS.NUMBER_LINE = COLORS.LIGHT_GREEN;

  //list of all possible shapes
  var SHAPES = [ 'PIES', 'HORIZONTAL_BARS', 'VERTICAL_BARS', 'PLUSES', 'GRID', 'PYRAMID', 'POLYGON', 'TETRIS', 'FLOWER', 'LETTER_L_SHAPES', 'INTERLEAVED_L_SHAPES', 'RING_OF_HEXAGONS', 'NINJA_STAR' ];

  function Constants() {
    // color constants
    this.COLORS = COLORS;

    // shapes type constants
    this.SHAPES = SHAPES;

    this.LEVEL_DESCRIPTION = [
    /**
     * Level 1
     * No mixed numbers
     * Only “exact” matches will be present. So for instance if there is a 3/6  and a pie with 6 divisions and 3 shaded slices, there will not be a ½  present .  In other words, the numerical representation on this level will exactly match the virtual manipulative.
     * Only numbers/representations ≦ 1 possible on this level
     * “Easy” shapes on this level (not some of the more abstract representations)
     */
      {
        fractions: [
          new Fraction( 1, 2 ),
          new Fraction( 1, 3 ),
          new Fraction( 2, 3 ),
          new Fraction( 1, 4 ),
          new Fraction( 3, 4 ),
          new Fraction( 1, 1 )
        ],
        numericScaleFactors: [ 1 ],
        fillType: [ FillType.SEQUENTIAL ],
        shapes: SHAPES.slice( 0, 3 )
      },
    /**
     * Level 2
     * Reduced fractions possible on this level. So, for instance 3/6 and ½  could both be present.  Or a virtual representation of 3/6 could have the numerical of ½ be its only possible match
     * Still only numbers/representations ≦ 1 possible
     * More shapes can be introduced
     */
      {
        fractions: [
          new Fraction( 1, 2 ),
          new Fraction( 1, 3 ),
          new Fraction( 2, 3 ),
          new Fraction( 2, 4 ),
          new Fraction( 3, 4 ),
          new Fraction( 2, 6 ),
          new Fraction( 3, 6 )
        ],
        numericScaleFactors: [ 1 ],
        fillType: [ FillType.SEQUENTIAL ],
        shapes: SHAPES.slice( 0 )
      },
    /**
     * Level 3:
     * Reduced fractions possible on this level. So, for instance 3/6 and ½  could both be present.  Or a virtual representation of 3/6 could have the numerical of ½ be its only possible match
     * Still only numbers/representations ≦ 1 possible
     * More shapes can be introduced
     */
      {
        fractions: [
          new Fraction( 3, 2 ),
          new Fraction( 4, 3 ),
          new Fraction( 5, 4 ),
          new Fraction( 6, 4 ),
          new Fraction( 7, 4 ),
          new Fraction( 4, 5 ),
          new Fraction( 2, 6 ),
          new Fraction( 3, 6 ),
          new Fraction( 4, 6 ),
          new Fraction( 5, 6 ),
          new Fraction( 7, 6 ),
          new Fraction( 3, 8 ),
          new Fraction( 4, 8 ),
          new Fraction( 5, 8 ),
          new Fraction( 6, 8 ),
          new Fraction( 7, 8 )
        ],
        numericScaleFactors: [ 1 ],
        fillType: [ FillType.SEQUENTIAL ],
        shapes: SHAPES.slice( 0 )
      },
    /**
     * Level 4:
     * All representations possible as well as complicated mixed/improper numbers
     */
      {
        fractions: [
          new Fraction( 13, 7 ),
          new Fraction( 13, 7 ),
          new Fraction( 6, 3 ),
          new Fraction( 9, 5 ),
          new Fraction( 9, 7 ),
          new Fraction( 9, 8 ),
          new Fraction( 14, 8 ),
          new Fraction( 2, 9 ),
          new Fraction( 3, 9 ),
          new Fraction( 4, 9 ),
          new Fraction( 6, 9 ),
          new Fraction( 8, 9 )
        ],
        numericScaleFactors: [ 1, 2 ],
        fillType: [ FillType.SEQUENTIAL ],
        shapes: SHAPES.slice( 0 )
      },
    /**
     * Level 5:
     * All representations possible as well as complicated mixed/improper numbers.  Same fractions as level 4 but different representations.
     */
      {
        fractions: [
          new Fraction( 13, 7 ),
          new Fraction( 13, 7 ),
          new Fraction( 6, 3 ),
          new Fraction( 9, 5 ),
          new Fraction( 9, 7 ),
          new Fraction( 9, 8 ),
          new Fraction( 14, 8 ),
          new Fraction( 2, 9 ),
          new Fraction( 3, 9 ),
          new Fraction( 4, 9 ),
          new Fraction( 6, 9 ),
          new Fraction( 8, 9 )
        ],
        numericScaleFactors: [ 1, 2, 3 ],
        fillType: [ FillType.SEQUENTIAL, FillType.MIXED ],
        shapes: SHAPES.slice( 0 )
      },
    /**
     * Level 6:
     * All representations possible as well as complicated mixed/improper numbers
     */
      {
        fractions: [
          new Fraction( 6, 5 ),
          new Fraction( 7, 5 ),
          new Fraction( 8, 5 ),
          new Fraction( 9, 5 ),
          new Fraction( 7, 6 ),
          new Fraction( 8, 6 ),
          new Fraction( 9, 6 ),
          new Fraction( 9, 7 ),
          new Fraction( 10, 7 ),
          new Fraction( 13, 7 ),
          new Fraction( 9, 8 ),
          new Fraction( 10, 8 ),
          new Fraction( 11, 8 ),
          new Fraction( 14, 8 ),
          new Fraction( 4, 9 ),
          new Fraction( 6, 9 ),
          new Fraction( 8, 9 ),
          new Fraction( 10, 9 ),
          new Fraction( 11, 9 )
        ],
        numericScaleFactors: [ 1, 4, 5 ],
        fillType: [ FillType.SEQUENTIAL, FillType.RANDOM ],
        shapes: SHAPES.slice( 0 )
      },
    /**
     * Level 7:
     * All representations possible as well as complicated mixed/improper numbers
     */
      {
        fractions: [
          new Fraction( 3, 2 ),
          new Fraction( 4, 3 ),
          new Fraction( 5, 3 ),
          new Fraction( 5, 4 ),
          new Fraction( 7, 4 ),
          new Fraction( 6, 5 ),
          new Fraction( 7, 5 ),
          new Fraction( 8, 5 ),
          new Fraction( 9, 5 ),
          new Fraction( 7, 6 ),
          new Fraction( 11, 6 )
        ],
        numericScaleFactors: [ 1, 6, 7 ],
        fillType: [ FillType.SEQUENTIAL, FillType.RANDOM ],
        shapes: SHAPES.slice( 0 )
      },
    /**
     * Level 8:
     * All representations possible as well as complicated mixed/improper numbers
     */
      {
        fractions: [
          new Fraction( 8, 7 ),
          new Fraction( 9, 7 ),
          new Fraction( 10, 7 ),
          new Fraction( 11, 7 ),
          new Fraction( 12, 7 ),
          new Fraction( 13, 7 ),
          new Fraction( 9, 8 ),
          new Fraction( 10, 8 ),
          new Fraction( 11, 8 ),
          new Fraction( 12, 8 ),
          new Fraction( 13, 8 ),
          new Fraction( 14, 8 ),
          new Fraction( 15, 8 ),
          new Fraction( 10, 9 ),
          new Fraction( 11, 9 ),
          new Fraction( 12, 9 ),
          new Fraction( 13, 9 ),
          new Fraction( 14, 9 ),
          new Fraction( 15, 9 ),
          new Fraction( 16, 9 ),
          new Fraction( 17, 9 )
        ],
        numericScaleFactors: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
        fillType: [ FillType.SEQUENTIAL, FillType.RANDOM ],
        shapes: SHAPES.slice( 0 )
      }
    ];
  }

  fractionMatcher.register( 'Constants', Constants );

  return Constants;
} );<commit_msg>add PHET_LOGO_BLUE, use in clients, https://github.com/phetsims/joist/issues/158<commit_after>// Copyright 2013-2015, University of Colorado Boulder

/**
 * General constants for Fraction Matcher.  While constants, they are extended by MixedNumberConstants, so they should be instantiated
 * like instance objects.  See https://github.com/phetsims/fraction-matcher/issues/43
 *
 * @author Andrey Zelenkov (Mlearner)
 */
define( function( require ) {
  'use strict';

  // modules
  var fractionMatcher = require( 'FRACTION_MATCHER/fractionMatcher' );
  var FillType = require( 'FRACTION_MATCHER/model/FillType' );
  var Fraction = require( 'PHETCOMMON/model/Fraction' );
  var PhetColorScheme = require( 'SCENERY_PHET/PhetColorScheme' );

  //colors
  var COLORS = {
    LIGHT_GREEN: 'rgb(140,198,63)',
    LIGHT_BLUE: PhetColorScheme.PHET_LOGO_BLUE, //to match the PhET Logo
    LIGHT_RED: 'rgb(233,69,69)',
    LIGHT_PINK: 'rgb(255,175,175)',
    ORANGE: 'rgb(255,200,0)',
    YELLOW: PhetColorScheme.PHET_LOGO_YELLOW, //to match the PhET Logo
    GREEN: 'rgb(0,255,0)',
    PINK: 'rgb(255,0,255)'
  };
  COLORS.CIRCLE_COLOR = COLORS.LIGHT_GREEN;
  COLORS.HORIZONTAL_SLICE_COLOR = COLORS.LIGHT_RED;
  COLORS.VERTICAL_SLICE_COLOR = COLORS.LIGHT_BLUE;
  COLORS.NUMBER_LINE = COLORS.LIGHT_GREEN;

  //list of all possible shapes
  var SHAPES = [ 'PIES', 'HORIZONTAL_BARS', 'VERTICAL_BARS', 'PLUSES', 'GRID', 'PYRAMID', 'POLYGON', 'TETRIS', 'FLOWER', 'LETTER_L_SHAPES', 'INTERLEAVED_L_SHAPES', 'RING_OF_HEXAGONS', 'NINJA_STAR' ];

  function Constants() {
    // color constants
    this.COLORS = COLORS;

    // shapes type constants
    this.SHAPES = SHAPES;

    this.LEVEL_DESCRIPTION = [
    /**
     * Level 1
     * No mixed numbers
     * Only “exact” matches will be present. So for instance if there is a 3/6  and a pie with 6 divisions and 3 shaded slices, there will not be a ½  present .  In other words, the numerical representation on this level will exactly match the virtual manipulative.
     * Only numbers/representations ≦ 1 possible on this level
     * “Easy” shapes on this level (not some of the more abstract representations)
     */
      {
        fractions: [
          new Fraction( 1, 2 ),
          new Fraction( 1, 3 ),
          new Fraction( 2, 3 ),
          new Fraction( 1, 4 ),
          new Fraction( 3, 4 ),
          new Fraction( 1, 1 )
        ],
        numericScaleFactors: [ 1 ],
        fillType: [ FillType.SEQUENTIAL ],
        shapes: SHAPES.slice( 0, 3 )
      },
    /**
     * Level 2
     * Reduced fractions possible on this level. So, for instance 3/6 and ½  could both be present.  Or a virtual representation of 3/6 could have the numerical of ½ be its only possible match
     * Still only numbers/representations ≦ 1 possible
     * More shapes can be introduced
     */
      {
        fractions: [
          new Fraction( 1, 2 ),
          new Fraction( 1, 3 ),
          new Fraction( 2, 3 ),
          new Fraction( 2, 4 ),
          new Fraction( 3, 4 ),
          new Fraction( 2, 6 ),
          new Fraction( 3, 6 )
        ],
        numericScaleFactors: [ 1 ],
        fillType: [ FillType.SEQUENTIAL ],
        shapes: SHAPES.slice( 0 )
      },
    /**
     * Level 3:
     * Reduced fractions possible on this level. So, for instance 3/6 and ½  could both be present.  Or a virtual representation of 3/6 could have the numerical of ½ be its only possible match
     * Still only numbers/representations ≦ 1 possible
     * More shapes can be introduced
     */
      {
        fractions: [
          new Fraction( 3, 2 ),
          new Fraction( 4, 3 ),
          new Fraction( 5, 4 ),
          new Fraction( 6, 4 ),
          new Fraction( 7, 4 ),
          new Fraction( 4, 5 ),
          new Fraction( 2, 6 ),
          new Fraction( 3, 6 ),
          new Fraction( 4, 6 ),
          new Fraction( 5, 6 ),
          new Fraction( 7, 6 ),
          new Fraction( 3, 8 ),
          new Fraction( 4, 8 ),
          new Fraction( 5, 8 ),
          new Fraction( 6, 8 ),
          new Fraction( 7, 8 )
        ],
        numericScaleFactors: [ 1 ],
        fillType: [ FillType.SEQUENTIAL ],
        shapes: SHAPES.slice( 0 )
      },
    /**
     * Level 4:
     * All representations possible as well as complicated mixed/improper numbers
     */
      {
        fractions: [
          new Fraction( 13, 7 ),
          new Fraction( 13, 7 ),
          new Fraction( 6, 3 ),
          new Fraction( 9, 5 ),
          new Fraction( 9, 7 ),
          new Fraction( 9, 8 ),
          new Fraction( 14, 8 ),
          new Fraction( 2, 9 ),
          new Fraction( 3, 9 ),
          new Fraction( 4, 9 ),
          new Fraction( 6, 9 ),
          new Fraction( 8, 9 )
        ],
        numericScaleFactors: [ 1, 2 ],
        fillType: [ FillType.SEQUENTIAL ],
        shapes: SHAPES.slice( 0 )
      },
    /**
     * Level 5:
     * All representations possible as well as complicated mixed/improper numbers.  Same fractions as level 4 but different representations.
     */
      {
        fractions: [
          new Fraction( 13, 7 ),
          new Fraction( 13, 7 ),
          new Fraction( 6, 3 ),
          new Fraction( 9, 5 ),
          new Fraction( 9, 7 ),
          new Fraction( 9, 8 ),
          new Fraction( 14, 8 ),
          new Fraction( 2, 9 ),
          new Fraction( 3, 9 ),
          new Fraction( 4, 9 ),
          new Fraction( 6, 9 ),
          new Fraction( 8, 9 )
        ],
        numericScaleFactors: [ 1, 2, 3 ],
        fillType: [ FillType.SEQUENTIAL, FillType.MIXED ],
        shapes: SHAPES.slice( 0 )
      },
    /**
     * Level 6:
     * All representations possible as well as complicated mixed/improper numbers
     */
      {
        fractions: [
          new Fraction( 6, 5 ),
          new Fraction( 7, 5 ),
          new Fraction( 8, 5 ),
          new Fraction( 9, 5 ),
          new Fraction( 7, 6 ),
          new Fraction( 8, 6 ),
          new Fraction( 9, 6 ),
          new Fraction( 9, 7 ),
          new Fraction( 10, 7 ),
          new Fraction( 13, 7 ),
          new Fraction( 9, 8 ),
          new Fraction( 10, 8 ),
          new Fraction( 11, 8 ),
          new Fraction( 14, 8 ),
          new Fraction( 4, 9 ),
          new Fraction( 6, 9 ),
          new Fraction( 8, 9 ),
          new Fraction( 10, 9 ),
          new Fraction( 11, 9 )
        ],
        numericScaleFactors: [ 1, 4, 5 ],
        fillType: [ FillType.SEQUENTIAL, FillType.RANDOM ],
        shapes: SHAPES.slice( 0 )
      },
    /**
     * Level 7:
     * All representations possible as well as complicated mixed/improper numbers
     */
      {
        fractions: [
          new Fraction( 3, 2 ),
          new Fraction( 4, 3 ),
          new Fraction( 5, 3 ),
          new Fraction( 5, 4 ),
          new Fraction( 7, 4 ),
          new Fraction( 6, 5 ),
          new Fraction( 7, 5 ),
          new Fraction( 8, 5 ),
          new Fraction( 9, 5 ),
          new Fraction( 7, 6 ),
          new Fraction( 11, 6 )
        ],
        numericScaleFactors: [ 1, 6, 7 ],
        fillType: [ FillType.SEQUENTIAL, FillType.RANDOM ],
        shapes: SHAPES.slice( 0 )
      },
    /**
     * Level 8:
     * All representations possible as well as complicated mixed/improper numbers
     */
      {
        fractions: [
          new Fraction( 8, 7 ),
          new Fraction( 9, 7 ),
          new Fraction( 10, 7 ),
          new Fraction( 11, 7 ),
          new Fraction( 12, 7 ),
          new Fraction( 13, 7 ),
          new Fraction( 9, 8 ),
          new Fraction( 10, 8 ),
          new Fraction( 11, 8 ),
          new Fraction( 12, 8 ),
          new Fraction( 13, 8 ),
          new Fraction( 14, 8 ),
          new Fraction( 15, 8 ),
          new Fraction( 10, 9 ),
          new Fraction( 11, 9 ),
          new Fraction( 12, 9 ),
          new Fraction( 13, 9 ),
          new Fraction( 14, 9 ),
          new Fraction( 15, 9 ),
          new Fraction( 16, 9 ),
          new Fraction( 17, 9 )
        ],
        numericScaleFactors: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
        fillType: [ FillType.SEQUENTIAL, FillType.RANDOM ],
        shapes: SHAPES.slice( 0 )
      }
    ];
  }

  fractionMatcher.register( 'Constants', Constants );

  return Constants;
} );<|endoftext|>