<commit_before>module.exports = {
  'AED': 'د.إ',
  'AFN': '؋',
  'ALL': 'L',
  'ANG': 'ƒ',
  'AOA': 'Kz',
  'ARS': '$',
  'AUD': '$',
  'AWG': 'ƒ',
  'AZN': '₼',
  'BAM': 'KM',
  'BBD': '$',
  'BDT': '৳',
  'BGN': 'лв',
  'BHD': '.د.ب',
  'BIF': 'FBu',
  'BMD': '$',
  'BND': '$',
  'BOB': 'Bs.',
  'BRL': 'R$',
  'BSD': '$',
  'BTC': '฿',
  'BTN': 'Nu.',
  'BWP': 'P',
  'BYR': 'p.',
  'BZD': 'BZ$',
  'CAD': '$',
  'CDF': 'FC',
  'CHF': 'Fr.',
  'CLP': '$',
  'CNY': '¥',
  'COP': '$',
  'CRC': '₡',
  'CUC': '$',
  'CUP': '₱',
  'CVE': '$',
  'CZK': 'Kč',
  'DJF': 'Fdj',
  'DKK': 'kr',
  'DOP': 'RD$',
  'DZD': 'دج',
  'EEK': 'kr',
  'EGP': '£',
  'ERN': 'Nfk',
  'ETB': 'Br',
  'ETH': 'Ξ',
  'EUR': '€',
  'FJD': '$',
  'FKP': '£',
  'GBP': '£',
  'GEL': '₾',
  'GGP': '£',
  'GHC': '₵',
  'GHS': 'GH₵',
  'GIP': '£',
  'GMD': 'D',
  'GNF': 'FG',
  'GTQ': 'Q',
  'GYD': '$',
  'HKD': '$',
  'HNL': 'L',
  'HRK': 'kn',
  'HTG': 'G',
  'HUF': 'Ft',
  'IDR': 'Rp',
  'ILS': '₪',
  'IMP': '£',
  'INR': '₹',
  'IQD': 'ع.د',
  'IRR': '﷼',
  'ISK': 'kr',
  'JEP': '£',
  'JMD': 'J$',
  'JPY': '¥',
  'KES': 'KSh',
  'KGS': 'лв',
  'KHR': '៛',
  'KMF': 'CF',
  'KPW': '₩',
  'KRW': '₩',
  'KYD': '$',
  'KZT': '₸',
  'LAK': '₭',
  'LBP': '£',
  'LKR': '₨',
  'LRD': '$',
  'LSL': 'M',
  'LTC': 'Ł',
  'LTL': 'Lt',
  'LVL': 'Ls',
  'LYD': 'LD',
  'MAD': 'MAD',
  'MDL': 'lei',
  'MGA': 'Ar',
  'MKD': 'ден',
  'MMK': 'K',
  'MNT': '₮',
  'MOP': 'MOP$',
  'MUR': '₨',
  'MVR': 'Rf',
  'MWK': 'MK',
  'MXN': '$',
  'MYR': 'RM',
  'MZN': 'MT',
  'NAD': '$',
  'NGN': '₦',
  'NIO': 'C$',
  'NOK': 'kr',
  'NPR': '₨',
  'NZD': '$',
  'OMR': '﷼',
  'PAB': 'B/.',
  'PEN': 'S/.',
  'PGK': 'K',
  'PHP': '₱',
  'PKR': '₨',
  'PLN': 'zł',
  'PYG': 'Gs',
  'QAR': '﷼',
  'RMB': '￥',
  'RON': 'lei',
  'RSD': 'Дин.',
  'RUB': '₽',
  'RWF': 'R₣',
  'SAR': '﷼',
  'SBD': '$',
  'SCR': '₨',
  'SDG': 'ج.س.',
  'SEK': 'kr',
  'SGD': '$',
  'SHP': '£',
  'SLL': 'Le',
  'SOS': 'S',
  'SRD': '$',
  'SSP': '£',
  'STD': 'Db',
  'SVC': '$',
  'SYP': '£',
  'SZL': 'E',
  'THB': '฿',
  'TJS': 'SM',
  'TMT': 'T',
  'TND': 'د.ت',
  'TOP': 'T$',
  'TRL': '₤',
  'TRY': '₺',
  'TTD': 'TT$',
  'TVD': '$',
  'TWD': 'NT$',
  'TZS': 'TSh',
  'UAH': '₴',
  'UGX': 'USh',
  'USD': '$',
  'UYU': '$U',
  'UZS': 'лв',
  'VEF': 'Bs',
  'VND': '₫',
  'VUV': 'VT',
  'WST': 'WS$',
  'XAF': 'FCFA',
  'XBT': 'Ƀ',
  'XCD': '$',
  'XOF': 'CFA',
  'XPF': '₣',
  'YER': '﷼',
  'ZAR': 'R',
  'ZWD': 'Z$'
}
<commit_msg>Add JOD<commit_after>module.exports = {
  'AED': 'د.إ',
  'AFN': '؋',
  'ALL': 'L',
  'ANG': 'ƒ',
  'AOA': 'Kz',
  'ARS': '$',
  'AUD': '$',
  'AWG': 'ƒ',
  'AZN': '₼',
  'BAM': 'KM',
  'BBD': '$',
  'BDT': '৳',
  'BGN': 'лв',
  'BHD': '.د.ب',
  'BIF': 'FBu',
  'BMD': '$',
  'BND': '$',
  'BOB': 'Bs.',
  'BRL': 'R$',
  'BSD': '$',
  'BTC': '฿',
  'BTN': 'Nu.',
  'BWP': 'P',
  'BYR': 'p.',
  'BZD': 'BZ$',
  'CAD': '$',
  'CDF': 'FC',
  'CHF': 'Fr.',
  'CLP': '$',
  'CNY': '¥',
  'COP': '$',
  'CRC': '₡',
  'CUC': '$',
  'CUP': '₱',
  'CVE': '$',
  'CZK': 'Kč',
  'DJF': 'Fdj',
  'DKK': 'kr',
  'DOP': 'RD$',
  'DZD': 'دج',
  'EEK': 'kr',
  'EGP': '£',
  'ERN': 'Nfk',
  'ETB': 'Br',
  'ETH': 'Ξ',
  'EUR': '€',
  'FJD': '$',
  'FKP': '£',
  'GBP': '£',
  'GEL': '₾',
  'GGP': '£',
  'GHC': '₵',
  'GHS': 'GH₵',
  'GIP': '£',
  'GMD': 'D',
  'GNF': 'FG',
  'GTQ': 'Q',
  'GYD': '$',
  'HKD': '$',
  'HNL': 'L',
  'HRK': 'kn',
  'HTG': 'G',
  'HUF': 'Ft',
  'IDR': 'Rp',
  'ILS': '₪',
  'IMP': '£',
  'INR': '₹',
  'IQD': 'ع.د',
  'IRR': '﷼',
  'ISK': 'kr',
  'JEP': '£',
  'JMD': 'J$',
  'JOD': 'JD',
  'JPY': '¥',
  'KES': 'KSh',
  'KGS': 'лв',
  'KHR': '៛',
  'KMF': 'CF',
  'KPW': '₩',
  'KRW': '₩',
  'KYD': '$',
  'KZT': '₸',
  'LAK': '₭',
  'LBP': '£',
  'LKR': '₨',
  'LRD': '$',
  'LSL': 'M',
  'LTC': 'Ł',
  'LTL': 'Lt',
  'LVL': 'Ls',
  'LYD': 'LD',
  'MAD': 'MAD',
  'MDL': 'lei',
  'MGA': 'Ar',
  'MKD': 'ден',
  'MMK': 'K',
  'MNT': '₮',
  'MOP': 'MOP$',
  'MUR': '₨',
  'MVR': 'Rf',
  'MWK': 'MK',
  'MXN': '$',
  'MYR': 'RM',
  'MZN': 'MT',
  'NAD': '$',
  'NGN': '₦',
  'NIO': 'C$',
  'NOK': 'kr',
  'NPR': '₨',
  'NZD': '$',
  'OMR': '﷼',
  'PAB': 'B/.',
  'PEN': 'S/.',
  'PGK': 'K',
  'PHP': '₱',
  'PKR': '₨',
  'PLN': 'zł',
  'PYG': 'Gs',
  'QAR': '﷼',
  'RMB': '￥',
  'RON': 'lei',
  'RSD': 'Дин.',
  'RUB': '₽',
  'RWF': 'R₣',
  'SAR': '﷼',
  'SBD': '$',
  'SCR': '₨',
  'SDG': 'ج.س.',
  'SEK': 'kr',
  'SGD': '$',
  'SHP': '£',
  'SLL': 'Le',
  'SOS': 'S',
  'SRD': '$',
  'SSP': '£',
  'STD': 'Db',
  'SVC': '$',
  'SYP': '£',
  'SZL': 'E',
  'THB': '฿',
  'TJS': 'SM',
  'TMT': 'T',
  'TND': 'د.ت',
  'TOP': 'T$',
  'TRL': '₤',
  'TRY': '₺',
  'TTD': 'TT$',
  'TVD': '$',
  'TWD': 'NT$',
  'TZS': 'TSh',
  'UAH': '₴',
  'UGX': 'USh',
  'USD': '$',
  'UYU': '$U',
  'UZS': 'лв',
  'VEF': 'Bs',
  'VND': '₫',
  'VUV': 'VT',
  'WST': 'WS$',
  'XAF': 'FCFA',
  'XBT': 'Ƀ',
  'XCD': '$',
  'XOF': 'CFA',
  'XPF': '₣',
  'YER': '﷼',
  'ZAR': 'R',
  'ZWD': 'Z$'
}
<|endoftext|>


<commit_before>/*jslint browser: true*/
/*global Tangram */
var picking = false;
map = (function () {
// (function () {
    // 'use strict';

    // defaults
    var map_start_location = [0, 0, 2]; // world
    var style_file = 'roads.yaml';

    /*** URL parsing ***/

    // leaflet-style URL hash pattern:
    // #[zoom],[lat],[lng]
    var url_hash = window.location.hash.slice(1).split('/');

    // location
    var defaultpos = true; // use default position
    // location is passed through url
    if (url_hash.length == 3) {
        var defaultpos = false;
        console.log('hash:', url_hash);
        map_start_location = [url_hash[1],url_hash[2], url_hash[0]];
        // convert from strings
        map_start_location = map_start_location.map(Number);
    }

    // normal case, eg: http://tangrams.github.io/nameless-maps/?roads#4/0/0
    var url_search = window.location.search.slice(1).split('/')[0];
    console.log('url_search', url_search);
    if (url_search.length > 0) {
        style_file = url_search + ".yaml";
        console.log('style_file', style_file);
    }

    /*** Map ***/

    var map = L.map('map',
        {"keyboardZoomOffset" : .05, "scrollWheelZoom": false }
    );
    map.setView(map_start_location.slice(0, 2), map_start_location[2]);

    var layer = Tangram.leafletLayer({
        scene: style_file,
        attribution: 'Tangram | © OSM contributors | Mapzen'
    });

    window.layer = layer;
    var scene = layer.scene;
    window.scene = scene;

    // setView expects format ([lat, long], zoom)
    var hash = new L.Hash(map);

    function updateKey(value) {
        keytext = value;

        for (layer in scene.config.layers) {
            if (layer == "earth") continue;
            scene.config.layers[layer].properties.key_text = value;
        }
        scene.rebuildGeometry();
        scene.requestRedraw();
    }

    function updateValue(value) {
        valuetext = value;

        for (layer in scene.config.layers) {
            if (layer == "earth") continue;
            scene.config.layers[layer].properties.value_text = value;
        }
        scene.rebuildGeometry();
        scene.requestRedraw();
    }

    // Feature selection
    function initFeatureSelection () {
        var info = document.getElementById('info'); // rollover-popup
        var popup = document.getElementById('popup'); // click-popup

        // Show selected feature on hover
//         map.getContainer().addEventListener('mousemove', function (event) {
//             if (picking) return;
//             var pixel = { x: event.clientX, y: event.clientY };
//
//             scene.getFeatureAt(pixel).then(function(selection) {
//                 if (!selection) {
//                     return;
//                 }
//                 var feature = selection.feature;
//                 if (feature != null) {
//
//                     var label = '';
//                     if (feature.properties != null) {
//
//                         var obj = JSON.parse(JSON.stringify(feature.properties));
//                         label = "";
//                         for (x in feature.properties) {
//                             if (x == "sort_key" || x == "id" || x == "source") continue;
//                             val = feature.properties[x]
//                             label += ""+x+" : "+val+"
"
//                         }
//                     }
//
//                     if (label != '') {
//                         info.innerHTML = '' + label + '';
//                         info.style.left = (pixel.x + 5) + 'px';
//                         info.style.top = (pixel.y + 10) + 'px';
//                         info.style.visibility = 'visible';
//                     }
//                     else if (info.parentNode != null) {
//                         info.style.visibility = 'hidden';
//                     }
//                 }
//                 else if (info.parentNode != null) {
//                     info.style.visibility = 'hidden';
//                 }
//             });
//
//         });

        // feature edit popup
        map.getContainer().addEventListener('mousemove', function (event) {
            picking = true;
            info.style.visibility = 'hidden';

            var pixel = { x: event.clientX, y: event.clientY };

            scene.getFeatureAt(pixel).then(function(selection) {
                var feature = selection.feature;
                if (!selection || feature == null) {
                    picking = false;
                    popup.style.visibility = 'hidden';
                    return;
                }

                // generate osm edit link
                var url = 'https://www.openstreetmap.org/edit?';

                if (scene.selection.feature && scene.selection.feature.properties.id) {
                    url += 'way=' + scene.selection.feature.properties.id;
                }

                // Ideally, we'd know the feature's center.lat and center.lng, but we only know the scene's, so skip this for now
                if (scene.center) {
                    var center = '19' + '/' + scene.center.lat + '/' + scene.center.lng;
                }
                // We want to zoom into the feature at a high zoom, but that's broken
                // url += '#map=' + center;
                // So we ignore this for now and hope OSM.org does the right thing

                var josmUrl = 'http://www.openstreetmap.org/edit?editor=remote#map='+center;

                // extra label information - currently unused
                var label = '';
                if (feature.properties != null) {
                    var obj = JSON.parse(JSON.stringify(feature.properties));
                    label = "";
                    for (x in feature.properties) {
                        if (x == "sort_key" || x == "id") continue;
                        val = feature.properties[x];
                        label += ""+x+" : "+val+"
"
                    }
                }

                popup.style.left = (pixel.x + 0) + 'px';
                popup.style.top = (pixel.y + 0) + 'px';
                if ( scene.selection.feature.properties.name == undefined) {
	                popup.style.visibility = 'visible';
	            }
                popup.innerHTML = '' + 'You found an unnamed street!' + '
';
                popup.innerHTML += '' + 'Edit with iD ➹' + '
';
                popup.innerHTML += '' + 'Edit with JOSM ➹' + '
';
            });
        });

        map.getContainer().addEventListener('mousedown', function (event) {
            info.style.visibility = 'hidden';
            popup.style.visibility = 'hidden';
        });

    }

    // Add map
    window.addEventListener('load', function () {
        // Scene initialized
        layer.on('init', function() {
            initFeatureSelection();
            console.log('1 map loc:', map_start_location, '\ncamera pos:', scene.camera.position);
            if (defaultpos && typeof scene.camera.position != "undefined") {
                map_start_location = [scene.camera.position[1], scene.camera.position[0], scene.camera.position[2]]
            }
            map.setView([map_start_location[0], map_start_location[1]], map_start_location[2]);
        });
        layer.addTo(map);
    });

    return map;

}());

<commit_msg>detect iframe and enable zoomscrollwheel otherwise<commit_after>/*jslint browser: true*/
/*global Tangram */
var picking = false;
map = (function () {
// (function () {
    // 'use strict';

    // defaults
    var map_start_location = [0, 0, 2]; // world
    var style_file = 'roads.yaml';

    /*** URL parsing ***/

    // leaflet-style URL hash pattern:
    // #[zoom],[lat],[lng]
    var url_hash = window.location.hash.slice(1).split('/');

    // location
    var defaultpos = true; // use default position
    // location is passed through url
    if (url_hash.length == 3) {
        var defaultpos = false;
        console.log('hash:', url_hash);
        map_start_location = [url_hash[1],url_hash[2], url_hash[0]];
        // convert from strings
        map_start_location = map_start_location.map(Number);
    }

    // normal case, eg: http://tangrams.github.io/nameless-maps/?roads#4/0/0
    var url_search = window.location.search.slice(1).split('/')[0];
    console.log('url_search', url_search);
    if (url_search.length > 0) {
        style_file = url_search + ".yaml";
        console.log('style_file', style_file);
    }

    /*** Map ***/

    var map = L.map('map',
        {"keyboardZoomOffset" : .05, "scrollWheelZoom": false }
    );
    map.setView(map_start_location.slice(0, 2), map_start_location[2]);

    var layer = Tangram.leafletLayer({
        scene: style_file,
        attribution: 'Tangram | © OSM contributors | Mapzen'
    });

    window.layer = layer;
    var scene = layer.scene;
    window.scene = scene;

    // setView expects format ([lat, long], zoom)
    var hash = new L.Hash(map);

    function updateKey(value) {
        keytext = value;

        for (layer in scene.config.layers) {
            if (layer == "earth") continue;
            scene.config.layers[layer].properties.key_text = value;
        }
        scene.rebuildGeometry();
        scene.requestRedraw();
    }

    function updateValue(value) {
        valuetext = value;

        for (layer in scene.config.layers) {
            if (layer == "earth") continue;
            scene.config.layers[layer].properties.value_text = value;
        }
        scene.rebuildGeometry();
        scene.requestRedraw();
    }

    // Feature selection
    function initFeatureSelection () {
        var info = document.getElementById('info'); // rollover-popup
        var popup = document.getElementById('popup'); // click-popup

        // Show selected feature on hover
//         map.getContainer().addEventListener('mousemove', function (event) {
//             if (picking) return;
//             var pixel = { x: event.clientX, y: event.clientY };
//
//             scene.getFeatureAt(pixel).then(function(selection) {
//                 if (!selection) {
//                     return;
//                 }
//                 var feature = selection.feature;
//                 if (feature != null) {
//
//                     var label = '';
//                     if (feature.properties != null) {
//
//                         var obj = JSON.parse(JSON.stringify(feature.properties));
//                         label = "";
//                         for (x in feature.properties) {
//                             if (x == "sort_key" || x == "id" || x == "source") continue;
//                             val = feature.properties[x]
//                             label += ""+x+" : "+val+"
"
//                         }
//                     }
//
//                     if (label != '') {
//                         info.innerHTML = '' + label + '';
//                         info.style.left = (pixel.x + 5) + 'px';
//                         info.style.top = (pixel.y + 10) + 'px';
//                         info.style.visibility = 'visible';
//                     }
//                     else if (info.parentNode != null) {
//                         info.style.visibility = 'hidden';
//                     }
//                 }
//                 else if (info.parentNode != null) {
//                     info.style.visibility = 'hidden';
//                 }
//             });
//
//         });

        // feature edit popup
        map.getContainer().addEventListener('mousemove', function (event) {
            picking = true;
            info.style.visibility = 'hidden';

            var pixel = { x: event.clientX, y: event.clientY };

            scene.getFeatureAt(pixel).then(function(selection) {
                var feature = selection.feature;
                if (!selection || feature == null) {
                    picking = false;
                    popup.style.visibility = 'hidden';
                    return;
                }

                // generate osm edit link
                var url = 'https://www.openstreetmap.org/edit?';

                if (scene.selection.feature && scene.selection.feature.properties.id) {
                    url += 'way=' + scene.selection.feature.properties.id;
                }

                // Ideally, we'd know the feature's center.lat and center.lng, but we only know the scene's, so skip this for now
                if (scene.center) {
                    var center = '19' + '/' + scene.center.lat + '/' + scene.center.lng;
                }
                // We want to zoom into the feature at a high zoom, but that's broken
                // url += '#map=' + center;
                // So we ignore this for now and hope OSM.org does the right thing

                var josmUrl = 'http://www.openstreetmap.org/edit?editor=remote#map='+center;

                // extra label information - currently unused
                var label = '';
                if (feature.properties != null) {
                    var obj = JSON.parse(JSON.stringify(feature.properties));
                    label = "";
                    for (x in feature.properties) {
                        if (x == "sort_key" || x == "id") continue;
                        val = feature.properties[x];
                        label += ""+x+" : "+val+"
"
                    }
                }

                popup.style.left = (pixel.x + 0) + 'px';
                popup.style.top = (pixel.y + 0) + 'px';
                if ( scene.selection.feature.properties.name == undefined) {
	                popup.style.visibility = 'visible';
	            }
                popup.innerHTML = '' + 'You found an unnamed street!' + '
';
                popup.innerHTML += '' + 'Edit with iD ➹' + '
';
                popup.innerHTML += '' + 'Edit with JOSM ➹' + '
';
            });
        });

        map.getContainer().addEventListener('mousedown', function (event) {
            info.style.visibility = 'hidden';
            popup.style.visibility = 'hidden';
        });

    }

    function inIframe () {
        try {
            return window.self !== window.top;
        } catch (e) {
            return true;
        }
    }

    // Add map
    window.addEventListener('load', function () {
        // Scene initialized
        layer.on('init', function() {
            initFeatureSelection();
            console.log('1 map loc:', map_start_location, '\ncamera pos:', scene.camera.position);
            if (defaultpos && typeof scene.camera.position != "undefined") {
                map_start_location = [scene.camera.position[1], scene.camera.position[0], scene.camera.position[2]]
            }
            map.setView([map_start_location[0], map_start_location[1]], map_start_location[2]);
        });
        if (!inIframe()) {
            map.scrollWheelZoom.enable();
        }
        layer.addTo(map);
    });

    return map;

}());

<|endoftext|>


<commit_before>
var expect = require('chai').expect;

// still undecided on how the mixin gets dependencies
_ = require('yobo')._;

var Backbone = require('yobo').Backbone;

var BackbonePolymerAttach = require('../backbone-polymer-mixin');

var PolymerElementMock = function() {

  var spliced = this.spliced = [];

  this.splice = function(path, index, removeCount, items) {
    spliced.push({path: path, index: index, removeCount: removeCount, items: items});
  };

  this.notifyPath = function() {
    console.log('Polymer got notifyPath', arguments);
  };

};

describe("Array modification through Polymer splices, emulate backbone events", function() {

  describe("Backbone events before backbone-polymer", function() {

    it("add model", function() {
      var c = new Backbone.Collection();
      var m = new Backbone.Model({id: 'a1', type: 'testmodel'})
      c.on('add', function(model, collection, options) {
        console.log('add', m === model ? '(model)' : model, c === collection ? '(collection)' : collection, JSON.stringify(options));
      });
      c.add(m);
    });

    it("add model at index", function() {
      var c = new Backbone.Collection();
      c.add({id: 'a2', type: 'testmodel2'});
      c.add({id: 'a3', type: 'testmodel3'});
      var m = new Backbone.Model({id: 'a1', type: 'testmodel'})
      c.on('add', function(model, collection, options) {
        console.log('add', m === model ? '(model)' : model, c === collection ? '(collection)' : collection, JSON.stringify(options));
      });
      var added = c.add(m, {at: 1});
      console.log('add returned', m === added ? '(model)' : model);
    });

  });

  describe("#add", function() {

    it("ATM accepts only a single item", function() {
      expect(function() {
        var c = new Backbone.Collection();
        BackbonePolymerAttach.call(c, new PolymerElementMock(), 'edit.units');
        c.add([]);
      }).to.throw(/single/);
    });

    it("ATM requires that item to be a real model", function() {
      expect(function() {
        var c = new Backbone.Collection();
        BackbonePolymerAttach.call(c, new PolymerElementMock(), 'edit.units');
        c.add({id: 'add1', type: 'test'});
      }).to.throw(/requires model instance/);
    });

    it("Is transparent to backbone add event listener", function() {
      var e = new PolymerElementMock();
      var c = new Backbone.Collection();
      var adds = [];
      c.on('add', function() { adds.push(arguments); });
      BackbonePolymerAttach.call(c, e, 'edit.units');
      var m = c.add(new Backbone.Model({id: 'add1', type: 'test'}));
      expect(m.get('type')).to.equal('test');
      expect(adds).to.have.length(1);
      expect(e.spliced).to.have.length(1);
    });

  });

});
<commit_msg>tests for Options object.<commit_after>
var expect = require('chai').expect;

// still undecided on how the mixin gets dependencies
_ = require('yobo')._;

var Backbone = require('yobo').Backbone;

var BackbonePolymerAttach = require('../backbone-polymer-mixin');

var PolymerElementMock = function() {

  var spliced = this.spliced = [];

  this.splice = function(path, index, removeCount, items) {
    spliced.push({path: path, index: index, removeCount: removeCount, items: items});
  };

  this.notifyPath = function() {
    console.log('Polymer got notifyPath', arguments);
  };

};

describe("Array modification through Polymer splices, emulate backbone events", function() {

  describe("Backbone events before backbone-polymer", function() {

    it("add model", function() {
      var c = new Backbone.Collection();
      var m = new Backbone.Model({id: 'a1', type: 'testmodel'})
      c.on('add', function(model, collection, options) {
        console.log('add', m === model ? '(model)' : model, c === collection ? '(collection)' : collection, JSON.stringify(options));
      });
      c.add(m);
    });

    it("add model at index", function() {
      var c = new Backbone.Collection();
      c.add({id: 'a2', type: 'testmodel2'});
      c.add({id: 'a3', type: 'testmodel3'});
      var m = new Backbone.Model({id: 'a1', type: 'testmodel'})
      c.on('add', function(model, collection, options) {
        console.log('add', m === model ? '(model)' : model, c === collection ? '(collection)' : collection, JSON.stringify(options));
      });
      var added = c.add(m, {at: 1});
      console.log('add returned', m === added ? '(model)' : model);
    });

  });

  describe("#add", function() {

    it("ATM accepts only a single item", function() {
      expect(function() {
        var c = new Backbone.Collection();
        BackbonePolymerAttach.call(c, new PolymerElementMock(), 'edit.units');
        c.add([]);
      }).to.throw(/single/);
    });

    it("ATM requires that item to be a real model", function() {
      expect(function() {
        var c = new Backbone.Collection();
        BackbonePolymerAttach.call(c, new PolymerElementMock(), 'edit.units');
        c.add({id: 'add1', type: 'test'});
      }).to.throw(/requires model instance/);
    });

    it("Is transparent to backbone add event listener", function() {
      var e = new PolymerElementMock();
      var c = new Backbone.Collection();
      var adds = [];

      c.on('add', function() { adds.push(arguments); });
      BackbonePolymerAttach.call(c, e, 'edit.units');
      var m = c.add(new Backbone.Model({id: 'add1', type: 'test'}));

      expect(m.get('type')).to.equal('test');
      expect(adds).to.have.length(1);
      expect(e.spliced).to.have.length(1);

      //Expects on the options obj.
      expect(adds[0][2]).to.be.an('object');
      expect(adds[0][2]).to.have.property('add').and.equal(true);
      expect(adds[0][2]).to.have.property('merge').and.equal(false);
      expect(adds[0][2]).to.have.property('remove').and.equal(false);

      var m1 = new Backbone.Model({id: 'add2', type: 'test'});
      c.add(m1, {at: 1});

      //Adding at an index, expects Options to have 'at'
      expect(adds[1][2]).to.have.property('add').and.equal(true);
      expect(adds[1][2]).to.have.property('at').and.equal(1);
      expect(e.spliced).to.have.length(2);

      //Adding again at index 2
      var m2 = new Backbone.Model({id: 'add3', type: 'test'});
      c.add(m2, {at: 2});

      expect(e.spliced[2]).to.have.property('index').and.equal(2);

    });

  });

});
<|endoftext|>


<commit_before>describe('aria-allowed-role', function() {
	'use strict';

	var fixture = document.getElementById('fixture');
	var checkContext = axe.testUtils.MockCheckContext();

	afterEach(function() {
		fixture.innerHTML = '';
		checkContext.reset();
	});

	it('returns true if given element is an ignoredTag in options', function() {
		var node = document.createElement('article');
		node.setAttribute('role', 'presentation');
		fixture.appendChild(node);
		var options = {
			ignoredTags: ['article']
		};
		var actual = checks['aria-allowed-role'].evaluate.call(
			checkContext,
			node,
			options
		);
		var expected = true;
		assert.equal(actual, expected);
		assert.isNull(checkContext._data, null);
	});

	it('returns false with implicit role of row for TR when allowImplicit is set to false via options', function() {
		fixture.innerHTML =
			'

';
		var target = fixture.querySelector('#target');
		var options = {
			allowImplicit: false
		};
		var actual = checks['aria-allowed-role'].evaluate.call(
			checkContext,
			target,
			options
		);
		var expected = false;
		assert.equal(actual, expected);
		assert.deepEqual(checkContext._data, ['row']);
	});

	it('returns true when A has namespace as svg', function() {
		var node = document.createElementNS('http://www.w3.org/2000/svg', 'a');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns undefined (needs review) when element is hidden and has unallowed role', function() {
		fixture.innerHTML =
			'<button id="target" type="button" aria-hidden="true"' +
			'role="presentation"></button>';
		var target = fixture.querySelector('#target');
		var actual = checks['aria-allowed-role'].evaluate.call(
			checkContext,
			target
		);
		assert.isUndefined(actual);
	});

	it('returns undefined (needs review) when element is with in hidden parent and has unallowed role', function() {
		fixture.innerHTML =
			'
' +
			'<button id="target" class="mm-tabstart" type="button"' +
			'role="presentation"></button>' +
			'
';
		var target = fixture.querySelector('#target');
		var actual = checks['aria-allowed-role'].evaluate.call(
			checkContext,
			target
		);
		assert.isUndefined(actual);
	});

	it('returns true when BUTTON has type menu and role as menuitem', function() {
		var node = document.createElement('button');
		node.setAttribute('type', 'menu');
		node.setAttribute('role', 'menuitem');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns false when img has no alt', function() {
		var node = document.createElement('img');
		node.setAttribute('role', 'presentation');
		fixture.appendChild(node);
		assert.isFalse(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
		assert.deepEqual(checkContext._data, ['presentation']);
	});

	it('returns true when input of type image and no role', function() {
		var node = document.createElement('img');
		node.setAttribute('type', 'image');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
		assert.isNull(checkContext._data, null);
	});

	it('returns true when INPUT type is checkbox and has aria-pressed attribute', function() {
		var node = document.createElement('input');
		node.setAttribute('type', 'checkbox');
		node.setAttribute('aria-pressed', '');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns true when INPUT type is text with role combobox', function() {
		var node = document.createElement('input');
		node.setAttribute('type', 'text');
		node.setAttribute('role', 'combobox');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns true when INPUT type is text with role spinbutton', function() {
		var node = document.createElement('input');
		node.setAttribute('type', 'text');
		node.setAttribute('role', 'spinbutton');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns true when INPUT type is text with role searchbox', function() {
		var node = document.createElement('input');
		node.setAttribute('type', 'text');
		node.setAttribute('role', 'searchbox');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns true when MENU has type context', function() {
		var node = document.createElement('menu');
		node.setAttribute('type', 'context');
		node.setAttribute('role', 'navigation');
		fixture.appendChild(node);
		assert.isFalse(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
		assert.deepEqual(checkContext._data, ['navigation']);
	});

	it('returns false when a role is set on an element that does not allow any role', function() {
		var node = document.createElement('dd');
		node.setAttribute('role', 'link');
		fixture.appendChild(node);
		assert.isFalse(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
		assert.deepEqual(checkContext._data, ['link']);
	});

	it('returns true when a role is set on an element that can have any role', function() {
		var node = document.createElement('div');
		node.setAttribute('role', 'link');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns true an  without a href to have any role', function() {
		var node = document.createElement('a');
		node.setAttribute('role', 'presentation');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns true  with a empty href to have any valid role', function() {
		var node = document.createElement('a');
		node.setAttribute('role', 'link');
		node.href = '';
		fixture.appendChild(node);
		var actual = checks['aria-allowed-role'].evaluate.call(checkContext, node);
		assert.isTrue(actual);
	});

	it('returns true  with a non-empty alt', function() {
		var node = document.createElement('img');
		node.setAttribute('role', 'banner');
		node.alt = 'some text';
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns false for  with a non-empty alt and role `presentation`', function() {
		var node = document.createElement('img');
		node.setAttribute('role', 'presentation');
		node.alt = 'some text';
		fixture.appendChild(node);
		assert.isFalse(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('should allow <select> without a multiple and size attribute to have a menu role', function() {
		var node = document.createElement('select');
		node.setAttribute('role', 'menu');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
		assert.isNull(checkContext._data, null);
	});

	it('returns true custom element <my-navbar> with a role of navigation', function() {
		var node = document.createElement('my-navbar');
		node.setAttribute('role', 'navigation');
		fixture.appendChild(node);
		var actual = checks['aria-allowed-role'].evaluate.call(checkContext, node);
		assert.isTrue(actual);
		assert.isNull(checkContext._data, null);
	});
});
<commit_msg>test: remove test as support for context menu is experimental (#1249)<commit_after>describe('aria-allowed-role', function() {
	'use strict';

	var fixture = document.getElementById('fixture');
	var checkContext = axe.testUtils.MockCheckContext();

	afterEach(function() {
		fixture.innerHTML = '';
		checkContext.reset();
	});

	it('returns true if given element is an ignoredTag in options', function() {
		var node = document.createElement('article');
		node.setAttribute('role', 'presentation');
		fixture.appendChild(node);
		var options = {
			ignoredTags: ['article']
		};
		var actual = checks['aria-allowed-role'].evaluate.call(
			checkContext,
			node,
			options
		);
		var expected = true;
		assert.equal(actual, expected);
		assert.isNull(checkContext._data, null);
	});

	it('returns false with implicit role of row for TR when allowImplicit is set to false via options', function() {
		fixture.innerHTML =
			'

';
		var target = fixture.querySelector('#target');
		var options = {
			allowImplicit: false
		};
		var actual = checks['aria-allowed-role'].evaluate.call(
			checkContext,
			target,
			options
		);
		var expected = false;
		assert.equal(actual, expected);
		assert.deepEqual(checkContext._data, ['row']);
	});

	it('returns true when A has namespace as svg', function() {
		var node = document.createElementNS('http://www.w3.org/2000/svg', 'a');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns undefined (needs review) when element is hidden and has unallowed role', function() {
		fixture.innerHTML =
			'<button id="target" type="button" aria-hidden="true"' +
			'role="presentation"></button>';
		var target = fixture.querySelector('#target');
		var actual = checks['aria-allowed-role'].evaluate.call(
			checkContext,
			target
		);
		assert.isUndefined(actual);
	});

	it('returns undefined (needs review) when element is with in hidden parent and has unallowed role', function() {
		fixture.innerHTML =
			'
' +
			'<button id="target" class="mm-tabstart" type="button"' +
			'role="presentation"></button>' +
			'
';
		var target = fixture.querySelector('#target');
		var actual = checks['aria-allowed-role'].evaluate.call(
			checkContext,
			target
		);
		assert.isUndefined(actual);
	});

	it('returns true when BUTTON has type menu and role as menuitem', function() {
		var node = document.createElement('button');
		node.setAttribute('type', 'menu');
		node.setAttribute('role', 'menuitem');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns false when img has no alt', function() {
		var node = document.createElement('img');
		node.setAttribute('role', 'presentation');
		fixture.appendChild(node);
		assert.isFalse(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
		assert.deepEqual(checkContext._data, ['presentation']);
	});

	it('returns true when input of type image and no role', function() {
		var node = document.createElement('img');
		node.setAttribute('type', 'image');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
		assert.isNull(checkContext._data, null);
	});

	it('returns true when INPUT type is checkbox and has aria-pressed attribute', function() {
		var node = document.createElement('input');
		node.setAttribute('type', 'checkbox');
		node.setAttribute('aria-pressed', '');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns true when INPUT type is text with role combobox', function() {
		var node = document.createElement('input');
		node.setAttribute('type', 'text');
		node.setAttribute('role', 'combobox');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns true when INPUT type is text with role spinbutton', function() {
		var node = document.createElement('input');
		node.setAttribute('type', 'text');
		node.setAttribute('role', 'spinbutton');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns true when INPUT type is text with role searchbox', function() {
		var node = document.createElement('input');
		node.setAttribute('type', 'text');
		node.setAttribute('role', 'searchbox');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns false when a role is set on an element that does not allow any role', function() {
		var node = document.createElement('dd');
		node.setAttribute('role', 'link');
		fixture.appendChild(node);
		assert.isFalse(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
		assert.deepEqual(checkContext._data, ['link']);
	});

	it('returns true when a role is set on an element that can have any role', function() {
		var node = document.createElement('div');
		node.setAttribute('role', 'link');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns true an  without a href to have any role', function() {
		var node = document.createElement('a');
		node.setAttribute('role', 'presentation');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns true  with a empty href to have any valid role', function() {
		var node = document.createElement('a');
		node.setAttribute('role', 'link');
		node.href = '';
		fixture.appendChild(node);
		var actual = checks['aria-allowed-role'].evaluate.call(checkContext, node);
		assert.isTrue(actual);
	});

	it('returns true  with a non-empty alt', function() {
		var node = document.createElement('img');
		node.setAttribute('role', 'banner');
		node.alt = 'some text';
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('returns false for  with a non-empty alt and role `presentation`', function() {
		var node = document.createElement('img');
		node.setAttribute('role', 'presentation');
		node.alt = 'some text';
		fixture.appendChild(node);
		assert.isFalse(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
	});

	it('should allow <select> without a multiple and size attribute to have a menu role', function() {
		var node = document.createElement('select');
		node.setAttribute('role', 'menu');
		fixture.appendChild(node);
		assert.isTrue(
			checks['aria-allowed-role'].evaluate.call(checkContext, node)
		);
		assert.isNull(checkContext._data, null);
	});

	it('returns true custom element <my-navbar> with a role of navigation', function() {
		var node = document.createElement('my-navbar');
		node.setAttribute('role', 'navigation');
		fixture.appendChild(node);
		var actual = checks['aria-allowed-role'].evaluate.call(checkContext, node);
		assert.isTrue(actual);
		assert.isNull(checkContext._data, null);
	});
});
<|endoftext|>


<commit_before>import {Config} from '../../src/base/utils'
import Styler from '../../src/base/styler'
import template from '../../src/base/template'
import MediaControl from '../../src/components/media_control'
import Playback from '../../src/base/playback'
import Container from '../../src/components/container'

describe('MediaControl', function() {
  beforeEach(function() {
    this.playback = new Playback()
    this.playback.getPlaybackType = function() {
      return Playback.VOD
    }
    this.container = new Container({playback: this.playback})
    this.mediaControl = new MediaControl({container: this.container})
    localStorage.removeItem('clappr.localhost.volume')
  })

  describe('#constructor', function() {
    it('can be built muted', function() {
      const mediaControl = new MediaControl({mute: true, container: this.container})
      expect(mediaControl.muted).to.be.equal(true)
      expect(mediaControl.volume).to.be.equal(0)
    })

    it('restores saved volume', function() {
      Config.persist('volume', 42)
      const mediaControl = new MediaControl({persistConfig: true, container: this.container})

      expect(mediaControl.volume).to.be.equal(42)
    })
  })

  describe('#setVolume', function() {
    // TODO fix. needs to wait for container to be ready because
    // setVolume only called at this point
   // it('sets the volume', function() {
   //   sinon.spy(this.container, 'setVolume');
   //   sinon.spy(this.mediaControl, 'updateVolumeUI');

   //   this.mediaControl.setVolume(42)

   //   expect(this.mediaControl.volume).to.be.equal(42)
   //   expect(this.mediaControl.muted).to.be.equal(false)
   //   expect(this.container.setVolume).called.once;
   //   expect(this.mediaControl.updateVolumeUI).called.once;
   // });

    it('limits volume to an integer between 0 and 100', function() {
      this.mediaControl.setVolume(1000)
      expect(this.mediaControl.volume).to.be.equal(100)

      this.mediaControl.setVolume(101)
      expect(this.mediaControl.volume).to.be.equal(100)

      this.mediaControl.setVolume(481)
      expect(this.mediaControl.volume).to.be.equal(100)

      this.mediaControl.setVolume(-1)
      expect(this.mediaControl.volume).to.be.equal(0)

      this.mediaControl.setVolume(0)
      expect(this.mediaControl.volume).to.be.equal(0)
    })

    it('mutes when volume is 0 or less than 0', function() {
      this.mediaControl.setVolume(10)
      expect(this.mediaControl.muted).to.be.equal(false)

      this.mediaControl.setVolume(0)
      expect(this.mediaControl.muted).to.be.equal(true)
    })

    it('persists volume when persistence is on', function() {
      // expected to be default value (100)
      expect(Config.restore('volume')).to.be.equal(100)

      const mediacontrol = new MediaControl({persistConfig: true, container: this.container})
      mediacontrol.setVolume(78)

      expect(Config.restore('volume')).to.be.equal(78)
    })
  })

  it('persists volume when persistence is on', function() {
    // expected to be default value (100)
    expect(Config.restore('volume')).to.be.equal(100)

    const mediacontrol = new MediaControl({persistConfig: true, container: this.container})
    mediacontrol.setVolume(78)

    expect(Config.restore('volume')).to.be.equal(78)
  })

  it('can appear when playback type is not NO_OP', function() {
    const mediaControl = new MediaControl({container: this.container})
    mediaControl.render()
    mediaControl.enable()
    expect(mediaControl.$el.hasClass('media-control-hide')).to.be.false
    expect(mediaControl.disabled).to.be.false
  })

  it('never appears when playback type is NO_OP', function() {
     this.playback.getPlaybackType = function() {
      return Playback.NO_OP
    }
    const mediaControl = new MediaControl({container: this.container})
    mediaControl.render()
    mediaControl.enable()
    expect(mediaControl.$el.hasClass('media-control-hide')).to.be.true
    expect(mediaControl.disabled).to.be.true
  })

  describe('custom media control', function() {
    it('can be extend the base mediacontrol with a custom template and stylesheet', function() {
      class MyMediaControl extends MediaControl {
        get template() { return template('
My HTML here
') }
        get stylesheet () { return Styler.getStyleFor('.my-css-class {}') }
        constructor(options) { super(options) }
      }

      const mediaControl = new MyMediaControl({mute: true, container: this.container})
      mediaControl.render()
      expect(mediaControl.muted).to.be.equal(true)
      expect(mediaControl.volume).to.be.equal(0)
      expect(mediaControl.$el.html()).to.be.equal(
        '
My HTML here
'
      )
    })
  })
})
<commit_msg>Fix lint<commit_after>import {Config} from '../../src/base/utils'
import Styler from '../../src/base/styler'
import template from '../../src/base/template'
import MediaControl from '../../src/components/media_control'
import Playback from '../../src/base/playback'
import Container from '../../src/components/container'

describe('MediaControl', function() {
  beforeEach(function() {
    this.playback = new Playback()
    this.playback.getPlaybackType = function() {
      return Playback.VOD
    }
    this.container = new Container({playback: this.playback})
    this.mediaControl = new MediaControl({container: this.container})
    localStorage.removeItem('clappr.localhost.volume')
  })

  describe('#constructor', function() {
    it('can be built muted', function() {
      const mediaControl = new MediaControl({mute: true, container: this.container})
      expect(mediaControl.muted).to.be.equal(true)
      expect(mediaControl.volume).to.be.equal(0)
    })

    it('restores saved volume', function() {
      Config.persist('volume', 42)
      const mediaControl = new MediaControl({persistConfig: true, container: this.container})

      expect(mediaControl.volume).to.be.equal(42)
    })
  })

  describe('#setVolume', function() {
    // TODO fix. needs to wait for container to be ready because
    // setVolume only called at this point
   // it('sets the volume', function() {
   //   sinon.spy(this.container, 'setVolume');
   //   sinon.spy(this.mediaControl, 'updateVolumeUI');

   //   this.mediaControl.setVolume(42)

   //   expect(this.mediaControl.volume).to.be.equal(42)
   //   expect(this.mediaControl.muted).to.be.equal(false)
   //   expect(this.container.setVolume).called.once;
   //   expect(this.mediaControl.updateVolumeUI).called.once;
   // });

    it('limits volume to an integer between 0 and 100', function() {
      this.mediaControl.setVolume(1000)
      expect(this.mediaControl.volume).to.be.equal(100)

      this.mediaControl.setVolume(101)
      expect(this.mediaControl.volume).to.be.equal(100)

      this.mediaControl.setVolume(481)
      expect(this.mediaControl.volume).to.be.equal(100)

      this.mediaControl.setVolume(-1)
      expect(this.mediaControl.volume).to.be.equal(0)

      this.mediaControl.setVolume(0)
      expect(this.mediaControl.volume).to.be.equal(0)
    })

    it('mutes when volume is 0 or less than 0', function() {
      this.mediaControl.setVolume(10)
      expect(this.mediaControl.muted).to.be.equal(false)

      this.mediaControl.setVolume(0)
      expect(this.mediaControl.muted).to.be.equal(true)
    })

    it('persists volume when persistence is on', function() {
      // expected to be default value (100)
      expect(Config.restore('volume')).to.be.equal(100)

      const mediacontrol = new MediaControl({persistConfig: true, container: this.container})
      mediacontrol.setVolume(78)

      expect(Config.restore('volume')).to.be.equal(78)
    })
  })

  it('persists volume when persistence is on', function() {
    // expected to be default value (100)
    expect(Config.restore('volume')).to.be.equal(100)

    const mediacontrol = new MediaControl({persistConfig: true, container: this.container})
    mediacontrol.setVolume(78)

    expect(Config.restore('volume')).to.be.equal(78)
  })

  it('can appear when playback type is not NO_OP', function() {
    const mediaControl = new MediaControl({container: this.container})
    mediaControl.render()
    mediaControl.enable()
    expect(mediaControl.$el.hasClass('media-control-hide')).to.be.false
    expect(mediaControl.disabled).to.be.false
  })

  it('never appears when playback type is NO_OP', function() {
    this.playback.getPlaybackType = function() {
      return Playback.NO_OP
    }
    const mediaControl = new MediaControl({container: this.container})
    mediaControl.render()
    mediaControl.enable()
    expect(mediaControl.$el.hasClass('media-control-hide')).to.be.true
    expect(mediaControl.disabled).to.be.true
  })

  describe('custom media control', function() {
    it('can be extend the base mediacontrol with a custom template and stylesheet', function() {
      class MyMediaControl extends MediaControl {
        get template() { return template('
My HTML here
') }
        get stylesheet () { return Styler.getStyleFor('.my-css-class {}') }
        constructor(options) { super(options) }
      }

      const mediaControl = new MyMediaControl({mute: true, container: this.container})
      mediaControl.render()
      expect(mediaControl.muted).to.be.equal(true)
      expect(mediaControl.volume).to.be.equal(0)
      expect(mediaControl.$el.html()).to.be.equal(
        '
My HTML here
'
      )
    })
  })
})
<|endoftext|>


<commit_before>var bbDetail, bbOverview, dataSet, svg;

var margin = {
    top: 50,
    right: 50,
    bottom: 50,
    left: 150
};

var width = 960 - margin.left - margin.right;

var height = 800 - margin.bottom - margin.top;

bbOverview = {
    x: 0,
    y: 10,
    w: width,
    h: 50
};

bbDetail = {
    x: 0,
    y: 100,
    w: width,
    h: 300
};

var x = d3.scale.linear()
    .range([0, bbOverview.w + 50]);

var y = d3.scale.linear()
    .range([bbOverview.h + 30, 0]);

var x1 = d3.scale.linear()
    .range([0, bbDetail.w]);

var y1 = d3.scale.linear()
    .range([bbDetail.h, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");

var line = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.health); });

var area = d3.svg.area()
    .x(function(d) { return x(d.date); })
    .y0(height)
    .y1(function(d) { return y(d.health); });

dataSet = [];

svg = d3.select("#visUN").append("svg").attr({
    width: width + margin.left + margin.right,
    height: height + margin.top + margin.bottom
}).append("g").attr({
        transform: "translate(" + margin.left + "," + margin.top + ")"
    });

var parseDate = d3.time.format("%Y%m%d").parse;

d3.csv("UN.csv", function(data) {

     data.forEach(function(d) {
      d.date = parseDate(d.date);
      d.health = +d.health;

    });

     dataSet = data;
     console.log(dataSet);

  x.domain(d3.extent(dataSet, function(d) { return d.date; }));
  y.domain(d3.extent(dataSet, function(d) { return d.health; }));

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + .1*height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Women's Health");

  svg.append("path")
      .datum(dataSet)
      .attr("class", "line")
      .attr("d", line);

  svg.append("path")
      .datum(dataSet)
      .attr("class", "area")
      .attr("d", area);

    // dataSet.forEach(function(d) {
    //   d.date = parseDate(d.date);
    // });

});

// var convertToInt = function(s) {
//     return parseInt(s.replace(/,/g, ""), 10);
// };

<commit_msg>Update unHealth.js<commit_after>var bbDetail, bbOverview, dataSet, svg;

var margin = {
    top: 50,
    right: 50,
    bottom: 50,
    left: 150
};

var width = 960 - margin.left - margin.right;

var height = 800 - margin.bottom - margin.top;

bbOverview = {
    x: 0,
    y: 10,
    w: width,
    h: 50
};

bbDetail = {
    x: 0,
    y: 100,
    w: width,
    h: 300
};

var chart1 = d3.select("#linegraph")
    .append("svg");

var chart2 = d3.select("#areagraph")
    .append("svg");

var x = d3.time.scale()
    .range([0, bbOverview.w]);

var y = d3.scale.linear()
    .range([bbOverview.h + 30, 0]);

var x1 = d3.time.scale()
    .range([0, bbDetail.w+50]);

var y1 = d3.scale.linear()
    .range([bbDetail.h+30, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var xAxis1 = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");

var yAxis1 = d3.svg.axis()
    .scale(y)
    .orient("left");

var line = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.health); });

var area = d3.svg.area()
    .x(function(d) { return x(d.date); })
    .y0(height)
    .y1(function(d) { return y(d.health); });

dataSet = [];

// svg = d3.select("#visUN").append("svg").attr({
//     width: width + margin.left + margin.right,
//     height: height + margin.top + margin.bottom
// }).append("g").attr({
//         transform: "translate(" + margin.left + "," + margin.top + ")"
//     });

var parseDate = d3.time.format("%Y%m%d").parse;

d3.csv("UN.csv", function(data) {

     data.forEach(function(d) {
      d.date = parseDate(d.date);
      d.health = +d.health;

    });

     dataSet = data;
     console.log(dataSet);

  x.domain(d3.extent(dataSet, function(d) { return d.date; }));
  y.domain(d3.extent(dataSet, function(d) { return d.health; }));
  x1.domain(d3.extent(dataSet, function(d) { return d.date; }));
  y1.domain(d3.extent(dataSet, function(d) { return d.health; }));

  chart1.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + .1*height + ")")
      .call(xAxis);

  chart1.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Women's Health");

  chart1.append("path")
      .datum(dataSet)
      .attr("class", "line")
      .attr("d", line);

  chart2.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + .1*height + ")")
      .call(xAxis1);

  chart2.append("g")
      .attr("class", "y axis")
      .call(yAxis1)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Women's Health");

  chart2.append("path")
      .datum(dataSet)
      .attr("class", "area")
      .attr("d", area);

});

<|endoftext|>


<commit_before>/**
 * Created by truthlighting on 9/20/2016.
 */
var proto = {
    /**
     * The creep for this role
     *
     * @type creep
     */
    creep: null,

    /**
     * Set the creep for this role
     *
     * @param {Creep} creep
     */
    setCreep: function(creep)
    {
        this.creep = creep;
        return this;
    },

    run: function()
    {
        if(this.creep.memory.onSpawned == undefined) {
            console.log("onSpawned undefined.");
            for (var key in this) { console.log(key); }
            this.onSpawn();
            console.log(this.creep.memory.onSpawned = true);
        }

        this.action(this.creep);

        if(this.creep.ticksToLive == 1)
            this.beforeAge();
    },

    handleEvents: function()
    {
        if(this.creep.memory.onSpawned == undefined) {
            this.onSpawnStart();
            this.onSpawn();
            this.creep.memory.onSpawned = true;
        }

        if(this.creep.memory.onSpawnEnd == undefined && !this.creep.spawning) {
            this.onSpawnEnd();
            this.creep.memory.onSpawnEnd = true;
        }
    },

    getParts: function() {
        //var _ = require('lodash');

        var extensions = Game.rooms['W2N48'].find(FIND_MY_STRUCTURES, {
            filter: function(structure)
            {
                return (structure.structureType == STRUCTURE_EXTENSION && structure.energy >= 50);
            }
        }).length;
        //console.log("extensions: " + extensions);

        var parts = _.cloneDeep(this.parts);
        //console.log("parts: " + parts);
        if(typeof parts[0] != "object")
            return this.parts;

        parts.reverse();

        for(var i in parts)
        {
            if((parts[i].length - 5) <= extensions) {
                return parts[i];
            }
        }
    },

    action: function() { },

    onSpawn: function() { },

    onSpawnStart: function() { },

    onSpawnEnd: function() { },

    beforeAge: function() { },

    /**
     * All credit goes to Djinni
     * @url https://bitbucket.org/Djinni/screeps/
     */
    rest: function(civilian)
    {
        var creep = this.creep;

        var distance = 4;
        var restTarget = creep.pos.findClosestByPath(FIND_MY_SPAWNS);

        if(!civilian) {
            var flags = Game.flags;
            for (var i in flags) {
                var flag = flags[i];
                if (creep.pos.inRangeTo(flag, distance) || creep.pos.findPathTo(flag).length > 0) {
                    restTarget = flag;
                    break;
                }
            }
        }

//		var flag = Game.flags['Flag1'];
//		if(flag !== undefined && civilian !== true)
//			restTarget = flag;
//
//		var flag2 = Game.flags['Flag2'];
//		if(flag !== undefined && civilian !== true && !creep.pos.inRangeTo(flag, distance) && !creep.pos.findPathTo(flag).length)
//			restTarget = flag2;

        if (creep.getActiveBodyparts(Game.HEAL)) {
//			distance = distance - 1;
        }
        else if (creep.getActiveBodyparts(Game.RANGED_ATTACK)) {
//			distance = distance - 1;
        }
        if (creep.pos.findPathTo(restTarget).length > distance) {
            creep.moveTo(restTarget);
        }
    },

    /**
     * All credit goes to Djinni
     * @url https://bitbucket.org/Djinni/screeps/
     */
    rangedAttack: function(target) {
        var creep = this.creep;

        if(!target)
            target = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS);

        if(target) {
            if (target.pos.inRangeTo(creep.pos, 3) ) {
                creep.rangedAttack(target);
                return target;
            }
        }
        return null;
    },

    keepAwayFromEnemies: function()
    {
        var creep = this.creep;

        var target = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
        if(target !== null && target.pos.inRangeTo(creep.pos, 3))
            creep.moveTo(creep.pos.x + creep.pos.x - target.pos.x, creep.pos.y + creep.pos.y - target.pos.y );
    },

    /**
     * All credit goes to Djinni
     * @url https://bitbucket.org/Djinni/screeps/
     */
    kite: function(target) {
        var creep = this.creep;

        if (target.pos.inRangeTo(creep.pos, 2)) {
            creep.moveTo(creep.pos.x + creep.pos.x - target.pos.x, creep.pos.y + creep.pos.y - target.pos.y );
            return true;
        } else if (target.pos.inRangeTo(creep.pos, 3)) {
            return true;
        }
        else {
            creep.moveTo(target);
            return true;
        }

        return false;
    },

    getRangedTarget: function()
    {
        var creep = this.creep;

        var closeArchers = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {
            filter: function(enemy)
            {
                return enemy.getActiveBodyparts(Game.RANGED_ATTACK) > 0
                    && creep.pos.inRangeTo(enemy, 3);
            }
        });

        if(closeArchers != null)
            return closeArchers;

        var closeMobileMelee = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {
            filter: function(enemy)
            {
                return enemy.getActiveBodyparts(Game.ATTACK) > 0
                    && enemy.getActiveBodyparts(Game.MOVE) > 0
                    && creep.pos.inRangeTo(enemy, 3);
            }
        });

        if(closeMobileMelee != null)
            return closeMobileMelee;

        var closeHealer = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {
            filter: function(enemy)
            {
                return enemy.getActiveBodyparts(Game.HEAL) > 0
                    && enemy.getActiveBodyparts(Game.MOVE) > 0
                    && creep.pos.inRangeTo(enemy, 3);
            }
        });

        if(closeHealer != null)
            return closeHealer;

        return creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
    }
};

module.exports = proto;<commit_msg>Starting the long process of fixing old code<commit_after>/**
 * Created by truthlighting on 9/20/2016.
 */
var proto = {
    /**
     * The creep for this role
     *
     * @type creep
     */
    creep: null,

    /**
     * Set the creep for this role
     *
     * @param {Creep} creep
     */
    setCreep: function(creep)
    {
        this.creep = creep;
        return this;
    },

    run: function()
    {
        if(this.creep.memory.onSpawned == undefined) {
            console.log("onSpawned undefined.");
            //for (var key in this) { console.log(key); }
            this.onSpawn();
            console.log(this.creep.memory.onSpawned = true);
        }

        this.action(this.creep);

        if(this.creep.ticksToLive == 1)
            this.beforeAge();
    },

    handleEvents: function()
    {
        if(this.creep.memory.onSpawned == undefined) {
            this.onSpawnStart();
            this.onSpawn();
            this.creep.memory.onSpawned = true;
        }

        if(this.creep.memory.onSpawnEnd == undefined && !this.creep.spawning) {
            this.onSpawnEnd();
            this.creep.memory.onSpawnEnd = true;
        }
    },

    getParts: function() {
        //var _ = require('lodash');

        var extensions = Game.rooms['W2N48'].find(FIND_MY_STRUCTURES, {
            filter: function(structure)
            {
                return (structure.structureType == STRUCTURE_EXTENSION && structure.energy >= 50);
            }
        }).length;
        //console.log("extensions: " + extensions);

        var parts = _.cloneDeep(this.parts);
        //console.log("parts: " + parts);
        if(typeof parts[0] != "object")
            return this.parts;

        parts.reverse();

        for(var i in parts)
        {
            if((parts[i].length - 5) <= extensions) {
                return parts[i];
            }
        }
    },

    action: function() { },

    onSpawn: function() { },

    onSpawnStart: function() { },

    onSpawnEnd: function() { },

    beforeAge: function() { },

    /**
     * All credit goes to Djinni
     * @url https://bitbucket.org/Djinni/screeps/
     */
    rest: function(civilian)
    {
        var creep = this.creep;

        var distance = 4;
        var restTarget = creep.pos.findClosestByPath(FIND_MY_SPAWNS);

        if(!civilian) {
            var flags = Game.flags;
            for (var i in flags) {
                var flag = flags[i];
                if (creep.pos.inRangeTo(flag, distance) || creep.pos.findPathTo(flag).length > 0) {
                    restTarget = flag;
                    break;
                }
            }
        }

//		var flag = Game.flags['Flag1'];
//		if(flag !== undefined && civilian !== true)
//			restTarget = flag;
//
//		var flag2 = Game.flags['Flag2'];
//		if(flag !== undefined && civilian !== true && !creep.pos.inRangeTo(flag, distance) && !creep.pos.findPathTo(flag).length)
//			restTarget = flag2;

        if (creep.getActiveBodyparts(Game.HEAL)) {
//			distance = distance - 1;
        }
        else if (creep.getActiveBodyparts(Game.RANGED_ATTACK)) {
//			distance = distance - 1;
        }
        if (creep.pos.findPathTo(restTarget).length > distance) {
            creep.moveTo(restTarget);
        }
    },

    /**
     * All credit goes to Djinni
     * @url https://bitbucket.org/Djinni/screeps/
     */
    rangedAttack: function(target) {
        var creep = this.creep;

        if(!target)
            target = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS);

        if(target) {
            if (target.pos.inRangeTo(creep.pos, 3) ) {
                creep.rangedAttack(target);
                return target;
            }
        }
        return null;
    },

    keepAwayFromEnemies: function()
    {
        var creep = this.creep;

        var target = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
        if(target !== null && target.pos.inRangeTo(creep.pos, 3))
            creep.moveTo(creep.pos.x + creep.pos.x - target.pos.x, creep.pos.y + creep.pos.y - target.pos.y );
    },

    /**
     * All credit goes to Djinni
     * @url https://bitbucket.org/Djinni/screeps/
     */
    kite: function(target) {
        var creep = this.creep;

        if (target.pos.inRangeTo(creep.pos, 2)) {
            creep.moveTo(creep.pos.x + creep.pos.x - target.pos.x, creep.pos.y + creep.pos.y - target.pos.y );
            return true;
        } else if (target.pos.inRangeTo(creep.pos, 3)) {
            return true;
        }
        else {
            creep.moveTo(target);
            return true;
        }

        return false;
    },

    getRangedTarget: function()
    {
        var creep = this.creep;

        var closeArchers = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {
            filter: function(enemy)
            {
                return enemy.getActiveBodyparts(Game.RANGED_ATTACK) > 0
                    && creep.pos.inRangeTo(enemy, 3);
            }
        });

        if(closeArchers != null)
            return closeArchers;

        var closeMobileMelee = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {
            filter: function(enemy)
            {
                return enemy.getActiveBodyparts(Game.ATTACK) > 0
                    && enemy.getActiveBodyparts(Game.MOVE) > 0
                    && creep.pos.inRangeTo(enemy, 3);
            }
        });

        if(closeMobileMelee != null)
            return closeMobileMelee;

        var closeHealer = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {
            filter: function(enemy)
            {
                return enemy.getActiveBodyparts(Game.HEAL) > 0
                    && enemy.getActiveBodyparts(Game.MOVE) > 0
                    && creep.pos.inRangeTo(enemy, 3);
            }
        });

        if(closeHealer != null)
            return closeHealer;

        return creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
    }
};

module.exports = proto;<|endoftext|>


<commit_before>var util = require('./util'),
	assert = util.assert
	q = util.q,
	debug = util.debug

var LPAREN = '(',
    RPAREN = ')',
    LBLOCK = '{',
    RBLOCK = '}'

var gToken, gIndex, gTokens, gState, gAST

exports.parse = function(tokens) {
	gTokens = tokens
	gIndex = -1
	gToken = null
	gAST = []

	while (true) {
		advance()
		if (gIndex == gTokens.length) { break }
		gAST.push(parseStatement())
	}

	return gAST
}

var parseStatement = function() {
	switch(gToken.type) {
		case 'string':
		case 'number':
			return getLiteralValue()
		case 'symbol':
			return parseXML() // only XML statements begin with a symbol (<)
		case 'name':
		    switch (gToken.value) {
        		case 'let': return parseDeclaration()
        		case 'for': return parseForLoop()
        		case 'if': return parseIfStatement()
        		default: return getAlias()
        	}

		default:
			throw new Error('Unknown parse statement token: ' + JSON.stringify(gToken))
	}
}

/*******************
 * Utility methods *
 *******************/
var advance = function(type, value, expressionType) {
	gToken = gTokens[++gIndex]
	function check(v1, v2) {
		assert.equal(v1, v2,
			['Expected the', q(type),
				value ? 'of value ' + q(value) : '',
				expressionType ? 'for the ' + expressionType : '',
				'on line:', gToken.line,
				'column:', gToken.column,
				'but found a', q(gToken.type),
				'of value', q(gToken.value)].join(' ')
	)}
	if (type) { check(type, gToken.type) }
	if (value) {
		if (value instanceof Array) { for (var i=0, val; val=value[i]; i++) {
			if (val != gToken.value) { continue }
			value = val // allow for the check to pass if one of the values passed in matches
			break
		}}
		check(value, gToken.value)
	}
}
var peek = function(amount) { return gTokens[gIndex + (amount || 1)] }
var isAhead = function(amount, type, value) {
	var token = gTokens[gIndex + amount]
	if (type && type != token.type) { return false }
	if (value && value != token.value) { return false }
	return true
}

/******************************
 * Aliases and literal values *
 ******************************/
function getAlias() {
	assert(gToken.type == 'name')
	// TODO Parse dot notation
	return { type:'ALIAS', name:gToken.value }
}

function getLiteralValue() {
	assert(gToken.type == 'string' || gToken.type == 'number')
	return { type:gToken.type.toUpperCase(), value:gToken.value }
}

/*******
 * XML *
 *******/
var parseXML = function() {
	debug('parseXML')
	advance('name', null, 'XML tag')
	var tagName = gToken.value,
		attributes = parseXMLAttributes()

	advance('symbol', ['>', '/'], 'end of XML tag')
	if (gToken.value == '/') {
		advance('symbol', '>', 'self-closing XML tag')
		return { type:'XML', tag:tagName, attributes:attributes, content:[] }
	} else {
		var statements = []
		while(true) {
			if (isAhead(1, 'symbol', '<') && isAhead(2, 'symbol', '/')) { break }
			advance()
			statements.push(parseStatement())
		}

		advance('symbol', '<')
		advance('symbol', '/')
		advance('name', tagName, 'matching XML tags')
		advance('symbol', '>')

		return { type:'XML', tag:tagName, attributes:attributes, block:statements }
	}
}

var parseXMLAttributes = function() {
	debug('parseXMLAttributes')
	if (!peek('name')) { return [] } // no attributes
}

/****************
 * Declarations *
 ****************/
function parseDeclaration() {
	debug('parseDeclaration')
	advance('name', null, 'declaration')
	var name = gToken.value
	advance('symbol', '=', 'declaration')
	value = parseDeclarable()
	return { type:'DECLARATION', name:name, value:value }
}
function parseDeclarable() {
	debug('parseDeclarable')
	advance()
	switch(gToken.type) {
		case 'name':
		    return getAlias()
		case 'symbol':
			// TODO Parse JSON literal
			return parseXML()
		case 'string':
		case 'number':
			return getLiteralValue()
		default:
			throw new Error('Unkown declarable token: ' + JSON.stringify(gToken))
	}
}

/*************
 * For loops *
 *************/
function parseForLoop() {
	debug('parseForLoop')
	throw new Error("For loops are not yet implemented")
}

/****************
 * If statement *
 ****************/
function parseIfStatement() {
	debug('parseIfStatement')

    advance('symbol', LPAREN, 'beginning of the if statement\'s conditional')
    var condition = parseCondition()
    advance('symbol', RPAREN, 'end of the if statement\'s conditional')

    advance('symbol', LBLOCK, 'beginning of the if statement\'s block')
    var statements = []
    while(true) {
		if (isAhead(1, 'symbol', RBLOCK)) { break }
		advance()
		statements.push(parseStatement())
	}
    advance('symbol', RBLOCK, 'end of the if statement\'s block')

    return { type:'IF_STATEMENT', condition:condition, block:statements }
}

function parseCondition() {
    // TODO Implement condition parsing
    advance()
    return {}
}<commit_msg>Whitespace fix<commit_after>var util = require('./util'),
	assert = util.assert
	q = util.q,
	debug = util.debug

var LPAREN = '(',
    RPAREN = ')',
    LBLOCK = '{',
    RBLOCK = '}'

var gToken, gIndex, gTokens, gState, gAST

exports.parse = function(tokens) {
	gTokens = tokens
	gIndex = -1
	gToken = null
	gAST = []

	while (true) {
		advance()
		if (gIndex == gTokens.length) { break }
		gAST.push(parseStatement())
	}

	return gAST
}

var parseStatement = function() {
	switch(gToken.type) {
		case 'string':
		case 'number':
			return getLiteralValue()
		case 'symbol':
			return parseXML() // only XML statements begin with a symbol (<)
		case 'name':
		    switch (gToken.value) {
        		case 'let': return parseDeclaration()
				case 'for': return parseForLoop()
				case 'if': return parseIfStatement()
				default: return getAlias()
			}

		default:
			throw new Error('Unknown parse statement token: ' + JSON.stringify(gToken))
	}
}

/*******************
 * Utility methods *
 *******************/
var advance = function(type, value, expressionType) {
	gToken = gTokens[++gIndex]
	function check(v1, v2) {
		assert.equal(v1, v2,
			['Expected the', q(type),
				value ? 'of value ' + q(value) : '',
				expressionType ? 'for the ' + expressionType : '',
				'on line:', gToken.line,
				'column:', gToken.column,
				'but found a', q(gToken.type),
				'of value', q(gToken.value)].join(' ')
	)}
	if (type) { check(type, gToken.type) }
	if (value) {
		if (value instanceof Array) { for (var i=0, val; val=value[i]; i++) {
			if (val != gToken.value) { continue }
			value = val // allow for the check to pass if one of the values passed in matches
			break
		}}
		check(value, gToken.value)
	}
}
var peek = function(amount) { return gTokens[gIndex + (amount || 1)] }
var isAhead = function(amount, type, value) {
	var token = gTokens[gIndex + amount]
	if (type && type != token.type) { return false }
	if (value && value != token.value) { return false }
	return true
}

/******************************
 * Aliases and literal values *
 ******************************/
function getAlias() {
	assert(gToken.type == 'name')
	// TODO Parse dot notation
	return { type:'ALIAS', name:gToken.value }
}

function getLiteralValue() {
	assert(gToken.type == 'string' || gToken.type == 'number')
	return { type:gToken.type.toUpperCase(), value:gToken.value }
}

/*******
 * XML *
 *******/
var parseXML = function() {
	debug('parseXML')
	advance('name', null, 'XML tag')
	var tagName = gToken.value,
		attributes = parseXMLAttributes()

	advance('symbol', ['>', '/'], 'end of XML tag')
	if (gToken.value == '/') {
		advance('symbol', '>', 'self-closing XML tag')
		return { type:'XML', tag:tagName, attributes:attributes, content:[] }
	} else {
		var statements = []
		while(true) {
			if (isAhead(1, 'symbol', '<') && isAhead(2, 'symbol', '/')) { break }
			advance()
			statements.push(parseStatement())
		}

		advance('symbol', '<')
		advance('symbol', '/')
		advance('name', tagName, 'matching XML tags')
		advance('symbol', '>')

		return { type:'XML', tag:tagName, attributes:attributes, block:statements }
	}
}

var parseXMLAttributes = function() {
	debug('parseXMLAttributes')
	if (!peek('name')) { return [] } // no attributes
}

/****************
 * Declarations *
 ****************/
function parseDeclaration() {
	debug('parseDeclaration')
	advance('name', null, 'declaration')
	var name = gToken.value
	advance('symbol', '=', 'declaration')
	value = parseDeclarable()
	return { type:'DECLARATION', name:name, value:value }
}
function parseDeclarable() {
	debug('parseDeclarable')
	advance()
	switch(gToken.type) {
		case 'name':
		    return getAlias()
		case 'symbol':
			// TODO Parse JSON literal
			return parseXML()
		case 'string':
		case 'number':
			return getLiteralValue()
		default:
			throw new Error('Unkown declarable token: ' + JSON.stringify(gToken))
	}
}

/*************
 * For loops *
 *************/
function parseForLoop() {
	debug('parseForLoop')
	throw new Error("For loops are not yet implemented")
}

/****************
 * If statement *
 ****************/
function parseIfStatement() {
	debug('parseIfStatement')

	advance('symbol', LPAREN, 'beginning of the if statement\'s conditional')
	var condition = parseCondition()
	advance('symbol', RPAREN, 'end of the if statement\'s conditional')

	advance('symbol', LBLOCK, 'beginning of the if statement\'s block')
	var statements = []
	while(true) {
		if (isAhead(1, 'symbol', RBLOCK)) { break }
		advance()
		statements.push(parseStatement())
	}
	advance('symbol', RBLOCK, 'end of the if statement\'s block')

	return { type:'IF_STATEMENT', condition:condition, block:statements }
}

function parseCondition() {
	// TODO Implement condition parsing
	advance()
	return {}
}
<|endoftext|>


<commit_before>"use strict";

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var nobleExtended = require('../../noble');

var HEADER = [0xAA, 0x0A, 0xFC, 0x3A, 0x86, 0x01];
var TAIL = [0x0D];

var SEQUENCE_ON = HEADER.concat([0x0A, 0x01, 0x01, 0x00, 0x28], TAIL);
var SEQUENCE_OFF = HEADER.concat([0x0A, 0x01, 0x00, 0x01, 0x28], TAIL);
var SEQUENCE_BRIGHNTESS = HEADER.concat([0x0C, 0x01, 0x00, 0xEC]);
var SEQUENCE_WHITE = HEADER.concat([0x0E, 0x01, 0x00, 0x14]);
var SEQUENCE_WHITE_RESET = HEADER.concat([0x0D, 0x06, 0x02, 0x20, 0x30, 0x40, 0x50, 0x60]);
var SEQUENCE_RGB = HEADER.concat([0x0D, 0x06, 0x01, 0x00, 0x00, 0x00, 0x20, 0x30, 0xF8]);

module.exports = function () {
  function AwoxSmartLight(lampMac, logger) {
    _classCallCheck(this, AwoxSmartLight);

    /*"d03972b84926"*/
    this.isScanning = false;
    this.lampMac = lampMac;
    this.timeout = null;
    this.logger = logger || console.log;
    this.commandsQueue = [];
    this.lightCommandDebounce = this._debounce(this._lightCommand.bind(this), 1000);
  }

  _createClass(AwoxSmartLight, [{
    key: "_lightCommand",
    value: function _lightCommand() {
      var _this = this;

      if (this.commandsQueue.length === 0) {
        this.logger("No command to send...");
        return;
      }

      var noble = new nobleExtended.Noble(nobleExtended.bindings);

      this.isScanning = true;
      // if nothing is done after 6s stop everything
      //this.timeout = setTimeout(this._onTimeOut.bind(this, noble), 6000);

      // wait for ble device before to start scanning for lamp
      noble.on('stateChange', function (state) {
        return _this._onStateChange(state, noble);
      });

      // then try to send command
      noble.on('discover', function (peripheral) {
        return _this._onPeripheralDiscover(peripheral, noble);
      });

      // start noble for scanning
      noble.start();
    }
  }, {
    key: "lightOn",
    value: function lightOn() {
      this.commandsQueue.push(SEQUENCE_ON);
      this.lightCommandDebounce();
    }
  }, {
    key: "lightOff",
    value: function lightOff() {
      this.commandsQueue.push(SEQUENCE_OFF);
      this.lightCommandDebounce();
    }
  }, {
    key: "lightBrightness",
    value: function lightBrightness(intensity) {
      // value
      SEQUENCE_BRIGHNTESS[8] = Math.floor(intensity * 9 + 2);
      // random
      SEQUENCE_BRIGHNTESS[9] = Math.floor(Math.random() * 0xFF) >>> 0;
      // checksum
      SEQUENCE_BRIGHNTESS.push(this._checksum(SEQUENCE_BRIGHNTESS));

      this.commandsQueue.push(SEQUENCE_BRIGHNTESS.concat(TAIL));
      this.lightCommandDebounce();
    }
  }, {
    key: "lightWhite",
    value: function lightWhite(temperature) {
      // value
      SEQUENCE_WHITE[8] = Math.floor(temperature * 9 + 2);
      // random
      SEQUENCE_WHITE[9] = Math.floor(Math.random() * 0xFF) >>> 0;
      // checksum
      SEQUENCE_WHITE.push(this._checksum(SEQUENCE_WHITE));
      this.commandsQueue.push(SEQUENCE_WHITE.concat(TAIL));
      this.lightCommandDebounce();
    }
  }, {
    key: "lightWhiteReset",
    value: function lightWhiteReset() {
      // random
      SEQUENCE_WHITE_RESET.push(Math.floor(Math.random() * 0xFF) >>> 0);
      // checksum
      SEQUENCE_WHITE_RESET.push(this._checksum(SEQUENCE_WHITE_RESET));
      this.commandsQueue.push(SEQUENCE_WHITE_RESET.concat(TAIL));
      this.lightCommandDebounce();
    }
  }, {
    key: "lightRgb",
    value: function lightRgb(r, g, b, special) {
      SEQUENCE_RGB[8] = special ? 0x02 : 0x01;
      // RGB values
      SEQUENCE_RGB[9] = r;
      SEQUENCE_RGB[10] = g;
      SEQUENCE_RGB[11] = b;
      // random
      SEQUENCE_RGB[14] = Math.floor(Math.random() * 0xFF) >>> 0;

      SEQUENCE_RGB.push(this._checksum(SEQUENCE_RGB));
      this.commandsQueue.push(SEQUENCE_RGB.concat(TAIL));
      this.lightCommandDebounce();
    }
  }, {
    key: "_checksum",
    value: function _checksum(data) {
      return data.slice(1).reduce(function (a, b) {
        return a + b;
      }) + 85 & 0xFF;
    }
  }, {
    key: "_onPeripheralDiscover",
    value: function _onPeripheralDiscover(peripheral, noble) {
      var _this2 = this;

      var lampMac = this.lampMac;
      if (peripheral.id.trim().toLowerCase() == lampMac.trim().toLowerCase()) {
        this.logger("found lamp with id:", peripheral.id, ". and name: ", peripheral.advertisement.localName);
        this.isScanning = false;
        noble.stopScanning();
        peripheral.connect(function (error) {
          if (error) {
            _this2.logger('connected to peripheral: ' + peripheral.uuid + ' with error ' + error);
            return;
          }

          _this2.logger('connected to peripheral: ' + peripheral.uuid);

          peripheral.discoverServices(['fff0'], function (error, services) {
            if (error) {
              _this2.logger('cant find service...');
              _this2.logger('the following error occured:' + error);
              if (_this2.commandsQueue.length === 0) peripheral.disconnect();
              return;
            }

            if (!services || services.length === 0) {
              _this2.logger('cant find service...');
              if (_this2.commandsQueue.length === 0) peripheral.disconnect();
              return;
            }

            _this2.logger('found service fff0...');

            services[0].discoverCharacteristics(['fff1'], function (error, characteristics) {
              if (error) {
                _this2.logger('cant find characteristic...');
                _this2.logger('the following error occured:' + error);
                if (_this2.commandsQueue.length === 0) peripheral.disconnect();
                return;
              }

              if (!characteristics || characteristics.length === 0) {
                _this2.logger('cant find characteristic...');
                if (_this2.commandsQueue.length === 0) peripheral.disconnect();
                return;
              }

              _this2.logger('found characteristic fff1');

              var command = null;
              var commandCharacteristic = characteristics[0];
              while (command = _this2.commandsQueue.shift()) {
                _this2.logger('command:' + command);
                commandCharacteristic.write(new Buffer(command), false, function (error) {
                  if (error) {
                    _this2.logger('cant send command');
                    _this2.logger('the following error occured:' + error);
                  } else {
                    _this2.logger('command sent');
                  }

                  if (_this2.commandsQueue.length === 0) peripheral.disconnect();
                });
              }
            });
          });
        });

        peripheral.on('disconnect', function () {
          _this2.logger("disconnected", peripheral.advertisement.localName);
          clearTimeout(_this2.timeout);
          peripheral.removeAllListeners();
          noble.removeAllListeners();
          noble.stop();
        });
      }
    }
  }, {
    key: "_onStateChange",
    value: function _onStateChange(state, noble) {
      if (state === 'poweredOn') {
        this.logger('start scanning');
        noble.startScanning();
      } else {
        this.logger('State change to ' + state + '. Stop scanning');
        noble.stopScanning();
      }
    }
  }, {
    key: "_onTimeOut",
    value: function _onTimeOut(noble) {
      this.isScanning = false;
      this.logger("timeout trying to connect to smartlight...");
      noble.stopScanning();
      noble.removeAllListeners();
      noble.stop();
      //delete this.noble;
    }
  }, {
    key: "_debounce",
    value: function _debounce(func, wait, immediate) {
      var _this3 = this,
          _arguments = arguments;

      var timeout;
      return function () {
        var context = _this3,
            args = _arguments;
        var later = function later() {
          timeout = null;
          if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
      };
    }
  }]);

  return AwoxSmartLight;
}();

<commit_msg>+ build<commit_after>"use strict";

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var nobleExtended = require('noble-extended');

var HEADER = [0xAA, 0x0A, 0xFC, 0x3A, 0x86, 0x01];
var TAIL = [0x0D];

var SEQUENCE_ON = HEADER.concat([0x0A, 0x01, 0x01, 0x00, 0x28], TAIL);
var SEQUENCE_OFF = HEADER.concat([0x0A, 0x01, 0x00, 0x01, 0x28], TAIL);
var SEQUENCE_BRIGHNTESS = HEADER.concat([0x0C, 0x01, 0x00, 0xEC]);
var SEQUENCE_WHITE = HEADER.concat([0x0E, 0x01, 0x00, 0x14]);
var SEQUENCE_WHITE_RESET = HEADER.concat([0x0D, 0x06, 0x02, 0x20, 0x30, 0x40, 0x50, 0x60]);
var SEQUENCE_RGB = HEADER.concat([0x0D, 0x06, 0x01, 0x00, 0x00, 0x00, 0x20, 0x30, 0xF8]);

module.exports = function () {
  function AwoxSmartLight(lampMac, logger) {
    _classCallCheck(this, AwoxSmartLight);

    /*"d03972b84926"*/
    this.isScanning = false;
    this.lampMac = lampMac;
    this.timeout = null;
    this.logger = logger || console.log;
    this.commandsQueue = [];
    this.lightCommandDebounce = this._debounce(this._lightCommand.bind(this), 1000);
  }

  _createClass(AwoxSmartLight, [{
    key: "_lightCommand",
    value: function _lightCommand() {
      var _this = this;

      if (this.commandsQueue.length === 0) {
        this.logger("No command to send...");
        return;
      }

      var noble = new nobleExtended.Noble(nobleExtended.bindings);

      this.isScanning = true;
      // if nothing is done after 6s stop everything
      //this.timeout = setTimeout(this._onTimeOut.bind(this, noble), 6000);

      // wait for ble device before to start scanning for lamp
      noble.on('stateChange', function (state) {
        return _this._onStateChange(state, noble);
      });

      // then try to send command
      noble.on('discover', function (peripheral) {
        return _this._onPeripheralDiscover(peripheral, noble);
      });

      // start noble for scanning
      noble.start();
    }
  }, {
    key: "lightOn",
    value: function lightOn() {
      this.commandsQueue.push(SEQUENCE_ON);
      this.lightCommandDebounce();
    }
  }, {
    key: "lightOff",
    value: function lightOff() {
      this.commandsQueue.push(SEQUENCE_OFF);
      this.lightCommandDebounce();
    }
  }, {
    key: "lightBrightness",
    value: function lightBrightness(intensity) {
      // value
      SEQUENCE_BRIGHNTESS[8] = Math.floor(intensity * 9 + 2);
      // random
      SEQUENCE_BRIGHNTESS[9] = Math.floor(Math.random() * 0xFF) >>> 0;
      // checksum
      SEQUENCE_BRIGHNTESS.push(this._checksum(SEQUENCE_BRIGHNTESS));

      this.commandsQueue.push(SEQUENCE_BRIGHNTESS.concat(TAIL));
      this.lightCommandDebounce();
    }
  }, {
    key: "lightWhite",
    value: function lightWhite(temperature) {
      // value
      SEQUENCE_WHITE[8] = Math.floor(temperature * 9 + 2);
      // random
      SEQUENCE_WHITE[9] = Math.floor(Math.random() * 0xFF) >>> 0;
      // checksum
      SEQUENCE_WHITE.push(this._checksum(SEQUENCE_WHITE));
      this.commandsQueue.push(SEQUENCE_WHITE.concat(TAIL));
      this.lightCommandDebounce();
    }
  }, {
    key: "lightWhiteReset",
    value: function lightWhiteReset() {
      // random
      SEQUENCE_WHITE_RESET.push(Math.floor(Math.random() * 0xFF) >>> 0);
      // checksum
      SEQUENCE_WHITE_RESET.push(this._checksum(SEQUENCE_WHITE_RESET));
      this.commandsQueue.push(SEQUENCE_WHITE_RESET.concat(TAIL));
      this.lightCommandDebounce();
    }
  }, {
    key: "lightRgb",
    value: function lightRgb(r, g, b, special) {
      SEQUENCE_RGB[8] = special ? 0x02 : 0x01;
      // RGB values
      SEQUENCE_RGB[9] = r;
      SEQUENCE_RGB[10] = g;
      SEQUENCE_RGB[11] = b;
      // random
      SEQUENCE_RGB[14] = Math.floor(Math.random() * 0xFF) >>> 0;

      SEQUENCE_RGB.push(this._checksum(SEQUENCE_RGB));
      this.commandsQueue.push(SEQUENCE_RGB.concat(TAIL));
      this.lightCommandDebounce();
    }
  }, {
    key: "_checksum",
    value: function _checksum(data) {
      return data.slice(1).reduce(function (a, b) {
        return a + b;
      }) + 85 & 0xFF;
    }
  }, {
    key: "_onPeripheralDiscover",
    value: function _onPeripheralDiscover(peripheral, noble) {
      var _this2 = this;

      var lampMac = this.lampMac;
      if (peripheral.id.trim().toLowerCase() == lampMac.trim().toLowerCase()) {
        this.logger("found lamp with id:", peripheral.id, ". and name: ", peripheral.advertisement.localName);
        this.isScanning = false;
        noble.stopScanning();
        peripheral.connect(function (error) {
          if (error) {
            _this2.logger('connected to peripheral: ' + peripheral.uuid + ' with error ' + error);
            return;
          }

          _this2.logger('connected to peripheral: ' + peripheral.uuid);

          peripheral.discoverServices(['fff0'], function (error, services) {
            if (error) {
              _this2.logger('cant find service...');
              _this2.logger('the following error occured:' + error);
              if (_this2.commandsQueue.length === 0) peripheral.disconnect();
              return;
            }

            if (!services || services.length === 0) {
              _this2.logger('cant find service...');
              if (_this2.commandsQueue.length === 0) peripheral.disconnect();
              return;
            }

            _this2.logger('found service fff0...');

            services[0].discoverCharacteristics(['fff1'], function (error, characteristics) {
              if (error) {
                _this2.logger('cant find characteristic...');
                _this2.logger('the following error occured:' + error);
                if (_this2.commandsQueue.length === 0) peripheral.disconnect();
                return;
              }

              if (!characteristics || characteristics.length === 0) {
                _this2.logger('cant find characteristic...');
                if (_this2.commandsQueue.length === 0) peripheral.disconnect();
                return;
              }

              _this2.logger('found characteristic fff1');

              var command = null;
              var commandCharacteristic = characteristics[0];
              while (command = _this2.commandsQueue.shift()) {
                _this2.logger('command:' + command);
                commandCharacteristic.write(new Buffer(command), false, function (error) {
                  if (error) {
                    _this2.logger('cant send command');
                    _this2.logger('the following error occured:' + error);
                  } else {
                    _this2.logger('command sent');
                  }

                  if (_this2.commandsQueue.length === 0) peripheral.disconnect();
                });
              }
            });
          });
        });

        peripheral.on('disconnect', function () {
          _this2.logger("disconnected", peripheral.advertisement.localName);
          clearTimeout(_this2.timeout);
          peripheral.removeAllListeners();
          noble.removeAllListeners();
          noble.stop();
        });
      }
    }
  }, {
    key: "_onStateChange",
    value: function _onStateChange(state, noble) {
      if (state === 'poweredOn') {
        this.logger('start scanning');
        noble.startScanning();
      } else {
        this.logger('State change to ' + state + '. Stop scanning');
        noble.stopScanning();
      }
    }
  }, {
    key: "_onTimeOut",
    value: function _onTimeOut(noble) {
      this.isScanning = false;
      this.logger("timeout trying to connect to smartlight...");
      noble.stopScanning();
      noble.removeAllListeners();
      noble.stop();
      //delete this.noble;
    }
  }, {
    key: "_debounce",
    value: function _debounce(func, wait, immediate) {
      var _this3 = this,
          _arguments = arguments;

      var timeout;
      return function () {
        var context = _this3,
            args = _arguments;
        var later = function later() {
          timeout = null;
          if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
      };
    }
  }]);

  return AwoxSmartLight;
}();

<|endoftext|>