<commit_before>;(function() {
    function Tablesort(el, options) {
        if (!el) throw new Error('Element not found');
        if (el.tagName !== 'TABLE') throw new Error('Element must be a table');
        this.init(el, options || {});
    }

    Tablesort.prototype = {

        init: function(el, options) {
            var that = this,
                firstRow;
            this.thead = false;
            this.options = options;

            if (el.rows && el.rows.length > 0) {
                if (el.tHead && el.tHead.rows.length > 0) {
                    firstRow = el.tHead.rows[el.tHead.rows.length - 1];
                    that.thead = true;
                } else {
                    firstRow = el.rows[0];
                }
            }

            if (!firstRow) return;

            var onClick = function() {
                if (that.current && that.current !== this) {
                    that.current.classList.remove(classSortUp);
                    that.current.classList.remove(classSortDown);
                }

                that.current = this;
                that.sortTable(this);
            };

            var defaultSort;

            // Assume first row is the header and attach a click handler to each.
            for (var i = 0; i < firstRow.cells.length; i++) {
                var cell = firstRow.cells[i];
                if (!cell.classList.contains('no-sort')) {
                    cell.classList.add('sort-header');
                    cell.addEventListener('click', onClick, false);

                    if (cell.classList.contains('sort-default')) {
                        defaultSort = cell;
                    }
                }
            }

            if (defaultSort) {
                that.current = defaultSort;
                that.sortTable(defaultSort);
            }
        },

        getFirstDataRowIndex: function() {
            // If table does not have a <thead>, assume that first row is
            // a header and skip it.
            if (!this.thead) {
                return 1;
            } else {
                return 0;
            }
        },

        sortTable: function(header) {
            var that = this,
                column = header.cellIndex,
                sortFunction,
                t = getParent(header, 'table'),
                item = '',
                items = [],
                i = that.getFirstDataRowIndex();

            if (t.rows.length <= 1) return;

            while (items.length < 3 && i < t.tBodies[0].rows.length) {
                item = getInnerText(t.tBodies[0].rows[i].cells[column]);
                item = item.trim();
                // Exclude cell values where commented out HTML exists
                if (item.substr(0, 4) !== '<!--' && item.length !== 0) {
                    items.push(item);
                }
                i++;
            }

            if (!items) return;

            // Possible sortFunction scenarios
            var sortCaseInsensitive = function(a, b) {
                var aa = getInnerText(a.cells[that.col]).toLowerCase(),
                    bb = getInnerText(b.cells[that.col]).toLowerCase();

                if (aa === bb) return 0;
                if (aa < bb) return 1;

                return -1;
            };

            var sortNumber = function(a, b) {
                var aa = getInnerText(a.cells[that.col]),
                    bb = getInnerText(b.cells[that.col]);

                aa = cleanNumber(aa);
                bb = cleanNumber(bb);
                return compareNumber(bb, aa);
            };

            var sortDate = function(a, b) {
                var aa = getInnerText(a.cells[that.col]).toLowerCase(),
                    bb = getInnerText(b.cells[that.col]).toLowerCase();
                return parseDate(bb) - parseDate(aa);
            };

            var sortDotSep = function(a, b) {
                var aa = getInnerText(a.cells[that.col]).split('.'),
                    bb = getInnerText(b.cells[that.col]).split('.');

                for (var i = 0, len = aa.length; i < len; i++) {
                    var aai = parseInt(aa[i]),
                        bbi = parseInt(bb[i]);

                    if (aai == bbi) continue;
                    if (aai > bbi) return -1;
                    if (aai < bbi) return 1;
                }
                return 0;
            };

            var sortFilesize = function(a, b) {
                var aa = filesize2num(getInnerText(a.cells[that.col])),
                    bb = filesize2num(getInnerText(b.cells[that.col]));

                return compareNumber(bb, aa);
            };

            // Sort dot separated numbers, e.g. ip addresses or version numbers
            if (items.every(testDotSeparatedNumbers)) {
                sortFunction = sortDotSep;
            }
            // sort filesize, e.g. "123.45 MB"
            else if (items.every(testFilesize)) {
                sortFunction = sortFilesize;
            }
            // Sort as number if a currency key exists or number
            else if (items.every(testNumber)) {
                sortFunction = sortNumber;
            } else if (items.every(testDate)) {
                sortFunction = sortDate;
            } else {
                sortFunction = sortCaseInsensitive;
            }

            this.col = column;
            var newRows = [],
                noSorts = {},
                j,
                totalRows = 0;

            for (i = 0; i < t.tBodies.length; i++) {
                for (j = 0; j < t.tBodies[i].rows.length; j++) {
                    var tr = t.tBodies[i].rows[j];
                    if (tr.classList.contains('no-sort')) {
                        // keep no-sorts in separate list to be able to insert
                        // them back at their original position later
                        noSorts[totalRows] = tr;
                    } else {
                        // Save the index for stable sorting
                        newRows.push({
                            tr: tr,
                            index: totalRows
                        });
                    }
                    totalRows++;
                }
            }

            var sortDir;
            if (header.classList.contains(classSortUp)) sortDir = classSortDown;
            else if (header.classList.contains(classSortDown)) sortDir = classSortUp;
            else sortDir = that.options.descending ? classSortUp : classSortDown;
            header.classList.remove(classSortUp);
            header.classList.remove(classSortDown);
            header.classList.add(sortDir);

            // Make a stable sort function
            var stabilize = function(sort) {
                return function(a, b) {
                    var unstableResult = sort(a.tr, b.tr);
                    if (unstableResult === 0) {
                        return a.index - b.index;
                    }
                    return unstableResult;
                };
            };

            // Make an `anti-stable` sort function. If two elements are equal
            // under the original sort function, then there relative order is
            // reversed.
            var antiStabilize = function(sort) {
                return function(a, b) {
                    var unstableResult = sort(a.tr, b.tr);
                    if (unstableResult === 0) {
                        return b.index - a.index;
                    }
                    return unstableResult;
                };
            };

            // Before we append should we reverse the new array or not?
            // If we reverse, the sort needs to be `anti-stable` so that
            // the double negatives cancel out
            if (sortDir === classSortDown) {
                newRows.sort(antiStabilize(sortFunction));
                newRows.reverse();
            } else {
                newRows.sort(stabilize(sortFunction));
            }

            // append rows that already exist rather than creating new ones
            var noSortsSoFar = 0;
            for (i = 0; i < totalRows; i++) {
                var whatToInsert;
                if (noSorts[i]) {
                    // We have a no-sort row for this position, insert it here.
                    whatToInsert = noSorts[i];
                    noSortsSoFar++;
                } else {
                    whatToInsert = newRows[i - noSortsSoFar].tr;
                }
                // appendChild(x) moves x if already present somewhere else in the DOM
                t.tBodies[0].appendChild(whatToInsert);
            }
            // callback
            if (that.options.callback && typeof that.options.callback === 'function') {
                that.options.callback(header);
            }
        },

        refresh: function() {
            if (this.current !== undefined) {
                this.sortTable(this.current);
            }
        }
    };

    var classSortUp   = 'sort-up',
        classSortDown = 'sort-down';

    var week       = /(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\.?\,?\s*/i,
        commonDate = /\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/,
        month      = /(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/i;

    var testDotSeparatedNumbers = function(item){
        return /^(\d+\.)+\d+$/.test(item);
    };

    var testFilesize = function(item){
        return /^\d+(\.\d+)? ?(k|M|G|T|P|E|Z|Y)?i?B?$/i.test(item);
    };

    var testNumber = function(item){
        return item.match(/^-?[£\x24Û¢´€]?\d+\s*([,\.]\d{0,2})/) || // prefixed currency
               item.match(/^-?\d+\s*([,\.]\d{0,2})?[£\x24Û¢´€]/) || // suffixed currency
               item.match(/^-?(\d)*-?([,\.]){0,1}-?(\d)+([E,e][\-+][\d]+)?%?$/); // number
    };

    var testDate = function(date) {
            return (
                date.search(week) !== -1 ||
                date.search(commonDate) !== -1  ||
                date.search(month !== -1)
            ) !== -1 && !isNaN(parseDate(date));
        },

        parseDate = function(date) {
            date = date.replace(/\-/g, '/');
            date = date.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/, '$1/$2/$3'); // format before getTime
            return new Date(date).getTime();
        },

        getParent = function(el, pTagName) {
            if (el === null) {
                return null;
            } else if (el.nodeType === 1 && el.tagName.toLowerCase() === pTagName.toLowerCase()) {
                return el;
            } else {
                return getParent(el.parentNode, pTagName);
            }
        },

        getInnerText = function(el) {
            if (typeof el === 'string' || typeof el === 'undefined') return el;

            return el.getAttribute('data-sort') || el.textContent || el.innerText || '';
        },

        compareNumber = function(a, b) {
            var aa = parseFloat(a),
                bb = parseFloat(b);

            a = isNaN(aa) ? 0 : aa;
            b = isNaN(bb) ? 0 : bb;
            return a - b;
        },

        cleanNumber = function(i) {
            return i.replace(/[^\-?0-9.]/g, '');
        },

        // Converts filesize to bytes
        // Ex. filesize2num("123 KB") -> 123000
        // Ex. filesize2num("123 KiB") -> 125952
        filesize2num = function(filesize) {
            var matches = filesize.match(/^(\d+(\.\d+)?) ?((k|M|G|T|P|E|Z|Y)?i?B?)$/i);

            var num    = parseFloat(cleanNumber(matches[1])),
                suffix = matches[3];

            return num * suffix2num(suffix);
        },

        // Returns suffix multiplier
        // Ex. suffix2num("KB") -> 1000
        // Ex. suffix2num("KiB") -> 1024
        suffix2num = function(suffix) {
            suffix = suffix.toLowerCase();
            var base = suffix[1] === "i" ? 1024 : 1000;

            switch(suffix[0]) {
                case "k":
                    return Math.pow(base, 2);
                case "m":
                    return Math.pow(base, 3);
                case "g":
                    return Math.pow(base, 4);
                case "t":
                    return Math.pow(base, 5);
                case "p":
                    return Math.pow(base, 6);
                case "e":
                    return Math.pow(base, 7);
                case "z":
                    return Math.pow(base, 8);
                case "y":
                    return Math.pow(base, 9);
                default:
                    return base;
            }
        };

    if (typeof module !== 'undefined' && module.exports) {
        module.exports = Tablesort;
    } else {
        window.Tablesort = Tablesort;
    }
})();
<commit_msg>Instead of searching for table element, simply store it<commit_after>;(function() {
    function Tablesort(el, options) {
        if (!el) throw new Error('Element not found');
        if (el.tagName !== 'TABLE') throw new Error('Element must be a table');
        this.init(el, options || {});
    }

    Tablesort.prototype = {

        init: function(el, options) {
            var that = this,
                firstRow;
            this.table = el;
            this.thead = false;
            this.options = options;

            if (el.rows && el.rows.length > 0) {
                if (el.tHead && el.tHead.rows.length > 0) {
                    firstRow = el.tHead.rows[el.tHead.rows.length - 1];
                    that.thead = true;
                } else {
                    firstRow = el.rows[0];
                }
            }

            if (!firstRow) return;

            var onClick = function() {
                if (that.current && that.current !== this) {
                    that.current.classList.remove(classSortUp);
                    that.current.classList.remove(classSortDown);
                }

                that.current = this;
                that.sortTable(this);
            };

            var defaultSort;

            // Assume first row is the header and attach a click handler to each.
            for (var i = 0; i < firstRow.cells.length; i++) {
                var cell = firstRow.cells[i];
                if (!cell.classList.contains('no-sort')) {
                    cell.classList.add('sort-header');
                    cell.addEventListener('click', onClick, false);

                    if (cell.classList.contains('sort-default')) {
                        defaultSort = cell;
                    }
                }
            }

            if (defaultSort) {
                that.current = defaultSort;
                that.sortTable(defaultSort);
            }
        },

        getFirstDataRowIndex: function() {
            // If table does not have a <thead>, assume that first row is
            // a header and skip it.
            if (!this.thead) {
                return 1;
            } else {
                return 0;
            }
        },

        sortTable: function(header) {
            var that = this,
                column = header.cellIndex,
                sortFunction,
                t = this.table,
                item = '',
                items = [],
                i = that.getFirstDataRowIndex();

            if (t.rows.length <= 1) return;

            while (items.length < 3 && i < t.tBodies[0].rows.length) {
                item = getInnerText(t.tBodies[0].rows[i].cells[column]);
                item = item.trim();
                // Exclude cell values where commented out HTML exists
                if (item.substr(0, 4) !== '<!--' && item.length !== 0) {
                    items.push(item);
                }
                i++;
            }

            if (!items) return;

            // Possible sortFunction scenarios
            var sortCaseInsensitive = function(a, b) {
                var aa = getInnerText(a.cells[that.col]).toLowerCase(),
                    bb = getInnerText(b.cells[that.col]).toLowerCase();

                if (aa === bb) return 0;
                if (aa < bb) return 1;

                return -1;
            };

            var sortNumber = function(a, b) {
                var aa = getInnerText(a.cells[that.col]),
                    bb = getInnerText(b.cells[that.col]);

                aa = cleanNumber(aa);
                bb = cleanNumber(bb);
                return compareNumber(bb, aa);
            };

            var sortDate = function(a, b) {
                var aa = getInnerText(a.cells[that.col]).toLowerCase(),
                    bb = getInnerText(b.cells[that.col]).toLowerCase();
                return parseDate(bb) - parseDate(aa);
            };

            var sortDotSep = function(a, b) {
                var aa = getInnerText(a.cells[that.col]).split('.'),
                    bb = getInnerText(b.cells[that.col]).split('.');

                for (var i = 0, len = aa.length; i < len; i++) {
                    var aai = parseInt(aa[i]),
                        bbi = parseInt(bb[i]);

                    if (aai == bbi) continue;
                    if (aai > bbi) return -1;
                    if (aai < bbi) return 1;
                }
                return 0;
            };

            var sortFilesize = function(a, b) {
                var aa = filesize2num(getInnerText(a.cells[that.col])),
                    bb = filesize2num(getInnerText(b.cells[that.col]));

                return compareNumber(bb, aa);
            };

            // Sort dot separated numbers, e.g. ip addresses or version numbers
            if (items.every(testDotSeparatedNumbers)) {
                sortFunction = sortDotSep;
            }
            // sort filesize, e.g. "123.45 MB"
            else if (items.every(testFilesize)) {
                sortFunction = sortFilesize;
            }
            // Sort as number if a currency key exists or number
            else if (items.every(testNumber)) {
                sortFunction = sortNumber;
            } else if (items.every(testDate)) {
                sortFunction = sortDate;
            } else {
                sortFunction = sortCaseInsensitive;
            }

            this.col = column;
            var newRows = [],
                noSorts = {},
                j,
                totalRows = 0;

            for (i = 0; i < t.tBodies.length; i++) {
                for (j = 0; j < t.tBodies[i].rows.length; j++) {
                    var tr = t.tBodies[i].rows[j];
                    if (tr.classList.contains('no-sort')) {
                        // keep no-sorts in separate list to be able to insert
                        // them back at their original position later
                        noSorts[totalRows] = tr;
                    } else {
                        // Save the index for stable sorting
                        newRows.push({
                            tr: tr,
                            index: totalRows
                        });
                    }
                    totalRows++;
                }
            }

            var sortDir;
            if (header.classList.contains(classSortUp)) sortDir = classSortDown;
            else if (header.classList.contains(classSortDown)) sortDir = classSortUp;
            else sortDir = that.options.descending ? classSortUp : classSortDown;
            header.classList.remove(classSortUp);
            header.classList.remove(classSortDown);
            header.classList.add(sortDir);

            // Make a stable sort function
            var stabilize = function(sort) {
                return function(a, b) {
                    var unstableResult = sort(a.tr, b.tr);
                    if (unstableResult === 0) {
                        return a.index - b.index;
                    }
                    return unstableResult;
                };
            };

            // Make an `anti-stable` sort function. If two elements are equal
            // under the original sort function, then there relative order is
            // reversed.
            var antiStabilize = function(sort) {
                return function(a, b) {
                    var unstableResult = sort(a.tr, b.tr);
                    if (unstableResult === 0) {
                        return b.index - a.index;
                    }
                    return unstableResult;
                };
            };

            // Before we append should we reverse the new array or not?
            // If we reverse, the sort needs to be `anti-stable` so that
            // the double negatives cancel out
            if (sortDir === classSortDown) {
                newRows.sort(antiStabilize(sortFunction));
                newRows.reverse();
            } else {
                newRows.sort(stabilize(sortFunction));
            }

            // append rows that already exist rather than creating new ones
            var noSortsSoFar = 0;
            for (i = 0; i < totalRows; i++) {
                var whatToInsert;
                if (noSorts[i]) {
                    // We have a no-sort row for this position, insert it here.
                    whatToInsert = noSorts[i];
                    noSortsSoFar++;
                } else {
                    whatToInsert = newRows[i - noSortsSoFar].tr;
                }
                // appendChild(x) moves x if already present somewhere else in the DOM
                t.tBodies[0].appendChild(whatToInsert);
            }
            // callback
            if (that.options.callback && typeof that.options.callback === 'function') {
                that.options.callback(header);
            }
        },

        refresh: function() {
            if (this.current !== undefined) {
                this.sortTable(this.current);
            }
        }
    };

    var classSortUp   = 'sort-up',
        classSortDown = 'sort-down';

    var week       = /(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\.?\,?\s*/i,
        commonDate = /\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/,
        month      = /(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/i;

    var testDotSeparatedNumbers = function(item){
        return /^(\d+\.)+\d+$/.test(item);
    };

    var testFilesize = function(item){
        return /^\d+(\.\d+)? ?(k|M|G|T|P|E|Z|Y)?i?B?$/i.test(item);
    };

    var testNumber = function(item){
        return item.match(/^-?[£\x24Û¢´€]?\d+\s*([,\.]\d{0,2})/) || // prefixed currency
               item.match(/^-?\d+\s*([,\.]\d{0,2})?[£\x24Û¢´€]/) || // suffixed currency
               item.match(/^-?(\d)*-?([,\.]){0,1}-?(\d)+([E,e][\-+][\d]+)?%?$/); // number
    };

    var testDate = function(date) {
            return (
                date.search(week) !== -1 ||
                date.search(commonDate) !== -1  ||
                date.search(month !== -1)
            ) !== -1 && !isNaN(parseDate(date));
        },

        parseDate = function(date) {
            date = date.replace(/\-/g, '/');
            date = date.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/, '$1/$2/$3'); // format before getTime
            return new Date(date).getTime();
        },

        getInnerText = function(el) {
            if (typeof el === 'string' || typeof el === 'undefined') return el;

            return el.getAttribute('data-sort') || el.textContent || el.innerText || '';
        },

        compareNumber = function(a, b) {
            var aa = parseFloat(a),
                bb = parseFloat(b);

            a = isNaN(aa) ? 0 : aa;
            b = isNaN(bb) ? 0 : bb;
            return a - b;
        },

        cleanNumber = function(i) {
            return i.replace(/[^\-?0-9.]/g, '');
        },

        // Converts filesize to bytes
        // Ex. filesize2num("123 KB") -> 123000
        // Ex. filesize2num("123 KiB") -> 125952
        filesize2num = function(filesize) {
            var matches = filesize.match(/^(\d+(\.\d+)?) ?((k|M|G|T|P|E|Z|Y)?i?B?)$/i);

            var num    = parseFloat(cleanNumber(matches[1])),
                suffix = matches[3];

            return num * suffix2num(suffix);
        },

        // Returns suffix multiplier
        // Ex. suffix2num("KB") -> 1000
        // Ex. suffix2num("KiB") -> 1024
        suffix2num = function(suffix) {
            suffix = suffix.toLowerCase();
            var base = suffix[1] === "i" ? 1024 : 1000;

            switch(suffix[0]) {
                case "k":
                    return Math.pow(base, 2);
                case "m":
                    return Math.pow(base, 3);
                case "g":
                    return Math.pow(base, 4);
                case "t":
                    return Math.pow(base, 5);
                case "p":
                    return Math.pow(base, 6);
                case "e":
                    return Math.pow(base, 7);
                case "z":
                    return Math.pow(base, 8);
                case "y":
                    return Math.pow(base, 9);
                default:
                    return base;
            }
        };

    if (typeof module !== 'undefined' && module.exports) {
        module.exports = Tablesort;
    } else {
        window.Tablesort = Tablesort;
    }
})();
<|endoftext|>


<commit_before>/**
 * Class constructor for Tabs WSK component.
 * Implements WSK component design pattern defined at:
 * https://github.com/jasonmayes/wsk-component-design-pattern
 * @param {HTMLElement} element The element that will be upgraded.
 */
function MaterialTabs(element) {
  'use strict';

  // Stores the HTML element.
  this.element_ = element;

  // Initialize instance.
  this.init();
}

/**
 * Store constants in one place so they can be updated easily.
 * @enum {string}
 * @private
 */
MaterialTabs.prototype.Constant_ = {
  // None at the moment.
};

/**
 * Store strings for class names defined by this component that are used in
 * JavaScript. This allows us to simply change it in one place should we
 * decide to modify at a later date.
 * @enum {string}
 * @private
 */
MaterialTabs.prototype.CssClasses_ = {
  TAB_CLASS: 'wsk-tabs__tab',
  PANEL_CLASS: 'wsk-tabs__panel',
  ACTIVE_CLASS: 'is-active',
  UPGRADED_CLASS: 'is-upgraded',

  WSK_JS_RIPPLE_EFFECT: 'wsk-js-ripple-effect',
  WSK_RIPPLE_CONTAINER: 'wsk-tabs__ripple-container',
  WSK_RIPPLE: 'wsk-ripple',
  WSK_JS_RIPPLE_EFFECT_IGNORE_EVENTS: 'wsk-js-ripple-effect--ignore-events'
};

/**
 * Handle clicks to a tabs component
 * @private
 */
MaterialTabs.prototype.initTabs_ = function(e) {
  'use strict';

  if (this.element_.classList.contains(this.CssClasses_.WSK_JS_RIPPLE_EFFECT)) {
    this.element_.classList.add(
      this.CssClasses_.WSK_JS_RIPPLE_EFFECT_IGNORE_EVENTS);
  }

  // Select element tabs, document panels
  this.tabs_ = this.element_.querySelectorAll('.' + this.CssClasses_.TAB_CLASS);
  this.panels_ =
      this.element_.querySelectorAll('.' + this.CssClasses_.PANEL_CLASS);

  // Create new tabs for each tab element
  for (var i = 0; i < this.tabs_.length; i++) {
    new MaterialTab(this.tabs_[i], this);
  }

  this.element_.classList.add(this.CssClasses_.UPGRADED_CLASS);
};

/**
 * Reset tab state, dropping active classes
 * @private
 */
MaterialTabs.prototype.resetTabState_ = function() {
  'use strict';

  for (var k = 0; k < this.tabs_.length; k++) {
    this.tabs_[k].classList.remove(this.CssClasses_.ACTIVE_CLASS);
  }
};

/**
 * Reset panel state, droping active classes
 * @private
 */
MaterialTabs.prototype.resetPanelState_ = function() {
  'use strict';

  for (var j = 0; j < this.panels_.length; j++) {
    this.panels_[j].classList.remove(this.CssClasses_.ACTIVE_CLASS);
  }
};

MaterialTabs.prototype.init = function() {
  'use strict';

  if (this.element_) {
    this.initTabs_();
  }
};

function MaterialTab(tab, ctx) {
  'use strict';

  if (tab) {
    if (ctx.element_.classList.contains(ctx.CssClasses_.WSK_JS_RIPPLE_EFFECT)) {
      var rippleContainer = document.createElement('span');
      rippleContainer.classList.add(ctx.CssClasses_.WSK_RIPPLE_CONTAINER);
      rippleContainer.classList.add(ctx.CssClasses_.WSK_JS_RIPPLE_EFFECT);
      var ripple = document.createElement('span');
      ripple.classList.add(ctx.CssClasses_.WSK_RIPPLE);
      rippleContainer.appendChild(ripple);
      tab.appendChild(rippleContainer);
    }

    tab.addEventListener('click', function(e) {
      e.preventDefault();
      var href = tab.href.split('#')[1];
      var panel = document.querySelector('#' + href);
      ctx.resetTabState_();
      ctx.resetPanelState_();
      tab.classList.add(ctx.CssClasses_.ACTIVE_CLASS);
      panel.classList.add(ctx.CssClasses_.ACTIVE_CLASS);
    });

  }
}

// The component registers itself. It can assume componentHandler is available
// in the global scope.
componentHandler.register({
  constructor: MaterialTabs,
  classAsString: 'MaterialTabs',
  cssClass: 'wsk-js-tabs'
});
<commit_msg>Don't rely on global querySelector() for MaterialTabs<commit_after>/**
 * Class constructor for Tabs WSK component.
 * Implements WSK component design pattern defined at:
 * https://github.com/jasonmayes/wsk-component-design-pattern
 * @param {HTMLElement} element The element that will be upgraded.
 */
function MaterialTabs(element) {
  'use strict';

  // Stores the HTML element.
  this.element_ = element;

  // Initialize instance.
  this.init();
}

/**
 * Store constants in one place so they can be updated easily.
 * @enum {string}
 * @private
 */
MaterialTabs.prototype.Constant_ = {
  // None at the moment.
};

/**
 * Store strings for class names defined by this component that are used in
 * JavaScript. This allows us to simply change it in one place should we
 * decide to modify at a later date.
 * @enum {string}
 * @private
 */
MaterialTabs.prototype.CssClasses_ = {
  TAB_CLASS: 'wsk-tabs__tab',
  PANEL_CLASS: 'wsk-tabs__panel',
  ACTIVE_CLASS: 'is-active',
  UPGRADED_CLASS: 'is-upgraded',

  WSK_JS_RIPPLE_EFFECT: 'wsk-js-ripple-effect',
  WSK_RIPPLE_CONTAINER: 'wsk-tabs__ripple-container',
  WSK_RIPPLE: 'wsk-ripple',
  WSK_JS_RIPPLE_EFFECT_IGNORE_EVENTS: 'wsk-js-ripple-effect--ignore-events'
};

/**
 * Handle clicks to a tabs component
 * @private
 */
MaterialTabs.prototype.initTabs_ = function(e) {
  'use strict';

  if (this.element_.classList.contains(this.CssClasses_.WSK_JS_RIPPLE_EFFECT)) {
    this.element_.classList.add(
      this.CssClasses_.WSK_JS_RIPPLE_EFFECT_IGNORE_EVENTS);
  }

  // Select element tabs, document panels
  this.tabs_ = this.element_.querySelectorAll('.' + this.CssClasses_.TAB_CLASS);
  this.panels_ =
      this.element_.querySelectorAll('.' + this.CssClasses_.PANEL_CLASS);

  // Create new tabs for each tab element
  for (var i = 0; i < this.tabs_.length; i++) {
    new MaterialTab(this.tabs_[i], this);
  }

  this.element_.classList.add(this.CssClasses_.UPGRADED_CLASS);
};

/**
 * Reset tab state, dropping active classes
 * @private
 */
MaterialTabs.prototype.resetTabState_ = function() {
  'use strict';

  for (var k = 0; k < this.tabs_.length; k++) {
    this.tabs_[k].classList.remove(this.CssClasses_.ACTIVE_CLASS);
  }
};

/**
 * Reset panel state, droping active classes
 * @private
 */
MaterialTabs.prototype.resetPanelState_ = function() {
  'use strict';

  for (var j = 0; j < this.panels_.length; j++) {
    this.panels_[j].classList.remove(this.CssClasses_.ACTIVE_CLASS);
  }
};

MaterialTabs.prototype.init = function() {
  'use strict';

  if (this.element_) {
    this.initTabs_();
  }
};

function MaterialTab(tab, ctx) {
  'use strict';

  if (tab) {
    if (ctx.element_.classList.contains(ctx.CssClasses_.WSK_JS_RIPPLE_EFFECT)) {
      var rippleContainer = document.createElement('span');
      rippleContainer.classList.add(ctx.CssClasses_.WSK_RIPPLE_CONTAINER);
      rippleContainer.classList.add(ctx.CssClasses_.WSK_JS_RIPPLE_EFFECT);
      var ripple = document.createElement('span');
      ripple.classList.add(ctx.CssClasses_.WSK_RIPPLE);
      rippleContainer.appendChild(ripple);
      tab.appendChild(rippleContainer);
    }

    tab.addEventListener('click', function(e) {
      e.preventDefault();
      var href = tab.href.split('#')[1];
      var panel = ctx.element_.querySelector('#' + href);
      ctx.resetTabState_();
      ctx.resetPanelState_();
      tab.classList.add(ctx.CssClasses_.ACTIVE_CLASS);
      panel.classList.add(ctx.CssClasses_.ACTIVE_CLASS);
    });

  }
}

// The component registers itself. It can assume componentHandler is available
// in the global scope.
componentHandler.register({
  constructor: MaterialTabs,
  classAsString: 'MaterialTabs',
  cssClass: 'wsk-js-tabs'
});
<|endoftext|>


<commit_before>//still testing github settings<commit_msg>add Day in year, Day in month and Day of week in month functions<commit_after>(function() {

	Date.prototype.format = function(format) {
		var pattern = '',
			returnValue = '',
			count = 0;

		for(var i = 0; i < format.length; i++) {
			var currentPattern = format.charAt(i);
            var nextPattern = format.charAt(i + 1);

            pattern += currentPattern;
            switch (pattern) {
            	case 'd':
            		count++;
	            	if(nextPattern === 'd') {
	            		if (this.getDate() < 10) {
	            			if (count >= 1) {
	            				returnValue += '0';
	            			}
	            		} else {
	            			if (count > 1) {
	            				returnValue += '0';
	            			}
	            		}
	            		pattern = '';
	            		break;
	            	}
	            	returnValue += this.getDate();
	            	pattern = '';
	            	break;
	            case 'D':
		            var start = new Date(this.getFullYear(), 0, 0);
		            var diff = this - start;
		            var oneDay = 1000 * 60 * 60 * 24;
	            	returnValue += Math.ceil(diff / oneDay);
	            	pattern = '';
	            	break;
	            case 'F':
	            	count++;
	            	if(nextPattern === 'F') {
	            		if (count >= 1) {
	            			returnValue += '0';
	            		}
	            		pattern = '';
	            		break;
	            	}
	            	var d = new Date(this.valueOf()),
	            		dayOfWeekInMonth = 0,
	            		month = this.getMonth();

	            	while (d.getMonth() === month) {
	            		dayOfWeekInMonth++;
	            		d.setDate(d.getDate() - 7);
	            	}

	            	returnValue += dayOfWeekInMonth;
	            	pattern = '';
	            	break;
            	default:
	            	returnValue += currentPattern;
	            	pattern = '';
	            	break;
            }
        }
        return returnValue;
    };

}).call(this);<|endoftext|>


<commit_before>module.exports = (dato, root, i18n) => {

  // inside the "post" directory...
  root.directory("site/content/post", (dir) => {

    // ...iterate over the "post" records...
    dato.posts.forEach(post => {

      // ...and create a markdown file for each article!
      dir.createPost(`${post.slug}.md`, "yaml", {
        frontmatter: {
          draft: post.draft,
          title: post.title,
          subtitle: post.subtitle,
          author: post.author.firstName,
          author_image: post.author.profilePicture.url(),
          author_id: post.author.id,
          type: "post",
          tags: post.tag.map(tag => tag.slug),
          category: post.category.name,
          date: post.date,
          country: {
              name: post.country.name,
              code: post.country.countryCode,
              continent: post.country.continent.name
          },
          feature_image: post.featureImage.url(),
          intro: post.introBlock,
          content: post.contentContainer.toMap()
        },
        content: post.content
      });
    });
  });
}
<commit_msg>Fix length counts<commit_after>module.exports = (dato, root, i18n) => {

  // inside the "post" directory...
  root.directory("site/content/post", (dir) => {

    // ...iterate over the "post" records...
    dato.posts.forEach(post => {

      const onlyContent = post.contentContainer.toMap().filter((container) => container.content).map(container => container.content);

      // ...and create a markdown file for each article!
      dir.createPost(`${post.slug}.md`, "yaml", {
        frontmatter: {
          draft: post.draft,
          title: post.title,
          subtitle: post.subtitle,
          author: post.author.firstName,
          author_image: post.author.profilePicture.url(),
          author_id: post.author.id,
          type: "post",
          tags: post.tag.map(tag => tag.slug),
          category: post.category.name,
          date: post.date,
          country: {
              name: post.country.name,
              code: post.country.countryCode,
              continent: post.country.continent.name
          },
          feature_image: post.featureImage.url(),
          intro: post.introBlock,
          content: post.contentContainer.toMap()
        },
        content: onlyContent
      });
    });
  });
}
<|endoftext|>


<commit_before>/*
 * Copyright 2020 Google LLC
 *
 * 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
 *
 *     https://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.
 */

/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';

export const DEFAULT_STORY_PAGE_ADVANCE_DURATION = 2000;

export const STORY_CONTEXT_MENU_ACTIONS = {
  OPEN_IN_EDITOR: 'open-in-editor-action',
  PREVIEW: 'preview-action',
  RENAME: 'rename-action',
  DUPLICATE: 'duplicate-action',
  CREATE_TEMPLATE: 'create-template-action',
  DELETE: 'delete-story-action',
};

export const STORY_CONTEXT_MENU_ITEMS = [
  {
    label: __('Open in editor', 'web-stories'),
    value: STORY_CONTEXT_MENU_ACTIONS.OPEN_IN_EDITOR,
  },
  {
    label: __('Preview', 'web-stories'),
    value: STORY_CONTEXT_MENU_ACTIONS.PREVIEW,
    inProgress: true,
  },
  { label: null, value: false, separator: true },
  {
    label: __('Rename', 'web-stories'),
    value: STORY_CONTEXT_MENU_ACTIONS.RENAME,
  },
  {
    label: __('Duplicate', 'web-stories'),
    value: STORY_CONTEXT_MENU_ACTIONS.DUPLICATE,
  },
  {
    label: __('Create Template', 'web-stories'),
    value: STORY_CONTEXT_MENU_ACTIONS.CREATE_TEMPLATE,
    inProgress: true,
  },
  { label: null, value: false, separator: true },
  {
    label: __('Delete Story', 'web-stories'),
    value: STORY_CONTEXT_MENU_ACTIONS.DELETE,
  },
];

export const SORT_DIRECTION = {
  ASC: 'asc',
  DESC: 'desc',
};

export const STORY_SORT_OPTIONS = {
  NAME: 'title',
  DATE_CREATED: 'date',
  LAST_MODIFIED: 'modified',
  CREATED_BY: 'story_author',
};

export const ORDER_BY_SORT = {
  [STORY_SORT_OPTIONS.NAME]: SORT_DIRECTION.ASC,
  [STORY_SORT_OPTIONS.DATE_CREATED]: SORT_DIRECTION.DESC,
  [STORY_SORT_OPTIONS.LAST_MODIFIED]: SORT_DIRECTION.DESC,
  [STORY_SORT_OPTIONS.CREATED_BY]: SORT_DIRECTION.ASC,
};

export const STORY_SORT_MENU_ITEMS = [
  {
    label: __('Name', 'web-stories'),
    value: STORY_SORT_OPTIONS.NAME,
  },
  {
    label: __('Date created', 'web-stories'),
    value: STORY_SORT_OPTIONS.DATE_CREATED,
  },
  {
    label: __('Last modified', 'web-stories'), // default
    value: STORY_SORT_OPTIONS.LAST_MODIFIED,
  },
  {
    label: __('Created by', 'web-stories'),
    value: STORY_SORT_OPTIONS.CREATED_BY,
  },
];

export const STORY_STATUS = {
  ALL: 'publish,draft,future',
  PUBLISHED_AND_FUTURE: 'publish,future',
  DRAFT: 'draft',
  FUTURE: 'future',
  PUBLISH: 'publish',
};

export const STORY_ITEM_CENTER_ACTION_LABELS = {
  [STORY_STATUS.PUBLISH]: __('View', 'web-stories'),
  [STORY_STATUS.FUTURE]: __('View', 'web-stories'),
  [STORY_STATUS.DRAFT]: __('Preview', 'web-stories'),
};

export const STORY_STATUSES = [
  {
    label: __('All Stories', 'web-stories'),
    value: STORY_STATUS.ALL,
    status: 'all',
  },
  {
    label: __('Drafts', 'web-stories'),
    value: STORY_STATUS.DRAFT,
    status: STORY_STATUS.DRAFT,
  },
  {
    label: __('Published', 'web-stories'),
    value: `${STORY_STATUS.PUBLISH},${STORY_STATUS.FUTURE}`,
    status: STORY_STATUS.PUBLISHED_AND_FUTURE,
  },
];

export const STORY_VIEWING_LABELS = {
  [STORY_STATUS.ALL]: __('Viewing all stories', 'web-stories'),
  [STORY_STATUS.DRAFT]: __('Viewing drafts', 'web-stories'),
  [STORY_STATUS.PUBLISHED_AND_FUTURE]: __(
    'Viewing published stories',
    'web-stories'
  ),
};

export const STORY_PAGE_STATE = {
  RESET: 'reset',
  PAUSED: 'paused',
  SCRUBBING: 'scrubbing',
  PLAYING: 'playing',
};
<commit_msg>Update assets/src/dashboard/constants/stories.js<commit_after>/*
 * Copyright 2020 Google LLC
 *
 * 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
 *
 *     https://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.
 */

/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';

export const DEFAULT_STORY_PAGE_ADVANCE_DURATION = 2000;

export const STORY_CONTEXT_MENU_ACTIONS = {
  OPEN_IN_EDITOR: 'open-in-editor-action',
  PREVIEW: 'preview-action',
  RENAME: 'rename-action',
  DUPLICATE: 'duplicate-action',
  CREATE_TEMPLATE: 'create-template-action',
  DELETE: 'delete-story-action',
};

export const STORY_CONTEXT_MENU_ITEMS = [
  {
    label: __('Open in editor', 'web-stories'),
    value: STORY_CONTEXT_MENU_ACTIONS.OPEN_IN_EDITOR,
  },
  {
    label: __('Preview', 'web-stories'),
    value: STORY_CONTEXT_MENU_ACTIONS.PREVIEW,
    inProgress: true,
  },
  { label: null, value: false, separator: true },
  {
    label: __('Rename', 'web-stories'),
    value: STORY_CONTEXT_MENU_ACTIONS.RENAME,
  },
  {
    label: __('Duplicate', 'web-stories'),
    value: STORY_CONTEXT_MENU_ACTIONS.DUPLICATE,
  },
  {
    label: __('Create Template', 'web-stories'),
    value: STORY_CONTEXT_MENU_ACTIONS.CREATE_TEMPLATE,
    inProgress: true,
  },
  { label: null, value: false, separator: true },
  {
    label: __('Delete Story', 'web-stories'),
    value: STORY_CONTEXT_MENU_ACTIONS.DELETE,
  },
];

export const SORT_DIRECTION = {
  ASC: 'asc',
  DESC: 'desc',
};

export const STORY_SORT_OPTIONS = {
  NAME: 'title',
  DATE_CREATED: 'date',
  LAST_MODIFIED: 'modified',
  CREATED_BY: 'story_author',
};

export const ORDER_BY_SORT = {
  [STORY_SORT_OPTIONS.NAME]: SORT_DIRECTION.ASC,
  [STORY_SORT_OPTIONS.DATE_CREATED]: SORT_DIRECTION.DESC,
  [STORY_SORT_OPTIONS.LAST_MODIFIED]: SORT_DIRECTION.DESC,
  [STORY_SORT_OPTIONS.CREATED_BY]: SORT_DIRECTION.ASC,
};

export const STORY_SORT_MENU_ITEMS = [
  {
    label: __('Name', 'web-stories'),
    value: STORY_SORT_OPTIONS.NAME,
  },
  {
    label: __('Date created', 'web-stories'),
    value: STORY_SORT_OPTIONS.DATE_CREATED,
  },
  {
    label: __('Last modified', 'web-stories'), // default
    value: STORY_SORT_OPTIONS.LAST_MODIFIED,
  },
  {
    label: __('Created by', 'web-stories'),
    value: STORY_SORT_OPTIONS.CREATED_BY,
  },
];

export const STORY_STATUS = {
  ALL: 'publish,draft,future',
  PUBLISHED_AND_FUTURE: 'publish,future',
  DRAFT: 'draft',
  FUTURE: 'future',
  PUBLISH: 'publish',
};

export const STORY_ITEM_CENTER_ACTION_LABELS = {
  [STORY_STATUS.PUBLISH]: __('View', 'web-stories'),
  [STORY_STATUS.FUTURE]: __('View', 'web-stories'),
  [STORY_STATUS.DRAFT]: __('Preview', 'web-stories'),
};

export const STORY_STATUSES = [
  {
    label: __('All Stories', 'web-stories'),
    value: STORY_STATUS.ALL,
    status: 'all',
  },
  {
    label: __('Drafts', 'web-stories'),
    value: STORY_STATUS.DRAFT,
    status: STORY_STATUS.DRAFT,
  },
  {
    label: __('Published', 'web-stories'),
    value: PUBLISHED_AND_FUTURE,
    status: STORY_STATUS.PUBLISHED_AND_FUTURE,
  },
];

export const STORY_VIEWING_LABELS = {
  [STORY_STATUS.ALL]: __('Viewing all stories', 'web-stories'),
  [STORY_STATUS.DRAFT]: __('Viewing drafts', 'web-stories'),
  [STORY_STATUS.PUBLISHED_AND_FUTURE]: __(
    'Viewing published stories',
    'web-stories'
  ),
};

export const STORY_PAGE_STATE = {
  RESET: 'reset',
  PAUSED: 'paused',
  SCRUBBING: 'scrubbing',
  PLAYING: 'playing',
};
<|endoftext|>


<commit_before>$.define("flow","flow,more/spec",function(){
    $.fixture('操作流模块-flow', {
        flow: function(id){
            var flow = new $.flow;
            var callback = function(a,b,c){
                $.log([].slice.call(arguments))
                expect([].slice.call(arguments),id).same([10,20,30])//测试多路监听时收集的返回值
                expect("此流程触发在aaa,bbb,ccc都被fire的情况下",id).eq("此流程触发在aaa,bbb,ccc都被fire的情况下")
            }
            var callback2 = function(a,b,c){
                $.log([].slice.call(arguments))
                expect("此流程触发在aaa,ddd都被fire的情况下",id).eq("此流程触发在aaa,ddd都被fire的情况下")
            }
            flow.bind("aaa,bbb,ccc",callback,false);
            flow.bind("aaa,ddd",callback2,true);
            // $.log(callback.deps)
            expect(callback.deps).same({
                __aaa:1,
                __bbb:1,
                __ccc:1
            });
            // $.log(callback.args)
            expect(callback.args).same(["__aaa", "__bbb", "__ccc"]);//必须这三个事件都被fire才执行callback
            // $.log(callback.reloadAll)
            expect(callback.reloadAll).eq(true);
            //  $.log(flow.root["__aaa"])
            expect(flow.root["__aaa"].unfire.length).eq(2);//__aaa这个事件未绑定的回调已达两个
            flow.fire("aaa",10)
            flow.fire("bbb",20)
            flow.fire("ccc",30);
             flow.fire("aaa",40);
              flow.fire("bbb",20)
               flow.fire("ccc",20)
        }
    });
})

<commit_msg>完成flow的测试<commit_after>$.define("flow","flow,more/spec",function(){
    $.fixture('操作流模块-flow', {
        "reloadAll = false": function(id){
            var flow = new $.flow;
            var callback = function(a,b,c){
                expect([].slice.call(arguments),id).same([10,20,30])//测试多路监听时收集的返回值
                expect("此流程触发在aaa,bbb,ccc都被fire的情况下",id).eq("此流程触发在aaa,bbb,ccc都被fire的情况下")
            }
            var fireCount = 0;//用于统计aaa,bbb这个组合的回调一共执行了多少次
            var callback2 = function(a,b,c){
                fireCount++;
            }
            flow.bind("aaa,bbb,ccc",callback,false);
            flow.bind("aaa,ddd",callback2,false);
            expect(callback.deps).same({
                __aaa:1,
                __bbb:1,
                __ccc:1
            });

            // $.log(callback.args)
            expect(callback.args).same(["__aaa", "__bbb", "__ccc"]);//必须这三个事件都被fire才执行callback
            // $.log(callback.reloadAll)
            expect(callback.reloadAll).eq(false);
            //  $.log(flow.root["__aaa"])
            expect(flow.root["__aaa"].unfire.length).eq(2);//__aaa这个事件未绑定的回调已达两个
            flow.fire("aaa",10);
            flow.fire("bbb",20);
            flow.fire("ccc",30);
            flow.fire("ddd",40);
            flow.fire("ddd",50);
            flow.fire("ddd",60);
            expect(fireCount).eq(3);
        },
        "reloadAll = true": function(){
            var flow = new $.flow;
            var fireCount = 0;//用于统计aa,bb这个组合的回调一共执行了多少次
            var callback = function(){
                fireCount++
            }
            flow.bind("aa,bb,cc",callback,true);
            flow.fire("aa",10);
            flow.fire("bb",20);
            flow.fire("cc",30);
            flow.fire("aa",40);
            flow.fire("bb",50);
            flow.fire("cc",60);
            flow.fire("aa",40);
            flow.fire("bb",50);
            flow.fire("cc",60);
            flow.fire("aa",40);
            flow.fire("bb",50);
            flow.fire("cc",60);
            expect(fireCount).eq(4);
        },
        "fire arguments":function(id){
            var flow = new $.flow;
            var callback = function(){
                var args = [].slice.call(arguments);
                expect(arguments.length ,id).eq( 9 );
                expect(args.join(",") ,id).eq("1,2,3,4,5,6,7,8,9");
            }
            flow.bind("aa,bb,cc",callback,true);
            flow.fire("aa",1,2,3);
            flow.fire("aa",4,5,6)
            flow.fire("aa",7,8,9)
        }

    });
})

<|endoftext|>


<commit_before>import {expect} from 'chai'

describe('Author names formatting', () => {

    it('Format name with one part', () => {
        expect(format('Guimaraes')).to.be.equal('GUIMARAES')
    })

    it('Format name with two parts', () => {
        expect(format('João Silva')).to.be.equal('SILVA, João')
    })

    it('Format name with two parts and preposition', () => {
        expect(format('João da Silva')).to.be.equal('SILVA, João da')
    })

    it('Format name with three parts and special name', () => {
        expect(format('João Henrique Filho')).to.be.equal('HENRIQUE FILHO, João')
    })

});

function format(name) {
    var nameParts = name.split(' ')
    var lastPart = nameParts[nameParts.length - 1].toUpperCase();

    if (nameParts.length == 1)
        return lastPart

    var firstName = ''
    for (let i = 0; i < nameParts.length - 1; i++) {
        firstName += ' ' + nameParts[i]
    }

    if (isSpecialName(lastPart) && nameParts.length >= 3) {
        var beforeLastPart = nameParts[nameParts.length - 2];
        lastPart = beforeLastPart.toUpperCase() + ' ' + lastPart
        firstName = firstName.replace(' ' + beforeLastPart, '')
    }

    return lastPart + ',' + firstName
}

function isSpecialName(name){
    return ["FILHO", "FILHA", "NETO", "NETA",
        "SOBRINHO", "SOBRINHA", "JUNIOR"].includes(name.toUpperCase())
}<commit_msg>fifth case<commit_after>import {expect} from 'chai'

describe('Author names formatting', () => {

    it('should format name with one part', () => {
        expect(format('Guimaraes')).to.be.equal('GUIMARAES')
    })

    it('should format name with two parts', () => {
        expect(format('João Silva')).to.be.equal('SILVA, João')
    })

    it('should format name with two parts and preposition', () => {
        expect(format('João da Silva')).to.be.equal('SILVA, João da')
    })

    it('should format name with three parts and special name', () => {
        expect(format('João Henrique Filho')).to.be.equal('HENRIQUE FILHO, João')
    })

    it('should capitalize words corretly', () => {
        expect(format('joão do henrique filho')).to.be.equal('HENRIQUE FILHO, João do')
    })

});

function format(name) {
    var nameParts = name.split(' ')
    var lastPart = nameParts[nameParts.length - 1].toUpperCase();

    if (nameParts.length == 1)
        return lastPart

    var firstName = ''
    for (let i = 0; i < nameParts.length - 1; i++) {
        firstName += ' ' + capitalize(nameParts[i])
    }

    if (isSpecialName(lastPart) && nameParts.length >= 3) {
        var beforeLastPart = nameParts[nameParts.length - 2];
        lastPart = beforeLastPart.toUpperCase() + ' ' + lastPart
        firstName = firstName.replace(' ' + capitalize(beforeLastPart), '')
    }

    return lastPart + ',' + firstName
}

function isSpecialName(name){
    return ["FILHO", "FILHA", "NETO", "NETA",
        "SOBRINHO", "SOBRINHA", "JUNIOR"].includes(name.toUpperCase())
}

function isPreposition(name){
    return ["da", "de", "do", "das", "dos"].includes(name.toLowerCase())
}

function capitalize(name){
    name = name.toLowerCase()
    if(isPreposition(name))
        return name
    return name.charAt(0).toUpperCase() + name.slice(1)
}<|endoftext|>


<commit_before>function Inspector(json) {
	var self = this;

	self.id = json.id;
	self.username= json.username;
	self.name = json.name;
	self.keywords = json.keywords;
	self.load = json.load;
	self.capacity = json.capacity;

	self.formattedCapacity = function() {
		return self.load + "/" + self.capacity;
	};
}

function InspectionViewModel() {
	var self = this;

	self.defaultDate = "2014-11-12";

	self.suggestedInspectors = ko.observableArray();
	self.otherInspectors = ko.observableArray();
	self.allInspectors = ko.observableArray();

	self.firstInspector = ko.observable();
	self.secondInspector = ko.observable();

	self.firstOtherInspector = ko.observable();
	self.secondOtherInspector = ko.observable();

	// Bind other inspectors changes
	self.firstInspectorHandler = ko.computed(function() {
		console.log(self.firstInspector());
	});
	self.secondInspectorHandler = ko.computed(function() {
		console.log(self.secondInspector());
	});
	self.firstOtherInspectorHandler = ko.computed(function() {
		//console.log(self.firstOtherInspector());
	});
	self.secondOtherInspectorHandler = ko.computed(function() {
		//console.log(self.secondOtherInspector());
	});

	// Inputs
	self.readSuggestedInspectors = function(json) {
    	var inspectors = [];
    	json.suggestedInspectors.forEach(function(inspectorJson) {
    		var inspector = new Inspector(inspectorJson);
    		inspectors.push(inspector);
    	});
    	self.suggestedInspectors(inspectors);
    	ko.utils.arrayPushAll(self.allInspectors, inspectors);
    	self.firstInspector(null);
	};

	self.readOtherInspectors = function(json) {
    	var inspectors = [];
    	json.otherInspectors.forEach(function(inspectorJson) {
    		var inspector = new Inspector(inspectorJson);
    		inspectors.push(inspector);
    	});
    	self.otherInspectors(inspectors);
    	ko.utils.arrayPushAll(self.allInspectors, inspectors);
    	self.secondInspector(null);
	};

	self.readFirstInspector = function(json) {
    	var firstInspector = self.inspectorWithID(json.firstInspectorID);
    	self.firstInspector(firstInspector);
	};

	self.readSecondInspector = function(json) {
    	var secondInspector = self.inspectorWithID(json.secondInspectorID);
    	self.secondInspector(secondInspector);
	};

	self.readInspectors = function() {
    	var jsonDiv = $('#json-variables');
    	var json = JSON.parse(jsonDiv.text());

		self.allInspectors([]);
		self.readSuggestedInspectors(json);
		self.readOtherInspectors(json);
		self.readFirstInspector(json);
		self.readSecondInspector(json);
	};

	// Getters
	self.inspectorWithID = function(inspectorID) {
		var inspector = null;
		self.allInspectors().forEach(function(i) {
			if (i.id == inspectorID) {
				inspector = i;
			}
		});
		return inspector;
	};

	self.getSlots = function(start, end, timezone, callback) {
		callback([]);
	};

	// Setters
	self.slotChanged = function(event, delta, revertFunc) {

	};

    self.setCalendarNeedUpdate = function() {
    	$('#calendar').fullCalendar( 'refetchEvents' );
    };

	// Start
	self.readInspectors();
	createCalendar(self);
}

var inspectionViewModel = new InspectionViewModel();
ko.applyBindings(inspectionViewModel);<commit_msg>fetch firstInspectorSlots<commit_after>function Inspector(json) {
	var self = this;

	self.id = json.id;
	self.username= json.username;
	self.name = json.name;
	self.keywords = json.keywords;
	self.load = json.load;
	self.capacity = json.capacity;

	self.formattedCapacity = function() {
		return self.load + "/" + self.capacity;
	};

	self.slots = [];
}

function InspectionViewModel() {
	var self = this;

	self.defaultDate = "2014-11-12";

	self.suggestedInspectors = ko.observableArray();
	self.otherInspectors = ko.observableArray();
	self.allInspectors = ko.observableArray();

	self.firstInspector = ko.observable();
	self.secondInspector = ko.observable();

	self.firstOtherInspector = ko.observable();
	self.secondOtherInspector = ko.observable();

	// Inputs
	self.readSuggestedInspectors = function(json) {
    	var inspectors = [];
    	json.suggestedInspectors.forEach(function(inspectorJson) {
    		var inspector = new Inspector(inspectorJson);
    		inspectors.push(inspector);
    	});
    	self.suggestedInspectors(inspectors);
    	ko.utils.arrayPushAll(self.allInspectors, inspectors);
    	self.firstInspector(null);
	};

	self.readOtherInspectors = function(json) {
    	var inspectors = [];
    	json.otherInspectors.forEach(function(inspectorJson) {
    		var inspector = new Inspector(inspectorJson);
    		inspectors.push(inspector);
    	});
    	self.otherInspectors(inspectors);
    	ko.utils.arrayPushAll(self.allInspectors, inspectors);
    	self.secondInspector(null);
	};

	self.readFirstInspector = function(json) {
    	var firstInspector = self.inspectorWithID(json.firstInspectorID);
    	self.firstInspector(firstInspector);
	};

	self.readSecondInspector = function(json) {
    	var secondInspector = self.inspectorWithID(json.secondInspectorID);
    	self.secondInspector(secondInspector);
	};

	self.readInspectors = function() {
    	var jsonDiv = $('#json-variables');
    	var json = JSON.parse(jsonDiv.text());

		self.allInspectors([]);
		self.readSuggestedInspectors(json);
		self.readOtherInspectors(json);
		self.readFirstInspector(json);
		self.readSecondInspector(json);
	};

	// Getters
	self.inspectorWithID = function(inspectorID) {
		var inspector = null;
		self.allInspectors().forEach(function(i) {
			if (i.id == inspectorID) {
				inspector = i;
			}
		});
		return inspector;
	};

	self.getSlots = function(start, end, timezone, callback) {
		var slots = [];
		if (self.firstInspector() != null) {
			slots = slots.concat(self.firstInspector().slots);
		}
		console.log(slots);
		callback(slots);
	};

	// Setters
	self.slotChanged = function(event, delta, revertFunc) {

	};

    self.setCalendarNeedUpdate = function() {
    	$('#calendar').fullCalendar( 'refetchEvents' );
    };

    // Fetchers
    self.fetchFirstInspectorSlots = function() {
    	if (self.firstInspector() != null) {
        	var userType = 'inspector';
        	var userID = self.firstInspector().id;

        	self.fetchAvailability(userType, userID, function(result) {
        		// if success
            	var json = JSON.parse(result);

            	json.slots.forEach(function(slot) {
            		slot.color = "yellow";
            		slot.rendering = "background";
            	});
            	self.firstInspector().slots = json.slots;
            	console.log(json.slots);
            	self.setCalendarNeedUpdate();
        	});
    	}
    };

    self.fetchAvailability = function(userType, userID, success) {
    	var contentType = 'json';
		$.ajax({
			url: '/PIMS/availability/?type=' + userType + '&id=' + userID +'&content='+ contentType,
			success: success,
			error: null
		});
    };

	// Bind other inspectors changes
	self.firstInspectorHandler = ko.computed(function() {
		console.log(self.firstInspector());
		self.fetchFirstInspectorSlots();
	});
	self.secondInspectorHandler = ko.computed(function() {
		console.log(self.secondInspector());
	});
	self.firstOtherInspectorHandler = ko.computed(function() {
		//console.log(self.firstOtherInspector());
	});
	self.secondOtherInspectorHandler = ko.computed(function() {
		//console.log(self.secondOtherInspector());
	});

	// Start
	self.readInspectors();
	createCalendar(self);
}

var inspectionViewModel = new InspectionViewModel();
ko.applyBindings(inspectionViewModel);<|endoftext|>


<commit_before>/*******************************************************************************
 * @license
 * Copyright (c) 2014 Pivotal Software Inc. and others.
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License v1.0
 * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution
 * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html).
 *
 * Contributors: Pivotal Software Inc. - initial API and implementation
 ******************************************************************************/

/*global window eclipse:true orion FileReader Blob*/
/*jslint forin:true devel:true*/

/** @namespace The global container for eclipse APIs. */
var eclipse = eclipse || {};

var callbacksCache = {};
var user;
var muteLiveEdit = true;
var editSession;
var markerService;

var counter = 1;
function generateCallbackId() {
	return counter++;
}

/**
 * An implementation of the file service that understands the Orion
 * server file API. This implementation is suitable for invocation by a remote plugin.
 */
eclipse.FluxEditor = (function() {
	/**
	 * @class Provides operations on files, folders, and projects.
	 * @name FileServiceImpl
	 */
	function FluxEditor(host, port, userId) {
		this._rootLocation = "flux:http://" + host +":" + port + "/" + userId + "/";
		user = userId;

		this.socket = io.connect(host, {
			port: port
		});

		this._resourceUrl = null;

		var self = this;

		this.socket.on('connect', function() {
//			while (user && !self._connectedToChannel) {
				self.socket.emit('connectToChannel', {
					'channel' : user
				}, function(answer) {
					if (answer.connectedToChannel) {
						self._connectedToChannel = true;
						console.log("EDITOR Connected to FLUX channel: " + user);
					}
				});
//			}
		});

		this.socket.on('getResourceResponse', function(data) {
			self._handleMessage(data);
		});

		this.socket.on('contentassistresponse', function(data) {
			self._handleMessage(data);
		});

		this.socket.on('liveResourceStartedResponse', function(data) {
			self._getResourceData().then(function(resourceMetadata) {
				if (data.username === resourceMetadata.username
					&& data.project === resourceMetadata.project
					&& data.resource === resourceMetadata.resource
					&& data.callback_id !== undefined
					&& resourceMetadata.timestamp === data.savePointTimestamp
					&& resourceMetadata.hash === data.savePointHash) {
					muteLiveEdit = true;
					self._editorContext.setText(data.liveContent).then(function() {
						muteLiveEdit = false;
					}, function() {
						muteLiveEdit = false;
					});;
				}
			}, function(err) {
				console.log(err);
			});
		});

		this.socket.on('liveResourceStarted', function(data) {
			self._getResourceData().then(function(resourceMetadata) {
				if (data.username === resourceMetadata.username
					&& data.project === resourceMetadata.project
					&& data.resource === resourceMetadata.resource
					&& data.callback_id !== undefined
					&& data.hash === resourceMetadata.hash
					&& data.timestamp === resourceMetadata.timestamp) {

					self._editorContext.getText().then(function(contents) {
						self.sendMessage('liveResourceStartedResponse', {
							'callback_id'        : data.callback_id,
							'requestSenderID'    : data.requestSenderID,
							'username'           : data.username,
							'project'            : data.project,
							'resource'           : data.resource,
							'savePointTimestamp' : resourceMetadata.timestamp,
							'savePointHash'      : resourceMetadata.hash,
							'liveContent'        : contents
						});
					});
				}
			});
		});

		this.socket.on('getLiveResourcesRequest', function(data) {
			self._getResourceData().then(function(resourceMetadata) {
				if (data.username === resourceMetadata.username
					&& data.callback_id !== undefined
					&& data.project === resourceMetadata.project) {

					self.sendMessage('getLiveResourcesResponse', {
						'callback_id'        : data.callback_id,
						'requestSenderID'    : data.requestSenderID,
						'liveEditUnits'      : [{
							'username'           : resourceMetadata.username,
							'project'            : resourceMetadata.project,
							'resource'           : resourceMetadata.resource,
							'savePointTimestamp' : resourceMetadata.timestamp,
							'savePointHash'      : resourceMetadata.hash
						}]
					});
				}
			});
		});

		this.socket.on('resourceStored', function(data) {
			var location = self._rootLocation + data.project + '/' + data.resource;
			if (self._resourceUrl === location) {
				this._resourceMetadata = data;
			}
		});

		this.socket.on('liveResourceChanged', function(data) {
			self._getResourceData().then(function(resourceMetadata) {
				if (data.username === resourceMetadata.username
					&& data.project === resourceMetadata.project
					&& data.resource === resourceMetadata.resource
					&& self._editorContext) {

					var text = data.addedCharacters !== undefined ? data.addedCharacters : "";

					muteLiveEdit = true;
					self._editorContext.setText(text, data.offset, data.offset + data.removedCharCount).then(function() {
						muteLiveEdit = false;
					}, function() {
						muteLiveEdit = false;
					});
				}
			});
		});

		this.socket.on('liveMetadataChanged', function (data) {
			self._getResourceData().then(function(resourceMetadata) {
				if (resourceMetadata.username === data.username
					&& resourceMetadata.project === data.project
					&& resourceMetadata.resource === data.resource
					&& data.problems !== undefined) {

					resourceMetadata.markers = [];
					var i;
					for(i = 0; i < data.problems.length; i++) {
//						var lineOffset = editor.getModel().getLineStart(data.problems[i].line - 1);

//						console.log(lineOffset);

						resourceMetadata.markers[i] = {
							'description' : data.problems[i].description,
//							'line' : data.problems[i].line,
							'severity' : data.problems[i].severity,
							'start' : /*(data.problems[i].start - lineOffset) + 1*/ data.problems[i].start,
							'end' : /*data.problems[i].end - lineOffset*/ data.problems[i].end
						};
					}
					if (markerService) {
						markerService._setProblems(resourceMetadata.markers);
					}
				}
				self._handleMessage(data);
			});
		});

	}

	FluxEditor.prototype = /**@lends eclipse.FluxEditor.prototype */
	{
		_normalizeLocation : function(location) {
			if (!location) {
				location = "/";
			} else {
				location = location.replace(this._rootLocation, "");
			}
			var indexOfDelimiter = location.indexOf('/');
			var project = indexOfDelimiter < 0 ? location : location.substr(0, indexOfDelimiter);
			location = indexOfDelimiter < 0 ? undefined : location.substr(indexOfDelimiter + 1);
			return { 'project' : project, 'path' : location };
		},
		sendMessage : function(type, message, callbacks) {
//			if (this._connectedToChannel) {
				if (callbacks) {
					message.callback_id = generateCallbackId();
					callbacksCache[message.callback_id] = callbacks;
				} else {
					message.callback_id = 0;
				}
				this.socket.emit(type, message);
				return true;
//			} else {
//				return false;
//			}
		},
		_handleMessage: function(data) {
			var callbacks = callbacksCache[data.callback_id];
			if (callbacks) {
				if (Array.isArray(callbacks)) {
					var fn = callbacks[0];
					fn.call(this, data);
					callbacks.shift();
					if (callbacks.length === 0) {
						delete callbacksCache[data.callback_id];
					}
					return true;
				} else if (callbacks.call) {
					callbacks.call(this, data);
					delete callbacksCache[data.callback_id];
					return true;
				}
			}
			return false;
		},

		_isFluxResource: function(resourceUrl) {
			return resourceUrl && resourceUrl.indexOf(this._rootLocation) === 0;
		},

		_getResourceData: function() {
			var request = new orion.Deferred();
			var self = this;
			if (self._resourceMetadata) {
				request.resolve(self._resourceMetadata);
			} else if (this._resourceUrl) {
				var normalizedLocation = this._normalizeLocation(this._resourceUrl);
				this.sendMessage("getResourceRequest", {
					'username' : user,
					'project' : normalizedLocation.project,
					'resource' : normalizedLocation.path,
				}, function(data) {
					var location = self._rootLocation + data.project + '/' + data.resource;
					if (self._resourceUrl === location) {
						self._resourceMetadata = data;
						self._resourceMetadata.markers = [];
						request.resolve(self._resourceMetadata);
					}
				});
			} else {
				request.reject("No resource URL!");
			}
			return request;
		},

		_setEditorInput: function(resourceUrl, editorContext) {
			var self = this;
			if (this._resourceUrl !== resourceUrl) {
				this._resourceUrl = null;
				this._editorContext = null;
				this._resourceMetadata = null;
				if (editSession) {
					editSession.resolve();
				}
				muteLiveEdit = true;
				if (this._isFluxResource(resourceUrl)) {
					this._resourceUrl = resourceUrl;
					editSession = new orion.Deferred();
					this._editorContext = editorContext;
					muteLiveEdit = false;

					this._getResourceData().then(function(resourceMetadata) {
						self.sendMessage('liveResourceStarted', {
							'callback_id' : 0,
							'username' : resourceMetadata.username,
							'project' : resourceMetadata.project,
							'resource' : resourceMetadata.resource,
							'hash' : resourceMetadata.hash,
							'timestamp' : resourceMetadata.timestamp
						});
					});
				}
			}
			return editSession;
		},

		onModelChanging: function(evt) {
			console.log("Editor changing: " + JSON.stringify(evt));
			var self = this;
			if (muteLiveEdit) {
				return;
			}
			this._getResourceData().then(function(resourceMetadata) {
				var changeData = {
					'username' : resourceMetadata.username,
					'project' : resourceMetadata.project,
					'resource' : resourceMetadata.resource,
					'offset' : evt.start,
					'removedCharCount' : evt.removedCharCount,
					'addedCharacters' : evt.text,
				};

				self.sendMessage('liveResourceChanged', changeData);
			});
		},

		computeContentAssist: function(editorContext, options) {
			var request = new orion.Deferred();
			var self = this;
			this._getResourceData().then(function(resourceMetadata) {
				self.sendMessage("contentassistrequest", {
					'username' : resourceMetadata.username,
					'project' : resourceMetadata.project,
					'resource' : resourceMetadata.resource,
					'offset' : options.offset,
					'prefix' : options.prefix,
					'selection' : options.selection
				}, function(data) {
					var proposals = [];
					if (data.proposals) {
						data.proposals.forEach(function(proposal) {
							var name;
							var description;
							if (proposal.description
								&& proposal.description.segments
								&& (Array.isArray && Array.isArray(proposal.description.segments) || proposal.description.segments instanceof Array)) {

								if (proposal.description.segments.length >= 2) {
									name = proposal.description.segments[0].value;
									description = proposal.description.segments[1].value;
								} else {
									description = proposal.description.segments[0].value;
								}
							} else {
								description = proposal.description;
							}
							if (!description) {
								description = proposal.proposal;
							}
							if (description) {
								proposals.push({
									'description' : description,
									'name' : name,
									'overwrite' : proposal.replace,
									'positions' : proposal.positions,
									'proposal' : proposal.proposal,
									'style' : "emphasis",
									'escapePosition' : proposal.escapePosition
								});
							}
						});
					}
					console.log("Editor content assist: " + JSON.stringify(proposals));
					request.resolve(proposals);
				});
			});
			return request;
		},

		computeProblems: function(editorContext, options) {
			console.log("Validator (Problems): " + JSON.stringify(options));
			var self = this;
			var problemsRequest = new orion.Deferred();
//			this._setEditorInput(options.title, editorContext);

			this._getResourceData().then(function(resourceMetadata) {
				if (self._resourceUrl === options.title) {
					var problems = resourceMetadata.markers ? resourceMetadata.markers : [];
					problemsRequest.resolve(problems);
				} else {
					problemsRequest.reject();
				}
			});

//			this._waitForProblemMarkers(this._resourceUrl, 50, function(markers) {
//				problemsRequest.resolve(markers);
//			}, function() {
//				problemsRequest.reject();
//			});
			return problemsRequest;
		},

		startEdit: function(editorContext, options, orionMarkerService) {
			console.log("LIVE EDIT: " + JSON.stringify(options));
			var url = options ? options.title : null;
			markerService = markerService || orionMarkerService;
			return this._setEditorInput(url, editorContext);
		},

		endEdit: function(resourceUrl) {
			this._resourceUrl = null;
			this._editorContext = null;
			this._resourceMetadata = null;
			if (editSession) {
				editSession.resolve();
			}
			muteLiveEdit = true;
		},

//		_waitForProblemMarkers: function(resourceUrl, interval, successCallback, failureCallback) {
//			var self = this;
//			var wait = function() {
//				self._getResourceData().then(function(resourceMetadata) {
//					if (self._resourceUrl === resourceUrl) {
//						if (resourceMetadata.markers) {
//							if (successCallback && successCallback.call) {
//								successCallback.call(self, resourceMetadata.markers);
//							}
//						} else {
//							setTimeout(wait, interval);
//						}
//					} else {
//						if (failureCallback && failureCallback.call) {
//							failureCallback.call(self);
//						}
//					}
//				});
//			};
//			wait.call(this);
//		},

	};

	return FluxEditor;
}());<commit_msg>Corrections for problem markers.<commit_after>/*******************************************************************************
 * @license
 * Copyright (c) 2014 Pivotal Software Inc. and others.
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License v1.0
 * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution
 * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html).
 *
 * Contributors: Pivotal Software Inc. - initial API and implementation
 ******************************************************************************/

/*global window eclipse:true orion FileReader Blob*/
/*jslint forin:true devel:true*/

/** @namespace The global container for eclipse APIs. */
var eclipse = eclipse || {};

var callbacksCache = {};
var user;
var muteLiveEdit = true;
var editSession;
var markerService;

var counter = 1;
function generateCallbackId() {
	return counter++;
}

/**
 * An implementation of the file service that understands the Orion
 * server file API. This implementation is suitable for invocation by a remote plugin.
 */
eclipse.FluxEditor = (function() {
	/**
	 * @class Provides operations on files, folders, and projects.
	 * @name FileServiceImpl
	 */
	function FluxEditor(host, port, userId) {
		this._rootLocation = "flux:http://" + host +":" + port + "/" + userId + "/";
		user = userId;

		this.socket = io.connect(host, {
			port: port
		});

		this._resourceUrl = null;

		var self = this;

		this.socket.on('connect', function() {
//			while (user && !self._connectedToChannel) {
				self.socket.emit('connectToChannel', {
					'channel' : user
				}, function(answer) {
					if (answer.connectedToChannel) {
						self._connectedToChannel = true;
						console.log("EDITOR Connected to FLUX channel: " + user);
					}
				});
//			}
		});

		this.socket.on('getResourceResponse', function(data) {
			self._handleMessage(data);
		});

		this.socket.on('getMetadataResponse', function(data) {
			self._handleMessage(data);
		});

		this.socket.on('contentassistresponse', function(data) {
			self._handleMessage(data);
		});

		this.socket.on('liveResourceStartedResponse', function(data) {
			self._getResourceData().then(function(resourceMetadata) {
				if (data.username === resourceMetadata.username
					&& data.project === resourceMetadata.project
					&& data.resource === resourceMetadata.resource
					&& data.callback_id !== undefined
					&& resourceMetadata.timestamp === data.savePointTimestamp
					&& resourceMetadata.hash === data.savePointHash) {
					muteLiveEdit = true;
					self._editorContext.setText(data.liveContent).then(function() {
						muteLiveEdit = false;
					}, function() {
						muteLiveEdit = false;
					});;
				}
			}, function(err) {
				console.log(err);
			});
		});

		this.socket.on('liveResourceStarted', function(data) {
			self._getResourceData().then(function(resourceMetadata) {
				if (data.username === resourceMetadata.username
					&& data.project === resourceMetadata.project
					&& data.resource === resourceMetadata.resource
					&& data.callback_id !== undefined
					&& data.hash === resourceMetadata.hash
					&& data.timestamp === resourceMetadata.timestamp) {

					self._editorContext.getText().then(function(contents) {
						self.sendMessage('liveResourceStartedResponse', {
							'callback_id'        : data.callback_id,
							'requestSenderID'    : data.requestSenderID,
							'username'           : data.username,
							'project'            : data.project,
							'resource'           : data.resource,
							'savePointTimestamp' : resourceMetadata.timestamp,
							'savePointHash'      : resourceMetadata.hash,
							'liveContent'        : contents
						});
					});
				}
			});
		});

		this.socket.on('getLiveResourcesRequest', function(data) {
			self._getResourceData().then(function(resourceMetadata) {
				if (data.username === resourceMetadata.username
					&& data.callback_id !== undefined
					&& data.project === resourceMetadata.project) {

					self.sendMessage('getLiveResourcesResponse', {
						'callback_id'        : data.callback_id,
						'requestSenderID'    : data.requestSenderID,
						'liveEditUnits'      : [{
							'username'           : resourceMetadata.username,
							'project'            : resourceMetadata.project,
							'resource'           : resourceMetadata.resource,
							'savePointTimestamp' : resourceMetadata.timestamp,
							'savePointHash'      : resourceMetadata.hash
						}]
					});
				}
			});
		});

		this.socket.on('resourceStored', function(data) {
			var location = self._rootLocation + data.project + '/' + data.resource;
			if (self._resourceUrl === location) {
				this._resourceMetadata = data;
			}
		});

		this.socket.on('liveResourceChanged', function(data) {
			self._getResourceData().then(function(resourceMetadata) {
				if (data.username === resourceMetadata.username
					&& data.project === resourceMetadata.project
					&& data.resource === resourceMetadata.resource
					&& self._editorContext) {

					var text = data.addedCharacters !== undefined ? data.addedCharacters : "";

					muteLiveEdit = true;
					self._editorContext.setText(text, data.offset, data.offset + data.removedCharCount).then(function() {
						muteLiveEdit = false;
					}, function() {
						muteLiveEdit = false;
					});
				}
			});
		});

		this.socket.on('liveMetadataChanged', function (data) {
			self._getResourceData().then(function(resourceMetadata) {
				if (resourceMetadata.username === data.username
					&& resourceMetadata.project === data.project
					&& resourceMetadata.resource === data.resource
					&& data.problems !== undefined) {

					resourceMetadata.liveMarkers = [];
					var i;
					for(i = 0; i < data.problems.length; i++) {
//						var lineOffset = editor.getModel().getLineStart(data.problems[i].line - 1);

//						console.log(lineOffset);

						resourceMetadata.liveMarkers[i] = {
							'description' : data.problems[i].description,
//							'line' : data.problems[i].line,
							'severity' : data.problems[i].severity,
							'start' : /*(data.problems[i].start - lineOffset) + 1*/ data.problems[i].start,
							'end' : /*data.problems[i].end - lineOffset*/ data.problems[i].end
						};
					}
					if (markerService) {
						markerService._setProblems(resourceMetadata.liveMarkers/*.concat(resourceMetadata.markers)*/);
					}
				}
				self._handleMessage(data);
			});
		});

	}

	FluxEditor.prototype = /**@lends eclipse.FluxEditor.prototype */
	{
		_normalizeLocation : function(location) {
			if (!location) {
				location = "/";
			} else {
				location = location.replace(this._rootLocation, "");
			}
			var indexOfDelimiter = location.indexOf('/');
			var project = indexOfDelimiter < 0 ? location : location.substr(0, indexOfDelimiter);
			location = indexOfDelimiter < 0 ? undefined : location.substr(indexOfDelimiter + 1);
			return { 'project' : project, 'path' : location };
		},
		sendMessage : function(type, message, callbacks) {
//			if (this._connectedToChannel) {
				if (callbacks) {
					message.callback_id = generateCallbackId();
					callbacksCache[message.callback_id] = callbacks;
				} else {
					message.callback_id = 0;
				}
				this.socket.emit(type, message);
				return true;
//			} else {
//				return false;
//			}
		},
		_handleMessage: function(data) {
			var callbacks = callbacksCache[data.callback_id];
			if (callbacks) {
				if (Array.isArray(callbacks)) {
					var fn = callbacks[0];
					fn.call(this, data);
					callbacks.shift();
					if (callbacks.length === 0) {
						delete callbacksCache[data.callback_id];
					}
					return true;
				} else if (callbacks.call) {
					callbacks.call(this, data);
					delete callbacksCache[data.callback_id];
					return true;
				}
			}
			return false;
		},

		_isFluxResource: function(resourceUrl) {
			return resourceUrl && resourceUrl.indexOf(this._rootLocation) === 0;
		},

		_getResourceData: function() {
			var request = new orion.Deferred();
			var self = this;
			if (self._resourceMetadata) {
				request.resolve(self._resourceMetadata);
			} else if (this._resourceUrl) {
				var normalizedLocation = this._normalizeLocation(this._resourceUrl);
				this.sendMessage("getResourceRequest", {
					'username' : user,
					'project' : normalizedLocation.project,
					'resource' : normalizedLocation.path,
				}, function(data) {
					var location = self._rootLocation + data.project + '/' + data.resource;
					if (self._resourceUrl === location) {
						self._resourceMetadata = data;
						self._resourceMetadata.liveMarkers = [];
						self._resourceMetadata.markers = [];
						request.resolve(self._resourceMetadata);
					}
				});
			} else {
				request.reject("No resource URL!");
			}
			return request;
		},

		_setEditorInput: function(resourceUrl, editorContext) {
			var self = this;
			if (this._resourceUrl !== resourceUrl) {
				this._resourceUrl = null;
				this._editorContext = null;
				this._resourceMetadata = null;
				if (editSession) {
					editSession.resolve();
				}
				muteLiveEdit = true;
				if (this._isFluxResource(resourceUrl)) {
					this._resourceUrl = resourceUrl;
					editSession = new orion.Deferred();
					this._editorContext = editorContext;
					muteLiveEdit = false;

					this._getResourceData().then(function(resourceMetadata) {
						self.sendMessage('liveResourceStarted', {
							'callback_id' : 0,
							'username' : resourceMetadata.username,
							'project' : resourceMetadata.project,
							'resource' : resourceMetadata.resource,
							'hash' : resourceMetadata.hash,
							'timestamp' : resourceMetadata.timestamp
						});
					});
				}
			}
			return editSession;
		},

		onModelChanging: function(evt) {
			console.log("Editor changing: " + JSON.stringify(evt));
			var self = this;
			if (muteLiveEdit) {
				return;
			}
			this._getResourceData().then(function(resourceMetadata) {
				var changeData = {
					'username' : resourceMetadata.username,
					'project' : resourceMetadata.project,
					'resource' : resourceMetadata.resource,
					'offset' : evt.start,
					'removedCharCount' : evt.removedCharCount,
					'addedCharacters' : evt.text,
				};

				self.sendMessage('liveResourceChanged', changeData);
			});
		},

		computeContentAssist: function(editorContext, options) {
			var request = new orion.Deferred();
			var self = this;
			this._getResourceData().then(function(resourceMetadata) {
				self.sendMessage("contentassistrequest", {
					'username' : resourceMetadata.username,
					'project' : resourceMetadata.project,
					'resource' : resourceMetadata.resource,
					'offset' : options.offset,
					'prefix' : options.prefix,
					'selection' : options.selection
				}, function(data) {
					var proposals = [];
					if (data.proposals) {
						data.proposals.forEach(function(proposal) {
							var name;
							var description;
							if (proposal.description
								&& proposal.description.segments
								&& (Array.isArray && Array.isArray(proposal.description.segments) || proposal.description.segments instanceof Array)) {

								if (proposal.description.segments.length >= 2) {
									name = proposal.description.segments[0].value;
									description = proposal.description.segments[1].value;
								} else {
									description = proposal.description.segments[0].value;
								}
							} else {
								description = proposal.description;
							}
							if (!description) {
								description = proposal.proposal;
							}
							if (description) {
								proposals.push({
									'description' : description,
									'name' : name,
									'overwrite' : proposal.replace,
									'positions' : proposal.positions,
									'proposal' : proposal.proposal,
									'style' : "emphasis",
									'escapePosition' : proposal.escapePosition
								});
							}
						});
					}
					console.log("Editor content assist: " + JSON.stringify(proposals));
					request.resolve(proposals);
				});
			});
			return request;
		},

		computeProblems: function(editorContext, options) {
			console.log("Validator (Problems): " + JSON.stringify(options));
			var self = this;
			var problemsRequest = new orion.Deferred();
//			this._setEditorInput(options.title, editorContext);

			this._getResourceData().then(function(resourceMetadata) {
				if (self._resourceUrl === options.title) {
					self.sendMessage("getMetadataRequest", {
						'username' : resourceMetadata.username,
						'project' : resourceMetadata.project,
						'resource' : resourceMetadata.resource
					}, function(data) {
						if (data.username === resourceMetadata.username
							&& data.project === resourceMetadata.project
							&& data.resource === resourceMetadata.resource) {

							resourceMetadata.markers = [];
							for(var i = 0; i < data.metadata.length; i++) {
								resourceMetadata.markers[i] = {
									'description' : data.metadata[i].description,
									'severity' : data.metadata[i].severity,
									'start' : data.metadata[i].start,
									'end' : data.metadata[i].end
								};
							}
						}
						problemsRequest.resolve(resourceMetadata.markers);
					});
				} else {
					problemsRequest.reject();
				}
			});

			return problemsRequest;
		},

		startEdit: function(editorContext, options, orionMarkerService) {
			console.log("LIVE EDIT: " + JSON.stringify(options));
			var url = options ? options.title : null;
			markerService = markerService || orionMarkerService;
			return this._setEditorInput(url, editorContext);
		},

		endEdit: function(resourceUrl) {
			this._setEditorInput(null, null);
		},

	};

	return FluxEditor;
}());<|endoftext|>


<commit_before>var gamejs = "", modBlocking = true;
var tester = document.getElementsByTagName("script");
var i = 0, main_out_url = "http://agar.io/main_out.js", discovered_mainouturl = 0;
var W = '';

for (i=0; i<tester.length; i++ ){
	src = tester[i].src;
	if (src.substring(0, main_out_url.length ) == main_out_url) {
		discovered_mainouturl = src.replace("http://agar.io/","");
	}
}
if(discovered_mainouturl != !1) {
	$.ajax({
  	url: discovered_mainouturl,
 	 	success:function(data){
			gamejs = "window.agariomods = " + data.replace("socket open","socket open (agariomods.com mod in place)");
			offset = gamejs.search("..b..src");
			W = gamejs.substr(offset,1);
			agariomodsRuntimeInjection();
  		}
	});
}
function agariomodsRuntimeInjection() {
	var tester = document.getElementsByTagName("html");
	var oldhtml = tester[0].innerHTML;
	var script = document.createElement("script");
	agariomodsRuntimePatches();
	script.innerHTML = gamejs;
	document.head.appendChild(script);
	agariomodsRuntimeHacks();
}
function agariomodsRuntimePatches() {
	gamejs = gamejs.replace(';reddit;',';reddit;electronoob;');
	gamejs = gamejs.replace(W + '[b]=new Image,'+W+'[b].src="skins/"+b+".png"',W +'[b]=new Image,'+W+'[b].crossOrigin = "Anonymous",'+W+'[b].src="skins/"+b+".png"');
	gamejs = gamejs.replace('b=this.name.toLowerCase();', 'b=this.name.toLowerCase();var agariomods="";if(b == "electronoob") {agariomods="http://agariomods.com/skins/electronoob";} else {agariomods="http://agar.io/skins/" + this.name.toLowerCase();}');
	gamejs = gamejs.replace(W +'[b].src="skins/"+b+".png"',W+'[b].src=agariomods+".png"');
}
function agariomodsRuntimeHacks() {
	var nodeDiv = document.createElement("div");
	//
	$( document ).ready(function() {
	hd = document.getElementById("helloDialog");
	cachedhd = hd.innerHTML;
	hd.innerHTML = cachedhd.replace("Hello", "AgarioMods.com Evergreen Scripts");
	});
	//
	document.getElementById("nick").placeholder = "Name";
	$( document ).ready(function() {
	nh = document.getElementById("overlays");
	cachednh = nh.innerHTML;
	nh.innerHTML = cachednh.replace("
Type your nick or leave it empty:
", "Type a username");
	});
	nodeDiv.id = "includedContent";
	nodeDiv.style.width = "640px"
	nodeDiv.style.backgroundColor = "#000000";
	nodeDiv.style.zIndex = 9999999999;
	nodeDiv.style.position = "relative";
	nodeDiv.style.padding = "5px";
	nodeDiv.style.left = "-170px";
	nodeDiv.style.borderRadius = "5px";
	nodeDiv.style.color = "#dddddd";
	nodeDiv.innerHTML = "
Version 1.6.0  custom skins on their way

Our Website Agariomods.com.
";
	nodeDiv.innerHTML += "connections steps";
	nodeDiv.innerHTML += "\

\

1: Get ip address from friend.
\

2: Put it in text box below.
\

3: Press the swirly icon next to it.
\

Note: Check with your friend to see whos #1 on the leaderboard
\

\

\

Disable adblocking software!
We finally tracked down an issue to adblocking software, Turns out that it breaks the game and our modifications in random and unexpected ways. Beside Zeach provides this game free and we all need to support him!\

\
	";
	nodeDiv.innerHTML += "
mumble.agariomods.com:2387
";
	jQuery('#region').parent().get(0).appendChild(document.createElement("br"));
	jQuery('#region').parent().get(0).appendChild(nodeDiv);
	var selector = jQuery('#region');
	var playBtn = jQuery('#playBtn');
	var nodeInput = document.createElement("input");
	var nodeSpan = document.createElement("span");
	var nodeBr = document.createElement("br");
	nodeSpan.className = "glyphicon glyphicon-refresh";
	nodeSpan.style.fontSize = "1.5em";
	nodeSpan.style.cssFloat = "left";
	nodeSpan.style.paddingTop = "5px";
	nodeSpan.style.paddingLeft = "15px";
	nodeSpan.addEventListener("click", function (e) {
	    if (modBlocking == false) {
                        //jQuery('#region').style.height = "0px";
                        jQuery('#region').hide();
                        //jQuery('#gamemode').style.height = "0px";
                        jQuery('#gamemode').hide();
	                      console.log ("clicked refresh");
				var oldregionval = jQuery('#region').val;
	                      jQuery('#region').val("EU-London");
       	               jQuery('#region').change();
       	               jQuery('#region').val("SG-Singapore");
			jQuery('#region').change();
			jQuery('#region').val(oldregionval);
			jQuery('#region').change();
			 jQuery('#gamemode').change();
			      //jQuery(this).fadeOut(100).fadeIn(100);
	    }
	});
	nodeInput.className = "form-control";
	nodeInput.id = "iphack"
	nodeInput.style.width = "85%";
	nodeInput.style.cssFloat = "left";
	nodeInput.style.cssClear = "right";
	nodeInput.style.border = "2px solid green";
	nodeInput.placeholder = "Alternative server ip:port here.";
	jQuery(playBtn).parent().get(0).appendChild(nodeBr);
	jQuery(playBtn).parent().get(0).appendChild(nodeInput);
	jQuery(playBtn).parent().get(0).appendChild(nodeSpan);
	jQuery('#iphack').change(function() {
	    if (jQuery('#iphack').val() == "") {
	        modBlocking = true;
	    }
	    modBlocking = false;
	});
	jQuery('#playBtn').off();
	$('.btn-needs-server').prop('disabled', false);
	jQuery('#playBtn').click(function() {
	    setNick(document.getElementById('nick').value);
	    return false;
	});

}

(function(window) {
    var WebSocket_original = window.WebSocket;
    window.WebSocket_original = WebSocket_original;
    var newWebSocket = 0;
    window.WebSocket = function(data) {
        if (modBlocking == true) {
            newWebSocket = new window.WebSocket_original(data);
		jQuery('#includedContent').html("Here is the IP address of the server you are connected to currently, pass it to your friends for team playing.
" + data.replace('ws://', '') + "
 ");
        } else {
            console.log("HAXXED: connecting to " + jQuery('#iphack').val() + "(ignoring: " + data + ")");
            newWebSocket = new window.WebSocket_original("ws://" + jQuery('#iphack').val());
		jQuery('#includedContent').html("
Connected to " +  jQuery('#iphack').val() + "

Check leaderboard with your friend to ensure you are both on the exact world on the sameserver.

If you cannot see the same people in the leaderboard as your friend, press the swirly icon next the ip box to try another world on the same game server.");

        }
        return newWebSocket;

    };
})(window);

<commit_msg>1.6.1<commit_after>var gamejs = "", modBlocking = true;
var tester = document.getElementsByTagName("script");
var i = 0, main_out_url = "http://agar.io/main_out.js", discovered_mainouturl = 0;
var W = '';

for (i=0; i<tester.length; i++ ){
	src = tester[i].src;
	if (src.substring(0, main_out_url.length ) == main_out_url) {
		discovered_mainouturl = src.replace("http://agar.io/","");
	}
}
if(discovered_mainouturl != !1) {
	$.ajax({
  	url: discovered_mainouturl,
 	 	success:function(data){
			gamejs = "window.agariomods = " + data.replace("socket open","socket open (agariomods.com mod in place)");
			offset = gamejs.search("..b..src");
			W = gamejs.substr(offset,1);
			agariomodsRuntimeInjection();
  		}
	});
}
function agariomodsRuntimeInjection() {
	var tester = document.getElementsByTagName("html");
	var oldhtml = tester[0].innerHTML;
	var script = document.createElement("script");
	agariomodsRuntimePatches();
	script.innerHTML = gamejs;
	document.head.appendChild(script);
	agariomodsRuntimeHacks();
}
function agariomodsRuntimePatches() {
	gamejs = gamejs.replace(';reddit;',';reddit;electronoob;');
	gamejs = gamejs.replace(W + '[b]=new Image,'+W+'[b].src="skins/"+b+".png"',W +'[b]=new Image,'+W+'[b].crossOrigin = "Anonymous",'+W+'[b].src="skins/"+b+".png"');
	gamejs = gamejs.replace('b=this.name.toLowerCase();', 'b=this.name.toLowerCase();var agariomods="";if(b == "electronoob") {agariomods="http://agariomods.com/skins/electronoob";} else {agariomods="http://agar.io/skins/" + this.name.toLowerCase();}');
	gamejs = gamejs.replace(W +'[b].src="skins/"+b+".png"',W+'[b].src=agariomods+".png"');
}
function agariomodsRuntimeHacks() {
	jQuery('#helloDialog').css({top: '-100px'});
	jQuery('#helloDialog').css({margin: '5px auto'});
	var nodeDiv = document.createElement("div");
	//
	$( document ).ready(function() {
	hd = document.getElementById("helloDialog");
	cachedhd = hd.innerHTML;
	hd.innerHTML = cachedhd.replace("Hello", "AgarioMods.com Evergreen Scripts");
	});
	//
	document.getElementById("nick").placeholder = "Name";
	$( document ).ready(function() {
	nh = document.getElementById("overlays");
	cachednh = nh.innerHTML;
	nh.innerHTML = cachednh.replace("
Type your nick or leave it empty:
", "enter a name");
	});
	nodeDiv.id = "includedContent";
	nodeDiv.style.width = "640px"
	nodeDiv.style.backgroundColor = "#000000";
	nodeDiv.style.zIndex = 9999999999;
	nodeDiv.style.position = "relative";
	nodeDiv.style.padding = "5px";
	nodeDiv.style.left = "-170px";
	nodeDiv.style.borderRadius = "5px";
	nodeDiv.style.color = "#dddddd";
	nodeDiv.innerHTML = "
Version 1.6.1  custom skins on their way

Our website, forum, and mumble.
";
	nodeDiv.innerHTML += "connections steps";
	nodeDiv.innerHTML += "\

\

1: Get ip address from friend.
\

2: Put it in text box below.
\

3: Press the swirly icon next to it.
\

Note: Check with your friend to see whos #1 on the leaderboard
\

\

\
	Disable adblocking software! We finally tracked down an issue to adblocking software, Turns out that it breaks the game and our modifications in random and unexpected ways. Beside Zeach provides this game free and we all need to support him!\

\
	";
	jQuery('#region').parent().get(0).appendChild(document.createElement("br"));
	jQuery('#region').parent().get(0).appendChild(nodeDiv);
	var selector = jQuery('#region');
	var playBtn = jQuery('#playBtn');
	var nodeInput = document.createElement("input");
	var nodeSpan = document.createElement("span");
	var nodeBr = document.createElement("br");
	nodeSpan.className = "glyphicon glyphicon-refresh";
	nodeSpan.style.fontSize = "1.5em";
	nodeSpan.style.cssFloat = "left";
	nodeSpan.style.paddingTop = "5px";
	nodeSpan.style.paddingLeft = "15px";
	nodeSpan.addEventListener("click", function (e) {
	    if (modBlocking == false) {
                        //jQuery('#region').style.height = "0px";
                        jQuery('#region').hide();
                        //jQuery('#gamemode').style.height = "0px";
                        jQuery('#gamemode').hide();
	                      console.log ("clicked refresh");
				var oldregionval = jQuery('#region').val;
	                      jQuery('#region').val("EU-London");
       	               jQuery('#region').change();
       	               jQuery('#region').val("SG-Singapore");
			jQuery('#region').change();
			jQuery('#region').val(oldregionval);
			jQuery('#region').change();
			 jQuery('#gamemode').change();
			      //jQuery(this).fadeOut(100).fadeIn(100);
	    }
	});
	nodeInput.className = "form-control";
	nodeInput.id = "iphack"
	nodeInput.style.width = "85%";
	nodeInput.style.cssFloat = "left";
	nodeInput.style.cssClear = "right";
	nodeInput.style.border = "2px solid green";
	nodeInput.placeholder = "Alternative server ip:port here.";
	jQuery(playBtn).parent().get(0).appendChild(nodeBr);
	jQuery(playBtn).parent().get(0).appendChild(nodeInput);
	jQuery(playBtn).parent().get(0).appendChild(nodeSpan);
	jQuery('#iphack').change(function() {
	    if (jQuery('#iphack').val() == "") {
	        modBlocking = true;
	    }
	    modBlocking = false;
	});
	jQuery('#playBtn').off();
	$('.btn-needs-server').prop('disabled', false);
	jQuery('#playBtn').click(function() {
	    setNick(document.getElementById('nick').value);
	    return false;
	});

}

(function(window) {
    var WebSocket_original = window.WebSocket;
    window.WebSocket_original = WebSocket_original;
    var newWebSocket = 0;
    window.WebSocket = function(data) {
        if (modBlocking == true) {
            newWebSocket = new window.WebSocket_original(data);
		jQuery('#includedContent').html("Here is the IP address of the server you are connected to currently, pass it to your friends for team playing.
" + data.replace('ws://', '') + "
 ");
        } else {
            console.log("HAXXED: connecting to " + jQuery('#iphack').val() + "(ignoring: " + data + ")");
            newWebSocket = new window.WebSocket_original("ws://" + jQuery('#iphack').val());
		jQuery('#includedContent').html("
Connected to " +  jQuery('#iphack').val() + "

Check leaderboard with your friend to ensure you are both on the exact world on the sameserver.

If you cannot see the same people in the leaderboard as your friend, press the swirly icon next the ip box to try another world on the same game server.");

        }
        return newWebSocket;

    };
})(window);

<|endoftext|>