<commit_before>/*
 * These are routines used by our testing code.
 *
 * jQuery is not necesarily present. Don't rely on it
 * for routine operations.
 */

function ph_select_query(sel) {
    var list, i, els = [], startIdx, braceCounter, searchText, containsSelector;
    containsSelector = ':contains(';
    startIdx = sel.indexOf(containsSelector);
    if (startIdx !== -1) {
        // in jQuery we have :contains, try to simulate that
        // behavior here - at least for plain text

        // we assume that our :contains() condition is the last condition of the selector
        braceCounter = 1;
        for (i = startIdx+containsSelector.length; i < sel.length; i++) {
            if (sel[i] == '(')
                braceCounter++;
            else if (sel[i] == ')')
                braceCounter--;

            if (!braceCounter)
                break;
        }
        // if there's more after the :contains() condition, bail out
        if ((i + 1) < sel.length)
            throw "'" + sel + "': we can only handle :contains without jquery if it's the last condition";
        searchText = sel.substr(startIdx + containsSelector.length, i - startIdx - containsSelector.length);
        list = Array.prototype.filter.call(
            document.querySelectorAll(sel.substr(0, startIdx)),function(x) {
                return x.textContent.indexOf(searchText) > -1;
            }
        );
    } else {
        list = document.querySelectorAll(sel);
    }
    for (i = 0; i < list.length; i++)
        els.push(list[i]);
    return els;
}

function ph_select(sel) {
    // if jQuery isn't available, use querySelectorAll
    if (!window.jQuery)
      return ph_select_query(sel);

    var list = window.jQuery(sel);
    var i, els = [];
    for (i = 0; i < list.length; i++)
        els.push(list[i]);
    return els;
}

function ph_only(els, sel)
{
    if (els.length === 0)
        throw sel + " not found";
    if (els.length > 1)
        throw sel + " is ambigous";
    return els[0];
}

function ph_find (sel)
{
    var els = ph_select(sel);
    return ph_only(els, sel);
}

function ph_count(sel) {
    var els = ph_select(sel);
    return els.length;
}

function ph_count_check(sel, expected_num) {
    count = ph_count(sel);
    if (count != expected_num)
        throw "found " + count + " " + sel + " not " + expected_num;
    return count;
}

function ph_val (sel)
{
    var el = ph_find(sel);
    if (el.value === undefined)
        throw sel + " does not have a value";
    return el.value;
}

function ph_set_val (sel, val)
{
    var el = ph_find(sel);
    if (el.value === undefined)
        throw sel + " does not have a value";
    el.value = val;
    var ev = document.createEvent("Event");
    ev.initEvent("change", true, false);
    el.dispatchEvent(ev);
}

function ph_has_val (sel, val)
{
    return ph_val(sel) == val;
}

function ph_text (sel)
{
    var el = ph_find(sel);
    if (el.textContent === undefined)
        throw sel + " can not have text";
    return el.textContent;
}

function ph_attr (sel, attr)
{
    return ph_find(sel).getAttribute(attr);
}

function ph_set_attr (sel, attr, val)
{
    var el = ph_find(sel);
    if (val === null || val === undefined)
        el.removeAttribute(attr);
    else
        el.setAttribute(attr, val);

    var ev = document.createEvent("Event");
    ev.initEvent("change", true, false);
    el.dispatchEvent(ev);
}

function ph_has_attr (sel, attr, val)
{
    return ph_attr(sel, attr) == val;
}

function ph_click(sel, force) {
    var el = ph_find(sel);

    /* The element has to be visible, and not collapsed */
    if (!force && (el.offsetWidth <= 0 || el.offsetHeight <= 0))
        throw sel + " is not visible";

    var ev = document.createEvent("MouseEvent");
    ev.initMouseEvent(
        "click",
        true /* bubble */, true /* cancelable */,
        window, null,
        0, 0, 0, 0, /* coordinates */
        false, false, false, false, /* modifier keys */
        0 /*left*/, null);

    /* The click has to actually work */
    var clicked = false;
    function click() {
        clicked = true;
    }

    el.addEventListener("click", click, true);

    /* Now dispatch the event */
    el.dispatchEvent(ev);

    el.removeEventListener("click", click, true);

    /* It really had to work */
    if (!clicked)
        throw sel + " is disabled or somehow not clickable";
}

function ph_set_checked (sel, val)
{
    var el = ph_find(sel);
    if (el.checked === undefined)
        throw sel + " is not checkable";
    el.checked = val;

    var ev = document.createEvent("Event");
    ev.initEvent("change", true, false);
    el.dispatchEvent(ev);
}

function ph_is_visible (sel)
{
    var el = ph_find(sel);
    return (el.offsetWidth > 0 || el.offsetHeight > 0) && el.style.visibility != "hidden";
}

function ph_is_present(sel)
{
    var els = ph_select(sel);
    return els.length > 0;
}

function ph_in_text (sel, text)
{
    return ph_text(sel).indexOf(text) != -1;
}

function ph_text_is (sel, text)
{
    return ph_text(sel) == text;
}

function ph_go(href) {
    if (href.indexOf("#") === 0) {
        window.location.hash = href;

    } else {
        if (window.name.indexOf("cockpit1") !== 0)
            throw "ph_go() called in non cockpit window";
        var control = {
            command: "jump",
            location: href
        };
        window.parent.postMessage("\n" + JSON.stringify(control), "*");
    }
}

function ph_focus(sel)
{
    ph_find(sel).focus();
}
<commit_msg>test: Fix contains selector without jquery<commit_after>/*
 * These are routines used by our testing code.
 *
 * jQuery is not necesarily present. Don't rely on it
 * for routine operations.
 */

function ph_select_query(sel) {
    var list, i, els = [], startIdx, braceCounter, searchText, containsSelector;
    containsSelector = ':contains(';
    startIdx = sel.indexOf(containsSelector);
    if (startIdx !== -1) {
        // in jQuery we have :contains, try to simulate that
        // behavior here - at least for plain text

        // we assume that our :contains() condition is the last condition of the selector
        braceCounter = 1;
        for (i = startIdx+containsSelector.length; i < sel.length; i++) {
            if (sel[i] == '(')
                braceCounter++;
            else if (sel[i] == ')')
                braceCounter--;

            if (!braceCounter)
                break;
        }
        // if there's more after the :contains() condition, bail out
        if ((i + 1) < sel.length)
            throw "'" + sel + "': we can only handle :contains without jquery if it's the last condition";
        searchText = sel.substr(startIdx + containsSelector.length, i - startIdx - containsSelector.length);
        var len = searchText.length;
        if ((searchText.charAt(0) === '"' && searchText.charAt(len-1) === '"') ||
            (searchText.charAt(0) === "'" && searchText.charAt(len-1) === "'")) {
                searchText = searchText.substr(1, len-2);
        }
        list = Array.prototype.filter.call(
            document.querySelectorAll(sel.substr(0, startIdx)),function(x) {
                return x.textContent.indexOf(searchText) > -1;
            }
        );
    } else {
        list = document.querySelectorAll(sel);
    }

    for (i = 0; i < list.length; i++)
        els.push(list[i]);
    return els;
}

function ph_select(sel) {
    // if jQuery isn't available, use querySelectorAll
    if (!window.jQuery)
      return ph_select_query(sel);

    var list = window.jQuery(sel);
    var i, els = [];
    for (i = 0; i < list.length; i++)
        els.push(list[i]);
    return els;
}

function ph_only(els, sel)
{
    if (els.length === 0)
        throw sel + " not found";
    if (els.length > 1)
        throw sel + " is ambigous";
    return els[0];
}

function ph_find (sel)
{
    var els = ph_select(sel);
    return ph_only(els, sel);
}

function ph_count(sel) {
    var els = ph_select(sel);
    return els.length;
}

function ph_count_check(sel, expected_num) {
    count = ph_count(sel);
    if (count != expected_num)
        throw "found " + count + " " + sel + " not " + expected_num;
    return count;
}

function ph_val (sel)
{
    var el = ph_find(sel);
    if (el.value === undefined)
        throw sel + " does not have a value";
    return el.value;
}

function ph_set_val (sel, val)
{
    var el = ph_find(sel);
    if (el.value === undefined)
        throw sel + " does not have a value";
    el.value = val;
    var ev = document.createEvent("Event");
    ev.initEvent("change", true, false);
    el.dispatchEvent(ev);
}

function ph_has_val (sel, val)
{
    return ph_val(sel) == val;
}

function ph_text (sel)
{
    var el = ph_find(sel);
    if (el.textContent === undefined)
        throw sel + " can not have text";
    return el.textContent;
}

function ph_attr (sel, attr)
{
    return ph_find(sel).getAttribute(attr);
}

function ph_set_attr (sel, attr, val)
{
    var el = ph_find(sel);
    if (val === null || val === undefined)
        el.removeAttribute(attr);
    else
        el.setAttribute(attr, val);

    var ev = document.createEvent("Event");
    ev.initEvent("change", true, false);
    el.dispatchEvent(ev);
}

function ph_has_attr (sel, attr, val)
{
    return ph_attr(sel, attr) == val;
}

function ph_click(sel, force) {
    var el = ph_find(sel);

    /* The element has to be visible, and not collapsed */
    if (!force && (el.offsetWidth <= 0 || el.offsetHeight <= 0))
        throw sel + " is not visible";

    var ev = document.createEvent("MouseEvent");
    ev.initMouseEvent(
        "click",
        true /* bubble */, true /* cancelable */,
        window, null,
        0, 0, 0, 0, /* coordinates */
        false, false, false, false, /* modifier keys */
        0 /*left*/, null);

    /* The click has to actually work */
    var clicked = false;
    function click() {
        clicked = true;
    }

    el.addEventListener("click", click, true);

    /* Now dispatch the event */
    el.dispatchEvent(ev);

    el.removeEventListener("click", click, true);

    /* It really had to work */
    if (!clicked)
        throw sel + " is disabled or somehow not clickable";
}

function ph_set_checked (sel, val)
{
    var el = ph_find(sel);
    if (el.checked === undefined)
        throw sel + " is not checkable";
    el.checked = val;

    var ev = document.createEvent("Event");
    ev.initEvent("change", true, false);
    el.dispatchEvent(ev);
}

function ph_is_visible (sel)
{
    var el = ph_find(sel);
    return (el.offsetWidth > 0 || el.offsetHeight > 0) && el.style.visibility != "hidden";
}

function ph_is_present(sel)
{
    var els = ph_select(sel);
    return els.length > 0;
}

function ph_in_text (sel, text)
{
    return ph_text(sel).indexOf(text) != -1;
}

function ph_text_is (sel, text)
{
    return ph_text(sel) == text;
}

function ph_go(href) {
    if (href.indexOf("#") === 0) {
        window.location.hash = href;

    } else {
        if (window.name.indexOf("cockpit1") !== 0)
            throw "ph_go() called in non cockpit window";
        var control = {
            command: "jump",
            location: href
        };
        window.parent.postMessage("\n" + JSON.stringify(control), "*");
    }
}

function ph_focus(sel)
{
    ph_find(sel).focus();
}
<|endoftext|>


<commit_before>(function(app) {
  'use strict';

  var jCore = require('jcore');
  var helper = app.helper || require('../helper.js');
  var dom = app.dom || require('../dom.js');

  var SidebarToggleButton = helper.inherits(function(props) {
    SidebarToggleButton.super_.call(this);

    this.type = this.prop(SidebarToggleButton.TYPE_COLLAPSE);
    this.disabled = this.prop(false);
    this.element = this.prop(props.element);
    this.cache = this.prop({});

    this.collapser = props.collapser;
    this.expander = props.expander;
  }, jCore.Component);

  SidebarToggleButton.prototype.toggler = (function() {
    var map = { collapse: 'collapser', expand: 'expander' };
    return function() {
      return this[map[this.type()]]();
    };
  })();

  SidebarToggleButton.prototype.switchType = (function() {
    var map = { collapse: 'expand', expand: 'collapse' };
    return function() {
      this.type(map[this.type()]);
    };
  })();

  SidebarToggleButton.prototype.registerTapListener = function() {
    var target;
    new dom.Draggable({
      element: this.element(),
      onstart: function(x, y, event) {
        target = dom.target(event);
        dom.cancel(event);
        dom.removeFocus();
      },
      onend: function(dx, dy, event) {
        if (dom.target(event) !== target)
          return;

        this.disabled(true);
        this.toggler().then(function() {
          this.switchType();
          this.disabled(false);
        }.bind(this)).catch(function() {
          this.disabled(false);
        }.bind(this));
      }.bind(this)
    });
  };

  SidebarToggleButton.prototype.redraw = function() {
    this.redrawType();
    this.redrawDisabled();
  };

  SidebarToggleButton.prototype.redrawType = function() {
    var type = this.type();
    var cache = this.cache();

    if (type === cache.type)
      return;

    dom.data(this.element(), 'type', type);
    cache.type = type;
  };

  SidebarToggleButton.prototype.redrawDisabled = function() {
    var disabled = this.disabled();
    var cache = this.cache();

    if (disabled === cache.disabled)
      return;

    dom.disabled(this.element(), disabled);
    cache.disabled = disabled;
  };

  SidebarToggleButton.TYPE_COLLAPSE = 'collapse';
  SidebarToggleButton.TYPE_EXPAND = 'expand';

  if (typeof module !== 'undefined' && module.exports)
    module.exports = SidebarToggleButton;
  else
    app.SidebarToggleButton = SidebarToggleButton;
})(this.app || (this.app = {}));
<commit_msg>Refactor code for tap listener of sidebar-toggle-button<commit_after>(function(app) {
  'use strict';

  var jCore = require('jcore');
  var helper = app.helper || require('../helper.js');
  var dom = app.dom || require('../dom.js');

  var SidebarToggleButton = helper.inherits(function(props) {
    SidebarToggleButton.super_.call(this);

    this.type = this.prop(SidebarToggleButton.TYPE_COLLAPSE);
    this.disabled = this.prop(false);
    this.element = this.prop(props.element);
    this.cache = this.prop({});

    this.collapser = props.collapser;
    this.expander = props.expander;
  }, jCore.Component);

  SidebarToggleButton.prototype.toggler = (function() {
    var map = { collapse: 'collapser', expand: 'expander' };
    return function() {
      return this[map[this.type()]]();
    };
  })();

  SidebarToggleButton.prototype.switchType = (function() {
    var map = { collapse: 'expand', expand: 'collapse' };
    return function() {
      this.type(map[this.type()]);
    };
  })();

  SidebarToggleButton.prototype.registerTapListener = function() {
    var target;
    new dom.Draggable({
      element: this.element(),
      onstart: function(x, y, event) {
        target = dom.target(event);
        dom.cancel(event);
        dom.removeFocus();
      },
      onend: function(dx, dy, event) {
        if (dom.target(event) === target)
          this.ontap();
      }.bind(this)
    });
  };

  SidebarToggleButton.prototype.redraw = function() {
    this.redrawType();
    this.redrawDisabled();
  };

  SidebarToggleButton.prototype.redrawType = function() {
    var type = this.type();
    var cache = this.cache();

    if (type === cache.type)
      return;

    dom.data(this.element(), 'type', type);
    cache.type = type;
  };

  SidebarToggleButton.prototype.redrawDisabled = function() {
    var disabled = this.disabled();
    var cache = this.cache();

    if (disabled === cache.disabled)
      return;

    dom.disabled(this.element(), disabled);
    cache.disabled = disabled;
  };

  SidebarToggleButton.prototype.ontap = function() {
    this.disabled(true);
    this.toggler().then(function() {
      this.switchType();
      this.disabled(false);
    }.bind(this)).catch(function() {
      this.disabled(false);
    }.bind(this));
  };

  SidebarToggleButton.TYPE_COLLAPSE = 'collapse';
  SidebarToggleButton.TYPE_EXPAND = 'expand';

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


<commit_before>turnDupesIntoGems(2, 7);
function turnDupesIntoGems(keepCnt, types){

	/*
	Item-Types

	3 - Wallpaper
	4 - Emoticon
	10 - Items from events (spring-cleaning, ...)
	*/
	var itemReg, result, sum=0;
	switch(types){
        case 1: itemReg = "3"; result = {'3': {}}; break;
		case 2: itemReg = "4"; result = {'4': {}}; break;
		case 4: itemReg = "10"; result = {'10': {}}; break;
        case 3: itemReg = "3|4"; result = {'3': {}, '4': {}}; break;
        case 5: itemReg = "3|10"; result = {'3': {}, '10': {}}; break;
        case 6: itemReg = "4|10"; result = {'4': {}, '10': {}}; break;
        case 7: itemReg = "3|4|10"; result = {'3': {}, '4': {}, '10': {}}; break;
        default: alert('This type is not set');
    }

	var itemTypes = new RegExp("item_class_("+itemReg+")");
    var inventory = window.g_ActiveInventory.m_rgPages;
    var nodes = inventory.map(page => { console.log(page); return Array.from(page[0]["m_$Page"][0].childNodes); });
    var childs = nodes.flat(1).reduce((r, child) => {
        if(child.rgItem
        && child.rgItem.contextid == 6
        && child.rgItem.appid == 753
        && child.rgItem.description
        && child.rgItem.description.tags)

        // find item_class (background, emoticon, ...)
        child.rgItem.description.tags.find(o => {
            if(!o.internal_name.match(itemTypes)) return;

            // find item-type
            var rg = child.rgItem;
            var instance = o.internal_name.replace(/\D+/g, '');
			var findLink = rg.description.owner_actions;
			var itype = 0;
            Object.keys(findLink).find(l => {
                if(findLink[l].link.indexOf('GetGooValue') < 1) return;
                itype = /(\d+),\s\d\s\)/.exec(findLink[l].link)[1];
                return false;
            });

            // set object by classid and push assetid's to it
			// use appid of market-hashname - since event-items are
			// using different appids for market_fee_app and hashname
            if(r[instance].hasOwnProperty(rg.classid)){
                r[instance][rg.classid]['assetid'].push(rg.assetid);
            } else {
                r[instance][rg.classid] = {
                    appid: /(\d+)-/.exec(rg.description.market_hash_name)[1],
                    name: rg.description.name,
                    assetid: [rg.assetid],
                    type: o.localized_tag_name,
                    itype: itype,
                    goos: 0
                };
            }
        })
        return r;
    }, result);

	// remove all matches with just 1 item left and keep x items
	Object.keys(childs).map(i => {
		Object.keys(childs[i]).map(f => {
			var asset = childs[i][f]['assetid'];
			if(asset.length <= keepCnt || asset.length <= 1){
				delete childs[i][f];
            } else {
				childs[i][f]['assetid'] = asset.slice(0,-keepCnt);
				sum += (asset.length-keepCnt);
			}
        });
	});
	console.log(`Total of ${sum} items`);
    console.log(childs);

	var obj = [];
	Object.keys(childs).map(i => {
		Object.keys(childs[i]).map(f => {
            obj.push(childs[i][f]);
        });
    });
	console.log(`There are ${obj.length} different items.`);
	console.log(obj);

	var arr = [];
	obj.map(o => {
		o['assetid'].map(a => {
			arr.push({
                appid: o.appid,
                assetid: a,
                type: o.type,
                goos: o.goos
            });
        });
    });
	console.log(arr);
}<commit_msg>Cleanup<commit_after><|endoftext|>


<commit_before>define(function (require) {
    'use strict';

    var util = require('util');
    var viewport = require('viewport');
    var Img = require('components/mip-img');
    var img = new Img();
    var clickEvent = util.event.create('click');

    var ele = document.createElement('script');
    ele.src = 'https://mipcache.bdstatic.com/static/v1/mip.js';
    document.body.appendChild(ele);

    var dispatchEvent = function (element, evt, event) {
        if (!element) {
            return;
        }
        if (document.createEventObject) {
            return element.fireEvent('on' + event, evt)
        } else {
            evt.initEvent(event, true, true);
            return !element.dispatchEvent(evt);
        }
    };

    var promise = new Promise(function (resolve, reject) {
        var HTML = "<mip-img id='mfivc' width=350 height=263 alt='mip img' popup src='https://www.mipengine.org/static/img/sample_01.jpg'></mip-img>";
        var ele = util.dom.create(HTML);
        document.body.prepend(ele);
        viewport.setScrollTop(0);
        setTimeout(function () {
            resolve();
        }, 1000);
    });

    describe('mip img', function () {
        it('firstInviewCallback', function () {
            var HTML = "<mip-img width=350 height=263 alt='mip img' popup src='https://www.mipengine.org/static/img/sample_01.jpg'></mip-img>";
            img.element = util.dom.create(HTML);
            img.customElement = {resourcesComplete:function(){}};
            img.firstInviewCallback();
            var ele = img.element.querySelectorAll('img');
            expect(ele.length).to.be.at.least(1);
        });

        it('load error', function () {
            var HTML = "<mip-img width=350 height=263 alt='mip img' popup src='https://www.mipengine.org/static/img/sample_01xx.jpg'></mip-img>";
            img.element = util.dom.create(HTML);
            img.customElement = {resourcesComplete:function(){}};
            img.firstInviewCallback();
            var ele = img.element.querySelectorAll('img');
            expect(ele.length).to.be.at.least(1);
        });

        it('has build', function () {
            var HTML = "<mip-img width=350 height=263 alt='mip img' popup src='https://www.mipengine.org/static/img/sample_01.jpg'></mip-img>";
            img.element = util.dom.create(HTML);
            img.customElement = {resourcesComplete:function(){}};
            var result = img.firstInviewCallback();
            expect(result).to.be.undefined;
        });

        it('event', function (done) {
            promise.then(function () {
                var renderEle = document.querySelector('#mfivc img');
                dispatchEvent(renderEle, clickEvent, 'click');
                var popupWrapper = document.querySelector('.mip-img-popUp-wrapper');
                dispatchEvent(popupWrapper, clickEvent, 'click');

                // resize
                var resizeEvent = util.event.create('resize');
                dispatchEvent(window, resizeEvent, 'resize');
                done();
            }).catch(done);
        });
    });
});<commit_msg>update<commit_after>define(function (require) {
    'use strict';

    var util = require('util');
    var viewport = require('viewport');
    var Img = require('components/mip-img');
    var img = new Img();
    var clickEvent = util.event.create('click');

    var dispatchEvent = function (element, evt, event) {
        if (!element) {
            return;
        }
        if (document.createEventObject) {
            return element.fireEvent('on' + event, evt)
        } else {
            evt.initEvent(event, true, true);
            return !element.dispatchEvent(evt);
        }
    };

    var promise = new Promise(function (resolve, reject) {
        var ele = document.createElement('script');
        ele.src = 'https://mipcache.bdstatic.com/static/v1/mip.js';
        document.body.appendChild(ele);
        ele.onload = function () {
            var HTML = "<mip-img id='mfivc' width=350 height=263 alt='mip img' popup src='https://www.mipengine.org/static/img/sample_01.jpg'></mip-img>";
            var ele = util.dom.create(HTML);
            document.body.prepend(ele);
            viewport.setScrollTop(0);
            setTimeout(function () {
                resolve();
            }, 1000);
        }

        ele.onerror = function () {
            reject();
        }
    });

    describe('mip img', function () {
        it('firstInviewCallback', function () {
            var HTML = "<mip-img width=350 height=263 alt='mip img' popup src='https://www.mipengine.org/static/img/sample_01.jpg'></mip-img>";
            img.element = util.dom.create(HTML);
            img.customElement = {resourcesComplete:function(){}};
            img.firstInviewCallback();
            var ele = img.element.querySelectorAll('img');
            expect(ele.length).to.be.at.least(1);
        });

        it('load error', function () {
            var HTML = "<mip-img width=350 height=263 alt='mip img' popup src='https://www.mipengine.org/static/img/sample_01xx.jpg'></mip-img>";
            img.element = util.dom.create(HTML);
            img.customElement = {resourcesComplete:function(){}};
            img.firstInviewCallback();
            var ele = img.element.querySelectorAll('img');
            expect(ele.length).to.be.at.least(1);
        });

        it('has build', function () {
            var HTML = "<mip-img width=350 height=263 alt='mip img' popup src='https://www.mipengine.org/static/img/sample_01.jpg'></mip-img>";
            img.element = util.dom.create(HTML);
            img.customElement = {resourcesComplete:function(){}};
            var result = img.firstInviewCallback();
            expect(result).to.be.undefined;
        });

        it('event', function (done) {
            promise.then(function () {
                var renderEle = document.querySelector('#mfivc img');
                dispatchEvent(renderEle, clickEvent, 'click');
                var popupWrapper = document.querySelector('.mip-img-popUp-wrapper');
                dispatchEvent(popupWrapper, clickEvent, 'click');

                // resize
                var resizeEvent = util.event.create('resize');
                dispatchEvent(window, resizeEvent, 'resize');
                done();
            });
        });
    });
});<|endoftext|>


<commit_before>import Ember from 'ember';
import layout from '../templates/components/sl-chart';
import { throwChartError } from '../utils/error';

/**
 * @module
 * @augments ember/Component
 */
export default Ember.Component.extend({

    // -------------------------------------------------------------------------
    // Dependencies

    // -------------------------------------------------------------------------
    // Attributes

    /** @type {String[]} */
    classNames: [
        'panel',
        'panel-default',
        'chart',
        'sl-ember-components'
    ],

    /** @type {Object} */
    layout,

    // -------------------------------------------------------------------------
    // Actions

    // -------------------------------------------------------------------------
    // Events

    /**
     * init event hook
     *
     * @returns {undefined}
     */
    init() {
        this._super( ...arguments );
        this.initialize();
    },

    /**
     * didInsertElement event hook
     *
     * @returns {undefined}
     */
    didInsertElement() {
        this._super( ...arguments );
        this.setupChart();
    },

    // -------------------------------------------------------------------------
    // Properties

    /**
     * The highchart instantiation
     *
     * @type {?Object}
     */
    chart: null,

    /**
     * Height value used for inline style
     *
     * @type {Number|String}
     */
    height: 'auto',

    /**
     * When true, the chart's panel body will be in a loading state
     *
     * @type {Boolean}
     */
    loading: false,

    /**
     * The collection of series data for the chart
     *
     * @type {?Object[]}
     */
    series: null,

    /**
     * Width value used for inline style
     *
     * @type {Number|String}
     */
    width: 'auto',

    // -------------------------------------------------------------------------
    // Observers

    /**
     * Updates the chart's height
     *
     * @function
     * @returns {undefined}
     */
    setHeight: Ember.observer(
        'height',
        function() {
            this.$( '> .panel-body > div' ).height( this.get( 'height' ) );
        }
    ),

    /**
     * Sets up Highcharts initialization
     *
     * @private
     * @returns {undefined}
     */
    setupChart() {
        const chartDiv = this.$( '> .panel-body > div' );

        this.setHeight();
        this.setWidth();

        chartDiv.highcharts( this.get( 'highchartsOptions' ) );
        this.set( 'chart', chartDiv.highcharts() );
        this.updateData();
    },

    /**
     * Updates the chart's width
     *
     * @function
     * @returns {undefined}
     */
    setWidth: Ember.observer(
        'width',
        function() {
            this.$( '> .panel-body > div' ).width( this.get( 'width' ) );
        }
    ),

    /**
     * Updates the chart's series data
     *
     * @function
     * @returns {undefined}
     */
    updateData: Ember.observer(
        'series',
        function() {
            const chart = this.get( 'chart' );
            const series = this.get( 'series' );

            if ( !chart.hasOwnProperty( 'series' ) ) {
                chart.series = [];
            }

            for ( let i = 0; i < series.length; i++ ) {
                if ( chart.series.length <= i ) {
                    chart.addSeries( series[ i ] );
                } else {
                    chart.series[ i ].setData( series[ i ].data );
                }
            }
        }
    ),

    // -------------------------------------------------------------------------
    // Methods

    /**
     * Check passed parameters on initialization
     *
     * @private
     * @throws {sl-ember-components/utils/error/chart} Series property must be an Array
     * @throws {sl-ember-components/utils/error/chart} Options property must be an Object
     * @returns {undefined}
     */
    initialize() {
        if ( 'array' !== Ember.typeOf( this.get( 'series' ) ) ) {
            throwChartError( 'Series property must be an array' );
        }

        /* jshint ignore:start */
        const options = this.get( 'options' );
        if (
            (
                'instance' !== Ember.typeOf( options ) &&
                'object' !== Ember.typeOf( options )
            ) ||
            'symbol' === typeof options
        ) {
            throwChartError( 'Options property must be an Object' );
        }
        /* jshint ignore:end */
    },

    /**
     * Options for Highcharts
     *
     * @function
     * @returns {Object}
     */
    highchartsOptions: Ember.computed(
        function() {
            const chartStyle = {
                fontFamily: [
                    'Helvetica',
                    'Arial',
                    'sans-serif'
                ].join( ', ' ),
                fontSize: '13px'
            };

            const options = Ember.$.extend( true, {
                title: '',
                chart: {
                    animation: false,
                    backgroundColor: 'rgba(255, 255, 255, 0)',
                    style: chartStyle
                },
                colors: [
                    '#298fce',
                    '#94302e',
                    '#00a14b',
                    '#f29c1e',
                    '#fadb00',
                    '#34495d'
                ],
                credits: {
                    enabled: false
                },
                legend: {
                    itemStyle: chartStyle
                },
                plotOptions: {
                    bar: {
                        borderColor: 'transparent'
                    },
                    series: {
                        animation: false
                    }
                },
                tooltip: {
                    animation: false,
                    backgroundColor: 'rgba(0, 0, 0, 0.8)',
                    borderWidth: 0,
                    shadow: false,
                    style: {
                        color: '#fff'
                    }
                },
                xAxis: {
                    labels: {
                        style: chartStyle
                    }
                },
                yAxis: {
                    labels: {
                        style: chartStyle
                    }
                }
            }, this.get( 'options' ) || {} );

            // Title property in options must be kept null in order to
            // suppress its default behavior for our specific usage
            options.title = null;

            return options;
        }
    )

});
<commit_msg>Fixed issues outlined in PR.<commit_after>import Ember from 'ember';
import layout from '../templates/components/sl-chart';
import { throwChartError } from '../utils/error';

/**
 * @module
 * @augments ember/Component
 */
export default Ember.Component.extend({

    // -------------------------------------------------------------------------
    // Dependencies

    // -------------------------------------------------------------------------
    // Attributes

    /** @type {String[]} */
    classNames: [
        'panel',
        'panel-default',
        'chart',
        'sl-ember-components'
    ],

    /** @type {Object} */
    layout,

    // -------------------------------------------------------------------------
    // Actions

    // -------------------------------------------------------------------------
    // Events

    /**
     * init event hook
     *
     * @returns {undefined}
     */
    init() {
        this._super( ...arguments );
        this.initialize();
    },

    /**
     * didInsertElement event hook
     *
     * @returns {undefined}
     */
    didInsertElement() {
        this._super( ...arguments );
        this.setupChart();
    },

    // -------------------------------------------------------------------------
    // Properties

    /**
     * The highchart instantiation
     *
     * @type {?Object}
     */
    chart: null,

    /**
     * Height value used for inline style
     *
     * @type {Number|String}
     */
    height: 'auto',

    /**
     * When true, the chart's panel body will be in a loading state
     *
     * @type {Boolean}
     */
    loading: false,

    /**
     * The collection of series data for the chart
     *
     * @type {?Object[]}
     */
    series: null,

    /**
     * Width value used for inline style
     *
     * @type {Number|String}
     */
    width: 'auto',

    // -------------------------------------------------------------------------
    // Observers

    /**
     * Options for Highcharts
     *
     * @function
     * @returns {Object}
     */
    highchartsOptions: Ember.computed(
        function() {
            const chartStyle = {
                fontFamily: [
                    'Helvetica',
                    'Arial',
                    'sans-serif'
                ].join( ', ' ),
                fontSize: '13px'
            };

            const options = Ember.$.extend( true, {
                title: '',
                chart: {
                    animation: false,
                    backgroundColor: 'rgba(255, 255, 255, 0)',
                    style: chartStyle
                },
                colors: [
                    '#298fce',
                    '#94302e',
                    '#00a14b',
                    '#f29c1e',
                    '#fadb00',
                    '#34495d'
                ],
                credits: {
                    enabled: false
                },
                legend: {
                    itemStyle: chartStyle
                },
                plotOptions: {
                    bar: {
                        borderColor: 'transparent'
                    },
                    series: {
                        animation: false
                    }
                },
                tooltip: {
                    animation: false,
                    backgroundColor: 'rgba(0, 0, 0, 0.8)',
                    borderWidth: 0,
                    shadow: false,
                    style: {
                        color: '#fff'
                    }
                },
                xAxis: {
                    labels: {
                        style: chartStyle
                    }
                },
                yAxis: {
                    labels: {
                        style: chartStyle
                    }
                }
            }, this.get( 'options' ) || {} );

            // Title property in options must be kept null in order to
            // suppress its default behavior for our specific usage
            options.title = null;

            return options;
        }
    ),

    /**
     * Updates the chart's height
     *
     * @function
     * @returns {undefined}
     */
    setHeight: Ember.observer(
        'height',
        function() {
            this.$( '> .panel-body > div' ).height( this.get( 'height' ) );
        }
    ),

    /**
     * Updates the chart's width
     *
     * @function
     * @returns {undefined}
     */
    setWidth: Ember.observer(
        'width',
        function() {
            this.$( '> .panel-body > div' ).width( this.get( 'width' ) );
        }
    ),

    /**
     * Updates the chart's series data
     *
     * @function
     * @returns {undefined}
     */
    updateData: Ember.observer(
        'series',
        function() {
            const chart = this.get( 'chart' );
            const series = this.get( 'series' );

            if ( !chart.hasOwnProperty( 'series' ) ) {
                chart.series = [];
            }

            for ( let i = 0; i < series.length; i++ ) {
                if ( chart.series.length <= i ) {
                    chart.addSeries( series[ i ] );
                } else {
                    chart.series[ i ].setData( series[ i ].data );
                }
            }
        }
    ),

    // -------------------------------------------------------------------------
    // Methods

    /**
     * Check passed parameters on initialization
     *
     * @private
     * @throws {sl-ember-components/utils/error/chart} Series property must be an Array
     * @throws {sl-ember-components/utils/error/chart} Options property must be an Object
     * @returns {undefined}
     */
    initialize() {
        if ( 'array' !== Ember.typeOf( this.get( 'series' ) ) ) {
            throwChartError( 'Series property must be an array' );
        }

        /* jshint ignore:start */
        const options = this.get( 'options' );
        if (
            (
                'instance' !== Ember.typeOf( options ) &&
                'object' !== Ember.typeOf( options )
            ) ||
            'symbol' === typeof options
        ) {
            throwChartError( 'Options property must be an Object' );
        }
        /* jshint ignore:end */
    },

    /**
     * Sets up Highcharts initialization
     *
     * @private
     * @returns {undefined}
     */
    setupChart() {
        const chartDiv = this.$( '> .panel-body > div' );

        this.setHeight();
        this.setWidth();

        chartDiv.highcharts( this.get( 'highchartsOptions' ) );
        this.set( 'chart', chartDiv.highcharts() );
        this.updateData();
    }

});
<|endoftext|>


<commit_before>define('bforms-toolbar', [
    'bforms-toolbar-advancedSearch',
    'bforms-toolbar-add',
    'bforms-toolbar-quickSearch',
    'jquery',
    'jquery-ui-core',
    'amplify',
    'bforms-form'
], function (AdvancedSearch, Add, QuickSearch) {

    jQuery.nsx('bforms.toolbar.defaults');
    jQuery.nsx('bforms.toolbar.controls');

    //#region Toolbar
    var Toolbar = function (opt) {
        this.options = opt;
        this._create();
    };

    Toolbar.prototype.options = {
        uniqueName: null,
        saveTabState: true,
        tabContainerSelector: '.grid_toolbar_form',
        autoInitControls: true,
        saveState: true,
        reset: function ($grid) {

            var quickSearch = this.getControl('quickSearch');

            if (quickSearch != null) {
                quickSearch.$element.find('input').val('');
            }

            var advancedSearch = this.getControl('advancedSearch');
            var data;
            if (advancedSearch != null) {
                advancedSearch.$container.bsForm('reset');
                data = advancedSearch.$container.bsForm('parse');
            }

            var widget = this.element.data('bformsBsToolbar');
            for (var i = 0; i < widget.subscribers.length; i++) {
                widget.subscribers[i].bsGrid('reset', data, true);
            }
        },
        controls: null
    };

    Toolbar.prototype._create = function () {

        $.bforms.toolbar.defaults.AdvancedSearch = AdvancedSearch;
        $.bforms.toolbar.defaults.Add = Add;
        $.bforms.toolbar.defaults.QuickSearch = QuickSearch;

    };

    Toolbar.prototype._init = function () {

        if(!this.options.uniqueName){
            this.options.uniqueName = this.element.attr('id');
        }

        if (!this.options.uniqueName) {
            throw 'toolbar needs a unique name or the element on which it is aplied has to have an id attr';
        }

        this._controls = [];

        if (this.options.autoInitControls) {
            //init default controls if any
            for (var k in $.bforms.toolbar.defaults) {
                if (k in $.bforms.toolbar.defaults) {
                    var control = new $.bforms.toolbar.defaults[k](this.element);
                    var $btn = this.element.find(control._defaultOptions.selector);
                    if ($btn.length > 0) {
                        control.$element = $btn;
                        this._controls.push(control);
                    }
                }
            }
            //init custom controls requested outside of toolbar
            for (var k in $.bforms.toolbar.controls) {
                if (k in $.bforms.toolbar.controls) {
                    var control = new $.bforms.toolbar.controls[k](this.element);
                    this._controls.push(control);
                }
            }
        }

        if (this.options.controls instanceof Array) {
            for (var i = 0; i < this.options.controls.length; i++) {
                var control = new this.options.controls[i](this.element);
                this._controls.push(control);
            }
        }

        this.subscribers = new Array();

        if (this.options.subscribers) {
            this._addSubscribers(this.options.subscribers);
        }

        this._addControls(this._controls);

        this._expandSavedTab();
        console.log(this._controls);
    };

    Toolbar.prototype.reset = function () {
        if (typeof this.options.reset === "function") {
            this.options.reset.apply(this, arguments);
        }
    };

    Toolbar.prototype._addDelegates = function () {

    };

    Toolbar.prototype.controls = function (controls) {

        for (var i = 0; i < controls.length; i++) {
            var control = controls[i];
            control.init();
            this._controls.push(control);
        }

        this._addControls(controls);

    };

    Toolbar.prototype._addControls = function (controls) {

        if (!controls) {
            return;
        }

        for (var i = 0; i < controls.length; i++) {

            var control = controls[i];

            switch (control.type) {
                case "action": {
                    this._addAction(control);
                    break;
                }
                case "tab": {

                    this._addTab(control);

                    break;
                }
                default: {

                    this._addCustomControl(control);

                    break;
                }
            }

        }

    };

    Toolbar.prototype._addTab = function (tab) {

        tab.$container = $('#' + tab.$element.data('tabid'))

        tab.$element.on('click', { tab: tab }, $.proxy(this._evBtnTabClick, this));

        //control.options.init.call(this, tab.$container, control.options);

    };

    Toolbar.prototype._expandSavedTab = function () {

        var tabs = this._getTabs();

        for (var i = 0; i < tabs.length; i++) {
            var tab = tabs[i];
            if (amplify.store('slide|' + this.options.uniqueName + '|' + tab.options.selector)) {
                tab.$element.trigger('click');
            }
        }

    };

    Toolbar.prototype._addCustomControl = function (control) {

        if (typeof control.name !== 'string' || control.name.trim().length == 0) {
            throw 'all controls must have a name';
        }

        if (typeof control.options.selector !== 'string' || control.options.selector.trim().length == 0) {
            throw 'all controls must have a name';
        }

        //control.options.init.call(this, $(control.options.selector), control.options);

    };

    Toolbar.prototype._addAction = function (buttonOpt) {

        if (typeof buttonOpt.handler !== 'function') {
            throw 'action ' + buttonOpt.name + ' must implement an event handler';
        }

        var $elem = this.element.find(buttonOpt.selector);

        $elem.on('click', { buttonOpt: buttonOpt }, $.proxy(this._evBtnClick, this));

        var control = {
            name: buttonOpt.name,
            type: 'action',
            $element: $elem,
            options: buttonOpt
        };

        this._controls.push(control);
    };

    Toolbar.prototype._addSubscribers = function (subscribers) {

        for (var i = 0; i < subscribers.length; i++) {
            this._addSubscriber(subscribers[i]);
        }

    };

    Toolbar.prototype._addSubscriber = function (subscriber) {
        this.subscribers.push(subscriber);
    };

    Toolbar.prototype._evBtnClick = function (e) {

        e.preventDefault();

        var buttonOpt = e.data.buttonOpt;

        buttonOpt.handler.call(this, e);
    };

    Toolbar.prototype._evBtnTabClick = function (e, triggeredTab) {

        e.preventDefault();

        var clickedTab = e.data.tab;

        var tabs = this._getTabs();

        //close other tab, if any
        for (var i = 0; i < tabs.length; i++) {
            var tab = tabs[i];

            if (tab.$element == clickedTab.$element) {
                continue;
            }

            if (tab.$element.hasClass('selected')) {
                this._toggleTab(tab);
            }
        }

        if (triggeredTab && triggeredTab.$element.hasClass('selected')) {
            return;
        }

        this._toggleTab(clickedTab);

    };

    Toolbar.prototype._toggleTab = function(tab) {

        tab.$element.toggleClass('selected');
        if (tab.name == 'advancedSearch') {
            var quickSearch = this.getControl('quickSearch');
            if (quickSearch != null) {
                quickSearch.$element.toggleClass('selected');
            }
        }

        tab.$container.stop(true, false).slideToggle();

        if (this.options.saveState) {
            amplify.store('slide|' + this.options.uniqueName + '|' + tab.options.selector, tab.$element.hasClass('selected'));
        }

    };

    //#region helpers
    Toolbar.prototype._getTabs = function () {

        return this._controls.filter(function (el) {
            return el.type == 'tab';
        });

    };

    Toolbar.prototype.getControl = function(name) {
        var control = $.grep(this._controls, function(el) {
            return el.name == name;
        });

        if (control != null && control[0] != null) return control[0];

        return null;
    };
    //#endregion

    //#endregion

    $.widget('bforms.bsToolbar', Toolbar.prototype);
});<commit_msg>removed console.log()<commit_after>define('bforms-toolbar', [
    'bforms-toolbar-advancedSearch',
    'bforms-toolbar-add',
    'bforms-toolbar-quickSearch',
    'jquery',
    'jquery-ui-core',
    'amplify',
    'bforms-form'
], function (AdvancedSearch, Add, QuickSearch) {

    jQuery.nsx('bforms.toolbar.defaults');
    jQuery.nsx('bforms.toolbar.controls');

    //#region Toolbar
    var Toolbar = function (opt) {
        this.options = opt;
        this._create();
    };

    Toolbar.prototype.options = {
        uniqueName: null,
        saveTabState: true,
        tabContainerSelector: '.grid_toolbar_form',
        autoInitControls: true,
        saveState: true,
        reset: function ($grid) {

            var quickSearch = this.getControl('quickSearch');

            if (quickSearch != null) {
                quickSearch.$element.find('input').val('');
            }

            var advancedSearch = this.getControl('advancedSearch');
            var data;
            if (advancedSearch != null) {
                advancedSearch.$container.bsForm('reset');
                data = advancedSearch.$container.bsForm('parse');
            }

            var widget = this.element.data('bformsBsToolbar');
            for (var i = 0; i < widget.subscribers.length; i++) {
                widget.subscribers[i].bsGrid('reset', data, true);
            }
        },
        controls: null
    };

    Toolbar.prototype._create = function () {

        $.bforms.toolbar.defaults.AdvancedSearch = AdvancedSearch;
        $.bforms.toolbar.defaults.Add = Add;
        $.bforms.toolbar.defaults.QuickSearch = QuickSearch;

    };

    Toolbar.prototype._init = function () {

        if(!this.options.uniqueName){
            this.options.uniqueName = this.element.attr('id');
        }

        if (!this.options.uniqueName) {
            throw 'toolbar needs a unique name or the element on which it is aplied has to have an id attr';
        }

        this._controls = [];

        if (this.options.autoInitControls) {
            //init default controls if any
            for (var k in $.bforms.toolbar.defaults) {
                if (k in $.bforms.toolbar.defaults) {
                    var control = new $.bforms.toolbar.defaults[k](this.element);
                    var $btn = this.element.find(control._defaultOptions.selector);
                    if ($btn.length > 0) {
                        control.$element = $btn;
                        this._controls.push(control);
                    }
                }
            }
            //init custom controls requested outside of toolbar
            for (var k in $.bforms.toolbar.controls) {
                if (k in $.bforms.toolbar.controls) {
                    var control = new $.bforms.toolbar.controls[k](this.element);
                    this._controls.push(control);
                }
            }
        }

        if (this.options.controls instanceof Array) {
            for (var i = 0; i < this.options.controls.length; i++) {
                var control = new this.options.controls[i](this.element);
                this._controls.push(control);
            }
        }

        this.subscribers = new Array();

        if (this.options.subscribers) {
            this._addSubscribers(this.options.subscribers);
        }

        this._addControls(this._controls);

        this._expandSavedTab();
    };

    Toolbar.prototype.reset = function () {
        if (typeof this.options.reset === "function") {
            this.options.reset.apply(this, arguments);
        }
    };

    Toolbar.prototype._addDelegates = function () {

    };

    Toolbar.prototype.controls = function (controls) {

        for (var i = 0; i < controls.length; i++) {
            var control = controls[i];
            control.init();
            this._controls.push(control);
        }

        this._addControls(controls);

    };

    Toolbar.prototype._addControls = function (controls) {

        if (!controls) {
            return;
        }

        for (var i = 0; i < controls.length; i++) {

            var control = controls[i];

            switch (control.type) {
                case "action": {
                    this._addAction(control);
                    break;
                }
                case "tab": {

                    this._addTab(control);

                    break;
                }
                default: {

                    this._addCustomControl(control);

                    break;
                }
            }

        }

    };

    Toolbar.prototype._addTab = function (tab) {

        tab.$container = $('#' + tab.$element.data('tabid'))

        tab.$element.on('click', { tab: tab }, $.proxy(this._evBtnTabClick, this));

        //control.options.init.call(this, tab.$container, control.options);

    };

    Toolbar.prototype._expandSavedTab = function () {

        var tabs = this._getTabs();

        for (var i = 0; i < tabs.length; i++) {
            var tab = tabs[i];
            if (amplify.store('slide|' + this.options.uniqueName + '|' + tab.options.selector)) {
                tab.$element.trigger('click');
            }
        }

    };

    Toolbar.prototype._addCustomControl = function (control) {

        if (typeof control.name !== 'string' || control.name.trim().length == 0) {
            throw 'all controls must have a name';
        }

        if (typeof control.options.selector !== 'string' || control.options.selector.trim().length == 0) {
            throw 'all controls must have a name';
        }

        //control.options.init.call(this, $(control.options.selector), control.options);

    };

    Toolbar.prototype._addAction = function (buttonOpt) {

        if (typeof buttonOpt.handler !== 'function') {
            throw 'action ' + buttonOpt.name + ' must implement an event handler';
        }

        var $elem = this.element.find(buttonOpt.selector);

        $elem.on('click', { buttonOpt: buttonOpt }, $.proxy(this._evBtnClick, this));

        var control = {
            name: buttonOpt.name,
            type: 'action',
            $element: $elem,
            options: buttonOpt
        };

        this._controls.push(control);
    };

    Toolbar.prototype._addSubscribers = function (subscribers) {

        for (var i = 0; i < subscribers.length; i++) {
            this._addSubscriber(subscribers[i]);
        }

    };

    Toolbar.prototype._addSubscriber = function (subscriber) {
        this.subscribers.push(subscriber);
    };

    Toolbar.prototype._evBtnClick = function (e) {

        e.preventDefault();

        var buttonOpt = e.data.buttonOpt;

        buttonOpt.handler.call(this, e);
    };

    Toolbar.prototype._evBtnTabClick = function (e, triggeredTab) {

        e.preventDefault();

        var clickedTab = e.data.tab;

        var tabs = this._getTabs();

        //close other tab, if any
        for (var i = 0; i < tabs.length; i++) {
            var tab = tabs[i];

            if (tab.$element == clickedTab.$element) {
                continue;
            }

            if (tab.$element.hasClass('selected')) {
                this._toggleTab(tab);
            }
        }

        if (triggeredTab && triggeredTab.$element.hasClass('selected')) {
            return;
        }

        this._toggleTab(clickedTab);

    };

    Toolbar.prototype._toggleTab = function(tab) {

        tab.$element.toggleClass('selected');
        if (tab.name == 'advancedSearch') {
            var quickSearch = this.getControl('quickSearch');
            if (quickSearch != null) {
                quickSearch.$element.toggleClass('selected');
            }
        }

        tab.$container.stop(true, false).slideToggle();

        if (this.options.saveState) {
            amplify.store('slide|' + this.options.uniqueName + '|' + tab.options.selector, tab.$element.hasClass('selected'));
        }

    };

    //#region helpers
    Toolbar.prototype._getTabs = function () {

        return this._controls.filter(function (el) {
            return el.type == 'tab';
        });

    };

    Toolbar.prototype.getControl = function(name) {
        var control = $.grep(this._controls, function(el) {
            return el.name == name;
        });

        if (control != null && control[0] != null) return control[0];

        return null;
    };
    //#endregion

    //#endregion

    $.widget('bforms.bsToolbar', Toolbar.prototype);
});<|endoftext|>


<commit_before>// construct query string
var params = d3.select("h1#api_key");
if (!params.empty()) {
  var api_key = params.attr('data-api_key');
  var uid_type = params.attr('data-uid_type');
  var uid = params.attr('data-uid');
  var query = encodeURI("/api/v5/articles?api_key=" + api_key + "&ids=" + uid + "&type=" + uid_type + "&info=detail");
}

// load the data from the ALM API
if (query) {
  d3.json(query, function(error, json) {
    if (error) return console.warn(error);

    eventViz(json);
  });
}

// add data to page
function eventViz(json) {
  data = json['data'];

  d3.select("#loading-events").remove();

  console.log(data);

  // for (var i=0; i<data.length; i++) {
  //   item = data[i];
  // }
};
<commit_msg>ALM-624 access sources data from API response<commit_after>// construct query string
var params = d3.select("h1#api_key");
if (!params.empty()) {
  var api_key = params.attr('data-api_key');
  var uid_type = params.attr('data-uid_type');
  var uid = params.attr('data-uid');
  var query = encodeURI("/api/v5/articles?api_key=" + api_key + "&ids=" + uid + "&type=" + uid_type + "&info=detail");
}

// load the data from the ALM API
if (query) {
  d3.json(query, function(error, json) {
    if (error) return console.warn(error);

    eventViz(json);
  });
}

// add data to page
function eventViz(json) {
  data = json['data']['sources'];

  d3.select("#loading-events").remove();

  for (var i=0; i<data.length; i++) {
    item = data[i];
    console.log(item);
  }
};
<|endoftext|>


<commit_before>// Copyright 2016, University of Colorado Boulder

/**
 * Class that represents a ray of light in the view.  Rays of light can have
 * shapes that reduce or block the amount of light passing through.
 *
 * @author John Blanco
 * @author Andrew Adare
 */
define( function( require ) {
  'use strict';

  // Modules
  var energyFormsAndChanges = require( 'ENERGY_FORMS_AND_CHANGES/energyFormsAndChanges' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Line = require( 'SCENERY/nodes/Line' );
  var Node = require( 'REPO/path/to/Node' );
  var Ray2 = require( 'DOT/Ray2' );
  var Vector2 = require( 'DOT/Vector2' );

  var STROKE_THICKNESS = 2;
  var SEARCH_ITERATIONS = 10;
  var FADE_COEFFICIENT_IN_AIR = 0.005;

  /**
   * @param {Vector2} point     position
   * @param {Number} fadeValue Fade coefficient
   * @constructor
   * @private
   */
  function PointAndFadeValue( point, fadeValue ) {
    this.point = point;
    this.fadeValue = fadeValue;
  }

  /**
   * @param {Vector2} origin
   * @param {Vector2} endpoint
   * @param {Color} color
   * @constructor
   */
  function LightRayNode( origin, endpoint, color ) {

    this.lightAbsorbingShapes = [];
    this.pointAndFadeValues = [];
    this.origin = origin;
    this.endpoint = endpoint;
    this.color = color;

    Node.call( this );

    this.updateLineSegments();
  }

  energyFormsAndChanges.register( 'LightRayNode', LightRayNode );

  return inherit( Node, LightRayNode, {

    /**
     * [addLightAbsorbingShape description]
     * @param {LightAbsorbingShape} lightAbsorbingShape [description]
     * @public
     */
    addLightAbsorbingShape: function( lightAbsorbingShape ) {
      lightAbsorbingShape.absorptionCoefficientProperty.link( function() {
        this.updateLineSegments();
      } );
      this.lightAbsorbingShapes.push( lightAbsorbingShape );
    },

    /**
     * [removeLightAbsorbingShape description]
     * @param  {LightAbsorbingShape} lightAbsorbingShape [description]
     * @return {[type]}
     * @public
     */
    removeLightAbsorbingShape: function( lightAbsorbingShape ) {
      lightAbsorbingShape.absorptionCoefficientProperty.unlinkAll();
      _.remove( this.lightAbsorbingShapes, lightAbsorbingShape );
      this.updateLineSegments();
    },

    /**
     * @private
     */
    updateLineSegments: function() {
      this.removeAllChildren();
      this.pointAndFadeValues.length = 0;

      this.pointAndFadeValues.push( new PointAndFadeValue( this.origin, FADE_COEFFICIENT_IN_AIR ) );
      this.pointAndFadeValues.push( new PointAndFadeValue( this.endpoint, 0 ) );

      var self = this;
      this.lightAbsorbingShapes.foreach( function( absorbingShape ) {
        if ( self.lineIntersectsShapeIntersects( self.origin, self.endpoint, absorbingShape.shape ) ) {
          var entryPoint = self.getShapeEntryPoint( self.origin, self.endpoint, absorbingShape.shape );

          // It's conceivable that we could handle a case where the line originates
          // in a shape, but we don't for now
          assert && assert( entryPoint !== null, 'entryPoint is null' );

          var fade = absorbingShape.absorptionCoefficientProperty.get();
          self.pointAndFadeValues.push( new PointAndFadeValue( entryPoint, fade ) );

          var exitPoint = self.getShapeExitPoint( self.origin, self.endpoint, absorbingShape.shape );
          if ( exitPoint !== null ) {
            self.pointAndFadeValues.push( new PointAndFadeValue( exitPoint, FADE_COEFFICIENT_IN_AIR ) );
          }
        }
      } );

      // // Sort the list by distance from the origin.
      // Collections.sort( pointAndFadeCoefficientList, new Comparator < PointAndFadeCoefficient > () {
      //   public int compare( PointAndFadeCoefficient p1, PointAndFadeCoefficient p2 ) {
      //     return Double.compare( p1.point.distance( origin ), p2.point.distance( origin ) );
      //   }
      // } );

      // // Add the segments that comprise the line.
      // int opacity = 255;
      // for ( int i = 0; i < pointAndFadeCoefficientList.size() - 1; i++ ) {
      //   final FadingLineNode fadingLineNode = new FadingLineNode( pointAndFadeCoefficientList.get( i ).point,
      //     pointAndFadeCoefficientList.get( i + 1 ).point,
      //     new Color( color.getRed(), color.getGreen(), color.getBlue(), opacity ),
      //     pointAndFadeCoefficientList.get( i ).fadeCoefficient,
      //     STROKE_THICKNESS );
      //   addChild( fadingLineNode );
      //   opacity = fadingLineNode.getOpacityAtEndpoint();
      // }

    },

    /**
     * [lineIntersectsShapeIntersects description]
     * @param  {Vector2} startPoint [description]
     * @param  {Vector2} endPoint   [description]
     * @param  {Shape} shape      [description]
     * @return {Boolean}            [description]
     * @private
     */
    lineIntersectsShapeIntersects: function( startPoint, endPoint, shape ) {
      var direction = endPoint.minus( startPoint ).normalized();
      var ray = new Ray2( startPoint, direction );
      return shape.windingIntersection( ray );
      // Warning: This only checks the bounding rect, not the full shape.
      // This was adequate in this case, but take care if reusing.
      // return shape.bounds.intersectsLine( startPoint.x, startPoint.y, endPoint.x, endPoint.y );
    },

    /**
     * [getLineIntersection description]
     * @param  {Line} line1 [description]
     * @param  {Line} line2 [description]
     * @return {Vector2}       [description]
     * @private
     */
    getLineIntersection: function( line1, line2 ) {
      var denominator = ( ( line1.p2.x - line1.p1.x ) * ( line2.p2.y - line2.p1.y ) ) -
        ( ( line1.p2.y - line1.p1.y ) * ( line2.p2.x - line2.p1.x ) );

      // Check if the lines are parallel, and thus don't intersect.
      if ( denominator === 0 ) {
        return null;
      }

      var numerator = ( ( line1.p1.y - line2.p1.y ) * ( line2.p2.x - line2.p1.x ) ) -
        ( ( line1.p1.x - line2.p1.x ) * ( line2.p2.y - line2.p1.y ) );
      var r = numerator / denominator;

      var numerator2 = ( ( line1.p1.y - line2.p1.y ) * ( line1.p2.x - line1.p1.x ) ) -
        ( ( line1.p1.x - line2.p1.x ) * ( line1.p2.y - line1.p1.y ) );
      var s = numerator2 / denominator;

      if ( ( r < 0 || r > 1 ) || ( s < 0 || s > 1 ) ) {
        return null;
      }

      // Find intersection point
      return new Vector2( line1.p1.x + ( r * ( line1.p2.x - line1.p1.x ) ),
        line1.p1.y + ( r * ( line1.p2.y - line1.p1.y ) ) );
    },

    /**
     * @param  {Vector2} origin   [description]
     * @param  {Vector2} endpoint [description]
     * @param  {Shape} shape    [description]
     * @return {Vector2}
     * @private
     */
    getShapeEntryPoint: function( origin, endpoint, shape ) {
      var shapeRect = shape.bounds;
      var entryPoint = null;
      var ray = new Ray2( origin, endpoint.minus( origin ).normalized() );
      if ( shapeRect.windingIntersection( ray ) ) {
        var boundsEntryPoint = this.getRectangleEntryPoint( origin, endpoint, shapeRect );
        if ( boundsEntryPoint === null ) {
          return null;
        }
        var boundsExitPoint = this.getRectangleExitPoint( origin, endpoint, shapeRect );
        var searchEndPoint = boundsExitPoint === null ? endpoint : boundsExitPoint;

        // Search linearly for edge of the shape.  BIG HAIRY NOTE - This
        // will not work in all cases.  It worked for the coarse shapes
        // and rough bounds needed for this simulation.  Don't reuse if you
        // need good general edge finding.
        var angle = endpoint.minus( origin ).angle;
        var incrementalDistance = boundsEntryPoint.distance( searchEndPoint ) / SEARCH_ITERATIONS;
        for ( var i = 0; i < SEARCH_ITERATIONS; i++ ) {
          var testPoint = boundsEntryPoint.plus( new Vector2( incrementalDistance * i, 0 ).rotated( angle ) );
          if ( shape.contains( testPoint ) ) {
            entryPoint = testPoint;
            break;
          }
        }
      }
      return entryPoint;
    },

    /**
     * @param  {Vector2} origin   [description]
     * @param  {Vector2} endpoint [description]
     * @param  {Shape} shape    [description]
     * @return {Vector2}
     * @private
     */
    getShapeExitPoint: function( origin, endpoint, shape ) {
      var shapeRect = shape.bounds;
      var exitPoint = null;

      if ( shape.contains( endpoint ) ) {
        // Line ends inside shape, return null.
        return null;
      }

      var ray = new Ray2( origin, endpoint.minus( origin ).normalized() );
      if ( !shape.contains( endpoint ) && shapeRect.intersectsLine( ray ) ) {
        // Phase I - Do a binary search to locate the edge of the
        // rectangle that encloses the shape.
        var angle = endpoint.minus( origin ).angle;
        var length = origin.distance( endpoint );
        var lengthChange = length / 2;
        for ( var i = 0; i < SEARCH_ITERATIONS; i++ ) {
          var start = origin.plus( new Vector2( length, 0 ).rotated( angle ) );
          var testLine = new Line( start.x, start.y, endpoint.x, endpoint.y );
          length += lengthChange * ( testLine.intersects( shapeRect ) ? 1 : -1 );
          lengthChange = lengthChange / 2;
        }
        exitPoint = origin.plus( new Vector2( length, 0 ).rotated( angle ) );
      }
      return exitPoint;
    },

    /**
     * @param  {Vector2} origin   [description]
     * @param  {Vector2} endpoint [description]
     * @param  {Rectangle} shape    [description]
     * @return {Vector2}
     * @private
     */
    getRectangleEntryPoint: function( origin, endpoint, rect ) {
      var intersectingPoints = this.getRectangleLineIntersectionPoints( rect, new Line( origin, endpoint ) );

      var closestIntersectionPoint = null;
      intersectingPoints.forEach( function( point ) {
        if ( closestIntersectionPoint === null ||
          closestIntersectionPoint.distance( origin ) > point.distance( origin ) ) {
          closestIntersectionPoint = point;
        }
      } );

      return closestIntersectionPoint;
    },

    /**
     * @param  {Vector2} origin   [description]
     * @param  {Vector2} endpoint [description]
     * @param  {Rectangle} shape    [description]
     * @return {Vector2}
     * @private
     */
    getRectangleExitPoint: function( origin, endpoint, rect ) {
      var intersectingPoints = this.getRectangleLineIntersectionPoints( rect, new Line( origin, endpoint ) );

      if ( intersectingPoints.length < 2 ) {
        // Line either doesn't intersect or ends inside the rectangle.
        return null;
      }

      var furthestIntersectionPoint = null;
      intersectingPoints.forEach( function( point ) {
        if ( furthestIntersectionPoint === null ||
          furthestIntersectionPoint.distance( origin ) < point.distance( origin ) ) {
          furthestIntersectionPoint = point;
        }
      } );

      return furthestIntersectionPoint;
    },

    /**
     * [getRectangleLineIntersectionPoints description]
     * @param  {Rectangle} rect [description]
     * @param  {Line} line [description]
     * @return {Array<Vector2>}      [description]
     */
    getRectangleLineIntersectionPoints: function( rect, line ) {
      var lines = []; // Lines that make up rectangle
      lines.push( new Line( rect.minX, rect.minY, rect.minX, rect.maxY ) );
      lines.push( new Line( rect.minX, rect.maxY, rect.maxX, rect.maxY ) );
      lines.push( new Line( rect.maxX, rect.maxY, rect.maxX, rect.minY ) );
      lines.push( new Line( rect.maxX, rect.minY, rect.minX, rect.minY ) );

      var intersectingPoints = [];
      var self = this;
      lines.forEach( function( rectLine ) {
        var intersectingPoint = self.getLineIntersection( rectLine, line );
        if ( intersectingPoint !== null ) {
          intersectingPoints.push( intersectingPoint );
        }
      } );

      return intersectingPoints;
    }

  } );
} );

<commit_msg>Finish initial port of updateLineSegments()<commit_after>// Copyright 2016, University of Colorado Boulder

/**
 * Class that represents a ray of light in the view.  Rays of light can have
 * shapes that reduce or block the amount of light passing through.
 *
 * @author John Blanco
 * @author Andrew Adare
 */
define( function( require ) {
  'use strict';

  // Modules
  var energyFormsAndChanges = require( 'ENERGY_FORMS_AND_CHANGES/energyFormsAndChanges' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Line = require( 'SCENERY/nodes/Line' );
  var LinearGradient = require( 'SCENERY/util/LinearGradient' );
  var Node = require( 'REPO/path/to/Node' );
  var Ray2 = require( 'DOT/Ray2' );
  var Vector2 = require( 'DOT/Vector2' );

  var STROKE_THICKNESS = 2;
  var SEARCH_ITERATIONS = 10;
  var FADE_COEFFICIENT_IN_AIR = 0.005;

  /**
   * @param {Vector2} point     position
   * @param {Number} fadeValue Fade coefficient
   * @constructor
   * @private
   */
  function PointAndFadeValue( point, fadeValue ) {
    this.point = point;
    this.fadeValue = fadeValue;
  }

  /**
   * @param {Vector2} origin
   * @param {Vector2} endpoint
   * @param {Color} color
   * @constructor
   */
  function LightRayNode( origin, endpoint, color ) {

    this.lightAbsorbingShapes = [];
    this.pointAndFadeValues = [];
    this.origin = origin;
    this.endpoint = endpoint;
    this.color = color;

    Node.call( this );

    this.updateLineSegments();
  }

  energyFormsAndChanges.register( 'LightRayNode', LightRayNode );

  return inherit( Node, LightRayNode, {

    /**
     * [addLightAbsorbingShape description]
     * @param {LightAbsorbingShape} lightAbsorbingShape [description]
     * @public
     */
    addLightAbsorbingShape: function( lightAbsorbingShape ) {
      lightAbsorbingShape.absorptionCoefficientProperty.link( function() {
        this.updateLineSegments();
      } );
      this.lightAbsorbingShapes.push( lightAbsorbingShape );
    },

    /**
     * [removeLightAbsorbingShape description]
     * @param  {LightAbsorbingShape} lightAbsorbingShape [description]
     * @return {[type]}
     * @public
     */
    removeLightAbsorbingShape: function( lightAbsorbingShape ) {
      lightAbsorbingShape.absorptionCoefficientProperty.unlinkAll();
      _.remove( this.lightAbsorbingShapes, lightAbsorbingShape );
      this.updateLineSegments();
    },

    /**
     * @private
     */
    updateLineSegments: function() {
      this.removeAllChildren();
      this.pointAndFadeValues.length = 0;

      this.pointAndFadeValues.push( new PointAndFadeValue( this.origin, FADE_COEFFICIENT_IN_AIR ) );
      this.pointAndFadeValues.push( new PointAndFadeValue( this.endpoint, 0 ) );

      var self = this;
      this.lightAbsorbingShapes.foreach( function( absorbingShape ) {
        if ( self.lineIntersectsShapeIntersects( self.origin, self.endpoint, absorbingShape.shape ) ) {
          var entryPoint = self.getShapeEntryPoint( self.origin, self.endpoint, absorbingShape.shape );

          // It's conceivable that we could handle a case where the line originates
          // in a shape, but we don't for now
          assert && assert( entryPoint !== null, 'entryPoint is null' );

          var fade = absorbingShape.absorptionCoefficientProperty.get();
          self.pointAndFadeValues.push( new PointAndFadeValue( entryPoint, fade ) );

          var exitPoint = self.getShapeExitPoint( self.origin, self.endpoint, absorbingShape.shape );
          if ( exitPoint !== null ) {
            self.pointAndFadeValues.push( new PointAndFadeValue( exitPoint, FADE_COEFFICIENT_IN_AIR ) );
          }
        }
      } );

      // Sort the list of PointAndFadeValues by their distance from the origin, closest first.
      var sorted = _.sortBy( this.pointAndFadeValues, function( p ) {
        return p.point.distance( this.origin );
      } );

      // Add the segments that comprise the line.
      // var opacity = 1;
      var transparent = 'rgba(255,255,255,0)';
      for ( var i = 0; i < sorted.length - 1; i++ ) {

        var start = sorted[ i ].point;
        var end = sorted[ i + 1 ].point;

        var rayGradient = new LinearGradient( start.x, start.y, end.x, end.y )
          .addColorStop( 0, this.color )
          .addColorStop( 1, transparent );

        var fadingLine = new Line( start, end, {
          stroke: rayGradient,
          lineWidth: STROKE_THICKNESS
        } );

        this.addChild( fadingLine );
      }
    },

    /**
     * [lineIntersectsShapeIntersects description]
     * @param  {Vector2} startPoint [description]
     * @param  {Vector2} endPoint   [description]
     * @param  {Shape} shape      [description]
     * @return {Boolean}            [description]
     * @private
     */
    lineIntersectsShapeIntersects: function( startPoint, endPoint, shape ) {
      var direction = endPoint.minus( startPoint ).normalized();
      var ray = new Ray2( startPoint, direction );
      return shape.windingIntersection( ray );
      // Warning: This only checks the bounding rect, not the full shape.
      // This was adequate in this case, but take care if reusing.
      // return shape.bounds.intersectsLine( startPoint.x, startPoint.y, endPoint.x, endPoint.y );
    },

    /**
     * [getLineIntersection description]
     * @param  {Line} line1 [description]
     * @param  {Line} line2 [description]
     * @return {Vector2}       [description]
     * @private
     */
    getLineIntersection: function( line1, line2 ) {
      var denominator = ( ( line1.p2.x - line1.p1.x ) * ( line2.p2.y - line2.p1.y ) ) -
        ( ( line1.p2.y - line1.p1.y ) * ( line2.p2.x - line2.p1.x ) );

      // Check if the lines are parallel, and thus don't intersect.
      if ( denominator === 0 ) {
        return null;
      }

      var numerator = ( ( line1.p1.y - line2.p1.y ) * ( line2.p2.x - line2.p1.x ) ) -
        ( ( line1.p1.x - line2.p1.x ) * ( line2.p2.y - line2.p1.y ) );
      var r = numerator / denominator;

      var numerator2 = ( ( line1.p1.y - line2.p1.y ) * ( line1.p2.x - line1.p1.x ) ) -
        ( ( line1.p1.x - line2.p1.x ) * ( line1.p2.y - line1.p1.y ) );
      var s = numerator2 / denominator;

      if ( ( r < 0 || r > 1 ) || ( s < 0 || s > 1 ) ) {
        return null;
      }

      // Find intersection point
      return new Vector2( line1.p1.x + ( r * ( line1.p2.x - line1.p1.x ) ),
        line1.p1.y + ( r * ( line1.p2.y - line1.p1.y ) ) );
    },

    /**
     * @param  {Vector2} origin   [description]
     * @param  {Vector2} endpoint [description]
     * @param  {Shape} shape    [description]
     * @return {Vector2}
     * @private
     */
    getShapeEntryPoint: function( origin, endpoint, shape ) {
      var shapeRect = shape.bounds;
      var entryPoint = null;
      var ray = new Ray2( origin, endpoint.minus( origin ).normalized() );
      if ( shapeRect.windingIntersection( ray ) ) {
        var boundsEntryPoint = this.getRectangleEntryPoint( origin, endpoint, shapeRect );
        if ( boundsEntryPoint === null ) {
          return null;
        }
        var boundsExitPoint = this.getRectangleExitPoint( origin, endpoint, shapeRect );
        var searchEndPoint = boundsExitPoint === null ? endpoint : boundsExitPoint;

        // Search linearly for edge of the shape.  BIG HAIRY NOTE - This
        // will not work in all cases.  It worked for the coarse shapes
        // and rough bounds needed for this simulation.  Don't reuse if you
        // need good general edge finding.
        var angle = endpoint.minus( origin ).angle;
        var incrementalDistance = boundsEntryPoint.distance( searchEndPoint ) / SEARCH_ITERATIONS;
        for ( var i = 0; i < SEARCH_ITERATIONS; i++ ) {
          var testPoint = boundsEntryPoint.plus( new Vector2( incrementalDistance * i, 0 ).rotated( angle ) );
          if ( shape.contains( testPoint ) ) {
            entryPoint = testPoint;
            break;
          }
        }
      }
      return entryPoint;
    },

    /**
     * @param  {Vector2} origin   [description]
     * @param  {Vector2} endpoint [description]
     * @param  {Shape} shape    [description]
     * @return {Vector2}
     * @private
     */
    getShapeExitPoint: function( origin, endpoint, shape ) {
      var shapeRect = shape.bounds;
      var exitPoint = null;

      if ( shape.contains( endpoint ) ) {
        // Line ends inside shape, return null.
        return null;
      }

      var ray = new Ray2( origin, endpoint.minus( origin ).normalized() );
      if ( !shape.contains( endpoint ) && shapeRect.intersectsLine( ray ) ) {
        // Phase I - Do a binary search to locate the edge of the
        // rectangle that encloses the shape.
        var angle = endpoint.minus( origin ).angle;
        var length = origin.distance( endpoint );
        var lengthChange = length / 2;
        for ( var i = 0; i < SEARCH_ITERATIONS; i++ ) {
          var start = origin.plus( new Vector2( length, 0 ).rotated( angle ) );
          var testLine = new Line( start.x, start.y, endpoint.x, endpoint.y );
          length += lengthChange * ( testLine.intersects( shapeRect ) ? 1 : -1 );
          lengthChange = lengthChange / 2;
        }
        exitPoint = origin.plus( new Vector2( length, 0 ).rotated( angle ) );
      }
      return exitPoint;
    },

    /**
     * @param  {Vector2} origin   [description]
     * @param  {Vector2} endpoint [description]
     * @param  {Rectangle} shape    [description]
     * @return {Vector2}
     * @private
     */
    getRectangleEntryPoint: function( origin, endpoint, rect ) {
      var intersectingPoints = this.getRectangleLineIntersectionPoints( rect, new Line( origin, endpoint ) );

      var closestIntersectionPoint = null;
      intersectingPoints.forEach( function( point ) {
        if ( closestIntersectionPoint === null ||
          closestIntersectionPoint.distance( origin ) > point.distance( origin ) ) {
          closestIntersectionPoint = point;
        }
      } );

      return closestIntersectionPoint;
    },

    /**
     * @param  {Vector2} origin   [description]
     * @param  {Vector2} endpoint [description]
     * @param  {Rectangle} shape    [description]
     * @return {Vector2}
     * @private
     */
    getRectangleExitPoint: function( origin, endpoint, rect ) {
      var intersectingPoints = this.getRectangleLineIntersectionPoints( rect, new Line( origin, endpoint ) );

      if ( intersectingPoints.length < 2 ) {
        // Line either doesn't intersect or ends inside the rectangle.
        return null;
      }

      var furthestIntersectionPoint = null;
      intersectingPoints.forEach( function( point ) {
        if ( furthestIntersectionPoint === null ||
          furthestIntersectionPoint.distance( origin ) < point.distance( origin ) ) {
          furthestIntersectionPoint = point;
        }
      } );

      return furthestIntersectionPoint;
    },

    /**
     * [getRectangleLineIntersectionPoints description]
     * @param  {Rectangle} rect [description]
     * @param  {Line} line [description]
     * @return {Array<Vector2>}      [description]
     */
    getRectangleLineIntersectionPoints: function( rect, line ) {
      var lines = []; // Lines that make up rectangle
      lines.push( new Line( rect.minX, rect.minY, rect.minX, rect.maxY ) );
      lines.push( new Line( rect.minX, rect.maxY, rect.maxX, rect.maxY ) );
      lines.push( new Line( rect.maxX, rect.maxY, rect.maxX, rect.minY ) );
      lines.push( new Line( rect.maxX, rect.minY, rect.minX, rect.minY ) );

      var intersectingPoints = [];
      var self = this;
      lines.forEach( function( rectLine ) {
        var intersectingPoint = self.getLineIntersection( rectLine, line );
        if ( intersectingPoint !== null ) {
          intersectingPoints.push( intersectingPoint );
        }
      } );

      return intersectingPoints;
    }

  } );
} );

<|endoftext|>


<commit_before>import Ember from 'ember';

var isArray = Ember.isArray;

/**
 * Wraps a native <select> element so that it can be object and
 * binding aware. It is used in conjuction with the
 * `x-option` component to construct select boxes. E.g.
 *
 *   {{#x-select value="bob" action="selectPerson"}}
 *     {{x-option value="fred"}}Fred Flintstone{{/x-option}}
 *     {{x-option value="bob"}}Bob Newhart{{/x-option}}
 *   {{/x-select}}
 *
 * the options are always up to date, so that when the object bound to
 * `value` changes, the corresponding option becomes selected.
 *
 * Whenever the select tag receives a change event, it will fire
 * `action`
 *
 * @class Ember.XSelectComponent
 * @extends Ember.Component
 */
export default Ember.Component.extend({
  tagName: "select",
  classNameBindings: [":x-select"],
  attributeBindings: ['disabled', 'tabindex', 'multiple', 'form', 'name', 'autofocus', 'required', 'size', 'title'],

  /**
   * Bound to the `disabled` attribute on the native <select> tag.
   *
   * @property disabled
   * @type Boolean
   * @default false
   */
  disabled: false,

  /**
   * Bound to the `multiple` attribute on the native <select> tag.
   *
   * @property multiple
   * @type Boolean
   * @default false
   */
  multiple: false,

  /**
   * Bound to the `tabindex` attribute on the native <select> tag.
   *
   * @property tabindex
   * @type Integer
   * @ default 0
   */
  tabindex: 0,

  /**
   * The collection of options for this select box. When options are
   * inserted into the dom, they will register themselves with their
   * containing `x-select`. This is for internal book-keeping only and should
   * not be changed from outside.
   *
   * @private
   * @property options
   */
  options: Ember.computed(function() {
    return Ember.A();
  }),

  /**
   * When the select DOM event fires on the element, trigger the
   * component's action with the current value.
   */
  change(event) {
    if (this.get('multiple')) {
      this._updateValueMultiple();
    } else {
      this._updateValueSingle();
    }

    this.sendAction('action', this.get('value'), this);
    this.sendAction('onchange', this, this.get('value'), event);
  },

  /**
   * When the click DOM event fires on the element, trigger the
   * component's action with the component, x-select value, and the jQuery event.
   */
  click(event) {
    this.sendAction('onclick', this, this.get('value'), event);
  },

  /**
   * When the blur DOM event fires on the element, trigger the
   * component's action with the component, x-select value, and the jQuery event.
   */
  blur(event) {
    this.sendAction('onblur', this, this.get('value'), event);
  },

  /**
   * When the focusOut DOM event fires on the element, trigger the
   * component's action with the component, x-select value, and the jQuery event.
   */
  focusOut(event) {
    this.sendAction('onfocusout', this, this.get('value'), event);
  },

  /**
   * Updates `value` with the object associated with the selected option tag
   *
   * @private
   */
  _updateValueSingle: function(){
    var option = this.get('options').find(function(option) {
      return option.$().is(':selected');
    });

    if (option) {
      this.set('value', option.get('value'));
    } else {
      this.set('value', null);
    }
  },

  /**
   * Updates `value` with an array of objects associated with the selected option tags
   *
   * @private
   */
  _updateValueMultiple: function() {
    var options = this.get('options').filter(function(option) {
      return option.$().is(':selected');
    });

    this.set('value', Ember.A(options).mapBy('value'));
  },

  /**
   * If no explicit value is set, apply default values based on selected=true in
   * the template.
   *
   * @private
   */
  _setDefaultValues: function() {
    if( !this.get('value')){
      if (this.get('multiple')) {
        this._updateValueMultiple();
      } else {
        this._updateValueSingle();
      }
    }
  },

  /**
   * @override
   */
  didInsertElement() {
    this._super.apply(this, arguments);

    this.$().on('blur', (event) => {
      this.blur(event);
    });
  },

  /**
   * @override
   */
  willDestroyElement: function() {
    this._super.apply(this, arguments);

    // might be overkill, but make sure options can get gc'd
    this.get('options').clear();
    this.$().off('blur');
  },

  /**
   * If this is a multi-select, and the value is not an array, that
   * probably indicates a misconfiguration somewhere, so we error out.
   *
   * @private
   */
  ensureProperType: Ember.on('init', Ember.observer('value', function() {
    let value = this.get('value');

    if (value != null && this.get('multiple') && !isArray(value)) {
      throw new Error(`x-select multiple=true was set, but value ${value} is not enumerable.`);
    }
  })),

  /**
   * @private
   */
  registerOption: function(option) {
    this.get('options').addObject(option);
    this._setDefaultValues();
  },

  /**
   * @private
   */
  unregisterOption: function(option) {
    this.get('options').removeObject(option);

    // We don't want to update the value if we're tearing the component down.
    if (!this.get('isDestroying')) {
      this._updateValueSingle();
    }
  }
});
<commit_msg>Add utility method for updating single/multi selects<commit_after>import Ember from 'ember';

var isArray = Ember.isArray;

/**
 * Wraps a native <select> element so that it can be object and
 * binding aware. It is used in conjuction with the
 * `x-option` component to construct select boxes. E.g.
 *
 *   {{#x-select value="bob" action="selectPerson"}}
 *     {{x-option value="fred"}}Fred Flintstone{{/x-option}}
 *     {{x-option value="bob"}}Bob Newhart{{/x-option}}
 *   {{/x-select}}
 *
 * the options are always up to date, so that when the object bound to
 * `value` changes, the corresponding option becomes selected.
 *
 * Whenever the select tag receives a change event, it will fire
 * `action`
 *
 * @class Ember.XSelectComponent
 * @extends Ember.Component
 */
export default Ember.Component.extend({
  tagName: "select",
  classNameBindings: [":x-select"],
  attributeBindings: ['disabled', 'tabindex', 'multiple', 'form', 'name', 'autofocus', 'required', 'size', 'title'],

  /**
   * Bound to the `disabled` attribute on the native <select> tag.
   *
   * @property disabled
   * @type Boolean
   * @default false
   */
  disabled: false,

  /**
   * Bound to the `multiple` attribute on the native <select> tag.
   *
   * @property multiple
   * @type Boolean
   * @default false
   */
  multiple: false,

  /**
   * Bound to the `tabindex` attribute on the native <select> tag.
   *
   * @property tabindex
   * @type Integer
   * @ default 0
   */
  tabindex: 0,

  /**
   * The collection of options for this select box. When options are
   * inserted into the dom, they will register themselves with their
   * containing `x-select`. This is for internal book-keeping only and should
   * not be changed from outside.
   *
   * @private
   * @property options
   */
  options: Ember.computed(function() {
    return Ember.A();
  }),

  /**
   * When the select DOM event fires on the element, trigger the
   * component's action with the current value.
   */
  change(event) {
    this._updateValue();

    this.sendAction('action', this.get('value'), this);
    this.sendAction('onchange', this, this.get('value'), event);
  },

  /**
   * When the click DOM event fires on the element, trigger the
   * component's action with the component, x-select value, and the jQuery event.
   */
  click(event) {
    this.sendAction('onclick', this, this.get('value'), event);
  },

  /**
   * When the blur DOM event fires on the element, trigger the
   * component's action with the component, x-select value, and the jQuery event.
   */
  blur(event) {
    this.sendAction('onblur', this, this.get('value'), event);
  },

  /**
   * When the focusOut DOM event fires on the element, trigger the
   * component's action with the component, x-select value, and the jQuery event.
   */
  focusOut(event) {
    this.sendAction('onfocusout', this, this.get('value'), event);
  },

  /**
   * Updates `value` with the object associated with the selected option tag
   *
   * @private
   */
  _updateValueSingle: function(){
    var option = this.get('options').find(function(option) {
      return option.$().is(':selected');
    });

    if (option) {
      this.set('value', option.get('value'));
    } else {
      this.set('value', null);
    }
  },

  /**
   * Updates `value` with an array of objects associated with the selected option tags
   *
   * @private
   */
  _updateValueMultiple: function() {
    var options = this.get('options').filter(function(option) {
      return option.$().is(':selected');
    });

    this.set('value', Ember.A(options).mapBy('value'));
  },

  /**
   * A utility method to determine if the select is multiple or single and call
   * its respective method to update the value.
   *
   * @private
   * @utility
   */
  _updateValue() {
    if (this.get('multiple')) {
      this._updateValueMultiple();
    } else {
      this.updateValueSingle();
    }
  },

  /**
   * If no explicit value is set, apply default values based on selected=true in
   * the template.
   *
   * @private
   */
  _setDefaultValues: function() {
    if (!this.get('value')) {
      this._updateValue();
    }
  },

  /**
   * @override
   */
  didInsertElement() {
    this._super.apply(this, arguments);

    this.$().on('blur', (event) => {
      this.blur(event);
    });
  },

  /**
   * @override
   */
  willDestroyElement: function() {
    this._super.apply(this, arguments);

    // might be overkill, but make sure options can get gc'd
    this.get('options').clear();
    this.$().off('blur');
  },

  /**
   * If this is a multi-select, and the value is not an array, that
   * probably indicates a misconfiguration somewhere, so we error out.
   *
   * @private
   */
  ensureProperType: Ember.on('init', Ember.observer('value', function() {
    let value = this.get('value');

    if (value != null && this.get('multiple') && !isArray(value)) {
      throw new Error(`x-select multiple=true was set, but value ${value} is not enumerable.`);
    }
  })),

  /**
   * @private
   */
  registerOption: function(option) {
    this.get('options').addObject(option);
    this._setDefaultValues();
  },

  /**
   * @private
   */
  unregisterOption: function(option) {
    this.get('options').removeObject(option);

    // We don't want to update the value if we're tearing the component down.
    if (!this.get('isDestroying')) {
      this._updateValue();
    }
  }
});
<|endoftext|>