<commit_before>#!/usr/bin/env node

var assert = require('assert');
var paxos  = require('./paxos');

function ballot_test() {
  console.log(".. ballot_test");
  with (paxos) {
    var a = ballot_mk(1, 0, 0);
    assert(ballot_gte(a, ballot_mk(-1, -1, -1)));
    assert(ballot_gte(ballot_mk(1, 1, 1), a));
    assert(ballot_gte(ballot_mk(1, 1, 0), a));
    assert(ballot_gte(ballot_mk(1, 0, 1), a));
    assert(ballot_gte(ballot_mk(1, 0, 0), a));
    assert(!ballot_gte(ballot_mk(0, 0, 0), a));
    assert(!ballot_gte(ballot_mk(0, 0, 1), a));
    assert(!ballot_gte(ballot_mk(0, 1, 0), a));
    assert(!ballot_gte(ballot_mk(0, 1, 1), a));
    assert(ballot_gte(ballot_inc(a), a));
    assert(ballot_gte(a, a));
    assert(ballot_eq(a, a));
    assert(!ballot_eq(ballot_inc(a), a));
  }
  console.log("ok ballot_test");
}
ballot_test();

function majority_test() {
  console.log(".. majority_test");
  with (paxos) {
    assert(majority(4) == 3);
    assert(majority(3) == 2);
    assert(majority(2) == 2);
    assert(majority(1) == 1);
    assert(majority(0) == 1);
  }
  console.log("ok majority_test");
}
majority_test();

function is_member_test() {
  console.log(".. is_member_test");
  with (paxos) {
    assert(is_member([10], 10));
    assert(is_member([10,20], 10));
    assert(is_member([10,20], 20));
    assert(!is_member([10,20], 30));
    assert(!is_member([10], 30));
    assert(!is_member([], 30));
  }
  console.log("ok is_member_test");
}
is_member_test();

function create_test() {
  console.log(".. create_test");
  with (paxos) {
    assert(proposer('A', 1, 0, ['A'], null, null));
    try {
      proposer('A', 1, 0, [], null, null);
      assert(false);
    } catch (ex) { assert(ex); }
  }
  console.log("ok create_test");
}
create_test();

// ------------------------------------------------

function log(msg) { console.log("     " + msg); }

var to_s = JSON.stringify;
var blackboard = {};

function mock_comm(label) {
  label = label || "";
  if (label.length > 0) {
    label = label + " ";
  }
  blackboard.broadcasts = [];
  var comm = {
    "broadcast": function(acceptors, msg) {
      log(label + "received: " + acceptors + ", " + JSON.stringify(msg));
      blackboard.broadcasts[blackboard.broadcasts.length] = [acceptors, msg];
    }
  };
  return comm;
}

propose_phase_test();

function propose_phase_test() {
  console.log(".. propose_phase_test");
  log("propose_phase_test1...");
  var proposer = blackboard.proposer =
    paxos.proposer('A', 1, 0, ['B'], mock_comm(),
                   { proposer_timeout: 100 });
  proposer.propose(123, propose_phase_test1);
}

function propose_phase_test1(err, info) {
  assert(err == 'timeout');
  assert(blackboard.broadcasts.length == 1);
  assert(blackboard.broadcasts[0][0].length == 1);
  assert(blackboard.broadcasts[0][0][0] == 'B');
  assert(blackboard.broadcasts[0][1].kind == paxos.REQ_PROPOSE);
  assert(paxos.ballot_eq(blackboard.broadcasts[0][1].ballot,
                         paxos.ballot_mk(0, 'A', 1)));
  assert(blackboard.proposer.stats().tot_propose_phase == 1);

  log("propose_phase_test1... done");
  log("propose_phase_test2...");

  // Two propose() calls.
  blackboard.callback_count = 0;
  var proposer = blackboard.proposer =
    paxos.proposer('A', 1, 0, ['B'], mock_comm(),
                   { proposer_timeout: 100 });
  proposer.propose(123, propose_phase_test2);
  proposer.propose(234, propose_phase_test2);
}

function propose_phase_test2(err, info) {
  // Should be called twice.
  assert(err == 'timeout');
  blackboard.callback_count++;
  assert(blackboard.callback_count <= 2);
  if (blackboard.callback_count < 2) {
    return;
  }

  assert(blackboard.broadcasts.length == 2);
  assert(blackboard.broadcasts[0][0].length == 1);
  assert(blackboard.broadcasts[0][0][0] == 'B');
  assert(blackboard.broadcasts[0][1].kind == paxos.REQ_PROPOSE);
  assert(paxos.ballot_eq(blackboard.broadcasts[0][1].ballot,
                         paxos.ballot_mk(0, 'A', 1)));
  assert(blackboard.broadcasts[1][0].length == 1);
  assert(blackboard.broadcasts[1][0][0] == 'B');
  assert(blackboard.broadcasts[1][1].kind == paxos.REQ_PROPOSE);
  assert(paxos.ballot_eq(blackboard.broadcasts[1][1].ballot,
                         paxos.ballot_mk(1, 'A', 1)));
  assert(blackboard.proposer.stats().tot_propose_phase == 2);

  log("propose_phase_test2... done");

  propose_2_acceptors_test();
}

function propose_2_acceptors_test() {
  log("propose_2_acceptors_test...");

  blackboard.callback_count = 0;
  var proposer = blackboard.proposer =
    paxos.proposer('A', 1, 0, ['B', 'C'], mock_comm(),
                   { proposer_timeout: 100 });
  proposer.propose(123, propose_2_acceptors_test1);
}

function propose_2_acceptors_test1(err, info) {
  assert(err == 'timeout');
  assert(blackboard.broadcasts.length == 1);
  assert(blackboard.broadcasts[0][0].length == 2);
  assert(blackboard.broadcasts[0][0][0] == 'B');
  assert(blackboard.broadcasts[0][0][1] == 'C');
  assert(blackboard.broadcasts[0][1].kind == paxos.REQ_PROPOSE);
  assert(paxos.ballot_eq(blackboard.broadcasts[0][1].ballot,
                         paxos.ballot_mk(0, 'A', 1)));
  assert(blackboard.proposer.stats().tot_propose_phase == 1);
  assert(blackboard.proposer.stats().tot_propose_send == 2);

  log("propose_2_acceptors_test...done");

  console.log("ok propose_phase_test");

  paxos_1_1_test();
}

function paxos_1_1_test() {
  console.log(".. paxos_1_1_test");

  blackboard = {};
  blackboard.history = [];

  console.log("ok paxos_1_1_test");

  done();
}

function done() {
  console.log("DONE.");
}

<commit_msg>Test mock_comm records sends.<commit_after>#!/usr/bin/env node

var assert = require('assert');
var paxos  = require('./paxos');

function ballot_test() {
  console.log(".. ballot_test");
  with (paxos) {
    var a = ballot_mk(1, 0, 0);
    assert(ballot_gte(a, ballot_mk(-1, -1, -1)));
    assert(ballot_gte(ballot_mk(1, 1, 1), a));
    assert(ballot_gte(ballot_mk(1, 1, 0), a));
    assert(ballot_gte(ballot_mk(1, 0, 1), a));
    assert(ballot_gte(ballot_mk(1, 0, 0), a));
    assert(!ballot_gte(ballot_mk(0, 0, 0), a));
    assert(!ballot_gte(ballot_mk(0, 0, 1), a));
    assert(!ballot_gte(ballot_mk(0, 1, 0), a));
    assert(!ballot_gte(ballot_mk(0, 1, 1), a));
    assert(ballot_gte(ballot_inc(a), a));
    assert(ballot_gte(a, a));
    assert(ballot_eq(a, a));
    assert(!ballot_eq(ballot_inc(a), a));
  }
  console.log("ok ballot_test");
}
ballot_test();

function majority_test() {
  console.log(".. majority_test");
  with (paxos) {
    assert(majority(4) == 3);
    assert(majority(3) == 2);
    assert(majority(2) == 2);
    assert(majority(1) == 1);
    assert(majority(0) == 1);
  }
  console.log("ok majority_test");
}
majority_test();

function is_member_test() {
  console.log(".. is_member_test");
  with (paxos) {
    assert(is_member([10], 10));
    assert(is_member([10,20], 10));
    assert(is_member([10,20], 20));
    assert(!is_member([10,20], 30));
    assert(!is_member([10], 30));
    assert(!is_member([], 30));
  }
  console.log("ok is_member_test");
}
is_member_test();

function create_test() {
  console.log(".. create_test");
  with (paxos) {
    assert(proposer('A', 1, 0, ['A'], null, null));
    try {
      proposer('A', 1, 0, [], null, null);
      assert(false);
    } catch (ex) { assert(ex); }
  }
  console.log("ok create_test");
}
create_test();

// ------------------------------------------------

function log(msg) { console.log("     " + msg); }

var to_s = JSON.stringify;
var blackboard = {};

function mock_comm(label) {
  label = label || "";
  if (label.length > 0) {
    label = label + " ";
  }
  blackboard.broadcasts = [];
  blackboard.sends = [];
  var comm = {
    "broadcast": function(acceptors, msg) {
      log(label + "received: " + acceptors + ", " + JSON.stringify(msg));
      blackboard.broadcasts[blackboard.broadcasts.length] = [acceptors, msg];
      for (var i in acceptors) {
        comm.send(acceptors[i], msg);
      }
    },
    "send": function(dst, msg) {
      blackboard.sends[blackboard.sends.length] = [dst, msg];
    }
  };
  return comm;
}

propose_phase_test();

function propose_phase_test() {
  console.log(".. propose_phase_test");
  log("propose_phase_test1...");
  var proposer = blackboard.proposer =
    paxos.proposer('A', 1, 0, ['B'], mock_comm(),
                   { proposer_timeout: 100 });
  proposer.propose(123, propose_phase_test1);
}

function propose_phase_test1(err, info) {
  assert(err == 'timeout');
  assert(blackboard.broadcasts.length == 1);
  assert(blackboard.broadcasts[0][0].length == 1);
  assert(blackboard.broadcasts[0][0][0] == 'B');
  assert(blackboard.broadcasts[0][1].kind == paxos.REQ_PROPOSE);
  assert(paxos.ballot_eq(blackboard.broadcasts[0][1].ballot,
                         paxos.ballot_mk(0, 'A', 1)));
  assert(blackboard.proposer.stats().tot_propose_phase == 1);

  log("propose_phase_test1... done");
  log("propose_phase_test2...");

  // Two propose() calls.
  blackboard.callback_count = 0;
  var proposer = blackboard.proposer =
    paxos.proposer('A', 1, 0, ['B'], mock_comm(),
                   { proposer_timeout: 100 });
  proposer.propose(123, propose_phase_test2);
  proposer.propose(234, propose_phase_test2);
}

function propose_phase_test2(err, info) {
  // Should be called twice.
  assert(err == 'timeout');
  blackboard.callback_count++;
  assert(blackboard.callback_count <= 2);
  if (blackboard.callback_count < 2) {
    return;
  }

  assert(blackboard.broadcasts.length == 2);
  assert(blackboard.broadcasts[0][0].length == 1);
  assert(blackboard.broadcasts[0][0][0] == 'B');
  assert(blackboard.broadcasts[0][1].kind == paxos.REQ_PROPOSE);
  assert(paxos.ballot_eq(blackboard.broadcasts[0][1].ballot,
                         paxos.ballot_mk(0, 'A', 1)));
  assert(blackboard.broadcasts[1][0].length == 1);
  assert(blackboard.broadcasts[1][0][0] == 'B');
  assert(blackboard.broadcasts[1][1].kind == paxos.REQ_PROPOSE);
  assert(paxos.ballot_eq(blackboard.broadcasts[1][1].ballot,
                         paxos.ballot_mk(1, 'A', 1)));
  assert(blackboard.proposer.stats().tot_propose_phase == 2);

  log("propose_phase_test2... done");

  propose_2_acceptors_test();
}

function propose_2_acceptors_test() {
  log("propose_2_acceptors_test...");

  blackboard.callback_count = 0;
  var proposer = blackboard.proposer =
    paxos.proposer('A', 1, 0, ['B', 'C'], mock_comm(),
                   { proposer_timeout: 100 });
  proposer.propose(123, propose_2_acceptors_test1);
}

function propose_2_acceptors_test1(err, info) {
  assert(err == 'timeout');
  assert(blackboard.broadcasts.length == 1);
  assert(blackboard.broadcasts[0][0].length == 2);
  assert(blackboard.broadcasts[0][0][0] == 'B');
  assert(blackboard.broadcasts[0][0][1] == 'C');
  assert(blackboard.broadcasts[0][1].kind == paxos.REQ_PROPOSE);
  assert(paxos.ballot_eq(blackboard.broadcasts[0][1].ballot,
                         paxos.ballot_mk(0, 'A', 1)));
  assert(blackboard.proposer.stats().tot_propose_phase == 1);
  assert(blackboard.proposer.stats().tot_propose_send == 2);

  log("propose_2_acceptors_test...done");

  console.log("ok propose_phase_test");

  paxos_1_1_test();
}

function paxos_1_1_test() {
  console.log(".. paxos_1_1_test");

  blackboard = {};

  console.log("ok paxos_1_1_test");

  done();
}

function done() {
  console.log("DONE.");
}

<|endoftext|>


<commit_before>!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("React")):"function"==typeof define&&define.amd?define("react-jsx-parser",["React"],t):"object"==typeof exports?exports["react-jsx-parser"]=t(require("React")):e["react-jsx-parser"]=t(e.React)}(this,function(e){return function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var r={};return t.m=e,t.c=r,t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=1)}([function(e,t,r){"use strict";function n(e){return e.replace(/([A-Z])([A-Z])/g,"$1 $2").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/[^a-zA-Z\u00C0-\u00ff]/g," ").toLowerCase().split(" ").filter(function(e){return e}).map(function(e,t){return t>0?e[0].toUpperCase()+e.slice(1):e}).join("")}Object.defineProperty(t,"__esModule",{value:!0}),t.default=n},function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},c=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),f=r(2),l=n(f),p=r(0),d=n(p),y=r(3),m=n(y),h=r(4),b=n(h),v=r(5),g=n(v),O=r(6),E=n(O),T=r(7),_=new DOMParser,x=function(e){var t=Array.from(e.documentElement.childNodes);console.warn("Unable to parse jsx. Found "+t.length+" error(s):");var r=function e(t,r){t.childNodes.length&&Array.from(t.childNodes).forEach(function(t){return e(t,r.concat(" "))}),console.warn(r+"==> "+t.nodeValue)};t.forEach(function(e){return r(e," ")})},w=function(e){function t(e){a(this,t);var r=i(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return r.parseJSX.bind(r),r.parseNode.bind(r),r.ParsedChildren=r.parseJSX(e.jsx||""),r}return u(t,e),c(t,[{key:"componentWillReceiveProps",value:function(e){this.ParsedChildren=this.parseJSX(e.jsx||"")}},{key:"parseJSX",value:function(e){if(!e||"string"!=typeof e)return[];var t=this.props.blacklistedTags.reduce(function(e,t){return e.replace(new RegExp("(</?)"+t,"ig"),"$1REMOVE")},e).trim(),r=(0,b.default)(t)?t:"<!DOCTYPE html>\n"+t+"",n=_.parseFromString(r,"application/xhtml+xml");if(!n)return[];Array.from(n.getElementsByTagName("REMOVE")).forEach(function(e){return e.parentNode.removeChild(e)});var a=n.getElementsByTagName("body")[0];if(!a||"parseerror"===a.nodeName.toLowerCase())return this.props.showWarnings&&x(n),[];var i=this.props.components.reduce(function(e,t){return s({},e,o({},t.prototype.constructor.name,t))},{});return this.parseNode(a.childNodes||[],i)}},{key:"parseNode",value:function(e){var t=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments[2];if(e instanceof NodeList||Array.isArray(e))return Array.from(e).map(function(e,n){return t.parseNode(e,r,n)}).filter(function(e){return e});if(e.nodeType===E.default.TEXT)return("textContent"in e?e.textContent:e.nodeValue||"").replace(/[\r\n\t\f\v]/g,"").replace(/\s{2,}/g," ");if(e.nodeType===E.default.ELEMENT){var o=void 0;return(0,T.canHaveChildren)(e.nodeName)&&(o=this.parseNode(e.childNodes,r),(0,T.canHaveWhitespace)(e.nodeName)||(o=o.filter(function(e){return"string"!=typeof e||!e.match(/^\s*$/)}))),l.default.createElement(r[e.nodeName]||e.nodeName,s({},this.props.bindings||{},this.parseAttrs(e.attributes,n)),o)}return this.props.showWarnings&&console.warn("JsxParser encountered a(n) "+E.default[e.nodeType]+" node, and discarded it."),null}},{key:"parseAttrs",value:function(e,t){if(!e||!e.length)return{key:t};var r=this.props.blacklistedAttrs;return Array.from(e).filter(function(e){return!r.map(function(t){return e.name.match(new RegExp(t,"gi"))}).filter(function(e){return null!==e}).length}).reduce(function(e,t){var r=t.name,n=t.value;return""===n&&(n=!0),r.match(/^on/i)?n=new Function(n):"style"===r&&(n=(0,m.default)(n)),r=g.default[r.toLowerCase()]||(0,d.default)(r),s({},e,o({},r,n))},{key:t})}},{key:"render",value:function(){return l.default.createElement("div",{className:"jsx-parser"},this.ParsedChildren)}}]),t}(f.Component);t.default=w;var N=r(8);w.propTypes={bindings:N.object.isRequired,blacklistedAttrs:N.arrayOf(N.string),blacklistedTags:N.arrayOf(N.string),components:function(e,t){if(!Array.isArray(e[t]))return new Error(t+" must be an Array of Components.");var r=!0;return e[t].forEach(function(e){e.prototype instanceof l.default.Component||e.prototype instanceof l.default.PureComponent||"function"==typeof e||(r=!1)}),r?null:new Error(t+" must contain only React.Component|PureComponent or functions.")},jsx:N.string,showWarnings:N.bool},w.defaultProps={bindings:{},blacklistedAttrs:["on[a-z]*"],blacklistedTags:["script"],components:[],jsx:"",showWarnings:!1}},function(t,r){t.exports=e},function(e,t,r){"use strict";function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e){switch(void 0===e?"undefined":i(e)){case"string":return e.split(";").filter(function(e){return e}).reduce(function(e,t){var r=t.slice(0,t.indexOf(":")).trim(),o=t.slice(t.indexOf(":")+1).trim();return a({},e,n({},(0,s.default)(r),o))},{});case"object":return e;default:return}}Object.defineProperty(t,"__esModule",{value:!0});var a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};t.default=o;var u=r(0),s=function(e){return e&&e.__esModule?e:{default:e}}(u)},function(e,t,r){"use strict";function n(e){return/<(\/?|!?)DOCTYPE html>/.test(e)&&/<(\/?|!?)html>/.test(e)&&/<(\/?|!?)head>/.test(e)&&/<(\/?|!?)body>/.test(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=n},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={class:"className",for:"htmlFor",maxlength:"maxLength",colspan:"colSpan",rowspan:"rowSpan"}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={ELEMENT:1,TEXT:3,PROCESSING_INSTRUCTION:7,COMMENT:8,DOCUMENT:9,DOCUMENT_TYPE:10,DOCUMENT_FRAGMENT:11,1:"Element",3:"Text",7:"Processing Instruction",8:"Comment",9:"Document",10:"Document Type",11:"Document Fragment",ATTRIBUTE:2,CDATA:4,XML_ENTITY_REFERENCE:5,XML_ENTITY:6,XML_NOTATION:12,2:"Attribute (Deprecated)",4:"CData (Deprecated)",5:"XML Entity Reference (Deprecated)",6:"XML Entity (Deprecated)",12:"XML Notation (Deprecated)"}},function(e,t,r){"use strict";function n(e){return-1===a.indexOf(e.toLowerCase())}function o(e){return-1!==i.indexOf(e.toLowerCase())}Object.defineProperty(t,"__esModule",{value:!0}),t.canHaveChildren=n,t.canHaveWhitespace=o;var a=["area","base","br","col","embed","hr","img","input","keygen","link","menuitem","meta","param","source","track","wbr"],i=["table","tbody","tfoot","thead","tr"];t.default=a},function(e,t,r){e.exports=r(9)()},function(e,t,r){"use strict";var n=r(10),o=r(11),a=r(12);e.exports=function(){function e(e,t,r,n,i,u){u!==a&&o(!1,"Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types")}function t(){return e}e.isRequired=e;var r={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t};return r.checkPropTypes=n,r.PropTypes=r,r}},function(e,t,r){"use strict";function n(e){return function(){return e}}var o=function(){};o.thatReturns=n,o.thatReturnsFalse=n(!1),o.thatReturnsTrue=n(!0),o.thatReturnsNull=n(null),o.thatReturnsThis=function(){return this},o.thatReturnsArgument=function(e){return e},e.exports=o},function(e,t,r){"use strict";function n(e,t,r,n,a,i,u,s){if(o(t),!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var f=[r,n,a,i,u,s],l=0;c=new Error(t.replace(/%s/g,function(){return f[l++]})),c.name="Invariant Violation"}throw c.framesToPop=1,c}}var o=function(e){};e.exports=n},function(e,t,r){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"}])});<commit_msg>Updating output package, now down to 9.05kb<commit_after>!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define("react-jsx-parser",["react"],t):"object"==typeof exports?exports["react-jsx-parser"]=t(require("react")):e["react-jsx-parser"]=t(e.react)}(this,function(e){return function(e){function t(n){if(r[n])return r[n].exports
var o=r[n]={i:n,l:!1,exports:{}}
return e[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var r={}
return t.m=e,t.c=r,t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e}
return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=1)}([function(e,t,r){"use strict"
function n(e){return e.replace(/([A-Z])([A-Z])/g,"$1 $2").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/[^a-zA-Z\u00C0-\u00ff]/g," ").toLowerCase().split(" ").filter(function(e){return e}).map(function(e,t){return t>0?e[0].toUpperCase()+e.slice(1):e}).join("")}Object.defineProperty(t,"__esModule",{value:!0}),t.default=n},function(e,t,r){"use strict"
function n(e){return e&&e.__esModule?e:{default:e}}function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called")
return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t)
e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0})
var c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t]
for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},s=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r]
n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),f=r(2),l=n(f),p=r(0),d=n(p),y=r(3),m=n(y),h=r(4),b=n(h),v=r(5),g=n(v),O=r(6),E=n(O),T=r(7),_=new DOMParser,x=function(e){var t=Array.from(e.documentElement.childNodes)
console.warn("Unable to parse jsx. Found "+t.length+" error(s):")
var r=function e(t,r){t.childNodes.length&&Array.from(t.childNodes).forEach(function(t){return e(t,r.concat(" "))}),console.warn(r+"==> "+t.nodeValue)}
t.forEach(function(e){return r(e," ")})},N=function(e){function t(e){a(this,t)
var r=i(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e))
return r.parseJSX.bind(r),r.parseNode.bind(r),r.ParsedChildren=r.parseJSX(e.jsx||""),r}return u(t,e),s(t,[{key:"componentWillReceiveProps",value:function(e){this.ParsedChildren=this.parseJSX(e.jsx||"")}},{key:"parseJSX",value:function(e){if(!e||"string"!=typeof e)return[]
var t=this.props.blacklistedTags.reduce(function(e,t){return e.replace(new RegExp("(</?)"+t,"ig"),"$1REMOVE")},e).trim(),r=(0,b.default)(t)?t:"<!DOCTYPE html>\n"+t+"",n=_.parseFromString(r,"application/xhtml+xml")
if(!n)return[]
Array.from(n.getElementsByTagName("REMOVE")).forEach(function(e){return e.parentNode.removeChild(e)})
var a=n.getElementsByTagName("body")[0]
if(!a||"parseerror"===a.nodeName.toLowerCase())return this.props.showWarnings&&x(n),[]
var i=this.props.components.reduce(function(e,t){return c({},e,o({},t.prototype.constructor.name,t))},{})
return this.parseNode(a.childNodes||[],i)}},{key:"parseNode",value:function(e){var t=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments[2]
if(e instanceof NodeList||Array.isArray(e))return Array.from(e).map(function(e,n){return t.parseNode(e,r,n)}).filter(function(e){return e})
if(e.nodeType===E.default.TEXT)return("textContent"in e?e.textContent:e.nodeValue||"").replace(/[\r\n\t\f\v]/g,"").replace(/\s{2,}/g," ")
if(e.nodeType===E.default.ELEMENT){var o=void 0
return(0,T.canHaveChildren)(e.nodeName)&&(o=this.parseNode(e.childNodes,r),(0,T.canHaveWhitespace)(e.nodeName)||(o=o.filter(function(e){return"string"!=typeof e||!e.match(/^\s*$/)}))),l.default.createElement(r[e.nodeName]||e.nodeName,c({},this.props.bindings||{},this.parseAttrs(e.attributes,n)),o)}return this.props.showWarnings&&console.warn("JsxParser encountered a(n) "+E.default[e.nodeType]+" node, and discarded it."),null}},{key:"parseAttrs",value:function(e,t){if(!e||!e.length)return{key:t}
var r=this.props.blacklistedAttrs
return Array.from(e).filter(function(e){return!r.map(function(t){return e.name.match(new RegExp(t,"gi"))}).filter(function(e){return null!==e}).length}).reduce(function(e,t){var r=t.name,n=t.value
return""===n&&(n=!0),r.match(/^on/i)?n=new Function(n):"style"===r&&(n=(0,m.default)(n)),r=g.default[r.toLowerCase()]||(0,d.default)(r),c({},e,o({},r,n))},{key:t})}},{key:"render",value:function(){return l.default.createElement("div",{className:"jsx-parser"},this.ParsedChildren)}}]),t}(f.Component)
t.default=N
r(8)
N.defaultProps={bindings:{},blacklistedAttrs:["on[a-z]*"],blacklistedTags:["script"],components:[],jsx:"",showWarnings:!1}},function(t,r){t.exports=e},function(e,t,r){"use strict"
function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e){switch(void 0===e?"undefined":i(e)){case"string":return e.split(";").filter(function(e){return e}).reduce(function(e,t){var r=t.slice(0,t.indexOf(":")).trim(),o=t.slice(t.indexOf(":")+1).trim()
return a({},e,n({},(0,c.default)(r),o))},{})
case"object":return e
default:return}}Object.defineProperty(t,"__esModule",{value:!0})
var a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t]
for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e}
t.default=o
var u=r(0),c=function(e){return e&&e.__esModule?e:{default:e}}(u)},function(e,t,r){"use strict"
function n(e){return/<(\/?|!?)DOCTYPE html>/.test(e)&&/<(\/?|!?)html>/.test(e)&&/<(\/?|!?)head>/.test(e)&&/<(\/?|!?)body>/.test(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=n},function(e,t,r){"use strict"
Object.defineProperty(t,"__esModule",{value:!0}),t.default={class:"className",for:"htmlFor",maxlength:"maxLength",colspan:"colSpan",rowspan:"rowSpan"}},function(e,t,r){"use strict"
Object.defineProperty(t,"__esModule",{value:!0}),t.default={ELEMENT:1,TEXT:3,PROCESSING_INSTRUCTION:7,COMMENT:8,DOCUMENT:9,DOCUMENT_TYPE:10,DOCUMENT_FRAGMENT:11,1:"Element",3:"Text",7:"Processing Instruction",8:"Comment",9:"Document",10:"Document Type",11:"Document Fragment",ATTRIBUTE:2,CDATA:4,XML_ENTITY_REFERENCE:5,XML_ENTITY:6,XML_NOTATION:12,2:"Attribute (Deprecated)",4:"CData (Deprecated)",5:"XML Entity Reference (Deprecated)",6:"XML Entity (Deprecated)",12:"XML Notation (Deprecated)"}},function(e,t,r){"use strict"
function n(e){return-1===a.indexOf(e.toLowerCase())}function o(e){return-1!==i.indexOf(e.toLowerCase())}Object.defineProperty(t,"__esModule",{value:!0}),t.canHaveChildren=n,t.canHaveWhitespace=o
var a=["area","base","br","col","embed","hr","img","input","keygen","link","menuitem","meta","param","source","track","wbr"],i=["table","tbody","tfoot","thead","tr"]
t.default=a},function(e,t,r){e.exports=r(9)()},function(e,t,r){"use strict"
var n=r(10),o=r(11),a=r(12)
e.exports=function(){function e(e,t,r,n,i,u){u!==a&&o(!1,"Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types")}function t(){return e}e.isRequired=e
var r={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t}
return r.checkPropTypes=n,r.PropTypes=r,r}},function(e,t,r){"use strict"
function n(e){return function(){return e}}var o=function(){}
o.thatReturns=n,o.thatReturnsFalse=n(!1),o.thatReturnsTrue=n(!0),o.thatReturnsNull=n(null),o.thatReturnsThis=function(){return this},o.thatReturnsArgument=function(e){return e},e.exports=o},function(e,t,r){"use strict"
function n(e,t,r,n,a,i,u,c){if(o(t),!e){var s
if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.")
else{var f=[r,n,a,i,u,c],l=0
s=new Error(t.replace(/%s/g,function(){return f[l++]})),s.name="Invariant Violation"}throw s.framesToPop=1,s}}var o=function(e){}
e.exports=n},function(e,t,r){"use strict"
e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"}])})
<|endoftext|>


<commit_before>/*
*
*    Copyright (c) 2011 Phil Ingrey, <philingrey.com>
*
*    Licensed under the MIT license - see ./license.txt
*
*
*/

// A standard 2D vector
function Vector2D(x, y){
   this.x = x;
   this.y = y;

   this.setV = function(x, y){
      this.x = x;
      this.y = y;
   }

   this.drawline = function(x1,y1,x2,y2) {
   	  // line from p1 to p2
   	  this.x = x2-x1;
   	  this.y = y2-y1;
   }

   this.normalize = function() {
      this.magnitude = Math.sqrt((this.x * this.x) + (this.y * this.y));
      if(this.magnitude == 0) return;

      this.x = this.x / this.magnitude;
      this.y = this.y / this.magnitude;
   }

   this.mult = function(m){
      return new Vector2D(this.x*m,this.y*m);
   }

   this.multEquals = function(m){
      this.x *= m;
      this.y *= m;
   }

   this.minus = function(v){
      return new Vector2D(this.x-v.x, this.y-v.y);
   }

   this.addEquals = function(v2){
   	  this.x+=v2.x;
   	  this.y+=v2.y;
   }
};

function Bubble(x, y, canvasid){

   this.left = x;
   this.top = y;
   this.mycanvas = document.getElementById(canvasid);
   this.ctx = this.mycanvas.getContext('2d');
   this.mywidth = this.mycanvas.width;
   this.myheight = this.mycanvas.height;
   this.right = x+this.mywidth;
   this.bottom = y+this.myheight;
   this.data = this.ctx.getImageData(0,0,this.mywidth,this.myheight).data;
   this.f = new Vector2D(0,0);
   this.weight = 0;

   // Calculate the weight
   for(var i=0;i<this.myheight;i++){
       for(var j=0;j<this.mywidth;j++){
           if(this.data[4*(this.mywidth*i+j)+3] != 0) this.weight++;
       }
   }

   this.draw = function(canvasid) {
      var cx = document.getElementById(canvasid).getContext('2d');

      cx.drawImage(this.ctx.canvas, this.left, this.top);
   }

   this.distanceTo = function(x, y) {
      /*var dx = this.x - x;
      var dy = this.y - y;

      return Math.sqrt((dx*dx) + (dy*dy));*/
   }

   this.moveBy = function(v) {
      this.left += v.x;
      this.right += v.x;
      this.top += v.y;
      this.bottom += v.y;
   }

   this.contains = function(x, y) {
   	  // returns if a point is within this bubble
   	  return ((this.left < x && x < this.right) && (y < this.top && this.bottom < y));
   }

   this.intersects = function(secondBubble) {
      // returns the overlap between two bubbles in the form [[x1,y1], [x2,y2]] (the first being the upper left corner of the intersection)
      // returns null if no overlap present
      var lowesttop = Math.max(this.top, secondBubble.top);
      var highestbottom = Math.min(this.bottom, secondBubble.bottom);
      var rightmostleft = Math.max(this.left, secondBubble.left);
      var leftmostright = Math.min(this.right, secondBubble.right);

      if(rightmostleft > leftmostright || lowesttop > highestbottom) return null;

      return [[rightmostleft,lowesttop],[leftmostright,highestbottom]];
   }

   this.usedPoint = function(x, y){
   	  // returns true if the point (x, y) has some importance in this canvas (i.e. it's opacity channel is non-zero)
   	  // assume the point is in this bubble (maybe should do checking, but it'll slow things down a lot!)
   	  return (this.data[4*(this.mywidth*(y-this.top)+(x-this.left))+3] != 0)
   }
};

// Main BubbleWraping class
function BubbleWrap(bubbles, maincanvasid){

   this.bubbles = bubbles;
   this.maincanvas = document.getElementById(maincanvasid);
   this.ctx = this.maincanvas.getContext('2d');
   this.damping = 0.98;
   this.canvasCenter = new Vector2D(this.maincanvas.width / 2, this.maincanvas.height / 2);
   this.timer = null;
   var that = this;

   var callBack = function()
   {
        that.iterate();
   }

   this.draw = function() {
   		// clear the canvas
        this.ctx.clearRect(0,0,this.maincanvas.width, this.maincanvas.height);
        for(var i in this.bubbles){
            this.bubbles[i].draw(maincanvasid);
        }
   }

   this.iterate = function(){
   		var overlap;
   		var forcesum;
   		var df = new Vector2D(0,0);
   		var bi,bj;
   		var kave, lave;
   		for(var i=0;i<this.bubbles.length;i++) bubbles[i].f.setV(0,0);

   		for(var i=0;i<this.bubbles.length;i++){
   			bi = bubbles[i];
   			for(var j=i+1;j<this.bubbles.length;j++){
   				bj = bubbles[j];
   				overlap = bi.intersects(bj);
   				if(overlap !== null){
   					//this.ctx.strokeRect(overlap[0][0],overlap[0][1],overlap[1][0]-overlap[0][0],overlap[1][1]-overlap[0][1]);

   					forcesum = 0;
   					kave = lave = 0;

   					for(var k=overlap[0][0]; k<overlap[1][0]; k++){
   						for(var l=overlap[0][1]; l<overlap[1][1]; l++){
   							if(bi.usedPoint(k,l) && bj.usedPoint(k,l)) {
   								// clash point
   								forcesum++;
   								kave += k;
   								lave += l;
   								//this.ctx.fillRect(k-0.5,l-0.5,1,1);
   							}
   						}
   					}
   					if(forcesum == 0) continue;
   					df.setV((bi.left+bi.mywidth/2)-kave/forcesum,(bi.top+bi.myheight/2)-lave/forcesum);
   					df.normalize();
   					//bi.f.addEquals(df.mult(50*forcesum/bi.weight));
   					df.setV((bj.left+bj.mywidth/2)-kave/forcesum,(bj.top+bj.myheight/2)-lave/forcesum);
   					df.normalize();
   					//bj.f.addEquals(df.mult(50*forcesum/bj.weight));
   				}
   			}
        }

        for(var i=0;i<this.bubbles.length;i++) {
        	    // gravity:
        	    df.setV(this.canvasCenter.x-(bubbles[i].left+bubbles[i].mywidth/2),this.canvasCenter.y-(bubbles[i].top+bubbles[i].myheight/2));
        	    df.normalize();
        	    bubbles[i].f.addEquals(df.mult(5*this.damping));
        	    bubbles[i].moveBy(bubbles[i].f);
        }

        this.damping *= 0.98;
        this.draw();
        if(this.damping > 0.02) this.timer = window.setTimeout(callBack,50);
   }
};
<commit_msg>added second type of canvas clear<commit_after>/*
*
*    Copyright (c) 2011 Phil Ingrey, <philingrey.com>
*
*    Licensed under the MIT license - see ./license.txt
*
*
*/

// A standard 2D vector
function Vector2D(x, y){
   this.x = x;
   this.y = y;

   this.setV = function(x, y){
      this.x = x;
      this.y = y;
   }

   this.drawline = function(x1,y1,x2,y2) {
   	  // line from p1 to p2
   	  this.x = x2-x1;
   	  this.y = y2-y1;
   }

   this.normalize = function() {
      this.magnitude = Math.sqrt((this.x * this.x) + (this.y * this.y));
      if(this.magnitude == 0) return;

      this.x = this.x / this.magnitude;
      this.y = this.y / this.magnitude;
   }

   this.mult = function(m){
      return new Vector2D(this.x*m,this.y*m);
   }

   this.multEquals = function(m){
      this.x *= m;
      this.y *= m;
   }

   this.minus = function(v){
      return new Vector2D(this.x-v.x, this.y-v.y);
   }

   this.addEquals = function(v2){
   	  this.x+=v2.x;
   	  this.y+=v2.y;
   }
};

function Bubble(x, y, canvasid){

   this.left = x;
   this.top = y;
   this.mycanvas = document.getElementById(canvasid);
   this.ctx = this.mycanvas.getContext('2d');
   this.mywidth = this.mycanvas.width;
   this.myheight = this.mycanvas.height;
   this.right = x+this.mywidth;
   this.bottom = y+this.myheight;
   this.data = this.ctx.getImageData(0,0,this.mywidth,this.myheight).data;
   this.f = new Vector2D(0,0);
   this.weight = 0;

   // Calculate the weight
   for(var i=0;i<this.myheight;i++){
       for(var j=0;j<this.mywidth;j++){
           if(this.data[4*(this.mywidth*i+j)+3] != 0) this.weight++;
       }
   }

   this.draw = function(canvasid) {
      var cx = document.getElementById(canvasid).getContext('2d');

      cx.drawImage(this.ctx.canvas, this.left, this.top);
   }

   this.distanceTo = function(x, y) {
      /*var dx = this.x - x;
      var dy = this.y - y;

      return Math.sqrt((dx*dx) + (dy*dy));*/
   }

   this.moveBy = function(v) {
      this.left += v.x;
      this.right += v.x;
      this.top += v.y;
      this.bottom += v.y;
   }

   this.contains = function(x, y) {
   	  // returns if a point is within this bubble
   	  return ((this.left < x && x < this.right) && (y < this.top && this.bottom < y));
   }

   this.intersects = function(secondBubble) {
      // returns the overlap between two bubbles in the form [[x1,y1], [x2,y2]] (the first being the upper left corner of the intersection)
      // returns null if no overlap present
      var lowesttop = Math.max(this.top, secondBubble.top);
      var highestbottom = Math.min(this.bottom, secondBubble.bottom);
      var rightmostleft = Math.max(this.left, secondBubble.left);
      var leftmostright = Math.min(this.right, secondBubble.right);

      if(rightmostleft > leftmostright || lowesttop > highestbottom) return null;

      return [[rightmostleft,lowesttop],[leftmostright,highestbottom]];
   }

   this.usedPoint = function(x, y){
   	  // returns true if the point (x, y) has some importance in this canvas (i.e. it's opacity channel is non-zero)
   	  // assume the point is in this bubble (maybe should do checking, but it'll slow things down a lot!)
   	  return (this.data[4*(this.mywidth*(y-this.top)+(x-this.left))+3] != 0)
   }
};

// Main BubbleWraping class
function BubbleWrap(bubbles, maincanvasid){

   this.bubbles = bubbles;
   this.maincanvas = document.getElementById(maincanvasid);
   this.ctx = this.maincanvas.getContext('2d');
   this.damping = 0.98;
   this.canvasCenter = new Vector2D(this.maincanvas.width / 2, this.maincanvas.height / 2);
   this.timer = null;
   var that = this;

   var callBack = function()
   {
        that.iterate();
   }

   this.draw = function() {
   		// clear the canvas
   	    this.maincanvas.width = this.maincanvas.width;
        this.ctx.clearRect(0,0,this.maincanvas.width, this.maincanvas.height);
        for(var i in this.bubbles){
            this.bubbles[i].draw(maincanvasid);
        }
   }

   this.iterate = function(){
   		var overlap;
   		var forcesum;
   		var df = new Vector2D(0,0);
   		var bi,bj;
   		var kave, lave;
   		for(var i=0;i<this.bubbles.length;i++) bubbles[i].f.setV(0,0);

   		for(var i=0;i<this.bubbles.length;i++){
   			bi = bubbles[i];
   			for(var j=i+1;j<this.bubbles.length;j++){
   				bj = bubbles[j];
   				overlap = bi.intersects(bj);
   				if(overlap !== null){
   					//this.ctx.strokeRect(overlap[0][0],overlap[0][1],overlap[1][0]-overlap[0][0],overlap[1][1]-overlap[0][1]);

   					forcesum = 0;
   					kave = lave = 0;

   					for(var k=overlap[0][0]; k<overlap[1][0]; k++){
   						for(var l=overlap[0][1]; l<overlap[1][1]; l++){
   							if(bi.usedPoint(k,l) && bj.usedPoint(k,l)) {
   								// clash point
   								forcesum++;
   								kave += k;
   								lave += l;
   								//this.ctx.fillRect(k-0.5,l-0.5,1,1);
   							}
   						}
   					}
   					if(forcesum == 0) continue;
   					df.setV((bi.left+bi.mywidth/2)-kave/forcesum,(bi.top+bi.myheight/2)-lave/forcesum);
   					df.normalize();
   					//bi.f.addEquals(df.mult(50*forcesum/bi.weight));
   					df.setV((bj.left+bj.mywidth/2)-kave/forcesum,(bj.top+bj.myheight/2)-lave/forcesum);
   					df.normalize();
   					//bj.f.addEquals(df.mult(50*forcesum/bj.weight));
   				}
   			}
        }

        for(var i=0;i<this.bubbles.length;i++) {
        	    // gravity:
        	    df.setV(this.canvasCenter.x-(bubbles[i].left+bubbles[i].mywidth/2),this.canvasCenter.y-(bubbles[i].top+bubbles[i].myheight/2));
        	    df.normalize();
        	    bubbles[i].f.addEquals(df.mult(5*this.damping));
        	    bubbles[i].moveBy(bubbles[i].f);
        }

        this.damping *= 0.98;
        this.draw();
        if(this.damping > 0.02) this.timer = window.setTimeout(callBack,50);
   }
};
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright The Closure Library Authors.
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @fileoverview Provides a soy renderer that allows registration of
 * injected data ("globals") that will be passed into the rendered
 * templates.
 */

goog.provide('goog.soy.Renderer');

goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.soy');
goog.require('goog.soy.data.SanitizedContent');
goog.require('goog.soy.data.SanitizedContentKind');
goog.requireType('goog.html.SafeHtml');
goog.requireType('goog.html.SafeStyleSheet');
goog.requireType('goog.soy.InjectedDataSupplier');
goog.requireType('goog.soy.data.SanitizedCss');
goog.requireType('goog.soy.data.SanitizedHtml');
goog.requireType('goog.soy.data.SanitizedUri');

/**
 * Creates a new soy renderer. Note that the renderer will only be
 * guaranteed to work correctly within the document scope provided in
 * the DOM helper.
 *
 * @param {?goog.soy.InjectedDataSupplier=} opt_injectedDataSupplier A supplier
 *     that provides an injected data.
 * @param {?goog.dom.DomHelper=} opt_domHelper Optional DOM helper;
 *     defaults to that provided by `goog.dom.getDomHelper()`.
 * @constructor
 */
goog.soy.Renderer = function(opt_injectedDataSupplier, opt_domHelper) {
  'use strict';
  /**
   * @const {!goog.dom.DomHelper}
   * @private
   */
  this.dom_ = opt_domHelper || goog.dom.getDomHelper();

  /**
   * @const {?goog.soy.InjectedDataSupplier}
   * @private
   */
  this.supplier_ = opt_injectedDataSupplier || null;
};

/**
 * Renders a Soy template into a single node or a document fragment.
 * Delegates to `goog.soy.renderAsFragment`.
 *
 * @param {function(ARG_TYPES, ?goog.soy.CompatibleIj=): *} template The Soy
 *     template defining the element's content.
 * @param {ARG_TYPES=} opt_templateData The data for the template.
 * @return {!Node} The resulting node or document fragment.
 * @template ARG_TYPES
 */
goog.soy.Renderer.prototype.renderAsFragment = function(
    template, opt_templateData) {
  'use strict';
  const node = goog.soy.renderAsFragment(
      template, opt_templateData, this.getInjectedData_(), this.dom_);
  this.handleRender(node, goog.soy.data.SanitizedContentKind.HTML);
  return node;
};

/**
 * Renders a Soy template into a single node. If the rendered HTML
 * string represents a single node, then that node is returned.
 * Otherwise, a DIV element is returned containing the rendered nodes.
 * Delegates to `goog.soy.renderAsElement`.
 *
 * @param {function(ARG_TYPES, ?goog.soy.CompatibleIj=): *} template The Soy
 *     template defining the element's content.
 * @param {ARG_TYPES=} opt_templateData The data for the template.
 * @return {!Element} Rendered template contents, wrapped in a parent DIV
 *     element if necessary.
 * @template ARG_TYPES
 */
goog.soy.Renderer.prototype.renderAsElement = function(
    template, opt_templateData) {
  'use strict';
  const element = goog.soy.renderAsElement(
      template, opt_templateData, this.getInjectedData_(), this.dom_);
  this.handleRender(element, goog.soy.data.SanitizedContentKind.HTML);
  return element;
};

/**
 * Renders a Soy template and then set the output string as the
 * innerHTML of the given element. Delegates to `goog.soy.renderElement`.
 *
 * @param {?Element} element The element whose content we are rendering.
 * @param {function(ARG_TYPES, ?goog.soy.CompatibleIj=): *} template The Soy
 *     template defining the element's content.
 * @param {ARG_TYPES=} opt_templateData The data for the template.
 * @template ARG_TYPES
 */
goog.soy.Renderer.prototype.renderElement = function(
    element, template, opt_templateData) {
  'use strict';
  goog.soy.renderElement(
      element, template, opt_templateData, this.getInjectedData_());
  this.handleRender(element, goog.soy.data.SanitizedContentKind.HTML);
};

/**
 * Renders a Soy template and returns the output string.
 * If the template is strict, it must be of kind HTML. To render strict
 * templates of other kinds, use `renderText` (for `kind="text"`) or
 * `renderStrictOfKind`.
 *
 * @param {function(ARG_TYPES, ?Object<string, *>=): *} template The Soy
 *     template to render.
 * @param {ARG_TYPES=} opt_templateData The data for the template.
 * @return {string} The return value of rendering the template directly.
 * @template ARG_TYPES
 */
goog.soy.Renderer.prototype.render = function(template, opt_templateData) {
  'use strict';
  const result = template(opt_templateData || {}, this.getInjectedData_());
  goog.asserts.assert(
      !(result instanceof goog.soy.data.SanitizedContent) ||
          result.contentKind === goog.soy.data.SanitizedContentKind.HTML,
      'render was called with a strict template of kind other than "html"' +
          ' (consider using renderText or renderStrict)');
  const contentKind = result instanceof goog.soy.data.SanitizedContent ?
      result.contentKind :
      null;
  this.handleRender(null /* node */, contentKind);
  return String(result);
};

/**
 * Renders a strict Soy template of kind="text" and returns the output string.
 * It is an error to use renderText on templates of kinds other than "text".
 *
 * @param {function(ARG_TYPES, ?Object<string,*>=): string} template The Soy
 *     template to render.
 * @param {ARG_TYPES=} opt_templateData The data for the template.
 * @return {string} The return value of rendering the template directly.
 * @template ARG_TYPES
 */
goog.soy.Renderer.prototype.renderText = function(template, opt_templateData) {
  'use strict';
  const result = template(opt_templateData || {}, this.getInjectedData_());
  goog.asserts.assertString(
      result,
      'renderText was called with a template of kind other than "text"');
  return String(result);
};

/**
 * Renders a strict Soy HTML template and returns the output SanitizedHtml
 * object.
 * @param {function(ARG_TYPES, ?Object<string,*>=):
 *     !goog.soy.data.SanitizedHtml} template The Soy template to render.
 * @param {ARG_TYPES=} opt_templateData The data for the template.
 * @return {!goog.soy.data.SanitizedHtml}
 * @template ARG_TYPES
 */
goog.soy.Renderer.prototype.renderStrict = function(
    template, opt_templateData) {
  'use strict';
  return this.renderStrictOfKind(
      template, opt_templateData, goog.soy.data.SanitizedContentKind.HTML);
};

/**
 * Renders a strict Soy template and returns the output SanitizedUri object.
 *
 * @param {function(ARG_TYPES, ?Object<string, *>=):
 *     !goog.soy.data.SanitizedUri} template The Soy template to render.
 * @param {ARG_TYPES=} opt_templateData The data for the template.
 * @return {!goog.soy.data.SanitizedUri}
 * @template ARG_TYPES
 */
goog.soy.Renderer.prototype.renderStrictUri = function(
    template, opt_templateData) {
  'use strict';
  return this.renderStrictOfKind(
      template, opt_templateData, goog.soy.data.SanitizedContentKind.URI);
};

/**
 * Renders a strict Soy template and returns the output SanitizedContent object.
 *
 * @param {function(ARG_TYPES, ?Object<string, *>=): RETURN_TYPE} template The
 *     Soy template to render.
 * @param {ARG_TYPES=} opt_templateData The data for the template.
 * @param {?goog.soy.data.SanitizedContentKind=} opt_kind The output kind to
 *     assert. If null, the template must be of kind="html" (i.e., opt_kind
 *     defaults to goog.soy.data.SanitizedContentKind.HTML).
 * @return {RETURN_TYPE} The SanitizedContent object. This return type is
 *     generic based on the return type of the template, such as
 *     goog.soy.data.SanitizedHtml.
 * @template ARG_TYPES, RETURN_TYPE
 */
goog.soy.Renderer.prototype.renderStrictOfKind = function(
    template, opt_templateData, opt_kind) {
  'use strict';
  const result = template(opt_templateData || {}, this.getInjectedData_());
  goog.asserts.assertInstanceof(
      result, goog.soy.data.SanitizedContent,
      'renderStrict cannot be called on a text soy template');
  goog.asserts.assert(
      result.contentKind ===
          (opt_kind || goog.soy.data.SanitizedContentKind.HTML),
      'renderStrict was called with the wrong kind of template');
  this.handleRender(null /* node */, result.contentKind);
  return result;
};

/**
 * Renders a strict Soy template of kind="html" and returns the result as
 * a goog.html.SafeHtml object.
 *
 * Rendering a template that is not a strict template of kind="html" results in
 * a runtime error.
 *
 * @param {function(ARG_TYPES, ?Object<string, *>=):
 *     !goog.soy.data.SanitizedHtml} template The Soy template to render.
 * @param {ARG_TYPES=} opt_templateData The data for the template.
 * @return {!goog.html.SafeHtml}
 * @template ARG_TYPES
 */
goog.soy.Renderer.prototype.renderSafeHtml = function(
    template, opt_templateData) {
  'use strict';
  const result = this.renderStrict(template, opt_templateData);
  // Convert from SanitizedHtml to SafeHtml.
  return result.toSafeHtml();
};

/**
 * Renders a strict Soy template of kind="css" and returns the result as
 * a goog.html.SafeStyleSheet object.
 *
 * Rendering a template that is not a strict template of kind="css" results in
 * a runtime and compile-time error.
 *
 * @param {function(ARG_TYPES, ?Object<string, *>=):
 *     !goog.soy.data.SanitizedCss} template The Soy template to render.
 * @param {ARG_TYPES=} opt_templateData The data for the template.
 * @return {!goog.html.SafeStyleSheet}
 * @template ARG_TYPES
 */
goog.soy.Renderer.prototype.renderSafeStyleSheet = function(
    template, opt_templateData) {
  'use strict';
  const result = this.renderStrictOfKind(
      template, opt_templateData, goog.soy.data.SanitizedContentKind.CSS);
  return result.toSafeStyleSheet();
};

/**
 * @return {!goog.dom.DomHelper}
 * @protected
 */
goog.soy.Renderer.prototype.getDom = function() {
  'use strict';
  return this.dom_;
};

/**
 * Observes rendering of non-text templates by this renderer.
 * @param {?Node} node Relevant node, if available. The node may or may
 *     not be in the document, depending on whether Soy is creating an element
 *     or writing into an existing one.
 * @param {?goog.soy.data.SanitizedContentKind} kind of the template, or null if
 *     it was not strict.
 * @protected
 */
goog.soy.Renderer.prototype.handleRender = goog.nullFunction;

/**
 * Creates the injectedParams map if necessary and calls the configuration
 * service to prepopulate it.
 * @return {?} The injected params.
 * @private
 */
goog.soy.Renderer.prototype.getInjectedData_ = function() {
  'use strict';
  return this.supplier_ ? this.supplier_.getData() : {};
};
<commit_msg>#v2 Convert Soy Renderer from goog.provide to goog.module. RELNOTES: n/a<commit_after>/**
 * @license
 * Copyright The Closure Library Authors.
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @fileoverview Provides a soy renderer that allows registration of
 * injected data ("globals") that will be passed into the rendered
 * templates.
 */

goog.module('goog.soy.Renderer');
goog.module.declareLegacyNamespace();

const InjectedDataSupplier = goog.requireType('goog.soy.InjectedDataSupplier');
const SafeHtml = goog.requireType('goog.html.SafeHtml');
const SafeStyleSheet = goog.requireType('goog.html.SafeStyleSheet');
const SanitizedContent = goog.require('goog.soy.data.SanitizedContent');
const SanitizedContentKind = goog.require('goog.soy.data.SanitizedContentKind');
const SanitizedCss = goog.requireType('goog.soy.data.SanitizedCss');
const SanitizedHtml = goog.requireType('goog.soy.data.SanitizedHtml');
const SanitizedUri = goog.requireType('goog.soy.data.SanitizedUri');
const asserts = goog.require('goog.asserts');
const dom = goog.require('goog.dom');
const soy = goog.require('goog.soy');

/**
 * Creates a new soy renderer. Note that the renderer will only be
 * guaranteed to work correctly within the document scope provided in
 * the DOM helper.
 */
class Renderer {
  /**
   * @param {?InjectedDataSupplier=} injectedDataSupplier A supplier that
   *     provides an injected data.
   * @param {?dom.DomHelper=} domHelper Optional DOM helper; defaults to that
   *     provided by `dom.getDomHelper()`.
   */
  constructor(injectedDataSupplier = undefined, domHelper = undefined) {
    /** @private @const {!dom.DomHelper} */
    this.dom_ = domHelper || dom.getDomHelper();

    /** @private @const {?InjectedDataSupplier} */
    this.supplier_ = injectedDataSupplier || null;
  }

  /**
   * Renders a Soy template into a single node or a document fragment.
   * Delegates to `soy.renderAsFragment`.
   * @param {function(ARG_TYPES, ?soy.CompatibleIj=): *} template The Soy
   *     template defining the element's content.
   * @param {ARG_TYPES=} templateData The data for the template.
   * @return {!Node} The resulting node or document fragment.
   * @template ARG_TYPES
   */
  renderAsFragment(template, templateData = undefined) {
    const node = soy.renderAsFragment(
        template, templateData, this.getInjectedData_(), this.dom_);
    this.handleRender(node, SanitizedContentKind.HTML);
    return node;
  }

  /**
   * Renders a Soy template into a single node. If the rendered HTML
   * string represents a single node, then that node is returned.
   * Otherwise, a DIV element is returned containing the rendered nodes.
   * Delegates to `soy.renderAsElement`.
   * @param {function(ARG_TYPES, ?soy.CompatibleIj=): *} template The Soy
   *     template defining the element's content.
   * @param {ARG_TYPES=} templateData The data for the template.
   * @return {!Element} Rendered template contents, wrapped in a parent DIV
   *     element if necessary.
   * @template ARG_TYPES
   */
  renderAsElement(template, templateData = undefined) {
    const element = soy.renderAsElement(
        template, templateData, this.getInjectedData_(), this.dom_);
    this.handleRender(element, SanitizedContentKind.HTML);
    return element;
  }

  /**
   * Renders a Soy template and then set the output string as the
   * innerHTML of the given element. Delegates to `soy.renderElement`.
   * @param {?Element} element The element whose content we are rendering.
   * @param {function(ARG_TYPES, ?soy.CompatibleIj=): *} template The Soy
   *     template defining the element's content.
   * @param {ARG_TYPES=} templateData The data for the template.
   * @template ARG_TYPES
   */
  renderElement(element, template, templateData = undefined) {
    soy.renderElement(element, template, templateData, this.getInjectedData_());
    this.handleRender(element, SanitizedContentKind.HTML);
  }

  /**
   * Renders a Soy template and returns the output string.
   * If the template is strict, it must be of kind HTML. To render strict
   * templates of other kinds, use `renderText` (for `kind="text"`) or
   * `renderStrictOfKind`.
   * @param {function(ARG_TYPES, ?Object<string, *>=): *} template The Soy
   *     template to render.
   * @param {ARG_TYPES=} templateData The data for the template.
   * @return {string} The return value of rendering the template directly.
   * @template ARG_TYPES
   */
  render(template, templateData = undefined) {
    const result = template(templateData || {}, this.getInjectedData_());
    asserts.assert(
        !(result instanceof SanitizedContent) ||
            result.contentKind === SanitizedContentKind.HTML,
        'render was called with a strict template of kind other than "html"' +
            ' (consider using renderText or renderStrict)');
    const contentKind =
        result instanceof SanitizedContent ? result.contentKind : null;
    this.handleRender(null /* node */, contentKind);
    return String(result);
  }

  /**
   * Renders a strict Soy template of kind="text" and returns the output string.
   * It is an error to use renderText on templates of kinds other than "text".
   * @param {function(ARG_TYPES, ?Object<string,*>=): string} template The Soy
   *     template to render.
   * @param {ARG_TYPES=} templateData The data for the template.
   * @return {string} The return value of rendering the template directly.
   * @template ARG_TYPES
   */
  renderText(template, templateData = undefined) {
    const result = template(templateData || {}, this.getInjectedData_());
    asserts.assertString(
        result,
        'renderText was called with a template of kind other than "text"');
    return String(result);
  }

  /**
   * Renders a strict Soy HTML template and returns the output SanitizedHtml
   * object.
   * @param {function(ARG_TYPES, ?Object<string,*>=):
   *     !SanitizedHtml} template The Soy template to render.
   * @param {ARG_TYPES=} templateData The data for the template.
   * @return {!SanitizedHtml}
   * @template ARG_TYPES
   */
  renderStrict(template, templateData = undefined) {
    return this.renderStrictOfKind(
        template, templateData, SanitizedContentKind.HTML);
  }

  /**
   * Renders a strict Soy template and returns the output SanitizedUri object.
   * @param {function(ARG_TYPES, ?Object<string, *>=):
   *     !SanitizedUri} template The Soy template to render.
   * @param {ARG_TYPES=} templateData The data for the template.
   * @return {!SanitizedUri}
   * @template ARG_TYPES
   */
  renderStrictUri(template, templateData = undefined) {
    return this.renderStrictOfKind(
        template, templateData, SanitizedContentKind.URI);
  }

  /**
   * Renders a strict Soy template and returns the output SanitizedContent
   * object.
   * @param {function(ARG_TYPES, ?Object<string, *>=): RETURN_TYPE} template The
   *     Soy template to render.
   * @param {ARG_TYPES=} templateData The data for the template.
   * @param {?SanitizedContentKind=} kind The output kind to assert. If null,
   *     the template must be of kind="html" (i.e., kind defaults to
   *     SanitizedContentKind.HTML).
   * @return {RETURN_TYPE} The SanitizedContent object. This return type is
   *     generic based on the return type of the template, such as
   *     soy.data.SanitizedHtml.
   * @template ARG_TYPES, RETURN_TYPE
   */
  renderStrictOfKind(template, templateData = undefined, kind = undefined) {
    const result = template(templateData || {}, this.getInjectedData_());
    asserts.assertInstanceof(
        result, SanitizedContent,
        'renderStrict cannot be called on a text soy template');
    asserts.assert(
        result.contentKind === (kind || SanitizedContentKind.HTML),
        'renderStrict was called with the wrong kind of template');
    this.handleRender(null /* node */, result.contentKind);
    return result;
  }

  /**
   * Renders a strict Soy template of kind="html" and returns the result as
   * a SafeHtml object.
   * Rendering a template that is not a strict template of kind="html" results
   * in a runtime error.
   * @param {function(ARG_TYPES, ?Object<string, *>=):
   *     !SanitizedHtml} template The Soy template to render.
   * @param {ARG_TYPES=} templateData The data for the template.
   * @return {!SafeHtml}
   * @template ARG_TYPES
   */
  renderSafeHtml(template, templateData = undefined) {
    const result = this.renderStrict(template, templateData);
    // Convert from SanitizedHtml to SafeHtml.
    return result.toSafeHtml();
  }

  /**
   * Renders a strict Soy template of kind="css" and returns the result as
   * a SafeStyleSheet object.
   * Rendering a template that is not a strict template of kind="css" results in
   * a runtime and compile-time error.
   * @param {function(ARG_TYPES, ?Object<string, *>=):
   *     !SanitizedCss} template The Soy template to render.
   * @param {ARG_TYPES=} templateData The data for the template.
   * @return {!SafeStyleSheet}
   * @template ARG_TYPES
   */
  renderSafeStyleSheet(template, templateData = undefined) {
    const result = this.renderStrictOfKind(
        template, templateData, SanitizedContentKind.CSS);
    return result.toSafeStyleSheet();
  }

  /**
   * @return {!dom.DomHelper}
   * @protected
   */
  getDom() {
    return this.dom_;
  }

  /**
   * Observes rendering of non-text templates by this renderer.
   * @param {?Node} node Relevant node, if available. The node may or may not be
   *     in the document, depending on whether Soy is creating an element or
   *     writing into an existing one.
   * @param {?SanitizedContentKind} kind of the template, or null if it was not
   *     strict.
   * @protected
   */
  handleRender(node, kind) {}

  /**
   * Creates the injectedParams map if necessary and calls the configuration
   * service to prepopulate it.
   * @return {?} The injected params.
   * @private
   */
  getInjectedData_() {
    return this.supplier_ ? this.supplier_.getData() : {};
  }
}

exports = Renderer;
<|endoftext|>


<commit_before>var intervalID;

function get_tips() {
    var tips_on_this_page = [];
    $("meta[name=microtip]").each(function(index, element) {
        var e = $(element);
        tips_on_this_page.push({
            'currency': e.data('currency'),
            'address': e.attr('content'),
            'ratio': e.data('ratio'),
            'recipient': e.data('recipient')
        });
    });
    return tips_on_this_page
}

chrome.storage.sync.get({
    when_to_send: null,
    blacklist_or_whitelist: null,
    domain_list: null,
    interval_seconds: null
}, function(items) {
    var tips = get_tips();
    if(tips.length <= 0) {
        return // No tips found
    }

    console.log("Autotip extension found " + tips.length + " microtip meta tags on this page");
    chrome.runtime.sendMessage({found_tips: tips});

    if(items.when_to_send == '5mins') {
        var five_minute_counter_start = new Date()
        intervalID = setInterval(function() {
            // update popup status every 1 second. After 5 minutes, make the tip
            var seconds_to_go = Math.floor(items.interval_seconds - ((new Date() - five_minute_counter_start) / 1000));
            if(seconds_to_go <= 0) {
                chrome.runtime.sendMessage({tips: tips, perform_tip: 'auto'});
                console.log('5 minutes past, tip made');
                clearInterval(intervalID);
            } else {
                var msg = "Sending tip in " + seconds_to_go + " Seconds"
                chrome.runtime.sendMessage({popup_timer: msg});
            }
        }, 1000);
    } else if(items.when_to_send == 'immediately') {
        // go ahead and make the tip automatically.
        chrome.runtime.sendMessage({tips: tips, perform_tip: 'auto'});
    }

    chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
        console.log("content script got message");
        if(request.end_5min_timer) {
            clearInterval(intervalID);
        }
    });

});
<commit_msg>implemented whitelist/blacklist<commit_after>var intervalID;

function get_tips() {
    var tips_on_this_page = [];
    $("meta[name=microtip]").each(function(index, element) {
        var e = $(element);
        tips_on_this_page.push({
            'currency': e.data('currency'),
            'address': e.attr('content'),
            'ratio': e.data('ratio'),
            'recipient': e.data('recipient')
        });
    });
    return tips_on_this_page
}

// testcases:
// pass_blacklist_and_whitelist('whitelist', ['aa', 'bb'], 'aa') == true; // in whitelist
// pass_blacklist_and_whitelist('whitelist', ['aa', 'bb'], 'xx') == false; // not in whitelist
// pass_blacklist_and_whitelist('blacklist', ['aa', 'bb'], 'aa') == false; // in blacklist
// pass_blacklist_and_whitelist('blacklist', ['aa', 'bb'], 'cc') == true; // not in blacklist
function pass_blacklist_and_whitelist(setting, domains, this_domain) {
    // setting: either 'blacklist' or 'whitelist'
    // domains: list of strings (domain's that make up the white/blacklist)
    // this_domain: the domain that this page is on
    // returns: true or false, depending on whether this_domain passes or fails the black/whitelist

    for(var i = 0; i < domains.length; i++){
        var domain = domains[i];
        if(domain == this_domain) {
            return setting == 'whitelist';
        }
    };

    return setting == 'blacklist';
}

chrome.storage.sync.get({
    when_to_send: null,
    blacklist_or_whitelist: null,
    domain_list: null,
    interval_seconds: null
}, function(items) {
    var tips = get_tips();
    if(tips.length <= 0) {
        return // No tips found
    }

    var pblwl = true;
    if(items.blacklist_or_whitelist != 'none') {
        // determine if this page's domain jives with the users black/whitelists.
        var pblwl = pass_blacklist_and_whitelist(
            items.blacklist_or_whitelist, items.domain_list, window.location.host
        )
    }

    if(!pblwl) {
        console.log("Autotip canceled because of", items.blacklist_or_whitelist);
        console.log(items.domain_list, window.location.host);
    }

    console.log("Autotip extension found " + tips.length + " microtip meta tags on this page");
    chrome.runtime.sendMessage({found_tips: tips});

    if(pblwl && items.when_to_send == '5mins') {
        var five_minute_counter_start = new Date();
        intervalID = setInterval(function() {
            // update popup status every 1 second. After 5 minutes (or whatever the setting is), make the tip
            var seconds_to_go = Math.floor(items.interval_seconds - ((new Date() - five_minute_counter_start) / 1000));
            if(seconds_to_go <= 0) {
                chrome.runtime.sendMessage({tips: tips, perform_tip: 'auto'});
                console.log('5 minutes past, tip made');
                clearInterval(intervalID);
            } else {
                var msg = "Sending tip in " + seconds_to_go + " Seconds";
                chrome.runtime.sendMessage({popup_timer: msg});
            }
        }, 1000);
    } else if(pblwl && items.when_to_send == 'immediately') {
        // go ahead and make the tip automatically.
        chrome.runtime.sendMessage({tips: tips, perform_tip: 'auto'});
    }

    chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
        console.log("content script got message");
        if(request.end_5min_timer) {
            clearInterval(intervalID);
        }
    });

});
<|endoftext|>


<commit_before>/**
 * MidiLeds v1.0 - An ADSR-based polyphonic MIDI LEDs display for JavaScript.
 * Hugo Hromic - http://github.com/hhromic
 * MIT license
 *
 * Depends: adsrenvelope.js, midicolorpalette.js
 */
/*jslint nomen: true*/

(function () {
    'use strict';

    // Default parameters per MIDI channel
    var _defaults = {
        attackTime: 80, // in milliseconds
        decayTime: 3000, // in milliseconds
        sustainLevel: 0.0, // 0..1 (float)
        releaseTime: 400, // in milliseconds
        baseBrightness: 0x00, // 0x00..0xFF
        enabled: true,
    };

    // Constructor (provide Uint32Array 'leds' for better performance)
    function MidiLeds (leds, noteMin, noteMax, numVoices, midiColorPalette) {
        this._leds = leds;
        this._noteMin = noteMin & 0x7F;
        this._noteMax = noteMax & 0x7F;
        this._numVoices = numVoices;
        this._midiColorPalette = midiColorPalette;

        // Initialise voices
        this._voices = new Array(numVoices);
        for (var i=numVoices; i--;)
            this._voices[i] = {
                channel: 0x0,
                note: 0x0,
                hsv8: [0x00, 0x00, 0x00],
                adsrEnvelope: new AdsrEnvelope(),
                age: 0,
            };
        this._activeVoices = 0;

        // Initialise parameters
        this._parameters = new Array(16);
        for (var i=16; i--;)
            this.reset(i);
    }

    // Prototype shortcut
    var proto = MidiLeds.prototype;

    // Get a voice index to use for a new MIDI note message
    proto._getVoiceIndex = function (channel, note) {
        var oldestIndex = undefined;
        var idleIndex = undefined;
        for (var i=this._numVoices; i--;) {
            if (this._voices[i].channel == channel && this._voices[i].note == note)
                return i;
            if (idleIndex === undefined || this._voices[i].adsrEnvelope.isIdle())
                idleIndex = i;
            if (oldestIndex === undefined || this._voices[i].age > this._voices[oldestIndex].age)
                oldestIndex = i;
        }
        return idleIndex !== undefined ? idleIndex : oldestIndex;
    }

    // Move voice with given index to the front of the voices array
    proto._moveVoice = function (index) {
        var movedVoice = this._voices[index];
        for (var i=index; i--;)
            this._voices[i + 1] = this._voices[i];
        this._voices[0] = movedVoice;
    }

    // Find the voice index corresponding to a MIDI note message, undefined if not found
    proto._findVoiceIndex = function (channel, note) {
        for (var i=this._numVoices; i--;)
            if (this._voices[i].channel == channel && this._voices[i].note == note && !this._voices[i].adsrEnvelope.isIdle())
                return i;
        return undefined;
    }

    // Get attack time for a MIDI channel
    proto.getAttackTime = function (channel) {
        return this._parameters[channel & 0xF].attackTime;
    }

    // Set attack time for a MIDI channel
    proto.setAttackTime = function (channel, attackTime) {
        this._parameters[channel & 0xF].attackTime = attackTime;
    }

    // Get decay time for a MIDI channel
    proto.getDecayTime = function (channel) {
        return this._parameters[channel & 0xF].decayTime;
    }

    // Set decay time for a MIDI channel
    proto.setDecayTime = function (channel, decayTime) {
        this._parameters[channel & 0xF].decayTime = decayTime;
    }

    // Get sustain level for a MIDI channel
    proto.getSustainLevel = function (channel) {
        return this._parameters[channel & 0xF].sustainLevel;
    }

    // Set sustain level for a MIDI channel
    proto.setSustainLevel = function (channel, sustainLevel) {
        this._parameters[channel & 0xF].sustainLevel = sustainLevel;
    }

    // Get release time for a MIDI channel
    proto.getReleaseTime = function (channel) {
        return this._parameters[channel & 0xF].releaseTime;
    }

    // Set release time for a MIDI channel
    proto.setReleaseTime = function (channel, releaseTime) {
        this._parameters[channel & 0xF].releaseTime = releaseTime;
    }

    // Get base brightness for a MIDI channel
    proto.getBaseBrightness = function (channel) {
        return this._parameters[channel & 0xF].baseBrightness;
    }

    // Set base brightness for a MIDI channel
    proto.setBaseBrightness = function (channel, baseBrightness) {
        this._parameters[channel & 0xF].baseBrightness = baseBrightness;
    }

    // Get enable state for a MIDI channel
    proto.isEnabled = function (channel) {
        return this._parameters[channel & 0xF].enabled;
    }

    // Set enable state for a MIDI channel
    proto.setEnabled = function (channel, state) {
        this._parameters[channel & 0xF].enabled = state;
    }

    // Get number of current active voices
    proto.getActiveVoices = function () {
        return this._activeVoices;
    }

    // Process a MIDI Note-On message
    proto.noteOn = function (channel, note, velocity) {
        var p = this._parameters[channel & 0xF];
        if (p.enabled && note >= this._noteMin && note <= this._noteMax) {
            var voiceIndex = this._getVoiceIndex(channel & 0xF, note & 0x7F);
            var voice = this._voices[voiceIndex];
            voice.channel = channel & 0xF;
            voice.note = note & 0x7F;
            voice.hsv8 = this._midiColorPalette.get(channel & 0xF, note & 0x7F, velocity & 0x7F);
            voice.adsrEnvelope.noteOn(p.attackTime, p.decayTime, p.sustainLevel, p.releaseTime);
            voice.age = 0;
            this._moveVoice(voiceIndex);
        }
    }

    // Process a MIDI Note-Off message
    proto.noteOff = function (channel, note) {
        if (this._parameters[channel & 0xF].enabled && note >= this._noteMin && note <= this._noteMax) {
            var voiceIndex = this._findVoiceIndex(channel & 0xF, note & 0x7F);
            if (voiceIndex !== undefined)
                this._voices[voiceIndex].adsrEnvelope.noteOff();
        }
    }

    // Turn all LEDs off for a MIDI channel
    proto.allLedsOff = function (channel) {
        for (var i=this._numVoices; i--;)
            if (this._voices[i].channel == (channel & 0xF) && !this._voices[i].adsrEnvelope.isIdle())
                this._voices[i].adsrEnvelope.noteOff();
    }

    // Reset parameters values to defaults for a MIDI channel
    proto.reset = function (channel) {
        this._parameters[channel & 0xF] = Object.create(_defaults);
    }

    // Process a clock tick signal
    proto.tick = function (time) {
        this._activeVoices = 0;
        for (var i=this._numVoices; i--;) {
            var voice = this._voices[i];
            if (!voice.adsrEnvelope.isIdle()) {
                voice.adsrEnvelope.tick(time);
                voice.age++;
                var brightness = Math.round(voice.hsv8[2] * voice.adsrEnvelope.getOutput());
                if (brightness < this._parameters[voice.channel].baseBrightness)
                    brightness = this._parameters[voice.channel].baseBrightness;
                this._leds[voice.note - this._noteMin] =
                    (voice.hsv8[0] << 16) + (voice.hsv8[1] << 8) + brightness;
                this._activeVoices++;
            }
        }
    }

    // Expose either via AMD, CommonJS or the global object
    if (typeof define === 'function' && define.amd) {
        define(function () {
            return MidiLeds;
        });
    }
    else if (typeof module === 'object' && module.exports) {
        module.exports = MidiLeds;
    }
    else {
        this.MidiLeds = MidiLeds;
    }
}.call(this));
<commit_msg>Added (unused) velocity argument.<commit_after>/**
 * MidiLeds v1.0 - An ADSR-based polyphonic MIDI LEDs display for JavaScript.
 * Hugo Hromic - http://github.com/hhromic
 * MIT license
 *
 * Depends: adsrenvelope.js, midicolorpalette.js
 */
/*jslint nomen: true*/

(function () {
    'use strict';

    // Default parameters per MIDI channel
    var _defaults = {
        attackTime: 80, // in milliseconds
        decayTime: 3000, // in milliseconds
        sustainLevel: 0.0, // 0..1 (float)
        releaseTime: 400, // in milliseconds
        baseBrightness: 0x00, // 0x00..0xFF
        enabled: true,
    };

    // Constructor (provide Uint32Array 'leds' for better performance)
    function MidiLeds (leds, noteMin, noteMax, numVoices, midiColorPalette) {
        this._leds = leds;
        this._noteMin = noteMin & 0x7F;
        this._noteMax = noteMax & 0x7F;
        this._numVoices = numVoices;
        this._midiColorPalette = midiColorPalette;

        // Initialise voices
        this._voices = new Array(numVoices);
        for (var i=numVoices; i--;)
            this._voices[i] = {
                channel: 0x0,
                note: 0x0,
                hsv8: [0x00, 0x00, 0x00],
                adsrEnvelope: new AdsrEnvelope(),
                age: 0,
            };
        this._activeVoices = 0;

        // Initialise parameters
        this._parameters = new Array(16);
        for (var i=16; i--;)
            this.reset(i);
    }

    // Prototype shortcut
    var proto = MidiLeds.prototype;

    // Get a voice index to use for a new MIDI note message
    proto._getVoiceIndex = function (channel, note) {
        var oldestIndex = undefined;
        var idleIndex = undefined;
        for (var i=this._numVoices; i--;) {
            if (this._voices[i].channel == channel && this._voices[i].note == note)
                return i;
            if (idleIndex === undefined || this._voices[i].adsrEnvelope.isIdle())
                idleIndex = i;
            if (oldestIndex === undefined || this._voices[i].age > this._voices[oldestIndex].age)
                oldestIndex = i;
        }
        return idleIndex !== undefined ? idleIndex : oldestIndex;
    }

    // Move voice with given index to the front of the voices array
    proto._moveVoice = function (index) {
        var movedVoice = this._voices[index];
        for (var i=index; i--;)
            this._voices[i + 1] = this._voices[i];
        this._voices[0] = movedVoice;
    }

    // Find the voice index corresponding to a MIDI note message, undefined if not found
    proto._findVoiceIndex = function (channel, note) {
        for (var i=this._numVoices; i--;)
            if (this._voices[i].channel == channel && this._voices[i].note == note && !this._voices[i].adsrEnvelope.isIdle())
                return i;
        return undefined;
    }

    // Get attack time for a MIDI channel
    proto.getAttackTime = function (channel) {
        return this._parameters[channel & 0xF].attackTime;
    }

    // Set attack time for a MIDI channel
    proto.setAttackTime = function (channel, attackTime) {
        this._parameters[channel & 0xF].attackTime = attackTime;
    }

    // Get decay time for a MIDI channel
    proto.getDecayTime = function (channel) {
        return this._parameters[channel & 0xF].decayTime;
    }

    // Set decay time for a MIDI channel
    proto.setDecayTime = function (channel, decayTime) {
        this._parameters[channel & 0xF].decayTime = decayTime;
    }

    // Get sustain level for a MIDI channel
    proto.getSustainLevel = function (channel) {
        return this._parameters[channel & 0xF].sustainLevel;
    }

    // Set sustain level for a MIDI channel
    proto.setSustainLevel = function (channel, sustainLevel) {
        this._parameters[channel & 0xF].sustainLevel = sustainLevel;
    }

    // Get release time for a MIDI channel
    proto.getReleaseTime = function (channel) {
        return this._parameters[channel & 0xF].releaseTime;
    }

    // Set release time for a MIDI channel
    proto.setReleaseTime = function (channel, releaseTime) {
        this._parameters[channel & 0xF].releaseTime = releaseTime;
    }

    // Get base brightness for a MIDI channel
    proto.getBaseBrightness = function (channel) {
        return this._parameters[channel & 0xF].baseBrightness;
    }

    // Set base brightness for a MIDI channel
    proto.setBaseBrightness = function (channel, baseBrightness) {
        this._parameters[channel & 0xF].baseBrightness = baseBrightness;
    }

    // Get enable state for a MIDI channel
    proto.isEnabled = function (channel) {
        return this._parameters[channel & 0xF].enabled;
    }

    // Set enable state for a MIDI channel
    proto.setEnabled = function (channel, state) {
        this._parameters[channel & 0xF].enabled = state;
    }

    // Get number of current active voices
    proto.getActiveVoices = function () {
        return this._activeVoices;
    }

    // Process a MIDI Note-On message
    proto.noteOn = function (channel, note, velocity) {
        var p = this._parameters[channel & 0xF];
        if (p.enabled && note >= this._noteMin && note <= this._noteMax) {
            var voiceIndex = this._getVoiceIndex(channel & 0xF, note & 0x7F);
            var voice = this._voices[voiceIndex];
            voice.channel = channel & 0xF;
            voice.note = note & 0x7F;
            voice.hsv8 = this._midiColorPalette.get(channel & 0xF, note & 0x7F, velocity & 0x7F);
            voice.adsrEnvelope.noteOn(p.attackTime, p.decayTime, p.sustainLevel, p.releaseTime);
            voice.age = 0;
            this._moveVoice(voiceIndex);
        }
    }

    // Process a MIDI Note-Off message
    proto.noteOff = function (channel, note, velocity) {
        if (this._parameters[channel & 0xF].enabled && note >= this._noteMin && note <= this._noteMax) {
            var voiceIndex = this._findVoiceIndex(channel & 0xF, note & 0x7F);
            if (voiceIndex !== undefined)
                this._voices[voiceIndex].adsrEnvelope.noteOff();
        }
    }

    // Turn all LEDs off for a MIDI channel
    proto.allLedsOff = function (channel) {
        for (var i=this._numVoices; i--;)
            if (this._voices[i].channel == (channel & 0xF) && !this._voices[i].adsrEnvelope.isIdle())
                this._voices[i].adsrEnvelope.noteOff();
    }

    // Reset parameters values to defaults for a MIDI channel
    proto.reset = function (channel) {
        this._parameters[channel & 0xF] = Object.create(_defaults);
    }

    // Process a clock tick signal
    proto.tick = function (time) {
        this._activeVoices = 0;
        for (var i=this._numVoices; i--;) {
            var voice = this._voices[i];
            if (!voice.adsrEnvelope.isIdle()) {
                voice.adsrEnvelope.tick(time);
                voice.age++;
                var brightness = Math.round(voice.hsv8[2] * voice.adsrEnvelope.getOutput());
                if (brightness < this._parameters[voice.channel].baseBrightness)
                    brightness = this._parameters[voice.channel].baseBrightness;
                this._leds[voice.note - this._noteMin] =
                    (voice.hsv8[0] << 16) + (voice.hsv8[1] << 8) + brightness;
                this._activeVoices++;
            }
        }
    }

    // Expose either via AMD, CommonJS or the global object
    if (typeof define === 'function' && define.amd) {
        define(function () {
            return MidiLeds;
        });
    }
    else if (typeof module === 'object' && module.exports) {
        module.exports = MidiLeds;
    }
    else {
        this.MidiLeds = MidiLeds;
    }
}.call(this));
<|endoftext|>