<commit_before>/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
/* Olaf Leidinger <oleid@mescharet.de>
   Thomas Liebetraut <thomas@tommie-lie.de>
*/

const Gio            = imports.gi.Gio;
const Lang           = imports.lang;
const Gettext        = imports.gettext;
const ExtensionUtils = imports.misc.extensionUtils;
const Me             = ExtensionUtils.getCurrentExtension();
const Config         = imports.misc.config;
const Gst            = imports.gi.Gst;

const TEATIME_STEEP_TIMES_KEY = 'steep-times';
const TEATIME_FULLSCREEN_NOTIFICATION_KEY = 'fullscreen-notification';
const TEATIME_GRAPHICAL_COUNTDOWN_KEY = 'graphical-countdown';
const TEATIME_USE_ALARM_SOUND_KEY = 'use-alarm-sound';
const TEATIME_ALARM_SOUND_KEY = 'alarm-sound-file';

function initTranslations(domain) {
    let extension = ExtensionUtils.getCurrentExtension();

    domain = domain || extension.metadata['gettext-domain'];

    Gettext.textdomain(domain);
    // check if this extension was built with "make zip-file", and thus
    // has the locale files in a subfolder
    // otherwise assume that extension has been installed in the
    // same prefix as gnome-shell
    let localeDir = extension.dir.get_child('locale');
    if (localeDir.query_exists(null))
        Gettext.bindtextdomain(domain, localeDir.get_path());
    else
        Gettext.bindtextdomain(domain, Config.LOCALEDIR);
}

function getSettings(schema) {
    let extension = ExtensionUtils.getCurrentExtension();

    schema = schema || extension.metadata['settings-schema'];

    const GioSSS = Gio.SettingsSchemaSource;

    // check if this extension was built with "make zip-file", and thus
    // has the schema files in a subfolder
    // otherwise assume that extension has been installed in the
    // same prefix as gnome-shell (and therefore schemas are available
    // in the standard folders)
    let schemaDir = extension.dir.get_child('schemas');
    let schemaSource;
    if (schemaDir.query_exists(null)) {
        schemaSource = GioSSS.new_from_directory(schemaDir.get_path(),
                                                 GioSSS.get_default(),
                                                 false);
    } else {
        schemaSource = GioSSS.get_default();
    }

    let schemaObj = schemaSource.lookup(schema, true);
    if (!schemaObj)
        throw new Error('Schema ' + schema + ' could not be found for extension '
                        + extension.metadata.uuid + '. Please check your installation.');

    return new Gio.Settings({ settings_schema: schemaObj });
}

function formatTime(sec_num) {
    /* toLocaleFormat would be nicer, however it doesn't work with
       Debian Wheezy and some later gnome versions */

    // based on code from
    //  http://stackoverflow.com/questions/6312993/javascript-seconds-to-time-with-format-hhmmss

    let hours   = Math.floor(sec_num / 3600);
    let minutes = Math.floor((sec_num - (hours * 3600)) / 60);
    let seconds = Math.round(sec_num - (hours * 3600) - (minutes * 60));

    if (hours   < 10) {hours   = "0"+hours;}
    if (minutes < 10) {minutes = "0"+minutes;}
    if (seconds < 10) {seconds = "0"+seconds;}

    return (( hours == "00") ?  "" : hours+':')  + minutes + ':' + seconds;
}

function playSound(uri) {
    Gst.init(null, 0);
    let player = Gst.ElementFactory.make("playbin","player");
    player.set_property('uri', uri);
    player.set_state(Gst.State.PLAYING);
}

function setCairoColorFromClutter(cr, c) {
  let s=1.0/255;
  cr.setSourceRGBA(s*c.red, s*c.green, s*c.blue, s*c.alpha);
}
<commit_msg>fix playback issue (#20)<commit_after>/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
/* Olaf Leidinger <oleid@mescharet.de>
   Thomas Liebetraut <thomas@tommie-lie.de>
*/

const Gio            = imports.gi.Gio;
const Lang           = imports.lang;
const Gettext        = imports.gettext;
const ExtensionUtils = imports.misc.extensionUtils;
const Me             = ExtensionUtils.getCurrentExtension();
const Config         = imports.misc.config;
const Gst            = imports.gi.Gst;

const TEATIME_STEEP_TIMES_KEY = 'steep-times';
const TEATIME_FULLSCREEN_NOTIFICATION_KEY = 'fullscreen-notification';
const TEATIME_GRAPHICAL_COUNTDOWN_KEY = 'graphical-countdown';
const TEATIME_USE_ALARM_SOUND_KEY = 'use-alarm-sound';
const TEATIME_ALARM_SOUND_KEY = 'alarm-sound-file';

function initTranslations(domain) {
    let extension = ExtensionUtils.getCurrentExtension();

    domain = domain || extension.metadata['gettext-domain'];

    Gettext.textdomain(domain);
    // check if this extension was built with "make zip-file", and thus
    // has the locale files in a subfolder
    // otherwise assume that extension has been installed in the
    // same prefix as gnome-shell
    let localeDir = extension.dir.get_child('locale');
    if (localeDir.query_exists(null))
        Gettext.bindtextdomain(domain, localeDir.get_path());
    else
        Gettext.bindtextdomain(domain, Config.LOCALEDIR);
}

function getSettings(schema) {
    let extension = ExtensionUtils.getCurrentExtension();

    schema = schema || extension.metadata['settings-schema'];

    const GioSSS = Gio.SettingsSchemaSource;

    // check if this extension was built with "make zip-file", and thus
    // has the schema files in a subfolder
    // otherwise assume that extension has been installed in the
    // same prefix as gnome-shell (and therefore schemas are available
    // in the standard folders)
    let schemaDir = extension.dir.get_child('schemas');
    let schemaSource;
    if (schemaDir.query_exists(null)) {
        schemaSource = GioSSS.new_from_directory(schemaDir.get_path(),
                                                 GioSSS.get_default(),
                                                 false);
    } else {
        schemaSource = GioSSS.get_default();
    }

    let schemaObj = schemaSource.lookup(schema, true);
    if (!schemaObj)
        throw new Error('Schema ' + schema + ' could not be found for extension '
                        + extension.metadata.uuid + '. Please check your installation.');

    return new Gio.Settings({ settings_schema: schemaObj });
}

function formatTime(sec_num) {
    /* toLocaleFormat would be nicer, however it doesn't work with
       Debian Wheezy and some later gnome versions */

    // based on code from
    //  http://stackoverflow.com/questions/6312993/javascript-seconds-to-time-with-format-hhmmss

    let hours   = Math.floor(sec_num / 3600);
    let minutes = Math.floor((sec_num - (hours * 3600)) / 60);
    let seconds = Math.round(sec_num - (hours * 3600) - (minutes * 60));

    if (hours   < 10) {hours   = "0"+hours;}
    if (minutes < 10) {minutes = "0"+minutes;}
    if (seconds < 10) {seconds = "0"+seconds;}

    return (( hours == "00") ?  "" : hours+':')  + minutes + ':' + seconds;
}

function playSound(uri) {
    if ( typeof this.player == 'undefined' ) {
        Gst.init(null, 0);
        this.player  = Gst.ElementFactory.make("playbin","player");
        this.playBus = this.player.get_bus();
        this.playBus.add_signal_watch();
        this.playBus.connect("message", Lang.bind(this,
        function(playBus, message) {
            if (message != null) {
                // IMPORTANT: to reuse the player, set state to READY
                let t = message.type;
                if ( t == Gst.MessageType.EOS || t == Gst.MessageType.ERROR) {
                    this.player.set_state(Gst.State.READY);
                }
            } // message handler
        }));
    } // if undefined
    this.player.set_property('uri', uri);
    this.player.set_state(Gst.State.PLAYING);
}

function setCairoColorFromClutter(cr, c) {
  let s=1.0/255;
  cr.setSourceRGBA(s*c.red, s*c.green, s*c.blue, s*c.alpha);
}
<|endoftext|>


<commit_before>/**
* Featherlight – ultra slim jQuery lightbox
* Version 0.1.0 – https://github.com/noelboss/featherlight
*
* Copyright 2012, Noel Bossart
* MIT Licensed.
*/
(function($) {
	"use strict";

	var setupFeatherlight = function(c, $content){
		var t = this,
			$t = $(this),
			variant = $t.attr('data-'+c.namespace+'-variant'),
			$bg = $(c.bg || '

X

');

		if($content.length < 1){
			t.$content = $($t.attr(c.targetAttr), c.context);
		} else {
			t.$content = $content;
		}

		if(t.$content.length > 0){
			// clone DOM for the background, wrapper and the closebutton
			t.$fl = $bg.clone();

			// add css class to override styles
			if(variant){
				t.$fl.addClass(variant);
			}

			// bind close function on close button
			t.$fl.find('.'+c.namespace+'-close')
				.on(c.closeTrigger+'.'+c.namespace, $.proxy(c.close, t))
				.after(t.$content.show()); // add content after closebutton

			// close when click on background
			if(c.clickBgClose){
				t.$fl.on(c.closeTrigger+'.'+c.namespace, $.proxy(c.close, t));
			}

			// bind open function
			if(t.hasOwnProperty('nodeName')){
				$t.on(c.openTrigger+'.'+c.namespace, $.proxy(c.open, t));
			} else {
				$.proxy(c.open, t)();
			}
		}
	};

	var fl = {
		featherlight: function($content, config) {
			var c = $.extend({}, $.fn.featherlight.defaults, config),
				$content = $content || $();

			if(typeof $content === 'string'){
				$content = $($content);
			}
			if($content.length > 0){
				$.proxy(setupFeatherlight, {}, c, $content)();
			}
		}
	};

	$.extend($, fl);

	// extend jQuery
	$.fn.featherlight = function(config, $content) {
		var c = $.extend({}, $.fn.featherlight.defaults, config),
				$content = $content || $();
		$(this).each(function(){
			$.proxy(setupFeatherlight, this, c, $content)();
		});
	}

	// featherlight defaults
	$.fn.featherlight.defaults = {
		selector:     '[data-featherlight]',  // elements that trigger the lightbox
		targetAttr:   'data-featherlight',    // attribut of the triggered element that contains the selector to the lightbox content
		openTrigger:  'click',                // event that triggers the lightbox
		closeTrigger: 'click',                // event that triggers the closing of the lightbox
		context:      'body',                 // context used to search for the lightbox content and triggers
		namespace:    'featherlight',         // name of the events and css class prefix
		clickBgClose: true,                   // close lightbox on click on the background
		bg: null,                             // custom DOM for the background, wrapper and the closebutton
		autostart:    true,                   // initialize all links with that match "selector" on document ready
		open: function(e){                    // opens the lightbox "this" contains $fl with the lightbox, and c with the configuration
			var t = this;
			t.$fl.prependTo('body').fadeIn();
			if(e) e.preventDefault();
		},
		close: function(e){                    // closes the lightbox "this" contains $fl with the lightbox, and c with the configuration
			var t = this;
			t.$fl.fadeOut(function(){
				t.$fl.detach();
			});
			if (e) e.preventDefault();
		}
	};

	// bind featherlight on ready if config autostart is true
	$(document).ready(function(){
		var c = $.fn.featherlight.defaults;
		if(c.autostart){
			$(c.selector, c.context).featherlight();
		}
	});
}(jQuery));
<commit_msg>Changed order of configuration<commit_after>/**
* Featherlight – ultra slim jQuery lightbox
* Version 0.1.0 – https://github.com/noelboss/featherlight
*
* Copyright 2012, Noel Bossart
* MIT Licensed.
*/
(function($) {
	"use strict";

	var setupFeatherlight = function(c, $content){
		var t = this,
			$t = $(this),
			variant = $t.attr('data-'+c.namespace+'-variant'),
			$bg = $(c.bg || '

X

');

		if($content.length < 1){
			t.$content = $($t.attr(c.targetAttr), c.context);
		} else {
			t.$content = $content;
		}

		if(t.$content.length > 0){
			// clone DOM for the background, wrapper and the closebutton
			t.$fl = $bg.clone();

			// add css class to override styles
			if(variant){
				t.$fl.addClass(variant);
			}

			// bind close function on close button
			t.$fl.find('.'+c.namespace+'-close')
				.on(c.closeTrigger+'.'+c.namespace, $.proxy(c.close, t))
				.after(t.$content.show()); // add content after closebutton

			// close when click on background
			if(c.clickBgClose){
				t.$fl.on(c.closeTrigger+'.'+c.namespace, $.proxy(c.close, t));
			}

			// bind open function
			if(t.hasOwnProperty('nodeName')){
				$t.on(c.openTrigger+'.'+c.namespace, $.proxy(c.open, t));
			} else {
				$.proxy(c.open, t)();
			}
		}
	};

	var fl = {
		featherlight: function($content, config) {
			var c = $.extend({}, $.fn.featherlight.defaults, config),
				$content = $content || $();

			if(typeof $content === 'string'){
				$content = $($content);
			}
			if($content.length > 0){
				$.proxy(setupFeatherlight, {}, c, $content)();
			}
		}
	};

	$.extend($, fl);

	// extend jQuery
	$.fn.featherlight = function(config, $content) {
		var c = $.extend({}, $.fn.featherlight.defaults, config),
				$content = $content || $();
		$(this).each(function(){
			$.proxy(setupFeatherlight, this, c, $content)();
		});
	}

	// featherlight defaults
	$.fn.featherlight.defaults = {
		selector:     '[data-featherlight]',  // elements that trigger the lightbox
		context:      'body',                 // context used to search for the lightbox content and triggers
		targetAttr:   'data-featherlight',    // attribut of the triggered element that contains the selector to the lightbox content
		openTrigger:  'click',                // event that triggers the lightbox
		closeTrigger: 'click',                // event that triggers the closing of the lightbox
		namespace:    'featherlight',         // name of the events and css class prefix
		clickBgClose: true,                   // close lightbox on click on the background
		bg: null,                             // custom DOM for the background, wrapper and the closebutton
		autostart:    true,                   // initialize all links with that match "selector" on document ready
		open: function(e){                    // opens the lightbox "this" contains $fl with the lightbox, and c with the configuration
			var t = this;
			t.$fl.prependTo('body').fadeIn();
			if(e) e.preventDefault();
		},
		close: function(e){                    // closes the lightbox "this" contains $fl with the lightbox, and c with the configuration
			var t = this;
			t.$fl.fadeOut(function(){
				t.$fl.detach();
			});
			if (e) e.preventDefault();
		}
	};

	// bind featherlight on ready if config autostart is true
	$(document).ready(function(){
		var c = $.fn.featherlight.defaults;
		if(c.autostart){
			$(c.selector, c.context).featherlight();
		}
	});
}(jQuery));
<|endoftext|>


<commit_before>/*
 * Copyright 2017, Maha Farhat
 *
 * This file is part of the software gentb, consisting of custom
 * code for the GenTB's django-based website.
 *
 * gentb is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * gentb is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with gentb.  If not, see <http://www.gnu.org/licenses/>.
 */

$(document).ready(function() {
  $('div.maps').each(function(map) {
//this needs to get the data somehow so we can initialize the legend and scale it dynamically
    var map = L.map(this.id).setView([12, 25], 2);
    var newLegend = function(map, max, color) {

            legend = L.control({
              position: 'topright'
          });

            legend.onAdd = function(map) {
              var div = L.DomUtil.create('div', 'legend');
              return div
            };
            legend.addTo(map);

            var x = d3.scale.linear()
              .domain([0, max])
              .range([0, 400]);

            var xAxis = d3.svg.axis()
              .scale(x)
              .orient("top")
              .tickSize(1)
              .tickValues(color.domain())

            var svg = d3.select(".legend.leaflet-control").append("svg")
              .attr("id", 'legend')
              .attr("width", 450)
              .attr("height", 40);

            var g = svg.append("g")
              .attr("class", "key")
              .attr("transform", "translate(25,16)");

            g.selectAll("rect")
              .data(color.range().map(function(d, i) {
                return {
                  x0: i ? x(color.domain()[i - 1]) : x.range()[0],
                  x1: i < color.domain().length ? x(color.domain()[i]) : x.range()[1],
                  z: d
                };
              }))
              .enter().append("rect")
              .attr("height", 10)
              .attr("x", function(d) {
                return d.x0;
              })
              .attr("width", function(d) {
                return d.x1 - d.x0;
              })
              .style("fill", function(d) {
                return d.z;
              });

            g.call(xAxis).append("text")
              .attr("class", "caption")
              .attr("y", 21)
              .text('Number of isolates');

        }
    initialiseStrainMap(map);
    $('#map-store').data('json-signal', function(data) {
      var getMaxAttribute = function (data, attribute) {
          var max = -10000000;
          for (var i=0 ; i<data.length ; i++) {
              if (attribute === "total_strains"){
                  max = Math.max(data[i]["properties"].values.Total, max);
              }
              else{
                  max = Math.max(data[i]["properties"][attribute], max);
              }
          }
          return Math.ceil(max);
      }
      var maxGDP = getMaxAttribute(data.features, "world_bank_gdp")
      var maxTotal = getMaxAttribute(data.features, "total_strains");
      var maxWealth = getMaxAttribute(data.features, "total_wealth");
      var maxFunding = getMaxAttribute(data.features, "total_funding");
      var maxPop = getMaxAttribute(data.features, "pop_dens");
      var maxTB = getMaxAttribute(data.features, "all_tb_incidence2018");
      var color_by_dict = {
          "feature.properties.world_bank_gdp": ["GDP (Trillions)", maxGDP, "world_bank_gdp"],
          "feature.properties.values.Total": ["Total isolates", maxTotal, "Total"],
          "feature.properties.total_wealth": ["Total Wealth per Capita", maxWealth, "total_wealth"],
          "feature.properties.total_funding": ["Total TB Funding", maxFunding, "total_funding"],
          "feature.properties.pop_dens": ["Total TB Funding", maxPop, "pop_dens"],
          "feature.properties.all_tb_incidence2018": ["TB Incidence (all types)", maxTB, "all_tb_incidence2018"]
      }

      mapStrainData(map, data, newLegend, maxGDP, maxTotal, maxWealth, color_by_dict);
      map.invalidateSize();
    });
  });
});

function matchKey(datapoint, key_variable) {
  if(key_variable[0]) {
      return (parseFloat(key_variable[0][datapoint]));
  }
  return "black";
}

var legend = null;
function initialiseStrainMap(map) {

  L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 18,
    attribution: '' //Map tiles (c) OpenStreetMap, Map data (c) genTB'
  }).addTo(map);

}
var map_layer = null;
function mapStrainData(map, data, newLegend, maxGDP, maxTotal, maxWealth, color_by_dict) {
  let color_max;
  let best_color;

  var existing = getTabData('map');

  if(map_layer) {
    // Remove previous layer
    map.removeLayer(map_layer);
  }

  function get_style(feature) {
    var color_by;
    if ($(".form-check-input:checked").val() == "feature.properties.values.Total"){
        color_by = feature.properties.values.Total
    }
    else {
        color_by = feature.properties[color_by_dict[$(".form-check-input:checked").val()][2]]
    }

    color_max = color_by_dict[$(".form-check-input:checked").val()][1]
    best_color = d3.scale.threshold()
        .domain([color_max/4, color_max/2, color_max*3/4, color_max])
        .range(['#FFFFCC', '#C7E9B4', '#7FCDBB', '#41B6C4', '#1D91C0']);
    if (!legend) {
        newLegend(map, maxTotal, best_color)
    }

    return {
     fillColor: best_color(color_by),
      weight: 1,
      opacity: 0.5,
      color: 'black',
      fillOpacity: 0.35
    };
  }

  //toggle mapping color
  $('.form-check-input').on('click',function(e){
      if(map_layer) {
        // Remove previous layer
        map.removeLayer(map_layer);
      }
      map_layer = L.geoJson(data,  {
        style: get_style,
        onEachFeature: onEachFeature
      }
    ).addTo(map)

    if(legend) {
      // Remove previous layer
      map.removeControl(legend);
    }

    newLegend(map, color_by_dict[$(".form-check-input:checked").val()][1], best_color);

    d3.select('.caption')
      .text(color_by_dict[$(".form-check-input:checked").val()][0]);

});

  function onEachFeature(feature, layer) {
    var country_code = feature.properties.value;
    ret = $('

');
    ret.append($('
' + feature.properties.name + '
'));
    $.each(['Sensitive', 'MDR', 'XDR', 'TDR'], function(key, value) {
      if (feature.properties.values[value]) {
        ret.append($('
Number of ' + value + ' isolates: ' + feature.properties.values[value] + "
"));
      }
    });
    ret.append($("

 WHO Estimated MDR (Percentage of new TB cases with rifampicin resistant TB): " + (feature.properties.who_est_mdr) + "
"));
    ret.append($("

 HIV Coincidence (Estimated incidence of TB cases who are HIV-positive): " + (feature.properties.hiv_incidence2018) + "
"));
    ret.append($("

 TB Incidence (all types): " + (feature.properties.all_tb_incidence2018) + "
"));
    if(Object.keys(feature.properties.values).length > 2) {
      ret.append($("

Total isolates: " + feature.properties.values.Total + "
"));
    }
    ret.append($('
' + 'Social Determinants of Health:' + '
'));
    ret.append($("

 GDP (Trillions): $" + (Math.round(feature.properties.world_bank_gdp* 100)/100) + "
"));
    ret.append($("

 Total Wealth per Capita: $" + (feature.properties.total_wealth) + "
"));
    ret.append($("

 Total TB Funding: $" + (feature.properties.total_funding) + "
"));
    ret.append($("

 Estimated average household size: " + (Math.round(feature.properties.household*10)/10) + "
"));
    ret.append($("

 Population Density (people per sq. km of land area): " + (feature.properties.pop_dens) + "
"));
    var button1 = $("<button class='btn btn-primary btn-xs'>Select Country</button>").click(function() {
        // WARNING: jquery class selectors and addClass/removeClass DO NOT work here

        var next = $('.country-'+country_code);
        // Set element id just in case it's useful later
        next[0].id = country_code;

        // Add the countrySelect class to highlight it
        next.attr('class', next.attr('class') + ' countrySelect');
        next.data('deselect', function() { button2.click(); });

        // Set the usable data for other charts
        addTabData('map', country_code, feature.properties.name, 'flag');

        button1.hide();
        button2.show();
        map.closePopup();
    });
    button1.attr('id', 'select-'+country_code);
    var button2 = $("<button class='btn btn-danger btn-xs'>Deselect</button>").click(function() {
        // WARNING: jquery class selectors and addClass/removeClass DO NOT work here
        var previous = $('.country-'+country_code);
        previous.attr('class', previous.attr('class').replace(' countrySelect', ''));
        removeTabData('map', country_code);
        button1.show();
        button2.hide();
        map.closePopup();
    });
    ret.append($("
"));
    ret.append(button1);
    ret.append(button2);
    layer.bindPopup(ret[0]);

    var id_cls = 'country-' + country_code;
    if(existing.includes(country_code)) {
        id_cls += ' countrySelect';
        button1.hide();
    } else {
        button2.hide();
    }
    layer.setStyle({className: id_cls});

  }

  map_layer = L.geoJson(data,  {
    style: get_style,
    onEachFeature: onEachFeature
  }
).addTo(map)

}
<commit_msg>legend editing<commit_after>/*
 * Copyright 2017, Maha Farhat
 *
 * This file is part of the software gentb, consisting of custom
 * code for the GenTB's django-based website.
 *
 * gentb is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * gentb is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with gentb.  If not, see <http://www.gnu.org/licenses/>.
 */

$(document).ready(function() {
  $('div.maps').each(function(map) {
//this needs to get the data somehow so we can initialize the legend and scale it dynamically
    var map = L.map(this.id).setView([12, 25], 2);
    var newLegend = function(map, max, color) {

            legend = L.control({
              position: 'topright'
          });

            legend.onAdd = function(map) {
              var div = L.DomUtil.create('div', 'legend');
              return div
            };
            legend.addTo(map);

            var x = d3.scale.linear()
              .domain([0, max])
              .range([0, 400]);

            var xAxis = d3.svg.axis()
              .scale(x)
              .orient("top")
              .tickSize(1)
              .tickValues(color.domain())

            var svg = d3.select(".legend.leaflet-control").append("svg")
              .attr("id", 'legend')
              .attr("width", 450)
              .attr("height", 40);

            var g = svg.append("g")
              .attr("class", "key")
              .attr("transform", "translate(25,16)");

            g.selectAll("rect")
              .data(color.range().map(function(d, i) {
                return {
                  x0: i ? x(color.domain()[i - 1]) : x.range()[0],
                  x1: i < color.domain().length ? x(color.domain()[i]) : x.range()[1],
                  z: d
                };
              }))
              .enter().append("rect")
              .attr("height", 10)
              .attr("x", function(d) {
                return d.x0;
              })
              .attr("width", function(d) {
                return d.x1 - d.x0;
              })
              .style("fill", function(d) {
                return d.z;
              });

            g.call(xAxis).append("text")
              .attr("class", "caption")
              .attr("y", 21)
              .text('Number of isolates');

        }
    initialiseStrainMap(map);
    $('#map-store').data('json-signal', function(data) {
      var getMaxAttribute = function (data, attribute) {
          var max = -10000000;
          var maxPlace;
          var roundPlace;
          for (var i=0 ; i<data.length ; i++) {
              if (attribute === "total_strains"){
                  max = Math.max(data[i]["properties"].values.Total, max);
              }
              else{
                  max = Math.max(data[i]["properties"][attribute], max);
              }
          }
        //   maxPlace = Math.ceil(Math.log10(max))
        //   roundPlace = Math.pow(10, maxPlace)
        //   console.log(attribute)
        //   console.log(Math.ceil(max / roundPlace)*roundPlace)
        //   return Math.ceil(max / roundPlace)*roundPlace
        return Math.ceil(max)
      }
      var maxGDP = getMaxAttribute(data.features, "world_bank_gdp")
      var maxTotal = getMaxAttribute(data.features, "total_strains");
      var maxWealth = getMaxAttribute(data.features, "total_wealth");
      var maxFunding = getMaxAttribute(data.features, "total_funding");
      var maxPop = getMaxAttribute(data.features, "pop_dens");
      var maxTB = getMaxAttribute(data.features, "all_tb_incidence2018");
      var color_by_dict = {
          "feature.properties.world_bank_gdp": ["GDP (Trillions)", maxGDP, "world_bank_gdp"],
          "feature.properties.values.Total": ["Total isolates", maxTotal, "Total"],
          "feature.properties.total_wealth": ["Total Wealth per Capita", maxWealth, "total_wealth"],
          "feature.properties.total_funding": ["Total TB Funding", maxFunding, "total_funding"],
          "feature.properties.pop_dens": ["Total TB Funding", maxPop, "pop_dens"],
          "feature.properties.all_tb_incidence2018": ["TB Incidence (all types)", maxTB, "all_tb_incidence2018"]
      }

      mapStrainData(map, data, newLegend, maxGDP, maxTotal, maxWealth, color_by_dict);
      map.invalidateSize();
    });
  });
});

function matchKey(datapoint, key_variable) {
  if(key_variable[0]) {
      return (parseFloat(key_variable[0][datapoint]));
  }
  return "black";
}

var legend = null;
function initialiseStrainMap(map) {

  L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 18,
    attribution: '' //Map tiles (c) OpenStreetMap, Map data (c) genTB'
  }).addTo(map);

}
var map_layer = null;
function mapStrainData(map, data, newLegend, maxGDP, maxTotal, maxWealth, color_by_dict) {
  let color_max;
  let best_color;

  var existing = getTabData('map');

  if(map_layer) {
    // Remove previous layer
    map.removeLayer(map_layer);
  }

  function get_style(feature) {
    var color_by;
    if ($(".form-check-input:checked").val() == "feature.properties.values.Total"){
        color_by = feature.properties.values.Total
    }
    else {
        color_by = feature.properties[color_by_dict[$(".form-check-input:checked").val()][2]]
    }

    color_max = color_by_dict[$(".form-check-input:checked").val()][1]
    best_color = d3.scale.threshold()
        .domain([color_max/4, color_max/2, color_max*3/4, color_max])
        .range(['#FFFFCC', '#C7E9B4', '#7FCDBB', '#41B6C4', '#1D91C0']);
    if (!legend) {
        newLegend(map, maxTotal, best_color)
    }

    return {
     fillColor: best_color(color_by),
      weight: 1,
      opacity: 0.5,
      color: 'black',
      fillOpacity: 0.35
    };
  }

  //toggle mapping color
  $('.form-check-input').on('click',function(e){
      if(map_layer) {
        // Remove previous layer
        map.removeLayer(map_layer);
      }
      map_layer = L.geoJson(data,  {
        style: get_style,
        onEachFeature: onEachFeature
      }
    ).addTo(map)

    if(legend) {
      // Remove previous layer
      map.removeControl(legend);
    }

    newLegend(map, color_by_dict[$(".form-check-input:checked").val()][1], best_color);

    d3.select('.caption')
      .text(color_by_dict[$(".form-check-input:checked").val()][0]);

});

  function onEachFeature(feature, layer) {
    var country_code = feature.properties.value;
    ret = $('

');
    ret.append($('
' + feature.properties.name + '
'));
    $.each(['Sensitive', 'MDR', 'XDR', 'TDR'], function(key, value) {
      if (feature.properties.values[value]) {
        ret.append($('
Number of ' + value + ' isolates: ' + feature.properties.values[value] + "
"));
      }
    });
    ret.append($("

 WHO Estimated MDR (Percentage of new TB cases with rifampicin resistant TB): " + (feature.properties.who_est_mdr) + "
"));
    ret.append($("

 HIV Coincidence (Estimated incidence of TB cases who are HIV-positive): " + (feature.properties.hiv_incidence2018) + "
"));
    ret.append($("

 TB Incidence (all types): " + (feature.properties.all_tb_incidence2018) + "
"));
    if(Object.keys(feature.properties.values).length > 2) {
      ret.append($("

Total isolates: " + feature.properties.values.Total + "
"));
    }
    ret.append($('
' + 'Social Determinants of Health:' + '
'));
    ret.append($("

 GDP (Trillions): $" + (Math.round(feature.properties.world_bank_gdp* 100)/100) + "
"));
    ret.append($("

 Total Wealth per Capita: $" + (feature.properties.total_wealth) + "
"));
    ret.append($("

 Total TB Funding: $" + (feature.properties.total_funding) + "
"));
    ret.append($("

 Estimated average household size: " + (Math.round(feature.properties.household*10)/10) + "
"));
    ret.append($("

 Population Density (people per sq. km of land area): " + (feature.properties.pop_dens) + "
"));
    var button1 = $("<button class='btn btn-primary btn-xs'>Select Country</button>").click(function() {
        // WARNING: jquery class selectors and addClass/removeClass DO NOT work here

        var next = $('.country-'+country_code);
        // Set element id just in case it's useful later
        next[0].id = country_code;

        // Add the countrySelect class to highlight it
        next.attr('class', next.attr('class') + ' countrySelect');
        next.data('deselect', function() { button2.click(); });

        // Set the usable data for other charts
        addTabData('map', country_code, feature.properties.name, 'flag');

        button1.hide();
        button2.show();
        map.closePopup();
    });
    button1.attr('id', 'select-'+country_code);
    var button2 = $("<button class='btn btn-danger btn-xs'>Deselect</button>").click(function() {
        // WARNING: jquery class selectors and addClass/removeClass DO NOT work here
        var previous = $('.country-'+country_code);
        previous.attr('class', previous.attr('class').replace(' countrySelect', ''));
        removeTabData('map', country_code);
        button1.show();
        button2.hide();
        map.closePopup();
    });
    ret.append($("
"));
    ret.append(button1);
    ret.append(button2);
    layer.bindPopup(ret[0]);

    var id_cls = 'country-' + country_code;
    if(existing.includes(country_code)) {
        id_cls += ' countrySelect';
        button1.hide();
    } else {
        button2.hide();
    }
    layer.setStyle({className: id_cls});

  }

  map_layer = L.geoJson(data,  {
    style: get_style,
    onEachFeature: onEachFeature
  }
).addTo(map)

}
<|endoftext|>


<commit_before>ace.define('ace/mode/wast_highlight_rules', function (acequire, exports, module) {
    "use strict";

    var oop = acequire("ace/lib/oop");
    var TextHighlightRules = acequire("ace/mode/text_highlight_rules").TextHighlightRules;

    var WastHighlightRules = function () {
        var keywords = "global|local|type|memory|module|table|import|export|param|offset|start|code|data|element";
        var types    = "i32|i64|f32|f64|anyfunc|func|void";
        var operator = [
            "const|if|else|loop|block|br|br_if|br_table|drop|select|end|return|call|call_indirect",
            "current_memory|grow_memory|get_local|set_local|tee_local|get_global|set_global",
            "load|load8_s|load8_u|load16_s|load16_u|load32_s|load32_u|store|store8|store16|store32",
            "eqz|eq|ne|lt_s|lt_u|lt|gt_s|gt_u|gt|le_s|le_u|le|ge_s|ge_u|ge|clz|ctz|popcnt|add|sub",
            "mul|div_s|div_u|div|rem_s|rem_u|and|xor|or|shl|shr_s|shr_u|rotl|rotr|abs|neg|ceil|floor",
            "trunc|nearest|sqrt|min|max|copysign|wrap|trunc_s|trunc_u|extend_s|extend_u|convert_s",
            "convert_u|demote|promote|reinterpret|unreachable|nop"
        ].join("|");

        var keywordMapper = this.createKeywordMapper({
            "keyword.control":  keywords,
            "keyword.operator": operator,
            "support.function": types
        }, "identifier", true);

        this.$rules = {
            "start": [{
                token: "constant.numeric", // hex
                regex: /0(?:[xX][0-9a-fA-F][0-9a-fA-F_]*|[bB][01][01_]*)\b/
            }, {
                token: "constant.numeric", // float
                regex: /[+-]?\d[\d_]*(?:(?:\.[\d_]*)?(?:[eE][+-]?[\d_]+)?)\b/
            }, {
                token: keywordMapper,
                regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
            }, {
                token: "lparen",
                regex: "[[({]"
            }, {
                token: "rparen",
                regex: "[\\])}]"
            }, {
                token: "text",
                regex: "\\s+"
            }]
        };
    };

    oop.inherits(WastHighlightRules, TextHighlightRules);
    exports.WastHighlightRules = WastHighlightRules;
});
<commit_msg>update wast grammar (WIP)<commit_after>ace.define('ace/mode/wast_highlight_rules', function (acequire, exports, module) {
    "use strict";

    var oop = acequire("ace/lib/oop");
    var TextHighlightRules = acequire("ace/mode/text_highlight_rules").TextHighlightRules;

    var WastHighlightRules = function () {
        var keywords = ["global|local|type|memory|module|table|import|export|param|offset|start|code",
                        "data|segment|element|invoke|label"].join("|");

        var types    = "i32|i64|f32|f64|anyfunc|func|void";
        var operator = [
            "const|if|else|loop|block|br|br_if|br_table|drop|select|end|return|call|call_indirect|call_import",
            "current_memory|grow_memory|get_local|set_local|tee_local|get_global|set_global",
            "load|load8_s|load8_u|load16_s|load16_u|load32_s|load32_u|store|store8|store16|store32",
            "eqz|eq|ne|lt_s|lt_u|lt|gt_s|gt_u|gt|le_s|le_u|le|ge_s|ge_u|ge|clz|ctz|popcnt|add|sub",
            "mul|div_s|div_u|div|rem_s|rem_u|and|xor|or|shl|shr_s|shr_u|rotl|rotr|abs|neg|ceil|floor",
            "trunc|nearest|sqrt|min|max|copysign|wrap|trunc_s|trunc_u|extend_s|extend_u|convert_s",
            "convert_u|demote|promote|reinterpret|failure|switch|case|tableswitch|unreachable|nop|has_feature",
            "assert_invalid|assert_trap|assert_return_nan|assert_return"
        ].join("|");

        var keywordMapper = this.createKeywordMapper({
            "keyword.control":  keywords,
            "keyword.operator": operator,
            "support.function": types
        }, "identifier", true);

        this.$rules = {
            "start": [{
                token: "constant.numeric", // hex, float, octal, binary
                regex: /\\b(((\\+|-)?0(x|X)[0-9a-fA-F]+\\.?[0-9a-fA-F]*((p|P)(\\+|-)?[0-9]+)?)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)\\b/
            }, {
                token: "constant.numeric",
                regex: '\\b(\\+|-)?(?i:infinity|nan)\\b'
            }, {
                token: keywordMapper,
                regex: "\$[a-zA-Z_][a-zA-Z_0-9.]*\\b"
            }, {
                token: "lparen",
                regex: "[[({]"
            }, {
                token: "rparen",
                regex: "[\\])}]"
            }, {
                token: "text",
                regex: "\\s+"
            }]
        };
    };

    oop.inherits(WastHighlightRules, TextHighlightRules);
    exports.WastHighlightRules = WastHighlightRules;
});
<|endoftext|>


<commit_before>// main routing file for data_downloader

$(document).ready(function() {
    // grab the available types
    var typesAjax = $.ajax({
        type: 'GET',
        url:  'types.json'
    })

    var countAjax = $.ajax({
        type: 'GET',
        url:  'type_counts.json',
    })

    $.when(typesAjax, countAjax).done(function(types, counts){
        addTypes(types[0], counts[0]);
    }).fail(ajaxError);

});

function addTypes(types, counts) {
    for (var i in types) {
        var type = types[i];
        $('#type-header').append('
 \

'+type+' \
                                    '+counts[i]+'
 \

 \

');

    }

//

}

function getNodesForType(type) {
    $.ajax({
        type: 'GET',
        url:  'http://kbase.us/services/shock-api/node?query&type=' + type
    }).done(loadDataTable)
      .fail(ajaxError);
}

function loadDataTable(ajaxData) {
    // check for error
    if (ajaxData.E !== null) {
        alert('error loading data');
        console.log(ajaxData.E, ajaxData.S);
        return;
    }

    var data = ajaxData.D;
    console.log(data);
}

function ajaxError(jqXHR, textStatus, errorThrown) {
    alert('error with ajax call');
    console.log(jqXHR, textStatus, errorThrown);
}

function addTestTable() {
    $('body').append('

Column 1	Column 2	etc	' +
		     '

Row 1 Data 1	Row 1 Data 2	etc

' +
		     'Row 2 Data 1	Row 2 Data 2	etc

');
    $('#table').dataTable();
}
<commit_msg>Changes to data_downloader<commit_after>(function($) {
    var type_cache = {};

    // define the routes
    var app = $.sammy(function() {

        this.get('#/', function() {
            $('#main').text('');
        });

        this.get('#/test', function() {
            $('#main').text('Hello World');
        });

    });

    $(document).ready(function() {
        // grab the available types
            var typesAjax = $.ajax({
                type: 'GET',
                url:  'types.json'
            });

        var countAjax = $.ajax({
            type: 'GET',
            url:  'type_counts.json'
        });

        $.when(typesAjax, countAjax).done(function(types, counts){
            addTypeRoutes(types[0]);
            addTypes(types[0], counts[0]);
        }).fail(ajaxError);

    });

    function addTypeRoutes(types) {

    }

    function addTypes(types, counts) {
        for (var i in types) {
            var type = types[i];
            $('#type-header').append('
 \

'+type+' \
                                          '+counts[i]+'
 \

 \

');

        }

//

    }

    function getNodesForType(type) {
        if (type_cache[type]) {
            console.log('loading type data from cache: ' + type);
            loadDataTable(type_cache[type]);
        } else {
            $('#type-table').empty().append('loading...');
            console.log('loading type data from AJAX call: ' + type);
            $.ajax({
                type: 'GET',
                url:  'http://kbase.us/services/shock-api/node?query&type=' + type
            }).done(function(data) {
                // check for error
                if (data.E !== null) {
                    alert('error loading data');
                    console.log(data.E, data.S);
                } else {
                    type_cache[type] = data.D;
                    loadDataTable(data.D);
                }
            }).fail(ajaxError);
        }
    }

    function loadDataTable(data) {
        $('#type-table').empty().append('data');
        console.log(data);
    }

    function ajaxError(jqXHR, textStatus, errorThrown) {
        alert('error with ajax call');
        console.log(jqXHR, textStatus, errorThrown);
    }

    function addTestTable() {
        $('body').append('

Column 1	Column 2	etc	' +
		         '

Row 1 Data 1	Row 1 Data 2	etc

' +
		         'Row 2 Data 1	Row 2 Data 2	etc

');
        $('#table').dataTable();
    }
})(jQuery);<|endoftext|>


<commit_before>var
	Client = require('./Client'),

	eone = require('../Misc/addresses').channels.everyone,

	msgs = require('../messages'),

	ca = new Client(eone);

ca.updateClientCache();

for (key in ca.getClientCache()){

	var data = ca.getClientCache()[key].data;

	var message = new msgs.Message(

		msgs.types.SINGLE_MESSAGE,
		ca.getProfile(),
		'Hello nigga'

	);

	ca.sendUDP(data.channel, message.toString());

}

<commit_msg>fixed test file<commit_after>var
	Client = require('./Client'),

	eone = require('../Misc/addresses').channels.everyone,

	msgs = require('../Misc/messages'),

	ca = new Client(eone);

ca.on('listening', function(){

	ca.updateClientCache();

	for (key in ca.getClientCache()){

		var data = ca.getClientCache()[key].data;

		console.log(data);

		// var message = new msgs.Message(

		// 	msgs.types.SINGLE_MESSAGE,
		// 	ca.getProfile(),
		// 	'Hello nigga'

		// );

		// ca.sendUDP(data.channel, message.toString());

	}

});

<|endoftext|>


<commit_before>"use strict";
var Construct = require("can-construct");
var define = require("can-define");
var defineHelpers = require("../define-helpers/define-helpers");
var ObservationRecorder = require("can-observation-recorder");
var ns = require("can-namespace");
var canLog = require("can-log");
var canLogDev = require("can-log/dev/dev");
var canReflect = require("can-reflect");
var canSymbol = require("can-symbol");
var queues = require("can-queues");
var addTypeEvents = require("can-event-queue/type/type");

var keysForDefinition = function(definitions) {
	var keys = [];
	for(var prop in definitions) {
		var definition = definitions[prop];
		if(typeof definition !== "object" || ("serialize" in definition ? !!definition.serialize : !definition.get)) {
			keys.push(prop);
		}
	}
	return keys;
};

function assign(source) {
	queues.batch.start();
	canReflect.assignMap(this, source || {});
	queues.batch.stop();
}
function update(source) {
	queues.batch.start();
	canReflect.updateMap(this, source || {});
	queues.batch.stop();
}
function assignDeep(source){
	queues.batch.start();
	// TODO: we should probably just throw an error instead of cleaning
	canReflect.assignDeepMap(this, source || {});
	queues.batch.stop();
}
function updateDeep(source){
	queues.batch.start();
	// TODO: we should probably just throw an error instead of cleaning
	canReflect.updateDeepMap(this, source || {});
	queues.batch.stop();
}
function setKeyValue(key, value) {
	var defined = defineHelpers.defineExpando(this, key, value);
	if(!defined) {
		this[key] = value;
	}
}
function getKeyValue(key) {
	var value = this[key];
	if(value !== undefined || key in this || Object.isSealed(this)) {
		return value;
	} else {
		ObservationRecorder.add(this, key);
		return this[key];
	}
}

var getSchemaSymbol = canSymbol.for("can.getSchema");

function getSchema() {
	var def = this.prototype._define;
	var definitions = def ? def.definitions : {};
	var schema = {
		type: "map",
		identity: [],
		keys: {}
	};
	return define.updateSchemaKeys(schema, definitions);
}

var DefineMap = Construct.extend("DefineMap",{
	setup: function(base){
		var key,
			prototype = this.prototype;
		if(DefineMap) {
			// we have already created
			var result = define(prototype, prototype, base.prototype._define);
				define.makeDefineInstanceKey(this, result);

			addTypeEvents(this);
			for(key in DefineMap.prototype) {
				define.defineConfigurableAndNotEnumerable(prototype, key, prototype[key]);
			}

			this.prototype.setup = function(props){
				define.setup.call(
					this,
					props || {},
					this.constructor.seal
				);
			};
		} else {
			for(key in prototype) {
				define.defineConfigurableAndNotEnumerable(prototype, key, prototype[key]);
			}
		}
		define.defineConfigurableAndNotEnumerable(prototype, "constructor", this);
		this[getSchemaSymbol] = getSchema;
	}
},{
	// setup for only dynamic DefineMap instances
	setup: function(props, sealed){
		if(!this._define) {
			Object.defineProperty(this,"_define",{
				enumerable: false,
				value: {
					definitions: {}
				}
			});
			Object.defineProperty(this,"_data",{
				enumerable: false,
				value: {}
			});
		}
		define.setup.call(
			this,
			props || {},
			sealed === true
		);
	},
	get: function(prop){
		if(prop) {
			return getKeyValue.call(this, prop);
		} else {
			return canReflect.unwrap(this, Map);
		}
	},
	set: function(prop, value){
		if(typeof prop === "object") {
			//!steal-remove-start
			if(process.env.NODE_ENV !== 'production') {
				canLogDev.warn('can-define/map/map.prototype.set is deprecated; please use can-define/map/map.prototype.assign or can-define/map/map.prototype.update instead');
			}
			//!steal-remove-end
			if(value === true) {
				updateDeep.call(this, prop);
			} else {
				assignDeep.call(this, prop);
			}

		} else {
			setKeyValue.call(this, prop, value);
		}

		return this;
	},
	assignDeep: function(prop) {
		assignDeep.call(this, prop);
		return this;
	},
	updateDeep: function(prop) {
		updateDeep.call(this, prop);
		return this;
	},
	assign: function(prop) {
		assign.call(this, prop);
		return this;
	},
	update: function(prop) {
		update.call(this, prop);
		return this;
	},
	serialize: function () {
		return canReflect.serialize(this, Map);
	},
	deleteKey: defineHelpers.deleteKey,
	forEach: (function(){

		var forEach = function(list, cb, thisarg){
			return canReflect.eachKey(list, cb, thisarg);
		},
			noObserve = ObservationRecorder.ignore(forEach);

		return function(cb, thisarg, observe) {
			return observe === false ? noObserve(this, cb, thisarg) : forEach(this, cb, thisarg);
		};

	})(),
	"*": {
		type: define.types.observable
	}
});

var defineMapProto = {
	// -type-
	"can.isMapLike": true,
	"can.isListLike":  false,
	"can.isValueLike": false,

	// -get/set-
	"can.getKeyValue": getKeyValue,
	"can.setKeyValue": setKeyValue,
	"can.deleteKeyValue": defineHelpers.deleteKey,

	// -shape
	"can.getOwnKeys": function() {
		var keys = canReflect.getOwnEnumerableKeys(this);
		if(this._computed) {
			var computedKeys = canReflect.getOwnKeys(this._computed);

			var key;
			for (var i=0; i<computedKeys.length; i++) {
				key = computedKeys[i];
				if (keys.indexOf(key) < 0) {
					keys.push(key);
				}
			}
		}

		return keys;
	},
	"can.getOwnEnumerableKeys": function(){
		ObservationRecorder.add(this, 'can.keys');
		return keysForDefinition(this._define.definitions).concat(keysForDefinition(this._instanceDefinitions) );
	},
	"can.hasOwnKey": function(key) {
		return Object.hasOwnProperty.call(this._define.definitions, key);
	},
	"can.hasKey": function(key) {
		return !!this._define.definitions[key];
	},

	// -shape get/set-
	"can.assignDeep": assignDeep,
	"can.updateDeep": updateDeep,
	"can.unwrap": defineHelpers.reflectUnwrap,
	"can.serialize": defineHelpers.reflectSerialize,

	// observable
	"can.keyHasDependencies": function(key) {
		return !!(this._computed && this._computed[key] && this._computed[key].compute);
	},
	"can.getKeyDependencies": function(key) {
		var ret;
		if(this._computed && this._computed[key] && this._computed[key].compute) {
			ret = {};
			ret.valueDependencies = new Set([
				this._computed[key].compute
			]);
		}
		return ret;
	}
};

//!steal-remove-start
if(process.env.NODE_ENV !== 'production') {
	defineMapProto["can.getName"] = function() {
		return canReflect.getName(this.constructor) + "{}";
	};
}
//!steal-remove-end

canReflect.assignSymbols(DefineMap.prototype, defineMapProto);

canReflect.setKeyValue(DefineMap.prototype, canSymbol.iterator, function() {
	return new define.Iterator(this);
});

// Add necessary event methods to this object.
for(var prop in define.eventsProto) {
	DefineMap[prop] = define.eventsProto[prop];
	Object.defineProperty(DefineMap.prototype, prop, {
		enumerable:false,
		value: define.eventsProto[prop],
		writable: true
	});
}
// @@can.onKeyValue and @@can.offKeyValue are also on define.eventsProto
//  but symbols are not enumerated in for...in loops
var eventsProtoSymbols = ("getOwnPropertySymbols" in Object) ?
  Object.getOwnPropertySymbols(define.eventsProto) :
  [canSymbol.for("can.onKeyValue"), canSymbol.for("can.offKeyValue")];

eventsProtoSymbols.forEach(function(sym) {
  Object.defineProperty(DefineMap.prototype, sym, {
    enumerable:false,
    value: define.eventsProto[sym],
    writable: true
  });
});

//!steal-remove-start
if(process.env.NODE_ENV !== 'production') {
	// call `map.log()` to log all event changes
	// pass `key` to only log the matching property, e.g: `map.log("foo")`
	DefineMap.prototype.log = defineHelpers.log;
}
//!steal-remove-end

// tells `can-define` to use this
define.DefineMap = DefineMap;

Object.defineProperty(DefineMap.prototype, "toObject", {
	enumerable: false,
	writable: true,
	value: function(){
		canLog.warn("Use DefineMap::get instead of DefineMap::toObject");
		return this.get();
	}
});

module.exports = ns.DefineMap = DefineMap;
<commit_msg>Add configurable to map events as well<commit_after>"use strict";
var Construct = require("can-construct");
var define = require("can-define");
var defineHelpers = require("../define-helpers/define-helpers");
var ObservationRecorder = require("can-observation-recorder");
var ns = require("can-namespace");
var canLog = require("can-log");
var canLogDev = require("can-log/dev/dev");
var canReflect = require("can-reflect");
var canSymbol = require("can-symbol");
var queues = require("can-queues");
var addTypeEvents = require("can-event-queue/type/type");

var keysForDefinition = function(definitions) {
	var keys = [];
	for(var prop in definitions) {
		var definition = definitions[prop];
		if(typeof definition !== "object" || ("serialize" in definition ? !!definition.serialize : !definition.get)) {
			keys.push(prop);
		}
	}
	return keys;
};

function assign(source) {
	queues.batch.start();
	canReflect.assignMap(this, source || {});
	queues.batch.stop();
}
function update(source) {
	queues.batch.start();
	canReflect.updateMap(this, source || {});
	queues.batch.stop();
}
function assignDeep(source){
	queues.batch.start();
	// TODO: we should probably just throw an error instead of cleaning
	canReflect.assignDeepMap(this, source || {});
	queues.batch.stop();
}
function updateDeep(source){
	queues.batch.start();
	// TODO: we should probably just throw an error instead of cleaning
	canReflect.updateDeepMap(this, source || {});
	queues.batch.stop();
}
function setKeyValue(key, value) {
	var defined = defineHelpers.defineExpando(this, key, value);
	if(!defined) {
		this[key] = value;
	}
}
function getKeyValue(key) {
	var value = this[key];
	if(value !== undefined || key in this || Object.isSealed(this)) {
		return value;
	} else {
		ObservationRecorder.add(this, key);
		return this[key];
	}
}

var getSchemaSymbol = canSymbol.for("can.getSchema");

function getSchema() {
	var def = this.prototype._define;
	var definitions = def ? def.definitions : {};
	var schema = {
		type: "map",
		identity: [],
		keys: {}
	};
	return define.updateSchemaKeys(schema, definitions);
}

var DefineMap = Construct.extend("DefineMap",{
	setup: function(base){
		var key,
			prototype = this.prototype;
		if(DefineMap) {
			// we have already created
			var result = define(prototype, prototype, base.prototype._define);
				define.makeDefineInstanceKey(this, result);

			addTypeEvents(this);
			for(key in DefineMap.prototype) {
				define.defineConfigurableAndNotEnumerable(prototype, key, prototype[key]);
			}

			this.prototype.setup = function(props){
				define.setup.call(
					this,
					props || {},
					this.constructor.seal
				);
			};
		} else {
			for(key in prototype) {
				define.defineConfigurableAndNotEnumerable(prototype, key, prototype[key]);
			}
		}
		define.defineConfigurableAndNotEnumerable(prototype, "constructor", this);
		this[getSchemaSymbol] = getSchema;
	}
},{
	// setup for only dynamic DefineMap instances
	setup: function(props, sealed){
		if(!this._define) {
			Object.defineProperty(this,"_define",{
				enumerable: false,
				value: {
					definitions: {}
				}
			});
			Object.defineProperty(this,"_data",{
				enumerable: false,
				value: {}
			});
		}
		define.setup.call(
			this,
			props || {},
			sealed === true
		);
	},
	get: function(prop){
		if(prop) {
			return getKeyValue.call(this, prop);
		} else {
			return canReflect.unwrap(this, Map);
		}
	},
	set: function(prop, value){
		if(typeof prop === "object") {
			//!steal-remove-start
			if(process.env.NODE_ENV !== 'production') {
				canLogDev.warn('can-define/map/map.prototype.set is deprecated; please use can-define/map/map.prototype.assign or can-define/map/map.prototype.update instead');
			}
			//!steal-remove-end
			if(value === true) {
				updateDeep.call(this, prop);
			} else {
				assignDeep.call(this, prop);
			}

		} else {
			setKeyValue.call(this, prop, value);
		}

		return this;
	},
	assignDeep: function(prop) {
		assignDeep.call(this, prop);
		return this;
	},
	updateDeep: function(prop) {
		updateDeep.call(this, prop);
		return this;
	},
	assign: function(prop) {
		assign.call(this, prop);
		return this;
	},
	update: function(prop) {
		update.call(this, prop);
		return this;
	},
	serialize: function () {
		return canReflect.serialize(this, Map);
	},
	deleteKey: defineHelpers.deleteKey,
	forEach: (function(){

		var forEach = function(list, cb, thisarg){
			return canReflect.eachKey(list, cb, thisarg);
		},
			noObserve = ObservationRecorder.ignore(forEach);

		return function(cb, thisarg, observe) {
			return observe === false ? noObserve(this, cb, thisarg) : forEach(this, cb, thisarg);
		};

	})(),
	"*": {
		type: define.types.observable
	}
});

var defineMapProto = {
	// -type-
	"can.isMapLike": true,
	"can.isListLike":  false,
	"can.isValueLike": false,

	// -get/set-
	"can.getKeyValue": getKeyValue,
	"can.setKeyValue": setKeyValue,
	"can.deleteKeyValue": defineHelpers.deleteKey,

	// -shape
	"can.getOwnKeys": function() {
		var keys = canReflect.getOwnEnumerableKeys(this);
		if(this._computed) {
			var computedKeys = canReflect.getOwnKeys(this._computed);

			var key;
			for (var i=0; i<computedKeys.length; i++) {
				key = computedKeys[i];
				if (keys.indexOf(key) < 0) {
					keys.push(key);
				}
			}
		}

		return keys;
	},
	"can.getOwnEnumerableKeys": function(){
		ObservationRecorder.add(this, 'can.keys');
		return keysForDefinition(this._define.definitions).concat(keysForDefinition(this._instanceDefinitions) );
	},
	"can.hasOwnKey": function(key) {
		return Object.hasOwnProperty.call(this._define.definitions, key);
	},
	"can.hasKey": function(key) {
		return !!this._define.definitions[key];
	},

	// -shape get/set-
	"can.assignDeep": assignDeep,
	"can.updateDeep": updateDeep,
	"can.unwrap": defineHelpers.reflectUnwrap,
	"can.serialize": defineHelpers.reflectSerialize,

	// observable
	"can.keyHasDependencies": function(key) {
		return !!(this._computed && this._computed[key] && this._computed[key].compute);
	},
	"can.getKeyDependencies": function(key) {
		var ret;
		if(this._computed && this._computed[key] && this._computed[key].compute) {
			ret = {};
			ret.valueDependencies = new Set([
				this._computed[key].compute
			]);
		}
		return ret;
	}
};

//!steal-remove-start
if(process.env.NODE_ENV !== 'production') {
	defineMapProto["can.getName"] = function() {
		return canReflect.getName(this.constructor) + "{}";
	};
}
//!steal-remove-end

canReflect.assignSymbols(DefineMap.prototype, defineMapProto);

canReflect.setKeyValue(DefineMap.prototype, canSymbol.iterator, function() {
	return new define.Iterator(this);
});

// Add necessary event methods to this object.
for(var prop in define.eventsProto) {
	DefineMap[prop] = define.eventsProto[prop];
	Object.defineProperty(DefineMap.prototype, prop, {
		enumerable:false,
		value: define.eventsProto[prop],
		writable: true
	});
}
// @@can.onKeyValue and @@can.offKeyValue are also on define.eventsProto
//  but symbols are not enumerated in for...in loops
var eventsProtoSymbols = ("getOwnPropertySymbols" in Object) ?
  Object.getOwnPropertySymbols(define.eventsProto) :
  [canSymbol.for("can.onKeyValue"), canSymbol.for("can.offKeyValue")];

eventsProtoSymbols.forEach(function(sym) {
  Object.defineProperty(DefineMap.prototype, sym, {
  	configurable: true,
    enumerable:false,
    value: define.eventsProto[sym],
    writable: true
  });
});

//!steal-remove-start
if(process.env.NODE_ENV !== 'production') {
	// call `map.log()` to log all event changes
	// pass `key` to only log the matching property, e.g: `map.log("foo")`
	DefineMap.prototype.log = defineHelpers.log;
}
//!steal-remove-end

// tells `can-define` to use this
define.DefineMap = DefineMap;

Object.defineProperty(DefineMap.prototype, "toObject", {
	enumerable: false,
	writable: true,
	value: function(){
		canLog.warn("Use DefineMap::get instead of DefineMap::toObject");
		return this.get();
	}
});

module.exports = ns.DefineMap = DefineMap;
<|endoftext|>


<commit_before>'use strict'
import React from 'react'
import PropTypes from 'prop-types'
import DisplayColumn from './DisplayColumn'
import SampleStory from './SampleStory'

const FeatureDisplay = ({
  featureStories,
  publishedTitles,
  srcHttp,
  format,
  moveThumb,
  holdThumb,
  setZoom,
  stopMove,
  savePosition,
  applyStory,
  clearStory,
  updated,
  thumbnailForm
}) => {
  let bsClass = 'col-sm-3'
  let storyCount = featureStories.length

  let formDisplay
  if (storyCount < 8) {
    storyCount++
  }
  const getBsClass = (storyCount, currentCount) => {
    switch (storyCount) {
      case 1:
        return 'col-12'
      case 2:
        return 'col-sm-6'
      case 3:
        return 'col-sm-4'
      case 4:
      case 8:
        return 'col-md-3 col-sm-6'
      case 5:
        if (currentCount > 3) {
          return 'col-sm-6'
        } else {
          return 'col-sm-4'
        }
      case 6:
        return 'col-sm-4'
      case 7:
        if (currentCount == 4) {
          return 'col-md-3 col-sm-6'
        } else if (currentCount >= 4) {
          return 'col-md-4 col-sm-6'
        } else {
          return 'col-sm-4 col-md-3'
        }
      default:
        return 'col-sm-3'
    }

  }

  let storyList = featureStories.map((value, key) => {
    const bsClass = getBsClass(storyCount, key + 1)
    return (
      <DisplayColumn
        key={key}
        bsClass={bsClass}
        story={value}
        publishedTitles={publishedTitles}
        thumbnailForm={thumbnailForm.bind(null, key)}
        applyStory={applyStory.bind(null, key)}
        clearStory={clearStory.bind(null, key)}
        savePosition={savePosition.bind(null, key)}
        stopMove={stopMove.bind(null, key)}
        moveThumb={moveThumb.bind(null, key)}
        holdThumb={holdThumb.bind(null, key)}
        setZoom={setZoom.bind(null, key)}
        updated={updated.indexOf(key) !== -1}
        format={format}/>
    )
  })
  if (storyCount < 8) {
    const bsClass = getBsClass(storyCount, storyCount)
    formDisplay = <DisplayColumn
      bsClass={bsClass}
      story={SampleStory(srcHttp)}
      applyStory={applyStory.bind(null, -1)}
      publishedTitles={publishedTitles}
      format={format}/>
  }
  return (
{storyList}{formDisplay}
)
}

FeatureDisplay.propTypes = {
  featureStories: PropTypes.array,
  publishedTitles: PropTypes.array,
  srcHttp: PropTypes.string,
  format: PropTypes.string,
  moveThumb: PropTypes.func,
  stopMove: PropTypes.func,
  holdThumb: PropTypes.func,
  applyStory: PropTypes.func,
  clearStory: PropTypes.func,
  setZoom: PropTypes.func,
  savePosition: PropTypes.func,
  thumbnailForm: PropTypes.func,
  updated: PropTypes.array
}

export default FeatureDisplay
<commit_msg>Removed unused variable.<commit_after>'use strict'
import React from 'react'
import PropTypes from 'prop-types'
import DisplayColumn from './DisplayColumn'
import SampleStory from './SampleStory'

const FeatureDisplay = ({
  featureStories,
  publishedTitles,
  srcHttp,
  format,
  moveThumb,
  holdThumb,
  setZoom,
  stopMove,
  savePosition,
  applyStory,
  clearStory,
  updated,
  thumbnailForm
}) => {
  let storyCount = featureStories.length

  let formDisplay
  if (storyCount < 8) {
    storyCount++
  }
  const getBsClass = (storyCount, currentCount) => {
    switch (storyCount) {
      case 1:
        return 'col-12'
      case 2:
        return 'col-sm-6'
      case 3:
        return 'col-sm-4'
      case 4:
      case 8:
        return 'col-md-3 col-sm-6'
      case 5:
        if (currentCount > 3) {
          return 'col-sm-6'
        } else {
          return 'col-sm-4'
        }
      case 6:
        return 'col-sm-4'
      case 7:
        if (currentCount == 4) {
          return 'col-md-3 col-sm-6'
        } else if (currentCount >= 4) {
          return 'col-md-4 col-sm-6'
        } else {
          return 'col-sm-4 col-md-3'
        }
      default:
        return 'col-sm-3'
    }

  }

  let storyList = featureStories.map((value, key) => {
    const bsClass = getBsClass(storyCount, key + 1)
    return (
      <DisplayColumn
        key={key}
        bsClass={bsClass}
        story={value}
        publishedTitles={publishedTitles}
        thumbnailForm={thumbnailForm.bind(null, key)}
        applyStory={applyStory.bind(null, key)}
        clearStory={clearStory.bind(null, key)}
        savePosition={savePosition.bind(null, key)}
        stopMove={stopMove.bind(null, key)}
        moveThumb={moveThumb.bind(null, key)}
        holdThumb={holdThumb.bind(null, key)}
        setZoom={setZoom.bind(null, key)}
        updated={updated.indexOf(key) !== -1}
        format={format}/>
    )
  })
  if (storyCount < 8) {
    const bsClass = getBsClass(storyCount, storyCount)
    formDisplay = <DisplayColumn
      bsClass={bsClass}
      story={SampleStory(srcHttp)}
      applyStory={applyStory.bind(null, -1)}
      publishedTitles={publishedTitles}
      format={format}/>
  }
  return (
{storyList}{formDisplay}
)
}

FeatureDisplay.propTypes = {
  featureStories: PropTypes.array,
  publishedTitles: PropTypes.array,
  srcHttp: PropTypes.string,
  format: PropTypes.string,
  moveThumb: PropTypes.func,
  stopMove: PropTypes.func,
  holdThumb: PropTypes.func,
  applyStory: PropTypes.func,
  clearStory: PropTypes.func,
  setZoom: PropTypes.func,
  savePosition: PropTypes.func,
  thumbnailForm: PropTypes.func,
  updated: PropTypes.array
}

export default FeatureDisplay
<|endoftext|>


<commit_before>define([
    'compiled/editor/stocktiny',
    'i18n!editor',
    'jquery',
    'str/htmlEscape',
    'jqueryui/slider',
    'jquery.instructure_misc_helpers',
    "modernizr.custom.34982",
    'backbone-0.9.9',
    "sketcher"
], function(tinymce, I18n, $) {

    var HandWrite,
        $mask,
        pluginProp = {id:"instructureHandWrite",name:"instructure_handWrite"},
        sketchSetting = {
            sketchType:"handWrite",
            id:"",
            lineW : 10,
            canvasW : 1000,
            canvasH : 240,
            color : {hex:"000000",rgb:[0,0,0]},
            tools : {type:"line",src:""},
            appName : "sketch_app",
            appTitle : "写字板"
        };

  tinymce.create('tinymce.plugins.' + pluginProp.id,  {
    init : function(ed, url) {
      ed.addCommand(pluginProp.id, function() {

          if( HandWrite == undefined ) {
              sketchSetting.id = ed.id;
              initial();
          }
              HandWrite.set("id",ed.id);

          //$("#ipadScale").attr("content","user-scalable=no");
          HandWrite.App.show();
          $mask.show();

          function initial(){
              var Write = Sketcher.extend({

                  onCanvasMouseDown : function () {
                      var self = this;

                      return function(event) {
                          if( event.button == 2 )return false;        // forbidden right mouse
                          self.writeState = true;
                          console.log("down")
                          clearTimeout(self.timeOut_mouseUp);
                          self.lines.push([]);

                          self.mouseMoveHandler = self.onCanvasMouseMove();
                          self.mouseUpHandler = self.onCanvasMouseUp();

                          // unbind the event if in ie, when drawing out the canvas to select the text out of canvas, than back in canvas drawing the line always drawing
                          if ( $.browser.msie ){self.canvas.unbind( self.mouseMoveEvent);}

                          self.canvas.bind( self.mouseMoveEvent, self.mouseMoveHandler );
                          $(document).bind(self.mouseUpEvent,self.mouseUpHandler);

                          self.updateMousePosition( event );
                          //self.renderFunction( event );           // click drawing
                          return false;      //**** ie & chrome bug, stop the mouse selecting the outer text
                      }
                  },

                  onCanvasMouseUp : function (event) {
                      var self = this;
                      return function(event) {

                          if( !self.writeState ) return;
                          console.log("up")
                          self.timeOut_mouseUp = setTimeout(function(){

                              if( !self.writeState ) return;

                                  self.saveImg();
                                  self.reset();

                          },700);

                          /*console.log( self.canvas.data("events") );
                          self.canvas.unbind( self.mouseMoveEvent, self.mouseMoveHandler );
                          $(document).unbind(self.mouseUpEvent,self.mouseUpHandler);*/

                          self.canvas.unbind( self.mouseMoveEvent );
                          $(document).unbind(self.mouseUpEvent );

                      }
                  },

                  reset : function () {
                      this.writeState = false;
                      clearTimeout(this.timeOut_mouseUp);
                      this.lines = [];
                      this.clear();
                      this.writingEdge = {leftTop:{x:9999,y:9999},rightBottom:{x:0,y:0}};
                  },

                  saveImg : function () {
                      var self = this;
                      //****** rewrite character and get the new data
                      var writeW = this.writingEdge.rightBottom.x - this.writingEdge.leftTop.x;
                      var writeH = this.get("canvasH");
                      var cropLeft = this.writingEdge.leftTop.x - this.canvas.offset().left;
                      var $copyCanvas = $("<canvas></canvas>").attr({
                          width: writeW/7 + 1,
                          height: writeH/7 + 1
                      });
                      var copyCanvasContext = $copyCanvas.get(0).getContext("2d");
                      copyCanvasContext.strokeStyle = "#000000";
                      copyCanvasContext.lineWidth = 1.2;
                      $.each(self.lines, function(i){
                          $.each(self.lines[i], function(k,value){
                              if( k == 0 ){
                                  copyCanvasContext.beginPath();

                                  copyCanvasContext.moveTo( ( value[0]-cropLeft )/7, ( value[1] ) /7 );
                              }else{
                                  copyCanvasContext.lineTo( ( value[0] - cropLeft )/7, ( value[1] )/7 );
                                  if( k == ( self.lines[i].length - 1 ) ){
                                      copyCanvasContext.stroke();
                                  }
                              }
                          });
                      });
                      var copyCanvasData = $copyCanvas.get(0).toDataURL();
                      // end

                      //****** insert image
                      var $div = $("

"),
                          $img = $("").attr("src",copyCanvasData).addClass(this.get("sketchType"));
                      $div.append($img);
                      var $editor = $("#" + this.get("id"));
                      $editor.editorBox('insert_code', $div.html());
                      // end

                  }

              });

              HandWrite = new Write(sketchSetting);

              //****** add  buttonSet

              //var $scale = $('<meta id="ipadScale" name="viewport" content="user-scalable=no" />').prependTo("head");
              var buttonSet = $("

");
              $mask = $("

").appendTo("body");

              var $dele = $("撤销")
                  .bind("mousedown",function(){
                      tinymce.activeEditor.undoManager.undo();
                  }).appendTo(buttonSet);

              var $return = $("换行")
                  .click(function(){
                      var $editor = $("#" + ed.id);
                      //tinyMCE.activeEditor.selection.select(tinyMCE.activeEditor.dom.select('p')[0]);
                     $editor.editorBox('insert_code', "
");
                  }).appendTo(buttonSet);

              var $close = $("关闭")
                  .click(function(e){
                      e.preventDefault();
                      HandWrite.App.hide();
                      $mask.hide();
                      $("#ipadScale").attr("content","user-scalable=yes");
                  }).appendTo(buttonSet);

              HandWrite.App.prepend(buttonSet);
              // end

              /*tinymce.activeEditor.dom.addClass(tinymce.activeEditor.dom.select('p'), 'someclass');
              ed.onUndo.add(function(ed, level) { console.log('Undo was performed: ' + level.content); });*/

              //****** choose brush
              HandWrite.brushSize = {width:9,height:9,step:1};
              $(".big_brush").trigger("click");
              // end

          }

      });

      ed.addButton(pluginProp.name, {
        title: sketchSetting.sketchType,
        cmd: pluginProp.id,
        image: url + '/img/' + sketchSetting.sketchType +'.png'
      });

    },

    getInfo : function() {
      return {
        longname : pluginProp.id,
        author : 'Rupert.qin',
        authorurl : 'http://www.instructure.com',
        infourl : 'http://www.instructure.com',
        version : tinymce.majorVersion + "." + tinymce.minorVersion
      };
    }

  });

  // Register plugin
tinymce.PluginManager.add(pluginProp.name, tinymce.plugins[pluginProp.id]);

});

<commit_msg>handwrite plugin<commit_after>define([
    'compiled/editor/stocktiny',
    'i18n!editor',
    'jquery',
    'str/htmlEscape',
    'jqueryui/slider',
    'jquery.instructure_misc_helpers',
    "modernizr.custom.34982",
    'backbone-0.9.9',
    "sketcher"
], function(tinymce, I18n, $) {

    var HandWrite,
        $mask,
        pluginProp = {id:"instructureHandWrite",name:"instructure_handWrite"},
        sketchSetting = {
            sketchType:"handWrite",
            id:"",
            lineW : 10,
            canvasW : 1000,
            canvasH : 240,
            color : {hex:"000000",rgb:[0,0,0]},
            tools : {type:"line",src:""},
            appName : "sketch_app",
            appTitle : "写字板"
        };

  tinymce.create('tinymce.plugins.' + pluginProp.id,  {
    init : function(ed, url) {
      ed.addCommand(pluginProp.id, function() {

          if( HandWrite == undefined ) {
              sketchSetting.id = ed.id;
              initial();
          }
              HandWrite.set("id",ed.id);

          //$("#ipadScale").attr("content","user-scalable=no");
          HandWrite.App.show();
          $mask.show();

          function initial(){
              var Write = Sketcher.extend({

                  onCanvasMouseDown : function () {
                      var self = this;

                      return function(event) {
                          if( event.button == 2 )return false;        // forbidden right mouse
                          self.writeState = true;
                          console.log("down")
                          clearTimeout(self.timeOut_mouseUp);
                          self.lines.push([]);

                          self.mouseMoveHandler = self.onCanvasMouseMove();
                          self.mouseUpHandler = self.onCanvasMouseUp();

                          // unbind the event if in ie, when drawing out the canvas to select the text out of canvas, than back in canvas drawing the line always drawing
                          if ( $.browser.msie ){self.canvas.unbind( self.mouseMoveEvent);}

                          self.canvas.bind( self.mouseMoveEvent, self.mouseMoveHandler );
                          $(document).bind(self.mouseUpEvent,self.mouseUpHandler);

                          self.updateMousePosition( event );
                          //self.renderFunction( event );           // click drawing
                          return false;      //**** ie & chrome bug, stop the mouse selecting the outer text
                      }
                  },

                  onCanvasMouseUp : function (event) {
                      var self = this;
                      return function(event) {

                          if( !self.writeState ) return;
                          console.log("up")
                          self.timeOut_mouseUp = setTimeout(function(){

                              if( !self.writeState ) return;

                                  self.saveImg();
                                  self.reset();

                          },700);

                          /*console.log( self.canvas.data("events") );
                          self.canvas.unbind( self.mouseMoveEvent, self.mouseMoveHandler );
                          $(document).unbind(self.mouseUpEvent,self.mouseUpHandler);*/

                          self.canvas.unbind( self.mouseMoveEvent );
                          $(document).unbind(self.mouseUpEvent );

                      }
                  },

                  reset : function () {
                      this.writeState = false;
                      clearTimeout(this.timeOut_mouseUp);
                      this.lines = [];
                      this.clear();
                      this.writingEdge = {leftTop:{x:9999,y:9999},rightBottom:{x:0,y:0}};
                  },

                  saveImg : function () {
                      var self = this;
                      //****** rewrite character and get the new data
                      var writeW = this.writingEdge.rightBottom.x - this.writingEdge.leftTop.x;
                      var writeH = this.get("canvasH");
                      var cropLeft = this.writingEdge.leftTop.x - this.canvas.offset().left;
                      var $copyCanvas = $("<canvas></canvas>").attr({
                          width: writeW/7 + 1,
                          height: writeH/7 + 1
                      });
                      var copyCanvasContext = $copyCanvas.get(0).getContext("2d");
                      copyCanvasContext.strokeStyle = "#000000";
                      copyCanvasContext.lineWidth = 1.2;
                      $.each(self.lines, function(i){
                          $.each(self.lines[i], function(k,value){
                              if( k == 0 ){
                                  copyCanvasContext.beginPath();

                                  copyCanvasContext.moveTo( ( value[0]-cropLeft )/7, ( value[1] ) /7 );
                              }else{
                                  copyCanvasContext.lineTo( ( value[0] - cropLeft )/7, ( value[1] )/7 );
                                  if( k == ( self.lines[i].length - 1 ) ){
                                      copyCanvasContext.stroke();
                                  }
                              }
                          });
                      });
                      var copyCanvasData = $copyCanvas.get(0).toDataURL();
                      // end

                      //****** insert image
                      var $div = $("

"),
                          $img = $("").attr("src",copyCanvasData).addClass(this.get("sketchType"));
                      $div.append($img);
                      var $editor = $("#" + this.get("id"));
                      $editor.editorBox('insert_code', $div.html());
                      // end

                  }

              });

              HandWrite = new Write(sketchSetting);

              //****** add  buttonSet

              //var $scale = $('<meta id="ipadScale" name="viewport" content="user-scalable=no" />').prependTo("head");
              var buttonSet = $("

");
              $mask = $("

").appendTo("body");

              var $dele = $("撤销")
                  .bind("mousedown",function(){
                      tinymce.activeEditor.undoManager.undo();
                  }).appendTo(buttonSet);

              /*var $return = $("换行")
                  .click(function(){
                      var $editor = $("#" + ed.id);
                      //tinyMCE.activeEditor.selection.select(tinyMCE.activeEditor.dom.select('p')[0]);
                     $editor.editorBox('insert_code', "
");
                  }).appendTo(buttonSet);*/

              var $close = $("关闭")
                  .click(function(e){
                      e.preventDefault();
                      HandWrite.App.hide();
                      $mask.hide();
                      $("#ipadScale").attr("content","user-scalable=yes");
                  }).appendTo(buttonSet);

              HandWrite.App.prepend(buttonSet);
              // end

              /*tinymce.activeEditor.dom.addClass(tinymce.activeEditor.dom.select('p'), 'someclass');
              ed.onUndo.add(function(ed, level) { console.log('Undo was performed: ' + level.content); });*/

              //****** choose brush
              HandWrite.brushSize = {width:9,height:9,step:1};
              $(".big_brush").trigger("click");
              // end

          }

      });

      ed.addButton(pluginProp.name, {
        title: sketchSetting.sketchType,
        cmd: pluginProp.id,
        image: url + '/img/' + sketchSetting.sketchType +'.png'
      });

    },

    getInfo : function() {
      return {
        longname : pluginProp.id,
        author : 'Rupert.qin',
        authorurl : 'http://www.instructure.com',
        infourl : 'http://www.instructure.com',
        version : tinymce.majorVersion + "." + tinymce.minorVersion
      };
    }

  });

  // Register plugin
tinymce.PluginManager.add(pluginProp.name, tinymce.plugins[pluginProp.id]);

});

<|endoftext|>


<commit_before>module.exports = function(RED) {
    "use strict";
    const util = require('util');
    const fs = require('fs');
    const crypto = require('crypto');
    const moment = require('moment');
    const validator = require("validator");
    const dns = require('dns');
    const spawn = require('child_process').spawn;

    function TestSSLScan(n) {
        RED.nodes.createNode(this,n);
        let scantarget      = n.host;
        let opensslpath     = n.opensslpath || '/usr/bin/openssl';
        let cabundlespath   = n.cabundlespath || '/etc/ssl';

        let node = this;

        this.on("input",function(msg) {
            let host            = scantarget || msg.host;
            let openssl         = opensslpath || msg.opensslpath;
            let capath          = cabundlespath || msg.cabundlespath;
            let scanID          = msg._msgid;
            let env             = Object.create( process.env );

            // setting openssl path
            if (openssl != undefined && openssl != "") {
                node.log(`[testssl][${scanID}] - using openssl executable: ${openssl}`);
                openssl = '--openssl=' + openssl;
            }

            // setting ca-bundles path
            if (capath != undefined && capath != "") {
                node.log(`[testssl][${scanID}] - using ca bundles path: ${capath}`);
                env.CA_BUNDLES_PATH = capath;
            }

            // checking host and port data provided
            if (host === undefined || host === "") {
                node.status({fill:"red",shape:"dot",text:'address missing'});
                return;
            }
            let tmpHost = '';
            let tmpPort = 443;
            let tmp1 = host.match(/^[A-Za-z0-9\x2E\x2D]*$/);        // check for host only
            let tmp2 = host.match(/^([^\x3A]*)\x3A([0-9]{1,5})$/);  // check for host + port
            if (tmp1 instanceof Array && tmp1.length === 1)
            {
                tmpHost = tmp1[0];
            }
            else if (tmp2 instanceof Array && tmp2.length === 3)
            {
                tmpHost = tmp2[1];
                tmpPort = parseInt(tmp2[2]);
            }
            else
            {
                node.status({fill:"red",shape:"dot",text:"invalid data given"});
                msg.payload = "you provided invalid data";
                node.send(msg);
                return;
            }

            // checking port
            if (tmpPort < 1 || tmpPort > 65535)
            {
                node.status({fill:"red",shape:"dot",text:"not a valid port"});
                msg.payload = "this is not a valid port";
                node.send(msg);
                return;
            }

            GetMyTarget(tmpHost, function(IPsToScan){
                if (typeof IPsToScan === "string") {
                    node.status({fill:"red",shape:"dot",text:IPsToScan});
                    msg.payload = IPsToScan;
                    node.send(msg);
                    return;
                }

                node.status({fill:"green",shape:"dot",text:"scanning " + tmpHost + " on port " + tmpPort});
                msg.payload = "scanning... " + IPsToScan.join() + ' on port ' + tmpPort;
                node.send(msg);
                node.log(`[testssl][${scanID}] - scanning ${tmpHost} via ${IPsToScan.join()} on port ${tmpPort}`);

                let timeBefore = moment();

                IPsToScan.forEach((singleAddrToScan, index, arr) => {

                    let output = "";
                    let error = "";
                    let timeout = false;
                    let hash = crypto.createHash('sha256').update(`${scanID}${tmpHost}${tmpPort}`).digest('hex');
                    let jsonfile = '/tmp/' + hash + 'json';
                    let htmlfile = '/tmp/' + hash + 'html';

                    let run = spawn('./testssl.sh',
                      [
                        openssl,
                        '--protocols',
                        '--server-defaults',
                        '--server-preference',
                        '--headers',
                        '--vulnerable',
                        '--cipher-per-proto',
                        '--pfs',
                        '--rc4',
                        '--nodns',
                        '--openssl-timeout',
                        '30',
                        '--jsonfile',
                        jsonfile,
                        '--htmlfile',
                        htmlfile,
                        '--ip',
                        singleAddrToScan,
                        tmpHost + ':' + tmpPort
                      ],
                      {
                          cwd: __dirname,
                          env: env
                      }
                    );

                    // timeout for scan of 10 minutes
                    timeout = setTimeout(function(){
                        if (run != null) {
                            node.log(`[testssl][${scanID}][${index}] - timeout of scan`);
                            node.status({fill:"red",shape:"dot",text:"timeout during scan"});
                            timeout = true;
                            run.kill();
                            return;
                        }
                    }, 600000);

                    // interval to inform user of ongoing activity
                    let interval = setInterval(() => {
                        if (run != null) {
                            msg.payload = "scan is still running (" + moment().diff(timeBefore, 'seconds') + " seconds) for " + singleAddrToScan + ":" + tmpPort;
                            node.send(msg);
                        }
                    }, 60000);

                    run.stdout.on('data', (data) => {
                        output+=data.toString();
                    });

                    run.stderr.on('data', (data) => {
                        error+=data.toString();
                    });

                    run.on('close', () => {
                        node.log(`[testssl][${scanID}][${index}] - scan finished for ${singleAddrToScan}:${tmpPort}`);
                        run = null;
                        clearTimeout(timeout);
                        clearInterval(interval);
                        if (error != "") {
                            node.status({fill:"red",shape:"dot",text:"error during scan"});
                            msg.payload = error.toString().trim().replace(/\[[^m]*m/g,'');
                            node.send(msg);
                        }
                        else {
                            let timeAfter = moment();
                            try {
                                let tmp = jsonfile;
                                jsonfile = fs.readFileSync(jsonfile).toString();
                                fs.unlinkSync(tmp);
                            }
                            catch (e) {
                                node.error(`[testssl][${scanID}][${index}] - ${e}`);
                            }
                            try {
                                let tmp = htmlfile;
                                htmlfile = fs.readFileSync(htmlfile).toString();
                                fs.unlinkSync(tmp);
                            }
                            catch (e) {
                                node.error(`[testssl][${scanID}][${index}] - ${e}`);
                            }
                            let payload = {
                                text: output,
                                html: htmlfile,
                                json: jsonfile,
                                timeout: timeout,
                                host: singleAddrToScan,
                                duration: timeAfter.diff(timeBefore, 'seconds'),
                                start: timeBefore.utc().format(),
                                end: timeAfter.utc().format()
                            }
                            msg.payload = payload;
                            node.status({});
                            node.send(msg);
                        }
                    });
                });
            });
        });
    }

    RED.nodes.registerType("testssl-node",TestSSLScan);

    const GetMyTarget = (tmpHost, cb) => {
        let IPsToScan    = [];
        if (validator.isIP(tmpHost, '4') === true)
        {
            IPsToScan.push(tmpHost);
            cb(IPsToScan);
        }
        else if (validator.isFQDN(tmpHost) === true)
        {
            dns.resolve(tmpHost, (err, addresses) => {
                if (err) {
                    cb("Error resolving host: " + err.message);
                    return;
                }
                for (var i=0; i < addresses.length; i++) {
                    IPsToScan.push(addresses[i]);
                }
                cb(IPsToScan);
            });
        }
        else
        {
            cb("this is not a valid host");
        }
    }
}
<commit_msg>fix mutliple scans for single domain<commit_after>module.exports = function(RED) {
    "use strict";
    const util = require('util');
    const fs = require('fs');
    const crypto = require('crypto');
    const moment = require('moment');
    const validator = require("validator");
    const dns = require('dns');
    const spawn = require('child_process').spawn;

    function TestSSLScan(n) {
        RED.nodes.createNode(this,n);
        let scantarget      = n.host;
        let opensslpath     = n.opensslpath || '/usr/bin/openssl';
        let cabundlespath   = n.cabundlespath || '/etc/ssl';

        let node = this;

        this.on("input",function(msg) {
            let host            = scantarget || msg.host;
            let openssl         = opensslpath || msg.opensslpath;
            let capath          = cabundlespath || msg.cabundlespath;
            let scanID          = msg._msgid;
            let env             = Object.create( process.env );

            // setting openssl path
            if (openssl != undefined && openssl != "") {
                node.log(`[testssl][${scanID}] - using openssl executable: ${openssl}`);
                openssl = '--openssl=' + openssl;
            }

            // setting ca-bundles path
            if (capath != undefined && capath != "") {
                node.log(`[testssl][${scanID}] - using ca bundles path: ${capath}`);
                env.CA_BUNDLES_PATH = capath;
            }

            // checking host and port data provided
            if (host === undefined || host === "") {
                node.status({fill:"red",shape:"dot",text:'address missing'});
                return;
            }
            let tmpHost = '';
            let tmpPort = 443;
            let tmp1 = host.match(/^[A-Za-z0-9\x2E\x2D]*$/);        // check for host only
            let tmp2 = host.match(/^([^\x3A]*)\x3A([0-9]{1,5})$/);  // check for host + port
            if (tmp1 instanceof Array && tmp1.length === 1)
            {
                tmpHost = tmp1[0];
            }
            else if (tmp2 instanceof Array && tmp2.length === 3)
            {
                tmpHost = tmp2[1];
                tmpPort = parseInt(tmp2[2]);
            }
            else
            {
                node.status({fill:"red",shape:"dot",text:"invalid data given"});
                msg.payload = "you provided invalid data";
                node.send(msg);
                return;
            }

            // checking port
            if (tmpPort < 1 || tmpPort > 65535)
            {
                node.status({fill:"red",shape:"dot",text:"not a valid port"});
                msg.payload = "this is not a valid port";
                node.send(msg);
                return;
            }

            GetMyTarget(tmpHost, function(IPsToScan){
                if (typeof IPsToScan === "string") {
                    node.status({fill:"red",shape:"dot",text:IPsToScan});
                    msg.payload = IPsToScan;
                    node.send(msg);
                    return;
                }

                node.status({fill:"green",shape:"dot",text:"scanning " + tmpHost + " on port " + tmpPort});
                msg.payload = "scanning... " + IPsToScan.join() + ' on port ' + tmpPort;
                node.send(msg);
                node.log(`[testssl][${scanID}] - scanning ${tmpHost} via ${IPsToScan.join()} on port ${tmpPort}`);

                let timeBefore = moment();

                IPsToScan.forEach((singleAddrToScan, index, arr) => {

                    let output = "";
                    let error = "";
                    let timeout = false;
                    let hash = crypto.createHash('sha256').update(`${scanID}${tmpHost}${tmpPort}${index}`).digest('hex');
                    let jsonfile = '/tmp/json' + hash;
                    let htmlfile = '/tmp/html' + hash;

                    let run = spawn('./testssl.sh',
                      [
                        openssl,
                        '--protocols',
                        '--server-defaults',
                        '--server-preference',
                        '--headers',
                        '--vulnerable',
                        '--cipher-per-proto',
                        '--pfs',
                        '--rc4',
                        '--nodns',
                        '--jsonfile',
                        jsonfile,
                        '--htmlfile',
                        htmlfile,
                        '--ip',
                        singleAddrToScan,
                        tmpHost + ':' + tmpPort
                      ],
                      {
                          cwd: __dirname,
                          env: env
                      }
                    );

                    // timeout for scan of 10 minutes
                    timeout = setTimeout(function(){
                        if (run != null) {
                            node.log(`[testssl][${scanID}][${index}] - timeout of scan`);
                            node.status({fill:"red",shape:"dot",text:"timeout during scan"});
                            timeout = true;
                            run.kill();
                            return;
                        }
                    }, 600000);

                    // interval to inform user of ongoing activity
                    let interval = setInterval(() => {
                        if (run != null) {
                            msg.payload = "scan is still running (" + moment().diff(timeBefore, 'seconds') + " seconds) for " + singleAddrToScan + ":" + tmpPort;
                            node.send(msg);
                        }
                    }, 60000);

                    run.stdout.on('data', (data) => {
                        output+=data.toString();
                    });

                    run.stderr.on('data', (data) => {
                        error+=data.toString();
                    });

                    run.on('close', () => {
                        node.log(`[testssl][${scanID}][${index}] - scan finished for ${singleAddrToScan}:${tmpPort}`);
                        run = null;
                        clearTimeout(timeout);
                        clearInterval(interval);
                        if (error != "") {
                            node.status({fill:"red",shape:"dot",text:"error during scan"});
                            msg.payload = error.toString().trim().replace(/\[[^m]*m/g,'');
                            node.send(msg);
                        }
                        else {
                            let timeAfter = moment();
                            try {
                                let tmp = jsonfile;
                                jsonfile = fs.readFileSync(jsonfile).toString();
                                fs.unlinkSync(tmp);
                            }
                            catch (e) {
                                node.error(`[testssl][${scanID}][${index}] - ${e}`);
                            }
                            try {
                                let tmp = htmlfile;
                                htmlfile = fs.readFileSync(htmlfile).toString();
                                fs.unlinkSync(tmp);
                            }
                            catch (e) {
                                node.error(`[testssl][${scanID}][${index}] - ${e}`);
                            }
                            let payload = {
                                text: output,
                                html: htmlfile,
                                json: jsonfile,
                                timeout: timeout,
                                host: singleAddrToScan,
                                duration: timeAfter.diff(timeBefore, 'seconds'),
                                start: timeBefore.utc().format(),
                                end: timeAfter.utc().format()
                            }
                            msg.payload = payload;
                            node.status({});
                            node.send(msg);
                        }
                    });
                });
            });
        });
    }

    RED.nodes.registerType("testssl-node",TestSSLScan);

    const GetMyTarget = (tmpHost, cb) => {
        let IPsToScan    = [];
        if (validator.isIP(tmpHost, '4') === true)
        {
            IPsToScan.push(tmpHost);
            cb(IPsToScan);
        }
        else if (validator.isFQDN(tmpHost) === true)
        {
            dns.resolve(tmpHost, (err, addresses) => {
                if (err) {
                    cb("Error resolving host: " + err.message);
                    return;
                }
                for (var i=0; i < addresses.length; i++) {
                    IPsToScan.push(addresses[i]);
                }
                cb(IPsToScan);
            });
        }
        else
        {
            cb("this is not a valid host");
        }
    }
}
<|endoftext|>