<commit_before>// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .

(function($) {
    /**
   * attaches a character counter to each textarea element in the jQuery object
   * usage: $("#myTextArea").charCounter(max, settings);
   */

  $.fn.charCounter = function (max, settings) {
    max = max || 100;
    settings = $.extend({
      container: "",
      classname: "charcounter",
      format: "(%1 characters remaining)",
      pulse: true,
      delay: 0
    }, settings);
    var p, timeout;

    function count(el, container) {
      el = $(el);
      if (el.val().length > max) {
          el.val(el.val().substring(0, max));
          if (settings.pulse && !p) {
            pulse(container, true);
          };
      };
      if (settings.delay > 0) {
        if (timeout) {
          window.clearTimeout(timeout);
        }
        timeout = window.setTimeout(function () {
          container.html(settings.format.replace(/%1/, (max - el.val().length)));
        }, settings.delay);
      } else {
        container.html(settings.format.replace(/%1/, (max - el.val().length)));
      }
    };

    function pulse(el, again) {
      if (p) {
        window.clearTimeout(p);
        p = null;
      };
      el.animate({ opacity: 0.1 }, 100, function () {
        $(this).animate({ opacity: 1.0 }, 100);
      });
      if (again) {
        p = window.setTimeout(function () { pulse(el) }, 200);
      };
    };

    return this.each(function () {
      var container;
      if (!settings.container.match(/^<.+>$/)) {
        // use existing element to hold counter message
        container = $(settings.container);
      } else {
        // append element to hold counter message (clean up old element first)
        $(this).next("." + settings.classname).remove();
        container = $(settings.container)
                .insertAfter(this)
                .addClass(settings.classname);
      }
      $(this)
        .unbind(".charCounter")
        .bind("keydown.charCounter", function () { count(this, container); })
        .bind("keypress.charCounter", function () { count(this, container); })
        .bind("keyup.charCounter", function () { count(this, container); })
        .bind("focus.charCounter", function () { count(this, container); })
        .bind("mouseover.charCounter", function () { count(this, container); })
        .bind("mouseout.charCounter", function () { count(this, container); })
        .bind("paste.charCounter", function () {
          var me = this;
          setTimeout(function () { count(me, container); }, 10);
        });
      if (this.addEventListener) {
        this.addEventListener('input', function () { count(this, container); }, false);
      };
      count(this, container);
    });
  };

})(jQuery);

$(document).ready(function () {

    $('#debt-form').validate({
      rules: {
        'debt[amount]': {
          number: true,
          min: 1,
          required: true
        },
        'debt[debtor_name]': {
          maxlength: 20,
          required: true
        },
        'debt[debtor_phone]': {
          required: true,
          maxlength: 17,
          minlength: 17
        },
        'debt[creditor_name]': {
          maxlength: 20,
          required: true
        },
        'debt[creditor_phone]': {
          required: true,
          maxlength: 17,
          minlength: 17
        },
        'debt[message]': {
          minlength: 4,
          maxlength: 160,
          required: true
        }
      },
      messages: {
        'debt[debtor_phone]': {
          minlength: "Please enter a valid phone number."
        },
        'debt[creditor_phone]': {
          minlength: "Please enter a valid phone number."
        }
      },
      highlight: function(element) {
        $(element).closest('.control-group').removeClass('success').addClass('error');
      },
      success: function(element) {
        $(element).closest('.control-group').removeClass('error');
        $(element).remove();
      }
    });

    $(function() {
      $("#message-box").charCounter(160,{container: "#counter"});
    });

    function update_message() {
      var amount = (!$("#amount").val()) ? "<amount>" : '$' + $.number( $("#amount").val(), 2 );
      var debtor_name = (!$("#debtor_name").val()) ? "<debtor>" : $("#debtor_name").val();
      var creditor_name = (!$("#creditor_name").val()) ? "<your_name>" : $("#creditor_name").val();

      var message_val = "Hey " + debtor_name + ", you still owe " + creditor_name + " " + amount + ". Just pay him back already! Otherwise, I’ll be badging you each day until you pay! Love, MoneyBadger"

      $("#message-box").val(message_val)
    };

  // $('#amount').number( true, 2 );

    $('#amount,#debtor_name,#creditor_name').on('input', function() {
      update_message();
    });

});

<commit_msg>Touch ups<commit_after>// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .

(function($) {
    /**
   * attaches a character counter to each textarea element in the jQuery object
   * usage: $("#myTextArea").charCounter(max, settings);
   */

  $.fn.charCounter = function (max, settings) {
    max = max || 100;
    settings = $.extend({
      container: "",
      classname: "charcounter",
      format: "(%1 characters remaining)",
      pulse: true,
      delay: 0
    }, settings);
    var p, timeout;

    function count(el, container) {
      el = $(el);
      if (el.val().length > max) {
          el.val(el.val().substring(0, max));
          if (settings.pulse && !p) {
            pulse(container, true);
          };
      };
      if (settings.delay > 0) {
        if (timeout) {
          window.clearTimeout(timeout);
        }
        timeout = window.setTimeout(function () {
          container.html(settings.format.replace(/%1/, (max - el.val().length)));
        }, settings.delay);
      } else {
        container.html(settings.format.replace(/%1/, (max - el.val().length)));
      }
    };

    function pulse(el, again) {
      if (p) {
        window.clearTimeout(p);
        p = null;
      };
      el.animate({ opacity: 0.1 }, 100, function () {
        $(this).animate({ opacity: 1.0 }, 100);
      });
      if (again) {
        p = window.setTimeout(function () { pulse(el) }, 200);
      };
    };

    return this.each(function () {
      var container;
      if (!settings.container.match(/^<.+>$/)) {
        // use existing element to hold counter message
        container = $(settings.container);
      } else {
        // append element to hold counter message (clean up old element first)
        $(this).next("." + settings.classname).remove();
        container = $(settings.container)
                .insertAfter(this)
                .addClass(settings.classname);
      }
      $(this)
        .unbind(".charCounter")
        .bind("keydown.charCounter", function () { count(this, container); })
        .bind("keypress.charCounter", function () { count(this, container); })
        .bind("keyup.charCounter", function () { count(this, container); })
        .bind("focus.charCounter", function () { count(this, container); })
        .bind("mouseover.charCounter", function () { count(this, container); })
        .bind("mouseout.charCounter", function () { count(this, container); })
        .bind("paste.charCounter", function () {
          var me = this;
          setTimeout(function () { count(me, container); }, 10);
        });
      if (this.addEventListener) {
        this.addEventListener('input', function () { count(this, container); }, false);
      };
      count(this, container);
    });
  };

})(jQuery);

$(document).ready(function () {

    $('#debt-form').validate({
      rules: {
        'debt[amount]': {
          number: true,
          min: 1,
          required: true
        },
        'debt[debtor_name]': {
          maxlength: 20,
          required: true
        },
        'debt[debtor_phone]': {
          required: true,
          maxlength: 17,
          minlength: 17
        },
        'debt[creditor_name]': {
          maxlength: 20,
          required: true
        },
        'debt[creditor_phone]': {
          required: true,
          maxlength: 17,
          minlength: 17
        },
        'debt[message]': {
          minlength: 4,
          maxlength: 160,
          required: true
        }
      },
      messages: {
        'debt[debtor_phone]': {
          minlength: "Please enter a valid phone number."
        },
        'debt[creditor_phone]': {
          minlength: "Please enter a valid phone number."
        }
      },
      highlight: function(element) {
        $(element).closest('.control-group').removeClass('success').addClass('error');
      },
      success: function(element) {
        $(element).closest('.control-group').removeClass('error');
        $(element).remove();
      }
    });

    $(function() {
      $("#message-box").charCounter(160,{container: "#counter"});
    });

    function update_message() {
      var amount = (!$("#amount").val()) ? "<amount>" : '$' + $.number( $("#amount").val(), 2 );
      var debtor_name = (!$("#debtor_name").val()) ? "<debtor>" : $("#debtor_name").val();
      var creditor_name = (!$("#creditor_name").val()) ? "<your_name>" : $("#creditor_name").val();

      var message_val = "Hey " + debtor_name + ", you still owe " + creditor_name + " " + amount + ". Just pay him back already! Otherwise, I’ll be badging you each day until you pay! Love, MoneyBadger"

      $("#message-box").val(message_val)
    };

  // $('#amount').number( true, 2 );

    $('#amount,#debtor_name,#creditor_name').on('input', function() {
      update_message();
    });

});

<|endoftext|>


<commit_before>PT = PT || {};

PT.downloadCsv = function(serverResponse){
  var survey = serverResponse.survey;
  var responses = serverResponse.responses;
  var a = document.createElement('a');
  var csvString = "";

  //Write title & prompts
  csvString += survey.title + "\n";
  csvString += '"Date of submission","Location of submission (lat, lon)",';
  survey.inputs.forEach(function(input){
    csvString += '"' + input.label.trim() + '",';
  })

  //Write responses
  responses.forEach(function(response){
    csvString += "\n" + '"' + new Date(response.timestamp) + '", '
      + '"' + response.locationstamp.lat + ", " + response.locationstamp.lon + '",';

    response.answers.forEach(function(answer){
      if(answer.value){
        if (typeof(answer.value) == "string" || typeof(answer.value) == "number"){
          csvString += '"' + answer.value + '"';
        } else if(answer.value.constructor == Array) {
          csvString += '"' + answer.value.join(",") + '"';
        } else if (typeof(answer.value) == "object") {
          csvString += '"' + answer.value.lat + ", " + answer.value.lon + '"';
        }
      } else {
        csvString += '""';
      }
      csvString += ",";
    })
  });

  var filename = "PT_Data_" + survey.code + ".csv";
  var blob = new Blob(["\uFEFF" + csvString], { encoding:"UTF-8", type: 'text/csv' });
  if (navigator.msSaveBlob) { // IE 10+
    navigator.msSaveBlob(blob, filename);
  } else {
    var link = document.createElement("a");
    if (link.download !== undefined) { // feature detection
      // Browsers that support HTML5 download attribute
      var url = URL.createObjectURL(blob);
      link.setAttribute("href", url);
      link.setAttribute("download", filename);
      link.style.visibility = 'hidden';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    }
  };
};<commit_msg>Remove line breaks from input labels in CSV download<commit_after>PT = PT || {};

PT.downloadCsv = function(serverResponse){
  var survey = serverResponse.survey;
  var responses = serverResponse.responses;
  var a = document.createElement('a');
  var csvString = "";

  //Write title & prompts
  csvString += survey.title + "\n";
  csvString += '"Date of submission","Location of submission (lat, lon)",';
  survey.inputs.forEach(function(input){
    csvString += '"' + input.label.replace(/(\r\n|\n|\r)/gm,"") + '",';
  })

  //Write responses
  responses.forEach(function(response){
    csvString += "\n" + '"' + new Date(response.timestamp) + '", '
      + '"' + response.locationstamp.lat + ", " + response.locationstamp.lon + '",';

    response.answers.forEach(function(answer){
      if(answer.value){
        if (typeof(answer.value) == "string" || typeof(answer.value) == "number"){
          csvString += '"' + answer.value + '"';
        } else if(answer.value.constructor == Array) {
          csvString += '"' + answer.value.join(",") + '"';
        } else if (typeof(answer.value) == "object") {
          csvString += '"' + answer.value.lat + ", " + answer.value.lon + '"';
        }
      } else {
        csvString += '""';
      }
      csvString += ",";
    })
  });

  var filename = "PT_Data_" + survey.code + ".csv";
  var blob = new Blob(["\uFEFF" + csvString], { encoding:"UTF-8", type: 'text/csv' });
  if (navigator.msSaveBlob) { // IE 10+
    navigator.msSaveBlob(blob, filename);
  } else {
    var link = document.createElement("a");
    if (link.download !== undefined) { // feature detection
      // Browsers that support HTML5 download attribute
      var url = URL.createObjectURL(blob);
      link.setAttribute("href", url);
      link.setAttribute("download", filename);
      link.style.visibility = 'hidden';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    }
  };
};<|endoftext|>


<commit_before>/*global jQuery, HDO, Handlebars */

(function ($, HDO, Handlebars) {
  HDO.issueEditor = {
    create: function (selector, url) {
      var instance = Object.create(this);
      instance.root = $(selector);
      instance.url = url;
      return instance;
    },

    init: function () {
      HDO.markdownEditor();

      this.saveButton            = this.root.find('button[name=save]');
      this.editorSelect          = this.root.find('select#issue_editor');
      this.categorySelect        = this.root.find('select#issue_categories');
      this.positionPartySelects  = this.root.find('select.position-parties');
      this.newPositionButton     = this.root.find('#new-position');
      this.newPartyCommentButton = this.root.find('#new-party-comment');
      this.tagList               = this.root.find('input[name=tags]');
      this.expandables           = this.root.find('[data-expands]');

      this.saveButton.click(this.save.bind(this));
      this.newPositionButton.click(this.notImplemented.bind(this));
      this.newPartyCommentButton.click(this.notImplemented.bind(this));
      this.expandables.click(this.toggleRow.bind(this));

      this.editorSelect.chosen();
      this.categorySelect.chosen();
      this.positionPartySelects.chosen();

      this.setupTagList();
      this.setupTemplates();
      this.setupCart();

      this.facetSearch({
        baseUrl:  '/promises',
        root:     this.root.find('#promise-search-tab'),
        spinner:  $("#promise-spinner"),
        template: this.templates['promise-search-template'],
        cart:     this.cart
      });

      this.facetSearch({
        baseUrl:  '/propositions',
        root:     this.root.find('#proposition-search-tab'),
        spinner:  $("#proposition-spinner"),
        template: this.templates['proposition-search-template'],
        cart:     this.cart
      });
    },

    save: function (e) {
      e.preventDefault();
      this.toggleSpin();

      // simulate xhr
      setTimeout(function () {
        this.toggleSpin();
      }.bind(this), 1000);
    },

    toggleSpin: function () {
      this.root.find('.accordion-group').toggle();
      $('#spinner').toggle();
    },

    data: function () {
      return this.root.parent('form').serializeArray();
    },

    setupTagList: function () {
      var el = this.tagList;
      el.tagsManager({
        prefilled: el.data('current-tags').split(","),
        preventSubmitOnEnter: true,
        typeahead: true,
        typeaheadSource: el.data('all-tags').split(","),
        hiddenTagListName: 'issue[tag_list]'
      });
    },

    setupTemplates: function () {
      var templates;
      this.templates = templates = {};

      $("script[type='text/x-handlebars-template']").each(function () {
        var el, name, partialName;

        el = $(this);
        name = el.attr('name');
        partialName = name.match(/^(\w+?)-partial$/);
        partialName = partialName && partialName[1];

        if (partialName) {
          Handlebars.registerPartial(partialName, el.html());
        } else {
          templates[name] = Handlebars.compile(el.html());
        }
      });
    },

    setupCart: function () {
      this.cart = this.createCart();
    },

    toggleRow: function (e) {
      var el = $(e.delegateTarget);
      el.find('.expandable, .expanded').toggleClass('expandable expanded');
      $(el.data('expands')).slideToggle();
    },

    notImplemented: function (e) {
      e.preventDefault();
      window.alert('ikke enda');
    },

    // facet search

    facetSearch: function (opts) {
      var baseUrl, root, template, spinner, query, cart;

      baseUrl  = opts.baseUrl;
      root     = opts.root;
      template = opts.template;
      spinner  = opts.spinner || $("#spinner");
      query    = opts.root.find('input[name=q]');
      cart     = opts.cart;

      function render(url) {
        spinner.toggleClass('hidden');

        $.ajax({
          url: url || baseUrl,
          dataType: 'json',
          success: function (data) { root.html(template(prepareData(data))); },
          error: function (xhr) { window.alert('Uffda, noe gikk helt galt ' + xhr.status); },
          complete: function () { spinner.toggleClass('hidden'); }
        });
      }

      function filterHandler(e) {
        e.preventDefault();
        render(e.target.href);
      }

      function queryHandler(e) {
        if (e.which === 13) {
          e.preventDefault();

          var target = $(this),
            url = decodeURI(target.data('url-template'));

          url = url.replace('{query}', encodeURIComponent(target.val()));
          render(url);
        }
      }

      function prepareData(data) {
        $.each(data.results, function (i, e) {
          e.selected = cart.isSelected(e.type, Number(e.id));
        });

        return data;
      }

      function toggleResult(e) {
        var el = $(this), type, id;

        type = el.data('type');
        id = el.data('id');

        el.toggleClass('selected');

        if (el.hasClass('selected')) {
          cart.add(type, id)
        } else {
          cart.remove(type, id)
        }
      }

      root.delegate('.navigators a, a[data-xhr]', 'click', filterHandler);
      root.delegate('input[name=q]', 'keypress', queryHandler);
      root.delegate('.search-result', 'click', toggleResult);

      render();
    },

    createCart: function () {
      var data, el, template;

      data = { promise: [], proposition: [] };
      el = $('.cart');
      template = this.templates['shopping-cart-template'];

      function isSelected(type, id) {
        return data[type].indexOf(id) != -1;
      }

      function add(type, id) {
        data[type].push(id);
        render();
      }

      function remove(type, id) {
        var idx = data[type].indexOf(id);
        if (idx > -1) {
          data[type].splice(idx, 1);
          render();
        }
      }

      function render() {
        el.html(template(data));
      }

      render();

      return {
        isSelected: isSelected,
        add: add,
        remove: remove
      };
    }

  };
}(jQuery, HDO, Handlebars));
<commit_msg>JS cleanup<commit_after>/*global jQuery, HDO, Handlebars */

(function ($, HDO, Handlebars) {
  HDO.issueEditor = {
    create: function (selector, url) {
      var instance = Object.create(this);
      instance.root = $(selector);
      instance.url = url;
      return instance;
    },

    init: function () {
      HDO.markdownEditor();

      this.saveButton            = this.root.find('button[name=save]');
      this.editorSelect          = this.root.find('select#issue_editor');
      this.categorySelect        = this.root.find('select#issue_categories');
      this.positionPartySelects  = this.root.find('select.position-parties');
      this.newPositionButton     = this.root.find('#new-position');
      this.newPartyCommentButton = this.root.find('#new-party-comment');
      this.tagList               = this.root.find('input[name=tags]');
      this.expandables           = this.root.find('[data-expands]');

      this.saveButton.click(this.save.bind(this));
      this.newPositionButton.click(this.notImplemented.bind(this));
      this.newPartyCommentButton.click(this.notImplemented.bind(this));
      this.expandables.click(this.toggleRow.bind(this));

      this.editorSelect.chosen();
      this.categorySelect.chosen();
      this.positionPartySelects.chosen();

      this.setupTagList();
      this.setupTemplates();
      this.setupCart();

      this.facetSearch({
        baseUrl:  '/promises',
        root:     this.root.find('#promise-search-tab'),
        spinner:  $("#promise-spinner"),
        template: this.templates['promise-search-template'],
        cart:     this.cart
      });

      this.facetSearch({
        baseUrl:  '/propositions',
        root:     this.root.find('#proposition-search-tab'),
        spinner:  $("#proposition-spinner"),
        template: this.templates['proposition-search-template'],
        cart:     this.cart
      });
    },

    save: function (e) {
      e.preventDefault();
      this.toggleSpin();

      // simulate xhr
      setTimeout(function () {
        this.toggleSpin();
      }.bind(this), 1000);
    },

    toggleSpin: function () {
      this.root.find('.accordion-group').toggle();
      $('#spinner').toggle();
    },

    data: function () {
      return this.root.parent('form').serializeArray();
    },

    setupTagList: function () {
      var el = this.tagList;
      el.tagsManager({
        prefilled: el.data('current-tags').split(","),
        preventSubmitOnEnter: true,
        typeahead: true,
        typeaheadSource: el.data('all-tags').split(","),
        hiddenTagListName: 'issue[tag_list]'
      });
    },

    setupTemplates: function () {
      var templates;
      this.templates = templates = {};

      $("script[type='text/x-handlebars-template']").each(function () {
        var el, name, partialName;

        el = $(this);
        name = el.attr('name');
        partialName = name.match(/^(\w+?)-partial$/);
        partialName = partialName && partialName[1];

        if (partialName) {
          Handlebars.registerPartial(partialName, el.html());
        } else {
          templates[name] = Handlebars.compile(el.html());
        }
      });
    },

    setupCart: function () {
      this.cart = this.createCart();
    },

    toggleRow: function (e) {
      var el = $(e.delegateTarget);
      el.find('.expandable, .expanded').toggleClass('expandable expanded');
      $(el.data('expands')).slideToggle();
    },

    notImplemented: function (e) {
      e.preventDefault();
      window.alert('ikke enda');
    },

    // facet search

    facetSearch: function (opts) {
      var baseUrl, root, template, spinner, query, cart;

      baseUrl  = opts.baseUrl;
      root     = opts.root;
      template = opts.template;
      spinner  = opts.spinner || $("#spinner");
      query    = opts.root.find('input[name=q]');
      cart     = opts.cart;

      function prepareData(data) {
        $.each(data.results, function (i, e) {
          e.selected = cart.isSelected(e.type, Number(e.id));
        });

        return data;
      }

      function render(url) {
        spinner.toggleClass('hidden');

        $.ajax({
          url: url || baseUrl,
          dataType: 'json',
          success: function (data) { root.html(template(prepareData(data))); },
          error: function (xhr) { window.alert('Uffda, noe gikk helt galt ' + xhr.status); },
          complete: function () { spinner.toggleClass('hidden'); }
        });
      }

      function filterHandler(e) {
        e.preventDefault();
        render(e.target.href);
      }

      function queryHandler(e) {
        if (e.which === 13) {
          e.preventDefault();

          var target = $(this),
            url = decodeURI(target.data('url-template'));

          url = url.replace('{query}', encodeURIComponent(target.val()));
          render(url);
        }
      }

      function toggleResult(e) {
        var el = $(this), type, id;

        type = el.data('type');
        id = el.data('id');

        el.toggleClass('selected');

        if (el.hasClass('selected')) {
          cart.add(type, id);
        } else {
          cart.remove(type, id);
        }
      }

      root.delegate('.navigators a, a[data-xhr]', 'click', filterHandler);
      root.delegate('input[name=q]', 'keypress', queryHandler);
      root.delegate('.search-result', 'click', toggleResult);

      render();
    },

    createCart: function () {
      var data, el, template;

      data = { promise: [], proposition: [] };
      el = $('.cart');
      template = this.templates['shopping-cart-template'];

      function render() {
        el.html(template(data));
      }

      function isSelected(type, id) {
        return data[type].indexOf(id) !== -1;
      }

      function add(type, id) {
        data[type].push(id);
        render();
      }

      function remove(type, id) {
        var idx = data[type].indexOf(id);
        if (idx > -1) {
          data[type].splice(idx, 1);
          render();
        }
      }

      render();

      return {
        isSelected: isSelected,
        add: add,
        remove: remove
      };
    }

  };
}(jQuery, HDO, Handlebars));
<|endoftext|>


<commit_before>var currentUrl = null;

$(document).ready(function () {
  initialize_menu();

  $("#navigation").resizable({handles: 'e, w', minWidth:199, maxWidth:500});

  $("#menu-toggle").click(function(){
    $('#content').toggleClass('extended-panel');
    $("#navigation").toggle();
  });

  // On resize of the left side panel, resize the grid
  $("#navigation").bind("resize", function(event, ui) {
    $("#content").css('left', $("#navigation").width()+1);
    $("#navigation").css('height', '100%');
  });

  History.Adapter.bind(window, 'statechange', function() {
    loadPageForHistoryState();
  });

  // Initial
  loadPageForHistoryState();
});

function loadPageForHistoryState() {
  var url = History.getState().url;
  if (url != currentUrl) {
    if (url === undefined) {
      $("#screen_content").empty();
      deselectMenuItems();
    } else {
      currentUrl = url;
      selectMenuItem(currentUrl);
      load_page(currentUrl);
    }
  }
}

function load_page(url) {
  $("#screen_content").empty();

  // Ekohe Add: Remove old columnpickers when screen changes
  $('.wulin-columnpicker').remove();

  // Ekohe Edit: Use screen_content_loader as new indicator

  // var indicators = $("#activity #indicators");
  // indicators.html(gridManager.buildIndicatorHtml("init_menu", "Loading page..."));
  // indicators.find("#init_menu").show();

  $('<div />').attr('id', 'screen_content_loader_container')
              .append($('<div />').attr('id', 'screen_content_loader'))
              .prependTo($('#content'));

  $.ajax({
    type: 'GET',
    dataType: 'html',
    url: url,
    success: function(html) {
      // Ekohe Edit: Use screen_content_loader defined in content view as new indicator
      // indicators.find("#init_menu_indicator").fadeOut();
      $('#screen_content_loader_container').remove();
      $("#screen_content").html(html);
      setTimeout(function() { trackGoogleAnalytics(); }, 250);
    },
    error: function() {
      // Ekohe Edit: Use screen_content_loader defined in content view as new indicator
      // indicators.find("#init_menu_indicator").fadeOut();
      $('#screen_content_loader_container').remove();
      // displayErrorMessage("An error occured while trying to load page. Please try again.");
    }
  });
}

function trackGoogleAnalytics() {
  if (typeof(ga)!='undefined') {
    ga('send', 'pageview', currentUrl);
  }
}

function deselectMenuItems() { $(".active").removeClass("active"); }

function selectMenuItem(url) {
  rootUrl = History.getRootUrl(),
  relativeUrl = url.replace(rootUrl,'/');
  deselectMenuItems();
  $currentLink = $('#menu li.item a[href="' + relativeUrl + '"]');
  $currentLink.parent().addClass('active');
}

function initialize_menu() {
  // Click to load screen page
  $("#menu li.item a").on('click', function() {
    currentUrl = $(this).attr('href');

    // If the item in the menu is an absolute URL, then go to the change password page.
    if (/^https?:\/\//i.test(currentUrl))
    {
      window.open(currentUrl);
      return;
    }

    // State management
    History.pushState(null, null, currentUrl);

    // Ekohe Delete
    // Since History.pushState triggers statechange event which calls load_page,
    // We do not need to load_page here.
    // load_page(currentUrl);

    return false;
  });

  // Click to open submenu
  $("#menu li.submenu a").click(function() {
    $(this).find(".indicator").toggleClass("closed");
    $(this).siblings("ul").toggle();
    return false;
  });

  // Click to go back to dashboard
  $("#navigation h1 a").click(function() {
    $("#menu .active").removeClass("active");
    // State management
    var state = {};
    currentUrl = "/";
    History.pushState(null, null, currentUrl);
    load_page(currentUrl);
    return false;
  });
}
<commit_msg>BUG - Delete old tooltips when loading page<commit_after>var currentUrl = null;

$(document).ready(function () {
  initialize_menu();

  $("#navigation").resizable({handles: 'e, w', minWidth:199, maxWidth:500});

  $("#menu-toggle").click(function(){
    $('#content').toggleClass('extended-panel');
    $("#navigation").toggle();
  });

  // On resize of the left side panel, resize the grid
  $("#navigation").bind("resize", function(event, ui) {
    $("#content").css('left', $("#navigation").width()+1);
    $("#navigation").css('height', '100%');
  });

  History.Adapter.bind(window, 'statechange', function() {
    loadPageForHistoryState();
  });

  // Initial
  loadPageForHistoryState();
});

function loadPageForHistoryState() {
  var url = History.getState().url;
  if (url != currentUrl) {
    if (url === undefined) {
      $("#screen_content").empty();
      deselectMenuItems();
    } else {
      currentUrl = url;
      selectMenuItem(currentUrl);
      load_page(currentUrl);
    }
  }
}

function load_page(url) {
  $("#screen_content").empty();

  // Ekohe Add: Remove old columnpickers, tooltips when screen changes
  $('.wulin-columnpicker').remove();
  $('.material-tooltip').remove();

  // Ekohe Edit: Use screen_content_loader as new indicator

  // var indicators = $("#activity #indicators");
  // indicators.html(gridManager.buildIndicatorHtml("init_menu", "Loading page..."));
  // indicators.find("#init_menu").show();

  $('<div />').attr('id', 'screen_content_loader_container')
              .append($('<div />').attr('id', 'screen_content_loader'))
              .prependTo($('#content'));

  $.ajax({
    type: 'GET',
    dataType: 'html',
    url: url,
    success: function(html) {
      // Ekohe Edit: Use screen_content_loader defined in content view as new indicator
      // indicators.find("#init_menu_indicator").fadeOut();
      $('#screen_content_loader_container').remove();
      $("#screen_content").html(html);
      setTimeout(function() { trackGoogleAnalytics(); }, 250);
    },
    error: function() {
      // Ekohe Edit: Use screen_content_loader defined in content view as new indicator
      // indicators.find("#init_menu_indicator").fadeOut();
      $('#screen_content_loader_container').remove();
      // displayErrorMessage("An error occured while trying to load page. Please try again.");
    }
  });
}

function trackGoogleAnalytics() {
  if (typeof(ga)!='undefined') {
    ga('send', 'pageview', currentUrl);
  }
}

function deselectMenuItems() { $(".active").removeClass("active"); }

function selectMenuItem(url) {
  rootUrl = History.getRootUrl(),
  relativeUrl = url.replace(rootUrl,'/');
  deselectMenuItems();
  $currentLink = $('#menu li.item a[href="' + relativeUrl + '"]');
  $currentLink.parent().addClass('active');
}

function initialize_menu() {
  // Click to load screen page
  $("#menu li.item a").on('click', function() {
    currentUrl = $(this).attr('href');

    // If the item in the menu is an absolute URL, then go to the change password page.
    if (/^https?:\/\//i.test(currentUrl))
    {
      window.open(currentUrl);
      return;
    }

    // State management
    History.pushState(null, null, currentUrl);

    // Ekohe Delete
    // Since History.pushState triggers statechange event which calls load_page,
    // We do not need to load_page here.
    // load_page(currentUrl);

    return false;
  });

  // Click to open submenu
  $("#menu li.submenu a").click(function() {
    $(this).find(".indicator").toggleClass("closed");
    $(this).siblings("ul").toggle();
    return false;
  });

  // Click to go back to dashboard
  $("#navigation h1 a").click(function() {
    $("#menu .active").removeClass("active");
    // State management
    var state = {};
    currentUrl = "/";
    History.pushState(null, null, currentUrl);
    load_page(currentUrl);
    return false;
  });
}
<|endoftext|>


<commit_before>// Generated by CoffeeScript 1.6.3
var ModalLogic, exports,
  __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

exports = exports != null ? exports : window;

exports.ModalLogic = ModalLogic = (function() {
  function ModalLogic() {
    this.showModal = __bind(this.showModal, this);
    this.createOrUpdateModalContent = __bind(this.createOrUpdateModalContent, this);
    var that;
    that = this;
    $('a[data-remote][modal],form[data-remote][modal]').live('ajax:complete', function(jq_event, xhr) {
      var response;
      response = JSON.parse(xhr.responseText);
      if (response != null) {
        if (response.close != null) {
          return window.location = response.redirect_location != null ? response.redirect_location : window.location;
        } else {
          return that.createOrUpdateModalContent(response);
        }
      } else {
        return that.createOrUpdateModalContent({
          title: 'Error',
          body: 'There was an error.  Please reload the page and try again'
        });
      }
    });
  }

  ModalLogic.prototype.createOrUpdateModalContent = function(context) {
    var $modal, html;
    html = HandlebarsTemplates['modal/crud']({
      modal: context
    });
    $modal = $('.modal.modal-logic');
    if ($modal.length > 0) {
      $modal.modal('hide').replaceWith(html);
    } else {
      $('body').append(html);
    }
    return this.showModal();
  };

  ModalLogic.prototype.showModal = function() {
    return $('.modal.modal-logic').modal('show');
  };

  return ModalLogic;

})();
<commit_msg>recompiled coffeescript<commit_after>// Generated by CoffeeScript 1.6.3
(function() {
  var ModalLogic, exports,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  exports = exports != null ? exports : window;

  exports.ModalLogic = ModalLogic = (function() {
    function ModalLogic() {
      this.showModal = __bind(this.showModal, this);
      this.createOrUpdateModalContent = __bind(this.createOrUpdateModalContent, this);
      var that;
      that = this;
      $('a[data-remote][modal],form[data-remote][modal]').live('ajax:complete', function(jq_event, xhr) {
        var response;
        response = JSON.parse(xhr.responseText);
        if (response != null) {
          if (response.close != null) {
            return window.location = response.redirect_location != null ? response.redirect_location : window.location;
          } else {
            return that.createOrUpdateModalContent(response);
          }
        } else {
          return that.createOrUpdateModalContent({
            title: 'Error',
            body: 'There was an error.  Please reload the page and try again'
          });
        }
      });
    }

    ModalLogic.prototype.createOrUpdateModalContent = function(context) {
      var $modal, html;
      html = HandlebarsTemplates['modal/crud']({
        modal: context
      });
      $modal = $('.modal.modal-logic');
      if ($modal.length > 0) {
        $modal.modal('hide').replaceWith(html);
      } else {
        $('body').append(html);
      }
      return this.showModal();
    };

    ModalLogic.prototype.showModal = function() {
      return $('.modal.modal-logic').modal('show');
    };

    return ModalLogic;

  })();

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


<commit_before>if("access_token" in window && isOGObject()){
  yam.connect.embedFeed({
    container: '#yammer-feed',
    feedType: 'open-graph',
    network: $('meta[name=network_id]').attr('content'),
    objectProperties: {
      url: $("[property='og:url']").attr('content'),
    type:  $("[property='og:type']").attr('content')
    }
  });
}
function isOGObject(){
  return $("[property='og:url']").length
}
<commit_msg>Remove blue bar at top of embedFeed<commit_after>if("access_token" in window && isOGObject()){
  yam.connect.embedFeed({
    container: '#yammer-feed',
    feedType: 'open-graph',
    config: {
      header: false
    },
    network: $('meta[name=network_id]').attr('content'),
    objectProperties: {
      url: $("[property='og:url']").attr('content'),
    type:  $("[property='og:type']").attr('content')
    }
  });
}
function isOGObject(){
  return $("[property='og:url']").length
}
<|endoftext|>


<commit_before>var EXPORTED_SYMBOLS = ['parse'];

Components.utils.import('resource://greasemonkey/extractMeta.js');
Components.utils.import('resource://greasemonkey/script.js');
Components.utils.import('resource://greasemonkey/scriptIcon.js');
Components.utils.import('resource://greasemonkey/scriptRequire.js');
Components.utils.import('resource://greasemonkey/scriptResource.js');
Components.utils.import('resource://greasemonkey/third-party/MatchPattern.js');
Components.utils.import('resource://greasemonkey/util.js');

var gIoService = Components.classes["@mozilla.org/network/io-service;1"]
    .getService(Components.interfaces.nsIIOService);
var gStringBundle = Components
    .classes["@mozilla.org/intl/stringbundle;1"]
    .getService(Components.interfaces.nsIStringBundleService)
    .createBundle("chrome://greasemonkey/locale/greasemonkey.properties");

/** Parse the source of a script; produce Script object. */
function parse(aSource, aUri, aFailWhenMissing, aNoMetaOk) {
  var meta = extractMeta(aSource).match(/.+/g);
  if (aFailWhenMissing && !meta && !aNoMetaOk) return null;

  var script = new Script();

  var name = null;
  if (aUri) script.downloadURL = aUri.spec;
  if (aUri && aUri.spec) {
    name = aUri.spec;
    name = name.substring(0, name.indexOf(".user.js"));
    name = name.substring(name.lastIndexOf("/") + 1);
    script._name = name;
  }
  if (aUri) script._namespace = aUri.host;

  if (!meta && aNoMetaOk) {
    setDefaults(script);
    return script;
  }

  var resourceNames = {};
  for (var i = 0, metaLine = ''; metaLine = meta[i]; i++) {
    try {
      var data = GM_util.parseMetaLine(metaLine.replace(/\s+$/, ''));
    } catch (e) {
      // Ignore invalid/unsupported meta lines.
      continue;
    }

    switch (data.keyword) {
    case 'noframes':
      script._noframes = true;
      break;

    case 'description':
    case 'name':
      var locale = data.locale;

      if (locale) {
        if (!script._locales[locale]) {
          script._locales[locale] = {};
        }
        script._locales[locale][data.keyword] = data.value;
      }
      else {
        if ((data.keyword == 'description')
            && (script['_' + data.keyword] == ''))
            script['_' + data.keyword] = data.value;
        if ((data.keyword == 'name')
            && ((script['_' + data.keyword] == 'user-script')
            || (script['_' + data.keyword] == name)))
            script['_' + data.keyword] = data.value;
      }

      break;

    case 'resource':
      var name = data.value1;
      var url = data.value2;

      if (name in resourceNames) {
        script.parseErrors.push(
            gStringBundle.GetStringFromName('parse.resource-duplicate')
                .replace('%1', resName));
        break;
      }
      resourceNames[name] = true;

      try {
        var resUri = GM_util.uriFromUrl(url, aUri);
        var scriptResource = new ScriptResource(script);
        scriptResource._name = name;
        scriptResource._downloadURL = resUri.spec;
        script._resources.push(scriptResource);
        script._rawMeta += data.keyword + '\0'
            + name + '\0'
            + resUri.spec + '\0';
      } catch (e) {
        script.parseErrors.push(
            gStringBundle.GetStringFromName('parse.resource-failed')
                .replace('%1', name).replace('%2', url)
            );
      }

      break;

    case 'namespace':
    case 'version':
      script['_' + data.keyword] = data.value;
      break;
    case 'exclude':
      script._excludes.push(data.value);
      break;
    case 'grant':
      script._grants.push(data.value);
      break;
    case 'include':
      script._includes.push(data.value);
      break;
    case 'run-at':
      script._runAt = data.value;
      break;

    case 'installURL':
      data.keyword = 'downloadURL';
    case 'downloadURL':
    case 'updateURL':
      try {
        var uri = GM_util.uriFromUrl(data.value, aUri);
        script[data.keyword] = uri.spec;
      } catch (e) {
        dump('Failed to parse ' + data.keyword
            + ' "' + data.value + '":\n' + e + '\n');
      }
      break;

    case 'icon':
      try {
        script.icon.setMetaVal(data.value);
        script._rawMeta += data.keyword + '\0' + data.value + '\0';
      } catch (e) {
        script.parseErrors.push(e.message);
      }
      break;

    case 'match':
      try {
        var match = new MatchPattern(data.value);
        script._matches.push(match);
      } catch (e) {
        script.parseErrors.push(
            gStringBundle.GetStringFromName('parse.ignoring-match')
                .replace('%1', data.value).replace('%2', e)
            );
      }
      break;

    case 'require':
      try {
        var reqUri = GM_util.uriFromUrl(data.value, aUri);
        var scriptRequire = new ScriptRequire(script);
        scriptRequire._downloadURL = reqUri.spec;
        script._requires.push(scriptRequire);
        script._rawMeta += data.keyword + '\0' + data.value + '\0';
      } catch (e) {
        dump('require err:'+e+'\n');
        script.parseErrors.push(
            gStringBundle.GetStringFromName('parse.require-failed')
                .replace('%1', data.value)
            );
      }
      break;
    }
  }

  setDefaults(script);
  return script;
}

function setDefaults(script) {
  if (!script.updateURL && script.downloadURL) {
    script.updateURL = script.downloadURL;
  }
  if ('document-start' != script._runAt && 'document-end' != script._runAt) {
    script._runAt = 'document-end';
  }
  if (script._includes.length == 0 && script._matches.length == 0) {
    script._includes.push('*');
  }
}
<commit_msg>Do not reference nonexistent `resName` var, reference `name` which exists.<commit_after>var EXPORTED_SYMBOLS = ['parse'];

Components.utils.import('resource://greasemonkey/extractMeta.js');
Components.utils.import('resource://greasemonkey/script.js');
Components.utils.import('resource://greasemonkey/scriptIcon.js');
Components.utils.import('resource://greasemonkey/scriptRequire.js');
Components.utils.import('resource://greasemonkey/scriptResource.js');
Components.utils.import('resource://greasemonkey/third-party/MatchPattern.js');
Components.utils.import('resource://greasemonkey/util.js');

var gIoService = Components.classes["@mozilla.org/network/io-service;1"]
    .getService(Components.interfaces.nsIIOService);
var gStringBundle = Components
    .classes["@mozilla.org/intl/stringbundle;1"]
    .getService(Components.interfaces.nsIStringBundleService)
    .createBundle("chrome://greasemonkey/locale/greasemonkey.properties");

/** Parse the source of a script; produce Script object. */
function parse(aSource, aUri, aFailWhenMissing, aNoMetaOk) {
  var meta = extractMeta(aSource).match(/.+/g);
  if (aFailWhenMissing && !meta && !aNoMetaOk) return null;

  var script = new Script();

  var name = null;
  if (aUri) script.downloadURL = aUri.spec;
  if (aUri && aUri.spec) {
    name = aUri.spec;
    name = name.substring(0, name.indexOf(".user.js"));
    name = name.substring(name.lastIndexOf("/") + 1);
    script._name = name;
  }
  if (aUri) script._namespace = aUri.host;

  if (!meta && aNoMetaOk) {
    setDefaults(script);
    return script;
  }

  var resourceNames = {};
  for (var i = 0, metaLine = ''; metaLine = meta[i]; i++) {
    try {
      var data = GM_util.parseMetaLine(metaLine.replace(/\s+$/, ''));
    } catch (e) {
      // Ignore invalid/unsupported meta lines.
      continue;
    }

    switch (data.keyword) {
    case 'noframes':
      script._noframes = true;
      break;

    case 'description':
    case 'name':
      var locale = data.locale;

      if (locale) {
        if (!script._locales[locale]) {
          script._locales[locale] = {};
        }
        script._locales[locale][data.keyword] = data.value;
      }
      else {
        if ((data.keyword == 'description')
            && (script['_' + data.keyword] == ''))
            script['_' + data.keyword] = data.value;
        if ((data.keyword == 'name')
            && ((script['_' + data.keyword] == 'user-script')
            || (script['_' + data.keyword] == name)))
            script['_' + data.keyword] = data.value;
      }

      break;

    case 'resource':
      var name = data.value1;
      var url = data.value2;

      if (name in resourceNames) {
        script.parseErrors.push(
            gStringBundle.GetStringFromName('parse.resource-duplicate')
                .replace('%1', name));
        break;
      }
      resourceNames[name] = true;

      try {
        var resUri = GM_util.uriFromUrl(url, aUri);
        var scriptResource = new ScriptResource(script);
        scriptResource._name = name;
        scriptResource._downloadURL = resUri.spec;
        script._resources.push(scriptResource);
        script._rawMeta += data.keyword + '\0'
            + name + '\0'
            + resUri.spec + '\0';
      } catch (e) {
        script.parseErrors.push(
            gStringBundle.GetStringFromName('parse.resource-failed')
                .replace('%1', name).replace('%2', url)
            );
      }

      break;

    case 'namespace':
    case 'version':
      script['_' + data.keyword] = data.value;
      break;
    case 'exclude':
      script._excludes.push(data.value);
      break;
    case 'grant':
      script._grants.push(data.value);
      break;
    case 'include':
      script._includes.push(data.value);
      break;
    case 'run-at':
      script._runAt = data.value;
      break;

    case 'installURL':
      data.keyword = 'downloadURL';
    case 'downloadURL':
    case 'updateURL':
      try {
        var uri = GM_util.uriFromUrl(data.value, aUri);
        script[data.keyword] = uri.spec;
      } catch (e) {
        dump('Failed to parse ' + data.keyword
            + ' "' + data.value + '":\n' + e + '\n');
      }
      break;

    case 'icon':
      try {
        script.icon.setMetaVal(data.value);
        script._rawMeta += data.keyword + '\0' + data.value + '\0';
      } catch (e) {
        script.parseErrors.push(e.message);
      }
      break;

    case 'match':
      try {
        var match = new MatchPattern(data.value);
        script._matches.push(match);
      } catch (e) {
        script.parseErrors.push(
            gStringBundle.GetStringFromName('parse.ignoring-match')
                .replace('%1', data.value).replace('%2', e)
            );
      }
      break;

    case 'require':
      try {
        var reqUri = GM_util.uriFromUrl(data.value, aUri);
        var scriptRequire = new ScriptRequire(script);
        scriptRequire._downloadURL = reqUri.spec;
        script._requires.push(scriptRequire);
        script._rawMeta += data.keyword + '\0' + data.value + '\0';
      } catch (e) {
        dump('require err:'+e+'\n');
        script.parseErrors.push(
            gStringBundle.GetStringFromName('parse.require-failed')
                .replace('%1', data.value)
            );
      }
      break;
    }
  }

  setDefaults(script);
  return script;
}

function setDefaults(script) {
  if (!script.updateURL && script.downloadURL) {
    script.updateURL = script.downloadURL;
  }
  if ('document-start' != script._runAt && 'document-end' != script._runAt) {
    script._runAt = 'document-end';
  }
  if (script._includes.length == 0 && script._matches.length == 0) {
    script._includes.push('*');
  }
}
<|endoftext|>


<commit_before>/**
 * Imports
 */

import ResetBoardButton from 'components/ResetBoardButton'
import GridBlock from 'components/GridOptions/GridBlock'
import DebugStats from 'components/DebugStats'
import PixelInspector from 'components/PixelInspector'
import {Block, Icon, Button, Toggle} from 'vdux-containers'
import TurnSelector from 'components/TurnSelector'
import ErrorTracker from 'components/ErrorTracker'
import ColorPicker from 'components/ColorPicker'
import PaintButton from 'components/PaintButton'
import RunWidget from 'components/RunWidget'
import OpacitySlider from './OpacitySlider'
import {component, element} from 'vdux'
import Canvas from 'components/Canvas'
import {throttle} from 'redux-timing'
import Grid from 'components/Grid'
import Tabs from 'components/Tabs'
import marked from 'marked'
import omit from '@f/omit'

/**
 * <Game Output/>
 */

export default component({
	initialState ({props}) {
		return {
			paintMode: false,
			paintColor: 'black',
			mode: props.type === 'project' ? 'paint' : '',
			inspectMode: false
		}
	},
	render ({props, state, actions, context}) {
		const {
			targetPainted,
			errorMessage,
			invalidCount,
			capabilities,
			userAnimal,
			prevAnimals,
			gameActions,
			permissions,
			frameNumber,
			correctness,
			description,
			animalMove,
			animalTurn,
			savedGame,
			levelSize,
			isProject,
			completed,
			readOnly,
			canPaint,
			isDraft,
			palette,
			animals,
			invalid,
			running,
			painted,
			frames,
			hasRun,
			active,
			paint,
			reset,
			steps,
			speed,
			size,
			type
		} = props

		const isRead = type === 'read'
		const spacer = type === 'project' ? 68 : 0
		const {opacity, paintMode, paintColor, mode, view = 'grid', inspectorData, inspectMode} = state
		const html = description ? marked(description) : ''
		const gridBlockActions = {...gameActions, ...actions}

		return (
			<Block mr='10px'>
				<Block relative pt='0' align='top' height='100%' mb>
					<Block column align='stretch center' border='1px solid divider' mr={12} bg='white' relative w={200}>
						<Block h={46} minHeight='46px' wide align='space-around center' px='20' borderBottom='1px solid divider'>
							<IconTab icon='grid_on' name='grid' setView={actions.setView} current={view} color='green'/>
							<IconTab icon='info' name='info' setView={actions.setView} current={view} color='blue'/>
							<IconTab icon='bug_report' name='debugStats' setView={actions.setView} current={view} color='red'/>
						</Block>
						<Block overflowY='auto' p sq='100%'>
							<Block hide={view !== 'grid'}>
								<Block pb='s' mt='-6' fs='xs'>GOAL:</Block>
								<Canvas
									id='mini-target'
									h={166}
									w={166}
									painted={targetPainted}
									numRows={levelSize[0]}
									numColumns={levelSize[1]} />
								<Toggle mt label='Show Layover' onChange={actions.toggleLayover} checked={!!opacity} />
								<PixelInspector
									mt
									inspectMode={inspectMode}
									data={inspectorData} />
							</Block>
							<Block
								hide={view !== 'info'}
								innerHTML={html}
								lh='1.4em'/>
							<DebugStats type={type} game={savedGame} hide={view !== 'debugStats'} />
						</Block>
					</Block>
					<Block >
						<Block relative zIndex='10'>
							<Block
								relative
								h={parseInt(size, 10) + spacer}
								w={size}
								>
								<GridBlock
									{...gridBlockActions}
									gridState={{mode, color: paintColor, painted: targetPainted}}
									id='target'
									animals={null}
									userAnimal={userAnimal}
									enableMove={false}
									enableSize={false}
									color={paintColor}
									mode={mode}
									painted={targetPainted}
									size='350px'
									palette={palette}
									capabilities={capabilities}
									isProject={type === 'project'}
									enableColorTips={!isRead}
									paintMode={paintMode}
									setCanvasContext={props.setCanvasContext}
									active={active}
									speed={speed}
									onClick={
										inspectMode
											? actions.inspectPixel
											: isRead && animalMove(active)
									}
									levelSize={levelSize}
									numRows={levelSize[0]}
									numColumns={levelSize[1]} />
							</Block>
							<Block
								absolute top left
								z={999}
								pointerEvents='none'
								mt={spacer}>
								<Canvas
									id='solution'
									mode='read'
									opacity={1 - opacity}
									name='solution'
									userAnimal={userAnimal}
									animals={animals}
									hasRun={hasRun}
									running={running}
									invalid={invalid}
									active={active}
									setCanvasContext={props.setCanvasContext}
									painted={painted}
									h={350}
									w={350}
									speed={speed}
									levelSize={size}
									numRows={levelSize[0]}
									numColumns={levelSize[1]} />
							</Block>
							{
								canPaint &&
									<Block align='center center' bgColor='white' border='1px solid divider' mt='0.5em' wide p>
										<ResetBoardButton
											{...btnProps('red')}
											onClick={props.reset}
											borderWidth='1'
											w={60}
											mr='s'
											/>
										<ColorPicker
											clickHandler={actions.setColor('')}
											animalType={animals[active].type}
											colors={palette}
											paintColor={paintColor}
											{...btnProps('green')}
											borderColor='rgba(black, .1)'
											borderRadius='3px 0 0 3px'
											borderWidth='0 1px 0 0'
											mr={0}
											w={60}
											swatchSize={30} />
										<PaintButton
											onClick={paint(active, paintColor)}
											{...btnProps('green')}
											borderRadius='0 3px 3px 0'
											flex />
										<TurnSelector
											clickHandler={actions.animalTurn(active)}
											animal={userAnimal}
											{...btnProps('#F6F6F6')}
											borderColor='#CCC'
											borderWidth='1'
											color='primary'
											w={60}
											ml='s'
											 />
									</Block>
							}
							{
								readOnly ||
									<RunWidget
										{...omit('painted', props)}
										steps={steps}
										running={running}
										teacherBotRunning={animals.some(a => {
											return a.type === 'teacherBot' && a.hidden === false
										})}
										isProject={isProject}
										completed={completed}
										hasRun={hasRun}
										hasCode={animals[active].sequence && animals[active].sequence.length > 0}
										canRun={!canPaint}
										speed={speed} />
							}
						</Block>
					</Block>
				</Block>
				<Block my relative minHeight={24} hide={!!readOnly}>
					<ErrorTracker invalid={invalidCount} errorMessage={errorMessage} />
				</Block>
			</Block>
		)
	},
	middleware: [
    throttle('inspectPixel', 100)
  ],
	controller: {
		* animalTurn ({props}, active, turn) {
			const nextTurn = -props.animals[active].current.rot + turn
			yield props.animalTurn(active, nextTurn)
		},
		* setPainted ({props, state}, grid, coordinates) {
			const {paintColor} = state

			yield props.gameActions.setPainted('targetPainted', coordinates, paintColor)
		},
		* erase ({props}, grid, coordinates) {
			yield props.gameActions.setPainted('targetPainted', coordinates, 'white')
		},
		* clearInspection ({props}) {
			const {targetCanvas, solutionCanvas} = props
			targetCanvas.clearSelection()
			solutionCanvas.clearSelection()
		},
		* initInspectMode ({props, state, actions}, inspect) {

			if (inspect) {
				yield actions.inspectPixel([0, 0])
			}

			yield actions.clearInspection()
			yield actions.setInspectorData(null)
			yield actions.setInspectMode(inspect)
		},
		* inspectPixel ({props, actions}, coordinates) {
			const {targetCanvas, solutionCanvas, painted, targetPainted, levelSize} = props
			targetCanvas.select(coordinates.slice().reverse())
			solutionCanvas.select(coordinates.slice().reverse())
			if (!!coordinates) {
				yield actions.setInspectorData({
					current: props.painted[coordinates] || 'white',
					target: props.targetPainted[coordinates] || 'white',
					coordinates: [coordinates[1], levelSize[0] - 1 - coordinates[0]]
				})
			}
		},
		* toggleLayover ({props, actions, state}) {
			const showLayover = !state.opacity
			yield actions.setOpacity( !showLayover ? 0 : 0.2)
			yield actions.initInspectMode(showLayover)
		}
	},
	reducer: {
		setOpacity: (state, opacity) => ({opacity}),
		setMode: (state, grid, mode) => ({mode}),
		setColor: (state, grid, paintColor) => ({paintColor}),
		setPaintMode: (state, grid, paintMode) => ({paintMode}),
		setView: (state, view) => ({view}),
		turn: (state, turn) => console.log('turn'),
		setSize: () => console.log('set size'),
		setInspectorData: (state, inspectorData) => ({inspectorData}),
		setInspectMode: (state, inspectMode) => ({inspectMode})
	}
})

function btnProps (color) {
	return {
		boxShadow: `0 4px rgba(black, .3), 0 4px rgba(${color}, 1)`,
		borderWidth: 0,
		color: 'white',
		bgColor: color,
		fs: 'xl',
		w: 100,
		h: 55,
		mb: 4
	}
}

function animalToInitial (animal) {
	return {
		...animal,
		current: animal.initial
	}
}

const IconTab = component({
	render({props, context}) {
		const {icon, name, setView, current, color = 'blue'} = props
		const active = name === current

		return (
			<Icon
				p='10'
				userSelect='none'
				color={active ? color : '#BBB'}
				onClick={setView(name)}
				name={icon}
				pointer
				fs='m' />
		)
	}
})<commit_msg>fixed error tracker<commit_after>/**
 * Imports
 */

import ResetBoardButton from 'components/ResetBoardButton'
import GridBlock from 'components/GridOptions/GridBlock'
import DebugStats from 'components/DebugStats'
import PixelInspector from 'components/PixelInspector'
import {Block, Icon, Button, Toggle} from 'vdux-containers'
import TurnSelector from 'components/TurnSelector'
import ErrorTracker from 'components/ErrorTracker'
import ColorPicker from 'components/ColorPicker'
import PaintButton from 'components/PaintButton'
import RunWidget from 'components/RunWidget'
import OpacitySlider from './OpacitySlider'
import {component, element} from 'vdux'
import Canvas from 'components/Canvas'
import {throttle} from 'redux-timing'
import Grid from 'components/Grid'
import Tabs from 'components/Tabs'
import marked from 'marked'
import omit from '@f/omit'

/**
 * <Game Output/>
 */

export default component({
	initialState ({props}) {
		return {
			paintMode: false,
			paintColor: 'black',
			mode: props.type === 'project' ? 'paint' : '',
			inspectMode: false
		}
	},
	render ({props, state, actions, context}) {
		const {
			targetPainted,
			errorMessage,
			invalidCount,
			capabilities,
			userAnimal,
			prevAnimals,
			gameActions,
			permissions,
			frameNumber,
			correctness,
			description,
			animalMove,
			animalTurn,
			savedGame,
			levelSize,
			isProject,
			completed,
			readOnly,
			canPaint,
			isDraft,
			palette,
			animals,
			invalid,
			running,
			painted,
			frames,
			hasRun,
			active,
			paint,
			reset,
			steps,
			speed,
			size,
			type
		} = props

		const isRead = type === 'read'
		const spacer = type === 'project' ? 68 : 0
		const {opacity, paintMode, paintColor, mode, view = 'grid', inspectorData, inspectMode} = state
		const html = description ? marked(description) : ''
		const gridBlockActions = {...gameActions, ...actions}

		return (
			<Block mr='10px'>
				<Block relative pt='0' align='top' height='100%' mb>
					<Block column align='stretch center' border='1px solid divider' mr={12} bg='white' relative w={200}>
						<Block h={46} minHeight='46px' wide align='space-around center' px='20' borderBottom='1px solid divider'>
							<IconTab icon='grid_on' name='grid' setView={actions.setView} current={view} color='green'/>
							<IconTab icon='info' name='info' setView={actions.setView} current={view} color='blue'/>
							<IconTab icon='bug_report' name='debugStats' setView={actions.setView} current={view} color='red'/>
						</Block>
						<Block overflowY='auto' p sq='100%'>
							<Block hide={view !== 'grid'}>
								<Block pb='s' mt='-6' fs='xs'>GOAL:</Block>
								<Canvas
									id='mini-target'
									h={166}
									w={166}
									painted={targetPainted}
									numRows={levelSize[0]}
									numColumns={levelSize[1]} />
								<Toggle mt label='Show Layover' onChange={actions.toggleLayover} checked={!!opacity} />
								<PixelInspector
									mt
									inspectMode={inspectMode}
									data={inspectorData} />
							</Block>
							<Block
								hide={view !== 'info'}
								innerHTML={html}
								lh='1.4em'/>
							<DebugStats type={type} game={savedGame} hide={view !== 'debugStats'} />
						</Block>
					</Block>
					<Block >
						<Block relative zIndex='10'>
							<Block
								relative
								h={parseInt(size, 10) + spacer}
								w={size}
								>
								<GridBlock
									{...gridBlockActions}
									gridState={{mode, color: paintColor, painted: targetPainted}}
									id='target'
									animals={null}
									userAnimal={userAnimal}
									enableMove={false}
									enableSize={false}
									color={paintColor}
									mode={mode}
									painted={targetPainted}
									size='350px'
									palette={palette}
									capabilities={capabilities}
									isProject={type === 'project'}
									enableColorTips={!isRead}
									paintMode={paintMode}
									setCanvasContext={props.setCanvasContext}
									active={active}
									speed={speed}
									onClick={
										inspectMode
											? actions.inspectPixel
											: isRead && animalMove(active)
									}
									levelSize={levelSize}
									numRows={levelSize[0]}
									numColumns={levelSize[1]} />
							</Block>
							<Block
								absolute top left
								z={999}
								pointerEvents='none'
								mt={spacer}>
								<Canvas
									id='solution'
									mode='read'
									opacity={1 - opacity}
									name='solution'
									userAnimal={userAnimal}
									animals={animals}
									hasRun={hasRun}
									running={running}
									invalid={invalid}
									active={active}
									setCanvasContext={props.setCanvasContext}
									painted={painted}
									h={350}
									w={350}
									speed={speed}
									levelSize={size}
									numRows={levelSize[0]}
									numColumns={levelSize[1]} />
							</Block>
							{
								canPaint &&
									<Block align='center center' bgColor='white' border='1px solid divider' mt='0.5em' wide p>
										<ResetBoardButton
											{...btnProps('red')}
											onClick={props.reset}
											borderWidth='1'
											w={60}
											mr='s'
											/>
										<ColorPicker
											clickHandler={actions.setColor('')}
											animalType={animals[active].type}
											colors={palette}
											paintColor={paintColor}
											{...btnProps('green')}
											borderColor='rgba(black, .1)'
											borderRadius='3px 0 0 3px'
											borderWidth='0 1px 0 0'
											mr={0}
											w={60}
											swatchSize={30} />
										<PaintButton
											onClick={paint(active, paintColor)}
											{...btnProps('green')}
											borderRadius='0 3px 3px 0'
											flex />
										<TurnSelector
											clickHandler={actions.animalTurn(active)}
											animal={userAnimal}
											{...btnProps('#F6F6F6')}
											borderColor='#CCC'
											borderWidth='1'
											color='primary'
											w={60}
											ml='s'
											 />
									</Block>
							}
							{
								readOnly ||
									<RunWidget
										{...omit('painted', props)}
										steps={steps}
										running={running}
										teacherBotRunning={animals.some(a => {
											return a.type === 'teacherBot' && a.hidden === false
										})}
										isProject={isProject}
										completed={completed}
										hasRun={hasRun}
										hasCode={animals[active].sequence && animals[active].sequence.length > 0}
										canRun={!canPaint}
										speed={speed} />
							}
						</Block>
					</Block>
				</Block>
				<Block my relative minHeight={24} hide={!readOnly}>
					<ErrorTracker invalid={invalidCount} errorMessage={errorMessage} />
				</Block>
			</Block>
		)
	},
	middleware: [
    throttle('inspectPixel', 100)
  ],
	controller: {
		* animalTurn ({props}, active, turn) {
			const nextTurn = -props.animals[active].current.rot + turn
			yield props.animalTurn(active, nextTurn)
		},
		* setPainted ({props, state}, grid, coordinates) {
			const {paintColor} = state

			yield props.gameActions.setPainted('targetPainted', coordinates, paintColor)
		},
		* erase ({props}, grid, coordinates) {
			yield props.gameActions.setPainted('targetPainted', coordinates, 'white')
		},
		* clearInspection ({props}) {
			const {targetCanvas, solutionCanvas} = props
			targetCanvas.clearSelection()
			solutionCanvas.clearSelection()
		},
		* initInspectMode ({props, state, actions}, inspect) {

			if (inspect) {
				yield actions.inspectPixel([0, 0])
			}

			yield actions.clearInspection()
			yield actions.setInspectorData(null)
			yield actions.setInspectMode(inspect)
		},
		* inspectPixel ({props, actions}, coordinates) {
			const {targetCanvas, solutionCanvas, painted, targetPainted, levelSize} = props
			targetCanvas.select(coordinates.slice().reverse())
			solutionCanvas.select(coordinates.slice().reverse())
			if (!!coordinates) {
				yield actions.setInspectorData({
					current: props.painted[coordinates] || 'white',
					target: props.targetPainted[coordinates] || 'white',
					coordinates: [coordinates[1], levelSize[0] - 1 - coordinates[0]]
				})
			}
		},
		* toggleLayover ({props, actions, state}) {
			const showLayover = !state.opacity
			yield actions.setOpacity( !showLayover ? 0 : 0.2)
			yield actions.initInspectMode(showLayover)
		}
	},
	reducer: {
		setOpacity: (state, opacity) => ({opacity}),
		setMode: (state, grid, mode) => ({mode}),
		setColor: (state, grid, paintColor) => ({paintColor}),
		setPaintMode: (state, grid, paintMode) => ({paintMode}),
		setView: (state, view) => ({view}),
		turn: (state, turn) => console.log('turn'),
		setSize: () => console.log('set size'),
		setInspectorData: (state, inspectorData) => ({inspectorData}),
		setInspectMode: (state, inspectMode) => ({inspectMode})
	}
})

function btnProps (color) {
	return {
		boxShadow: `0 4px rgba(black, .3), 0 4px rgba(${color}, 1)`,
		borderWidth: 0,
		color: 'white',
		bgColor: color,
		fs: 'xl',
		w: 100,
		h: 55,
		mb: 4
	}
}

function animalToInitial (animal) {
	return {
		...animal,
		current: animal.initial
	}
}

const IconTab = component({
	render({props, context}) {
		const {icon, name, setView, current, color = 'blue'} = props
		const active = name === current

		return (
			<Icon
				p='10'
				userSelect='none'
				color={active ? color : '#BBB'}
				onClick={setView(name)}
				name={icon}
				pointer
				fs='m' />
		)
	}
})<|endoftext|>


<commit_before>window.maxParticles = require('../config').snowFall.particles;

$(window).load(function () {
    //canvas init
    var canvas = document.getElementById("snowCanvas");
    var ctx = canvas.getContext("2d");

    //canvas dimensions
    var $doc = $(document);
    var W = $doc.width();
    var H = $doc.height();
    canvas.width = W;
    canvas.height = H;

    $(window).resize(function () {
        W = $doc.width();
        H = $doc.height();
        canvas.width = W;
        canvas.height = H;
    });

    //snowflake particles
    var mp = window.maxParticles; //max particles
    var particles = [];
    for (var i = 0; i < mp; i++) {
        particles.push({
            x: Math.random() * W, //x-coordinate
            y: Math.random() * H, //y-coordinate
            r: Math.random() * 4 + 1, //radius
            d: Math.random() * mp //density
        })
    }

    //Lets draw the flakes
    function draw() {
        ctx.clearRect(0, 0, W, H);

        ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
        ctx.beginPath();
        for (var i = 0; i < mp; i++) {
            var p = particles[i];
            ctx.moveTo(p.x, p.y);
            ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2, true);
        }
        ctx.fill();
        update();
    }

    //Function to move the snowflakes
    //angle will be an ongoing incremental flag. Sin and Cos functions will be applied to it to create vertical and horizontal movements of the flakes
    var angle = 0;

    function update() {
        angle += 0.01;
        for (var i = 0; i < mp; i++) {
            var p = particles[i];
            //Updating X and Y coordinates
            //We will add 1 to the cos function to prevent negative values which will lead flakes to move upwards
            //Every particle has its own density which can be used to make the downward movement different for each flake
            //Lets make it more random by adding in the radius
            p.y += Math.cos(angle + p.d) + 1 + p.r / 2;
            p.x += Math.sin(angle) * 2;

            //Sending flakes back from the top when it exits
            //Lets make it a bit more organic and let flakes enter from the left and right also.
            if (p.x > W + 5 || p.x < -5 || p.y > H) {
                if (i % 3 > 0) //66.67% of the flakes
                {
                    particles[i] = {x: Math.random() * W, y: -10, r: p.r, d: p.d};
                }
                else {
                    //If the flake is exitting from the right
                    if (Math.sin(angle) > 0) {
                        //Enter from the left
                        particles[i] = {x: -5, y: Math.random() * H, r: p.r, d: p.d};
                    }
                    else {
                        //Enter from the right
                        particles[i] = {x: W + 5, y: Math.random() * H, r: p.r, d: p.d};
                    }
                }
            }
        }
    }

    //animation loop
    setInterval(draw, 33);
});<commit_msg>.load --> .ready (former was deprecated with jquery3)<commit_after>window.maxParticles = require('../config').snowFall.particles;

$(window).ready(function () {
    //canvas init
    var canvas = document.getElementById("snowCanvas");
    var ctx = canvas.getContext("2d");

    //canvas dimensions
    var $doc = $(document);
    var W = $doc.width();
    var H = $doc.height();
    canvas.width = W;
    canvas.height = H;

    $(window).resize(function () {
        W = $doc.width();
        H = $doc.height();
        canvas.width = W;
        canvas.height = H;
    });

    //snowflake particles
    var mp = window.maxParticles; //max particles
    var particles = [];
    for (var i = 0; i < mp; i++) {
        particles.push({
            x: Math.random() * W, //x-coordinate
            y: Math.random() * H, //y-coordinate
            r: Math.random() * 4 + 1, //radius
            d: Math.random() * mp //density
        })
    }

    //Lets draw the flakes
    function draw() {
        ctx.clearRect(0, 0, W, H);

        ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
        ctx.beginPath();
        for (var i = 0; i < mp; i++) {
            var p = particles[i];
            ctx.moveTo(p.x, p.y);
            ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2, true);
        }
        ctx.fill();
        update();
    }

    //Function to move the snowflakes
    //angle will be an ongoing incremental flag. Sin and Cos functions will be applied to it to create vertical and horizontal movements of the flakes
    var angle = 0;

    function update() {
        angle += 0.01;
        for (var i = 0; i < mp; i++) {
            var p = particles[i];
            //Updating X and Y coordinates
            //We will add 1 to the cos function to prevent negative values which will lead flakes to move upwards
            //Every particle has its own density which can be used to make the downward movement different for each flake
            //Lets make it more random by adding in the radius
            p.y += Math.cos(angle + p.d) + 1 + p.r / 2;
            p.x += Math.sin(angle) * 2;

            //Sending flakes back from the top when it exits
            //Lets make it a bit more organic and let flakes enter from the left and right also.
            if (p.x > W + 5 || p.x < -5 || p.y > H) {
                if (i % 3 > 0) //66.67% of the flakes
                {
                    particles[i] = {x: Math.random() * W, y: -10, r: p.r, d: p.d};
                }
                else {
                    //If the flake is exitting from the right
                    if (Math.sin(angle) > 0) {
                        //Enter from the left
                        particles[i] = {x: -5, y: Math.random() * H, r: p.r, d: p.d};
                    }
                    else {
                        //Enter from the right
                        particles[i] = {x: W + 5, y: Math.random() * H, r: p.r, d: p.d};
                    }
                }
            }
        }
    }

    //animation loop
    setInterval(draw, 33);
});
<|endoftext|>


<commit_before>const emojiReplacer = (function(){

	const wrappers = {
		'parentheses': ['(', ')'],
		'squarebrackets': ['[', ']'],
		'colons': [':', ':'],
	}

	const settings = {};

	settings.showEmoji = true;
	settings.wrapper = 'parentheses';
	settings.wrapStart = '';
	settings.wrapEnd = '';
	settings.ignoreFlags = true;

	const pattern = buildPattern();
	const template = document.createElement('template');

	return {
		settings,
		set,
		pattern,
		translateTextNode: buildTranslatedNodes
	}

	function buildPattern() {
		const pattern = [];

		namesDictionary['ranges'].forEach(range => {
			if (typeof range === 'number') {
				const paddedCodePoint = toPaddedHex(range);
				pattern.push(wrapMatch(escapeUnicode(paddedCodePoint)));
			} else if (Array.isArray(range)) {
				const escapedRange = range.map(value => escapeUnicode(toPaddedHex(value)));
				pattern.push(wrapMatch(`[${escapedRange[0]}-${escapedRange[1]}]`))
			}
		});

		return new RegExp(pattern.join('|'), 'ug');
	}

	function replaceMatch(match) {
		const codePoint = match.codePointAt();
		const name = namesDictionary['names'][codePoint];
		let translation = '';
		if (settings.ignoreFlags && /[\u{1F1E6}-\u{1F1FF}]/u.test(match)) {
			return match;
		}
		if (settings.showEmoji) {
                        if (settings.nameInMouseover) {
                            translation += "";
                            translation += match;
                            translation += "";
                        } else {
                            translation += match;
                        }
		}
		if (settings.nameAfterEmoji) {
                    translation += nameWithDelimiter(name);
                }
		return translation;
	}

	function nameWithDelimiter(namegoeshere) {
                let result = '';
                if (settings.wrapper !== 'nothing') {
                        if (settings.wrapper === 'custom') {
                                result += [settings.wrapStart, settings.wrapEnd].join(namegoeshere);
                        } else {
                                result += wrappers[settings.wrapper].join(namegoeshere);
                        }
                } else {
                        result += namegoeshere;
                }
                return result;
        }

	// returns list of translated emojis and list of surrounding texts
	// if no emojis are found, returns false
	function getReplacedParts(original) {
		if (pattern.test(original)) {
			const splits = original.split(pattern);
			const translations = original.match(pattern).map(string => replaceMatch(string));
			return {splits, translations};
		}
		return false;
	}

	function buildTranslatedNodes(originalNode) {
		const originalText = originalNode.nodeValue;
		const parent = originalNode.parentElement;

		// do not replace script contents
		if (!parent || parent.tagName.toLowerCase() !== 'script') {

			// splice together translations and surrounding text
			const {splits, translations} = getReplacedParts(originalText);
			if (splits) {
				const parts = splits.map(string => document.createTextNode(string));
				parts.forEach((node, index) => {
					// insert nodes for non-matched/surrounding text from original
					parent.insertBefore(node, originalNode);

					// insert nodes for translated matches
					if (index < parts.length-1) {
						// use `innerHTML` to support formatted html code
						template.innerHTML = translations[index];
						parent.insertBefore(template.content, originalNode);
					}
				});
				// clear original text node
				originalNode.nodeValue = "";
			}

		}
	}

	function toPaddedHex(number) {
		return (`000000${number.toString(16)}`).slice(-6);
	}

	function wrapMatch(inside) {
		return `(?:${inside})`;
	}

	function escapeUnicode(codePoint) {
		return `\\u{${codePoint}}`;
	}

	function set(setting, value) {
		settings[setting] = value;
	}
}());<commit_msg>code cleanup<commit_after>const emojiReplacer = (function(){

	const wrappers = {
		'parentheses': ['(', ')'],
		'squarebrackets': ['[', ']'],
		'colons': [':', ':'],
	}

	const settings = {};

	settings.showEmoji = true;
	settings.wrapper = 'parentheses';
	settings.wrapStart = '';
	settings.wrapEnd = '';
	settings.ignoreFlags = true;

	const pattern = buildPattern();
	const template = document.createElement('template');

	return {
		settings,
		set,
		pattern,
		translateTextNode: buildTranslatedNodes
	}

	function buildPattern() {
		const pattern = [];

		namesDictionary['ranges'].forEach(range => {
			if (typeof range === 'number') {
				const paddedCodePoint = toPaddedHex(range);
				pattern.push(wrapMatch(escapeUnicode(paddedCodePoint)));
			} else if (Array.isArray(range)) {
				const escapedRange = range.map(value => escapeUnicode(toPaddedHex(value)));
				pattern.push(wrapMatch(`[${escapedRange[0]}-${escapedRange[1]}]`))
			}
		});

		return new RegExp(pattern.join('|'), 'ug');
	}

	function replaceMatch(match) {
		const codePoint = match.codePointAt();
		const name = namesDictionary['names'][codePoint];
		let translation = '';
		if (settings.ignoreFlags && /[\u{1F1E6}-\u{1F1FF}]/u.test(match)) {
			return match;
		}
		if (settings.showEmoji) {
			if (settings.nameInMouseover) {
				translation = `<span title="${nameWithDelimiter(name)}">${match}</span>`
			} else {
				translation = match;
			}
		}
		if (settings.nameAfterEmoji) {
			translation += nameWithDelimiter(name);
		}
		return translation;
	}

	function nameWithDelimiter(namegoeshere) {
		let result = '';
		if (settings.wrapper !== 'nothing') {
			if (settings.wrapper === 'custom') {
				result += [settings.wrapStart, settings.wrapEnd].join(namegoeshere);
			} else {
				result += wrappers[settings.wrapper].join(namegoeshere);
			}
		} else {
			result += namegoeshere;
		}
		return result;
	}

	// returns list of translated emojis and list of surrounding texts
	// if no emojis are found, returns false
	function getReplacedParts(original) {
		if (pattern.test(original)) {
			const splits = original.split(pattern);
			const translations = original.match(pattern).map(string => replaceMatch(string));
			return {splits, translations};
		}
		return false;
	}

	function buildTranslatedNodes(originalNode) {
		const originalText = originalNode.nodeValue;
		const parent = originalNode.parentElement;

		// do not replace script contents
		if (!parent || parent.tagName.toLowerCase() !== 'script') {

			// splice together translations and surrounding text
			const {splits, translations} = getReplacedParts(originalText);
			if (splits) {
				const parts = splits.map(string => document.createTextNode(string));
				parts.forEach((node, index) => {
					// insert nodes for non-matched/surrounding text from original
					parent.insertBefore(node, originalNode);

					// insert nodes for translated matches
					if (index < parts.length-1) {
						// use `innerHTML` to support formatted html code
						template.innerHTML = translations[index];
						parent.insertBefore(template.content, originalNode);
					}
				});
				// clear original text node
				originalNode.nodeValue = "";
			}

		}
	}

	function toPaddedHex(number) {
		return (`000000${number.toString(16)}`).slice(-6);
	}

	function wrapMatch(inside) {
		return `(?:${inside})`;
	}

	function escapeUnicode(codePoint) {
		return `\\u{${codePoint}}`;
	}

	function set(setting, value) {
		settings[setting] = value;
	}
}());<|endoftext|>


<commit_before>import Ember from 'ember';
const { assert } = Ember;

export default class HandlerConfig {

  constructor() {
    var args = [...arguments];
    assert("Expects 2 to 4 arguments: event, root (optional), selector (optional) and callback", args.length > 1 && args.length < 5);

    this.func = args.pop();
    assert("Last argument must be a callback function", typeof this.func === 'function');

    this.event = args.shift();
    assert("Event argument must be a string", typeof this.event === 'string');

    this.root = args.shift();
    if (['component', 'body', 'window'].includes(this.root)) {
      this.selector = args.pop();
    } else {
      this.selector = this.root;
      this.root = 'component';
    }
    assert("Element argument must be a string or undefined", ['string', 'undefined'].includes(typeof this.selector));

    this.auto = true;
  }

  setManual() {
    this.auto = false;
    return this;
  }
}
<commit_msg>don't require babel polyfill<commit_after>import Ember from 'ember';
const { assert } = Ember;

export default class HandlerConfig {

  constructor() {
    var args = [...arguments];
    assert("Expects 2 to 4 arguments: event, root (optional), selector (optional) and callback", args.length > 1 && args.length < 5);

    this.func = args.pop();
    assert("Last argument must be a callback function", typeof this.func === 'function');

    this.event = args.shift();
    assert("Event argument must be a string", typeof this.event === 'string');

    this.root = args.shift();
    if (Ember.A(['component', 'body', 'window']).contains(this.root)) {
      this.selector = args.pop();
    } else {
      this.selector = this.root;
      this.root = 'component';
    }
    assert("Element argument must be a string or undefined", Ember.A(['string', 'undefined']).contains(typeof this.selector));

    this.auto = true;
  }

  setManual() {
    this.auto = false;
    return this;
  }
}
<|endoftext|>


<commit_before>// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
// JavaScript Dynamic Content shim for Windows Store apps
(function () {

  if (window.MSApp && MSApp.execUnsafeLocalFunction) {

    // Some nodes will have an "attributes" property which shadows the Node.prototype.attributes property
    //  and means we don't actually see the attributes of the Node (interestingly the VS debug console
    //  appears to suffer from the same issue).
    //
    var Element_setAttribute = Object.getOwnPropertyDescriptor(Element.prototype, "setAttribute").value;
    var Element_removeAttribute = Object.getOwnPropertyDescriptor(Element.prototype, "removeAttribute").value;
    var HTMLElement_insertAdjacentHTMLPropertyDescriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "insertAdjacentHTML");
    var Node_get_attributes = Object.getOwnPropertyDescriptor(Node.prototype, "attributes").get;
    var Node_get_childNodes = Object.getOwnPropertyDescriptor(Node.prototype, "childNodes").get;
    var detectionDiv = document.createElement("div");

    function getAttributes(element) {
      return Node_get_attributes.call(element);
    }

    function setAttribute(element, attribute, value) {
      try {
        Element_setAttribute.call(element, attribute, value);
      } catch (e) {
        // ignore
      }
    }

    function removeAttribute(element, attribute) {
      Element_removeAttribute.call(element, attribute);
    }

    function childNodes(element) {
      return Node_get_childNodes.call(element);
    }

    function empty(element) {
      while (element.childNodes.length) {
        element.removeChild(element.lastChild);
      }
    }

    function insertAdjacentHTML(element, position, html) {
      HTMLElement_insertAdjacentHTMLPropertyDescriptor.value.call(element, position, html);
    }

    function inUnsafeMode() {
      var isUnsafe = true;
      try {
        detectionDiv.innerHTML = "<test/>";
      }
      catch (ex) {
        isUnsafe = false;
      }

      return isUnsafe;
    }

    function cleanse(html, targetElement) {
      var cleaner = document.implementation.createHTMLDocument("cleaner");
      empty(cleaner.documentElement);
      MSApp.execUnsafeLocalFunction(function () {
        insertAdjacentHTML(cleaner.documentElement, "afterbegin", html);
      });

      var scripts = cleaner.documentElement.querySelectorAll("script");
      Array.prototype.forEach.call(scripts, function (script) {
        switch (script.type.toLowerCase()) {
          case "":
            script.type = "text/inert";
            break;
          case "text/javascript":
          case "text/ecmascript":
          case "text/x-javascript":
          case "text/jscript":
          case "text/livescript":
          case "text/javascript1.1":
          case "text/javascript1.2":
          case "text/javascript1.3":
            script.type = "text/inert-" + script.type.slice("text/".length);
            break;
          case "application/javascript":
          case "application/ecmascript":
          case "application/x-javascript":
            script.type = "application/inert-" + script.type.slice("application/".length);
            break;

          default:
            break;
        }
      });

      function cleanseAttributes(element) {
        var attributes = getAttributes(element);
        if (attributes && attributes.length) {
          // because the attributes collection is live it is simpler to queue up the renames
          var events;
          for (var i = 0, len = attributes.length; i < len; i++) {
            var attribute = attributes[i];
            var name = attribute.name;
            if ((name[0] === "o" || name[0] === "O") &&
              (name[1] === "n" || name[1] === "N")) {
              events = events || [];
              events.push({ name: attribute.name, value: attribute.value });
            }
          }
          if (events) {
            for (var i = 0, len = events.length; i < len; i++) {
              var attribute = events[i];
              removeAttribute(element, attribute.name);
              setAttribute(element, "x-" + attribute.name, attribute.value);
            }
          }
        }
        var children = childNodes(element);
        for (var i = 0, len = children.length; i < len; i++) {
          cleanseAttributes(children[i]);
        }
      }
      cleanseAttributes(cleaner.documentElement);

      var cleanedNodes = [];

      if (targetElement.tagName === 'HTML') {
        cleanedNodes = Array.prototype.slice.call(document.adoptNode(cleaner.documentElement).childNodes);
      } else {
        if (cleaner.head) {
          cleanedNodes = cleanedNodes.concat(Array.prototype.slice.call(document.adoptNode(cleaner.head).childNodes));
        }
        if (cleaner.body) {
          cleanedNodes = cleanedNodes.concat(Array.prototype.slice.call(document.adoptNode(cleaner.body).childNodes));
        }
      }

      return cleanedNodes;
    }

    function cleansePropertySetter(property, setter) {
      var propertyDescriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, property);
      var originalSetter = propertyDescriptor.set;
      Object.defineProperty(HTMLElement.prototype, property, {
        get: propertyDescriptor.get,
        set: function (value) {
          if(window.WinJS && window.WinJS._execUnsafe && inUnsafeMode()) {
            originalSetter.call(this, value);
          } else {
            var that = this;
            var nodes = cleanse(value, that);
            MSApp.execUnsafeLocalFunction(function () {
              setter(propertyDescriptor, that, nodes);
            });
          }
        },
        enumerable: propertyDescriptor.enumerable,
        configurable: propertyDescriptor.configurable,
      });
    }
    cleansePropertySetter("innerHTML", function (propertyDescriptor, target, elements) {
      empty(target);
      for (var i = 0, len = elements.length; i < len; i++) {
        target.appendChild(elements[i]);
      }
    });
    cleansePropertySetter("outerHTML", function (propertyDescriptor, target, elements) {
      for (var i = 0, len = elements.length; i < len; i++) {
        target.insertAdjacentElement("afterend", elements[i]);
      }
      target.parentNode.removeChild(target);
    });

  }

}());
<commit_msg>update win js compat<commit_after>// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
// JavaScript Dynamic Content shim for Windows Store apps
(function () {

  if (window.MSApp && MSApp.execUnsafeLocalFunction) {

    // Some nodes will have an "attributes" property which shadows the Node.prototype.attributes property
    //  and means we don't actually see the attributes of the Node (interestingly the VS debug console
    //  appears to suffer from the same issue).
    //
    var Element_setAttribute = Object.getOwnPropertyDescriptor(Element.prototype, "setAttribute").value;
    var Element_removeAttribute = Object.getOwnPropertyDescriptor(Element.prototype, "removeAttribute").value;
    var HTMLElement_insertAdjacentHTMLPropertyDescriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "insertAdjacentHTML");
    var Node_get_attributes = Object.getOwnPropertyDescriptor(Node.prototype, "attributes").get;
    var Node_get_childNodes = Object.getOwnPropertyDescriptor(Node.prototype, "childNodes").get;

    function getAttributes(element) {
      return Node_get_attributes.call(element);
    }

    function setAttribute(element, attribute, value) {
      try {
        Element_setAttribute.call(element, attribute, value);
      } catch (e) {
        // ignore
      }
    }

    function removeAttribute(element, attribute) {
      Element_removeAttribute.call(element, attribute);
    }

    function childNodes(element) {
      return Node_get_childNodes.call(element);
    }

    function empty(element) {
      while (element.childNodes.length) {
        element.removeChild(element.lastChild);
      }
    }

    function insertAdjacentHTML(element, position, html) {
      HTMLElement_insertAdjacentHTMLPropertyDescriptor.value.call(element, position, html);
    }

    function cleanse(html) {
      var cleaner = document.implementation.createHTMLDocument("cleaner");
      empty(cleaner.documentElement);
      MSApp.execUnsafeLocalFunction(function () {
        insertAdjacentHTML(cleaner.documentElement, "afterbegin", html);
      });

      var scripts = cleaner.documentElement.querySelectorAll("script");
      Array.prototype.forEach.call(scripts, function (script) {
        switch (script.type.toLowerCase()) {
          case "":
            script.type = "text/inert";
            break;
          case "text/javascript":
          case "text/ecmascript":
          case "text/x-javascript":
          case "text/jscript":
          case "text/livescript":
          case "text/javascript1.1":
          case "text/javascript1.2":
          case "text/javascript1.3":
            script.type = "text/inert-" + script.type.slice("text/".length);
            break;
          case "application/javascript":
          case "application/ecmascript":
          case "application/x-javascript":
            script.type = "application/inert-" + script.type.slice("application/".length);
            break;

          default:
            break;
        }
      });

      function cleanseAttributes(element) {
        var attributes = getAttributes(element);
        if (attributes && attributes.length) {
          // because the attributes collection is live it is simpler to queue up the renames
          var events;
          for (var i = 0, len = attributes.length; i < len; i++) {
            var attribute = attributes[i];
            var name = attribute.name;
            if ((name[0] === "o" || name[0] === "O") &&
              (name[1] === "n" || name[1] === "N")) {
              events = events || [];
              events.push({ name: attribute.name, value: attribute.value });
            }
          }
          if (events) {
            for (var i = 0, len = events.length; i < len; i++) {
              var attribute = events[i];
              removeAttribute(element, attribute.name);
              setAttribute(element, "x-" + attribute.name, attribute.value);
            }
          }
        }
        var children = childNodes(element);
        for (var i = 0, len = children.length; i < len; i++) {
          cleanseAttributes(children[i]);
        }
      }
      cleanseAttributes(cleaner.documentElement);

      var docElement = cleaner.documentElement.childNodes[1];

      if (docElement == null) {
        docElement = cleaner.documentElement;
      }

      return Array.prototype.slice.call(document.adoptNode(docElement).childNodes);
    }

    function cleansePropertySetter(property, setter) {
      var propertyDescriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, property);
      Object.defineProperty(HTMLElement.prototype, property, {
        get: propertyDescriptor.get,
        set: function (value) {
          var that = this;
          var nodes = cleanse(value);
          MSApp.execUnsafeLocalFunction(function () {
            setter(propertyDescriptor, that, nodes);
          });
        },
        enumerable: propertyDescriptor.enumerable,
        configurable: propertyDescriptor.configurable,
      });
    }
    cleansePropertySetter("innerHTML", function (propertyDescriptor, target, elements) {
      empty(target);
      for (var i = 0, len = elements.length; i < len; i++) {
        target.appendChild(elements[i]);
      }
    });
    cleansePropertySetter("outerHTML", function (propertyDescriptor, target, elements) {
      for (var i = 0, len = elements.length; i < len; i++) {
        target.insertAdjacentElement("afterend", elements[i]);
      }
      target.parentNode.removeChild(target);
    });

  }

}());
<|endoftext|>