Skip to content

Instantly share code, notes, and snippets.

@karmiphuc
Last active April 5, 2016 09:49
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save karmiphuc/686e9c4066d475f54562d795727236f2 to your computer and use it in GitHub Desktop.
BitCoin Big Bang: Amazing visualization from Elliptic.co https://www.elliptic.co/bigbang-v1.html
<!doctype html public>
<!--[if lt IE 7]> <html lang="en-us" class="lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html lang="en-us" class="lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html lang="en-us" class="lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html lang="en-us"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<title>Elliptic - The Bitcoin Big Bang</title>
<meta name="viewport" content="width=device-width">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="assets/icons/style.css">
<link rel="stylesheet" type="text/css" href="dist/style.css">
</head>
<body>
<div class="viz">
</div>
<div class="node-search">
</div>
<a class="elliptic-link">
<img src="assets/images/logo.svg" class="elliptic-link__logo">
</a>
<header>
<h1>The Bitcoin <br/>Big Bang</h1>
</header>
<footer>
<span class="information-button-toggle information-button-toggle--show" title="Show Legend">?</span>
</footer>
<div class="information">
<span class="information-button-toggle information-button-toggle--hide" title="Hide Legend">×</span>
<div class="information__scrollable-box">
<h1>The Bitcoin Big Bang</h1>
<hr>
<p align="left">This visualisation shows the emergence over time of the largest entities on the Bitcoin blockchain, and their interconnectivity.</p>
<p>We have anonymised most active businesses and private individuals in order to protect their identities.</p>
<p>The distance from the centre represents the first appearance of each entity, with Satoshi Nakomoto in the middle, depicting the genesis of Bitcoin in 2009.</p>
<p>The colour of an entity represents its type:</p>
<table class="color-key">
<tr class="color-key__row color-key__row--yellow">
<th>
<div class="color-key__node color-key__node--yellow"></div>
</th>
<td class="color-key__label-cell">
<p>Creator</p>
</td>
</tr>
<tr class="color-key__row color-key__row--green">
<th>
<div class="color-key__node color-key__node--green"></div>
</th>
<td class="color-key__label-cell">
<p>Payment Processor</p>
<p>Lending Service</p>
<p>Mining Pool</p>
<p>Forum User</p>
<p>Exchange</p>
<p>Charity</p>
<p>Wallet Service</p>
<p>Faucet</p>
</td>
</tr>
<tr class="color-key__row color-key__row--red">
<th>
<div class="color-key__node color-key__node--red"></div>
</th>
<td class="color-key__label-cell">
<p>Dark Marketplace</p>
<p>Tumbler</p>
<p>Scam</p>
</td>
</tr>
<tr class="color-key__row color-key__row--orange">
<th>
<div class="color-key__node color-key__node--orange"></div>
</th>
<td class="color-key__label-cell">
<p>Gambling Service</p>
</td>
</tr>
<tr class="color-key__row color-key__row--white">
<th>
<div class="color-key__node color-key__node--white"></div>
</th>
<td class="color-key__label-cell">
<p>Unidentified</p>
</td>
</tr>
</table>
<p>The size of the entity represents the total volume of its bitcoin transactions.</p>
<!--<img src="assets/images/sizeKey.png" alt="">-->
<p>The lines show transactions between entities, with thicker lines indicating higher total transaction volumes.</p>
<p>Select an entity to highlight its major transaction flows.</p>
</div>
</div>
<script src="dist/d3.min.js" type="text/javascript" charset="utf-8"></script>
<script src="dist/pixi.min.js" type="text/javascript" charset="utf-8"></script>
<script src="dist/bundle.min.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>
{
"nodes": [
{
"name": "satoshi nakamoto",
"transacted": 0.1503194650817236,
"appeared": "2009-01-03t18:15:05z",
"type": "creator",
"id": 0
},
{
"name": "mt. gox",
"transacted": 10,
"appeared": "2010-11-08t02:29:49z",
"type": "exchange",
"id": 281475210091085
},
{
"name": "silk road",
"transacted": 0.9500133745913819,
"appeared": "2012-06-18t01:02:15z",
"type": "dark marketplace",
"id": 281475012263700
},
{
"name": "known exchange",
"transacted": 0.7545605338781575,
"appeared": "2011-08-08t14:40:32z",
"type": "exchange",
"id": 281474988879238
},
{
"name": "silk road 2.0",
"transacted": 0.023559418053491828,
"appeared": "2013-11-11t05:07:40z",
"type": "dark marketplace",
"id": 281475202912575
},
{
"name": "known exchange",
"transacted": 0.053286913684992575,
"appeared": "2013-05-20t15:42:34z",
"type": "exchange",
"id": 281475129278567
},
{
"name": "localbitcoins",
"transacted": 0.13384572500742942,
"appeared": "2012-07-24t08:13:31z",
"type": "exchange",
"id": 281475026831048
},
{
"name": "betvip",
"transacted": 0.034669926419019316,
"appeared": "2012-09-26t06:20:30z",
"type": "gambling service",
"id": 281475265851748
},
{
"name": "known payment processor",
"transacted": 0.1901246778603269,
"appeared": "2011-07-02t04:00:53z",
"type": "payment processor",
"id": 281474985643606
},
{
"name": "known exchange",
"transacted": 0.02718612426448737,
"appeared": "2013-09-17t13:51:37z",
"type": "exchange",
"id": 281475180042200
},
{
"name": null,
"transacted": 0.0022022080014858845,
"appeared": "2013-06-16t19:55:17z",
"type": "-",
"id": 281475147489673
},
{
"name": "agora",
"transacted": 0.014518219019316493,
"appeared": "2013-12-04t23:02:15z",
"type": "dark marketplace",
"id": 281475219091935
},
{
"name": "known exchange",
"transacted": 0.8445278154531946,
"appeared": "2011-08-17t14:31:40z",
"type": "exchange",
"id": 281474987869318
},
{
"name": "instawallet",
"transacted": 0.3154634759286776,
"appeared": "2011-05-03t23:14:27z",
"type": "wallet",
"id": 281474980772798
},
{
"name": "known forum user",
"transacted": 0.545384563001486,
"appeared": "2011-06-18t07:57:46z",
"type": "forum user",
"id": 281474984658672
},
{
"name": "bitcoin fog",
"transacted": 0.12619356160475484,
"appeared": "2011-11-10t23:44:03z",
"type": "tumbler",
"id": 281474993401991
},
{
"name": "mintpal",
"transacted": 0.023797802808320955,
"appeared": "2014-02-02t19:39:41z",
"type": "exchange",
"id": 281475253600611
},
{
"name": null,
"transacted": 0.003616231514115899,
"appeared": "2013-05-30t18:02:19z",
"type": "-",
"id": 281475133010629
},
{
"name": "known exchange",
"transacted": 0.009510247494799406,
"appeared": "2014-02-13t07:33:40z",
"type": "exchange",
"id": 281475270412585
},
{
"name": "known exchange",
"transacted": 0.16169727726597324,
"appeared": "2011-08-26t16:55:12z",
"type": "exchange",
"id": 281474990790137
},
{
"name": "bitzino",
"transacted": 0.049969710252600295,
"appeared": "2012-06-08t01:38:41z",
"type": "gambling service",
"id": 281475009385593
},
{
"name": "sheep marketplace",
"transacted": 0.010893237139673106,
"appeared": "2013-02-01t15:35:28z",
"type": "dark marketplace",
"id": 281475183520613
},
{
"name": "999 dice",
"transacted": 0.0006490699778603268,
"appeared": "2013-12-28t01:35:39z",
"type": "gambling service",
"id": 281475232837820
},
{
"name": null,
"transacted": 0.001079786681129272,
"appeared": "2014-03-15t10:51:25z",
"type": "-",
"id": 281475281982646
},
{
"name": "known exchange",
"transacted": 0.007110667921248143,
"appeared": "2014-01-14t02:19:11z",
"type": "exchange",
"id": 281475246802390
},
{
"name": null,
"transacted": 0.012459598901931648,
"appeared": "2013-06-28t22:05:47z",
"type": "-",
"id": 281475144797344
},
{
"name": "known exchange",
"transacted": 0.048916768142644874,
"appeared": "2011-06-09t16:21:45z",
"type": "exchange",
"id": 281474982015110
},
{
"name": "evolution",
"transacted": 0.0010098281069836552,
"appeared": "2014-01-16t17:32:51z",
"type": "dark marketplace",
"id": 281475295775581
},
{
"name": null,
"transacted": 0.007986186572065379,
"appeared": "2011-09-12t11:01:07z",
"type": "-",
"id": 281475003263315
},
{
"name": "known exchange",
"transacted": 0.03072745191679049,
"appeared": "2013-09-09t08:16:24z",
"type": "exchange",
"id": 281475188793046
},
{
"name": "pandora open market",
"transacted": 0.0023176115037147104,
"appeared": "2013-10-22t01:20:17z",
"type": "dark marketplace",
"id": 281475215986089
},
{
"name": "known exchange",
"transacted": 0.03917733135215453,
"appeared": "2012-07-15t12:43:36z",
"type": "exchange",
"id": 281475110926830
},
{
"name": null,
"transacted": 0.10603298154531947,
"appeared": "2013-12-27t19:36:28z",
"type": "-",
"id": 281475236428593
},
{
"name": null,
"transacted": 0.007913692202080238,
"appeared": "2013-07-12t09:04:17z",
"type": "-",
"id": 281475151542740
},
{
"name": "mcxnow",
"transacted": 0.016103525378900446,
"appeared": "2013-04-27t11:45:31z",
"type": "exchange",
"id": 281475116278995
},
{
"name": "known exchange",
"transacted": 0.03553858325408618,
"appeared": "2011-07-31t11:00:06z",
"type": "exchange",
"id": 281474987662543
},
{
"name": "known exchange",
"transacted": 0.09555288973254086,
"appeared": "2013-11-24t13:04:39z",
"type": "exchange",
"id": 281475226624011
},
{
"name": null,
"transacted": 0.010906866698365528,
"appeared": "2013-10-24t21:32:24z",
"type": "-",
"id": 281475193922855
},
{
"name": "known exchange",
"transacted": 0.007688420696879643,
"appeared": "2013-05-11t18:49:21z",
"type": "exchange",
"id": 281475123155348
},
{
"name": "known exchange",
"transacted": 0.2508215181277861,
"appeared": "2013-09-02t14:24:41z",
"type": "exchange",
"id": 281475264419261
},
{
"name": null,
"transacted": 0.006300720820208024,
"appeared": "2013-08-27t14:26:58z",
"type": "-",
"id": 281475167158536
},
{
"name": null,
"transacted": 0.01193224727191679,
"appeared": "2013-08-13t20:39:23z",
"type": "-",
"id": 281475160479472
},
{
"name": "sealswithclubs",
"transacted": 0.02323082309063893,
"appeared": "2011-10-08t08:12:31z",
"type": "gambling service",
"id": 281474994950401
},
{
"name": "btc dice",
"transacted": 0.009893619803863298,
"appeared": "2012-07-10t08:30:21z",
"type": "gambling service",
"id": 281475016972288
},
{
"name": "just-dice",
"transacted": 0.042420097325408614,
"appeared": "2013-06-20t03:47:33z",
"type": "gambling service",
"id": 281475141004665
},
{
"name": null,
"transacted": 0.007403132331352154,
"appeared": "2014-01-13t14:42:04z",
"type": "-",
"id": 281475240193197
},
{
"name": null,
"transacted": 0.009988887429420506,
"appeared": "2013-04-15t09:32:20z",
"type": "-",
"id": 281475113307130
},
{
"name": "known wallet service",
"transacted": 0.030742688573551266,
"appeared": "2012-04-05t22:16:35z",
"type": "wallet",
"id": 281475001032288
},
{
"name": "known exchange",
"transacted": 0.006029742881129271,
"appeared": "2014-04-03t12:44:01z",
"type": "exchange",
"id": 281475292573256
},
{
"name": "known exchange",
"transacted": 0.00968032883655275,
"appeared": "2013-06-01t20:23:49z",
"type": "exchange",
"id": 281475139885675
},
{
"name": "known exchange",
"transacted": 0.0032282881010401187,
"appeared": "2012-12-01t21:12:39z",
"type": "exchange",
"id": 281475114779368
},
{
"name": null,
"transacted": 0.0828527486627043,
"appeared": "2011-09-05t17:35:32z",
"type": "-",
"id": 281474989733990
},
{
"name": "bitcoin roulette",
"transacted": 0.002849925567607727,
"appeared": "2012-04-05t16:07:33z",
"type": "gambling service",
"id": 281475003395431
},
{
"name": null,
"transacted": 0.03793127285289748,
"appeared": "2011-12-09t01:18:16z",
"type": "-",
"id": 281474993866807
},
{
"name": "known exchange",
"transacted": 0.04049494887072808,
"appeared": "2011-07-06t17:26:16z",
"type": "exchange",
"id": 281474984571778
},
{
"name": "known exchange",
"transacted": 0.02196573854383358,
"appeared": "2012-05-31t18:10:17z",
"type": "exchange",
"id": 281475018933925
},
{
"name": null,
"transacted": 0.02710177716196137,
"appeared": "2012-04-04t14:16:52z",
"type": "-",
"id": 281475000472806
},
{
"name": "known exchange",
"transacted": 0.019766188187221395,
"appeared": "2014-07-20t08:39:02z",
"type": "exchange",
"id": 281475362745677
},
{
"name": null,
"transacted": 0.0008100829576523031,
"appeared": "2014-02-08t10:32:27z",
"type": "-",
"id": 281475260404909
},
{
"name": "known forum user",
"transacted": 0.00017125116998514115,
"appeared": "2012-01-25t09:52:48z",
"type": "forum user",
"id": 281474997632233
},
{
"name": null,
"transacted": 0.00041182865616641904,
"appeared": "2013-11-26t19:20:44z",
"type": "-",
"id": 281475211959472
},
{
"name": null,
"transacted": 0.006484166184249628,
"appeared": "2012-06-08t22:14:43z",
"type": "-",
"id": 281475009177097
},
{
"name": "known exchange",
"transacted": 0.0639036414858841,
"appeared": "2011-04-24t07:34:16z",
"type": "exchange",
"id": 281474980419003
},
{
"name": null,
"transacted": 0.007709351187221397,
"appeared": "2012-05-21t00:50:20z",
"type": "-",
"id": 281475005000946
},
{
"name": null,
"transacted": 0.05250982745913819,
"appeared": "2012-10-25t05:58:43z",
"type": "-",
"id": 281475052946851
},
{
"name": null,
"transacted": 0.032328509479940565,
"appeared": "2013-07-09t09:40:47z",
"type": "-",
"id": 281475153218308
},
{
"name": null,
"transacted": 0.0058528652897474,
"appeared": "2012-09-15t21:02:10z",
"type": "-",
"id": 281475035199473
},
{
"name": "bitmit",
"transacted": 0.003935695063893017,
"appeared": "2011-08-03t22:08:19z",
"type": "exchange",
"id": 281474986870464
},
{
"name": "pandora marketplace",
"transacted": 0.0012403145390787519,
"appeared": "2014-04-27t13:41:44z",
"type": "dark marketplace",
"id": 281475309660615
},
{
"name": "bitcoin video casino",
"transacted": 0.002559014736998514,
"appeared": "2014-01-02t06:47:24z",
"type": "gambling service",
"id": 281475234100993
},
{
"name": "blue sky marketplace",
"transacted": 0.0012960660129271919,
"appeared": "2013-12-06t16:33:06z",
"type": "dark marketplace",
"id": 281475229250564
},
{
"name": null,
"transacted": 0.0013342523693907877,
"appeared": "2013-07-22t20:11:28z",
"type": "-",
"id": 281475155547156
},
{
"name": null,
"transacted": 0.0384059273551263,
"appeared": "2012-06-17t18:48:36z",
"type": "-",
"id": 281475012223763
},
{
"name": "inputs.io",
"transacted": 0.013071427613670134,
"appeared": "2013-06-25t07:29:41z",
"type": "wallet",
"id": 281475143704011
},
{
"name": null,
"transacted": 0.00007074628008915305,
"appeared": "2012-02-11t17:25:10z",
"type": "-",
"id": 281474997726930
},
{
"name": "known payment processor",
"transacted": 0.03349867719167905,
"appeared": "2012-03-07t09:18:16z",
"type": "payment processor",
"id": 281474998934375
},
{
"name": "known forum user",
"transacted": 0.14166472943536407,
"appeared": "2010-04-27t02:30:05z",
"type": "forum user",
"id": 281474977355381
},
{
"name": null,
"transacted": 0.012056194673105496,
"appeared": "2010-07-19t00:39:33z",
"type": "-",
"id": 281474977620388
},
{
"name": null,
"transacted": 0.009688583704309065,
"appeared": "2013-03-24t06:57:19z",
"type": "-",
"id": 281475101361223
},
{
"name": "coinroll",
"transacted": 0.0017065881203566122,
"appeared": "2013-04-25t10:27:43z",
"type": "gambling service",
"id": 281475122352426
},
{
"name": "mercado bitcoin",
"transacted": 0.01668808661218425,
"appeared": "2011-07-27t06:45:43z",
"type": "gambling service",
"id": 281474987955397
},
{
"name": "satoshibet",
"transacted": 0.0006692555956909361,
"appeared": "2013-12-10t18:16:38z",
"type": "gambling service",
"id": 281475221463628
},
{
"name": null,
"transacted": 0.010122511052005942,
"appeared": "2012-06-07t02:30:46z",
"type": "-",
"id": 281475008772185
},
{
"name": null,
"transacted": 0.015741820163447252,
"appeared": "2011-07-15t08:43:01z",
"type": "-",
"id": 281474985866991
},
{
"name": null,
"transacted": 0.011566931136701337,
"appeared": "2013-12-17t06:12:07z",
"type": "-",
"id": 281475235093341
},
{
"name": "known exchange",
"transacted": 0.01026173323922734,
"appeared": "2011-10-22t15:05:01z",
"type": "exchange",
"id": 281474995055321
},
{
"name": null,
"transacted": 0.002119457566121843,
"appeared": "2013-11-10t14:12:42z",
"type": "-",
"id": 281475201906447
},
{
"name": null,
"transacted": 0.02040565985141159,
"appeared": "2011-12-29t03:52:58z",
"type": "-",
"id": 281475021525259
},
{
"name": null,
"transacted": 0.013380525913818723,
"appeared": "2014-02-10t17:35:40z",
"type": "-",
"id": 281475256720206
},
{
"name": null,
"transacted": 0.008885763459138187,
"appeared": "2013-09-02t16:24:32z",
"type": "-",
"id": 281475171251847
},
{
"name": null,
"transacted": 0.03147300863298663,
"appeared": "2011-10-17t16:06:59z",
"type": "-",
"id": 281474991672959
},
{
"name": "known forum user",
"transacted": 0.0018687176790490342,
"appeared": "2012-10-19t23:48:34z",
"type": "forum user",
"id": 281475043793309
},
{
"name": "known forum user",
"transacted": 0.007457411212481426,
"appeared": "2011-12-26t05:58:45z",
"type": "forum user",
"id": 281474994618715
},
{
"name": null,
"transacted": 0.007724976413075781,
"appeared": "2013-10-10t02:43:06z",
"type": "-",
"id": 281475187606240
},
{
"name": "known exchange",
"transacted": 0.0037732682867756316,
"appeared": "2014-03-16t16:05:39z",
"type": "exchange",
"id": 281475280756614
},
{
"name": "known exchange",
"transacted": 0.09739917484398217,
"appeared": "2012-03-24t22:32:02z",
"type": "exchange",
"id": 281475000439797
},
{
"name": null,
"transacted": 0.007453405126300148,
"appeared": "2013-03-13t13:41:22z",
"type": "-",
"id": 281475095106166
},
{
"name": "nitrogen sports",
"transacted": 0.002557420870728083,
"appeared": "2013-11-29t18:17:10z",
"type": "gambling service",
"id": 281475217097383
},
{
"name": "known exchange",
"transacted": 0.0014636425215453193,
"appeared": "2013-06-25t18:24:46z",
"type": "exchange",
"id": 281475147035820
},
{
"name": "black market reloaded",
"transacted": 0.0045707242927191674,
"appeared": "2012-10-30t05:30:15z",
"type": "dark marketplace",
"id": 281475047371518
},
{
"name": "bitcoin faucet",
"transacted": 0.01568094408618128,
"appeared": "2012-03-02t21:56:45z",
"type": "faucet",
"id": 281475037563976
},
{
"name": "satoshi roulette",
"transacted": 0.0001552812543833581,
"appeared": "2013-10-07t03:10:13z",
"type": "gambling service",
"id": 281475185368467
},
{
"name": "crypto rush",
"transacted": 0.0009756986582466568,
"appeared": "2013-04-08t13:14:28z",
"type": "exchange",
"id": 281475247833907
},
{
"name": "known forum user",
"transacted": 0.0020919791144130757,
"appeared": "2014-07-29t19:24:10z",
"type": "forum user",
"id": 281475368715547
},
{
"name": "known exchange",
"transacted": 0.01327367887369985,
"appeared": "2012-05-22t23:05:58z",
"type": "exchange",
"id": 281475005723784
},
{
"name": "known forum user",
"transacted": 0.0005820673109955424,
"appeared": "2011-06-18t19:05:18z",
"type": "forum user",
"id": 281474983258892
},
{
"name": "known forum user",
"transacted": 0.003262137895988113,
"appeared": "2012-05-09t01:55:11z",
"type": "forum user",
"id": 281475002942591
},
{
"name": null,
"transacted": 0.0199409620653789,
"appeared": "2011-07-31t19:05:24z",
"type": "-",
"id": 281474986793379
},
{
"name": "crypto-trade",
"transacted": 0.002356450221396731,
"appeared": "2013-05-19t22:00:34z",
"type": "exchange",
"id": 281475130294428
},
{
"name": "known exchange",
"transacted": 0.030375569153046064,
"appeared": "2013-08-01t03:05:58z",
"type": "exchange",
"id": 281475206412470
},
{
"name": null,
"transacted": 0.043021895245170874,
"appeared": "2014-01-21t00:59:53z",
"type": "-",
"id": 281475244207011
},
{
"name": "known lending service",
"transacted": 0.0010777306524517088,
"appeared": "2014-05-28t05:13:12z",
"type": "lending service",
"id": 281475328353703
},
{
"name": "primedice",
"transacted": 0.0007232400658246656,
"appeared": "2014-06-16t12:58:46z",
"type": "gambling service",
"id": 281475340893413
},
{
"name": null,
"transacted": 0.013532370092124815,
"appeared": "2012-09-04t05:18:08z",
"type": "-",
"id": 281475032245742
},
{
"name": null,
"transacted": 0.006168950843982169,
"appeared": "2012-06-05t11:26:09z",
"type": "-",
"id": 281475008561530
},
{
"name": "betcoins",
"transacted": 0.0002474652808320951,
"appeared": "2013-02-27t21:53:43z",
"type": "gambling service",
"id": 281475091828341
},
{
"name": "known mining pool",
"transacted": 0.11184565191679048,
"appeared": "2012-11-06t21:10:47z",
"type": "mining pool",
"id": 281475048031940
},
{
"name": "primedice",
"transacted": 0.000441907046359584,
"appeared": "2014-08-09t17:40:53z",
"type": "gambling service",
"id": 281475376679396
},
{
"name": "known payment processor",
"transacted": 0.042251995958395246,
"appeared": "2013-04-16t13:21:18z",
"type": "payment processor",
"id": 281475113272497
},
{
"name": "known forum user",
"transacted": 0.005145274459138188,
"appeared": "2011-12-10t04:39:47z",
"type": "forum user",
"id": 281474993903979
},
{
"name": "known wallet service",
"transacted": 0.04131037854383358,
"appeared": "2010-12-29t22:53:46z",
"type": "wallet",
"id": 281474978298062
},
{
"name": null,
"transacted": 0.013870414377414562,
"appeared": "2013-06-12t23:22:34z",
"type": "-",
"id": 281475138010711
},
{
"name": null,
"transacted": 0.0016682053150074293,
"appeared": "2012-07-11t16:46:18z",
"type": "-",
"id": 281475020670630
},
{
"name": "known exchange",
"transacted": 0.002695268268945022,
"appeared": "2013-01-02t15:08:37z",
"type": "exchange",
"id": 281475071096971
},
{
"name": "known exchange",
"transacted": 0.007743297903417534,
"appeared": "2011-10-31t12:25:04z",
"type": "exchange",
"id": 281474992553399
},
{
"name": "known forum user",
"transacted": 0.0018458603655274889,
"appeared": "2012-08-27t12:31:41z",
"type": "forum user",
"id": 281475053530700
},
{
"name": "bitcoin roulette",
"transacted": 0.00012485444961367014,
"appeared": "2013-04-08t14:23:02z",
"type": "gambling service",
"id": 281475106789676
},
{
"name": null,
"transacted": 0.0923518078306092,
"appeared": "2013-02-04t09:29:46z",
"type": "-",
"id": 281475076855361
},
{
"name": "known payment processor",
"transacted": 0.00043799081797919764,
"appeared": "2013-08-05t21:47:22z",
"type": "payment processor",
"id": 281475180113265
},
{
"name": null,
"transacted": 0.0044693307310549775,
"appeared": "2011-03-28t17:15:33z",
"type": "-",
"id": 281474981005547
},
{
"name": "bitcoin-24",
"transacted": 0.0369766788410104,
"appeared": "2012-11-06t13:38:49z",
"type": "exchange",
"id": 281475048020634
},
{
"name": "vault of satoshi",
"transacted": 0.0013943584520059434,
"appeared": "2014-01-29t21:43:39z",
"type": "wallet",
"id": 281475252773947
},
{
"name": null,
"transacted": 0.0582246018127786,
"appeared": "2013-06-26t11:48:03z",
"type": "-",
"id": 281475170210314
},
{
"name": "known exchange",
"transacted": 0.0003603184841010401,
"appeared": "2014-02-07t14:40:42z",
"type": "exchange",
"id": 281475254896533
},
{
"name": null,
"transacted": 0.004520748294205052,
"appeared": "2011-06-18t18:58:25z",
"type": "-",
"id": 281474982934082
},
{
"name": "known forum user",
"transacted": 0.017753090312035664,
"appeared": "2010-09-12t01:17:52z",
"type": "forum user",
"id": 281474978457429
},
{
"name": "known exchange",
"transacted": 0.00248467403268945,
"appeared": "2013-07-22t21:50:56z",
"type": "exchange",
"id": 281475151740837
},
{
"name": "bitfloor",
"transacted": 0.03431425603268945,
"appeared": "2012-09-21t08:53:02z",
"type": "exchange",
"id": 281475036710988
},
{
"name": null,
"transacted": 0.00034616465616641904,
"appeared": "2012-12-26t12:16:25z",
"type": "-",
"id": 281475061970820
},
{
"name": "satoshibet",
"transacted": 0.00031780547533432393,
"appeared": "2013-06-26t23:34:59z",
"type": "gambling service",
"id": 281475144205819
},
{
"name": "dkms polska",
"transacted": 0.0011446825630014859,
"appeared": "2014-03-01t16:13:21z",
"type": "charity",
"id": 281475274476097
},
{
"name": null,
"transacted": 0.005914814898959881,
"appeared": "2012-07-10t08:10:40z",
"type": "-",
"id": 281475016996696
},
{
"name": "known exchange",
"transacted": 0.0011808285680534917,
"appeared": "2014-05-26t14:15:38z",
"type": "exchange",
"id": 281475327438328
},
{
"name": "mybitcoin",
"transacted": 0.01093011318127786,
"appeared": "2011-06-18t15:00:05z",
"type": "wallet",
"id": 281474985647265
},
{
"name": "known exchange ",
"transacted": 0.0006088352907875186,
"appeared": "2013-04-05t15:26:25z",
"type": "exchange",
"id": 281475108753703
},
{
"name": null,
"transacted": 0.01150714085884101,
"appeared": "2012-04-19t19:59:08z",
"type": "-",
"id": 281475001343013
},
{
"name": "coingaming",
"transacted": 0.00018888236077265974,
"appeared": "2013-12-05t19:57:23z",
"type": "gambling service",
"id": 281475218452267
},
{
"name": "flexcoin",
"transacted": 0.006471076739970282,
"appeared": "2011-07-18t20:49:58z",
"type": "wallet",
"id": 281474985584341
},
{
"name": null,
"transacted": 0.004802893352154532,
"appeared": "2012-03-28t15:52:04z",
"type": "-",
"id": 281475020950766
},
{
"name": "aggaming",
"transacted": 0.005490299367013373,
"appeared": "2013-12-11t02:30:18z",
"type": "gambling service",
"id": 281475221654588
},
{
"name": null,
"transacted": 0.04259320745913818,
"appeared": "2014-04-23t18:53:09z",
"type": "-",
"id": 281475305515717
},
{
"name": "known forum user",
"transacted": 0.000423386597473997,
"appeared": "2012-12-16t08:29:45z",
"type": "forum user",
"id": 281475058679082
},
{
"name": null,
"transacted": 0.005053231977711739,
"appeared": "2010-12-14t15:42:27z",
"type": "-",
"id": 281474978312731
},
{
"name": "peerbet",
"transacted": 0.0001379676730757801,
"appeared": "2013-10-12t13:53:21z",
"type": "gambling service",
"id": 281475200747599
},
{
"name": "betcoin.ag (old)",
"transacted": 0.0005012965196136702,
"appeared": "2013-11-12t23:07:12z",
"type": "gambling service",
"id": 281475213918095
},
{
"name": "bitcoin minefield",
"transacted": 0.00010733117720653787,
"appeared": "2012-08-06t14:41:40z",
"type": "gambling service",
"id": 281475028770482
},
{
"name": null,
"transacted": 0.005267627607726598,
"appeared": "2013-01-23t17:13:13z",
"type": "-",
"id": 281475071921387
},
{
"name": "known exchange",
"transacted": 0.010616245915304605,
"appeared": "2012-03-01t10:53:51z",
"type": "exchange",
"id": 281474999940018
},
{
"name": "betsofbitco.in",
"transacted": 0.0059648282763744434,
"appeared": "2011-08-12t23:02:03z",
"type": "gambling service",
"id": 281474987596389
},
{
"name": "known forum user",
"transacted": 0.0033147092421991083,
"appeared": "2013-01-24t12:42:38z",
"type": "forum user",
"id": 281475074919716
},
{
"name": null,
"transacted": 0.00008266170276374443,
"appeared": "2013-06-08t10:05:43z",
"type": "-",
"id": 281475136570761
},
{
"name": null,
"transacted": 0.00534224456166419,
"appeared": "2014-02-12t10:37:51z",
"type": "-",
"id": 281475282106701
},
{
"name": "known mining pool",
"transacted": 0.07466753534918276,
"appeared": "2012-07-31t16:15:21z",
"type": "mining pool",
"id": 281475105016529
},
{
"name": null,
"transacted": 0.004606957560178306,
"appeared": "2012-08-02t15:01:12z",
"type": "-",
"id": 281475022867883
},
{
"name": "known exchange",
"transacted": 0.00019776440728083212,
"appeared": "2014-08-04t15:57:43z",
"type": "exchange",
"id": 281475372688630
},
{
"name": null,
"transacted": 0.00007661540141158989,
"appeared": "2013-08-06t11:26:07z",
"type": "-",
"id": 281475157743726
},
{
"name": "known exchange",
"transacted": 0.00031451911768202084,
"appeared": "2014-01-26t15:03:36z",
"type": "exchange",
"id": 281475256021078
},
{
"name": "coin-swap",
"transacted": 0.000024319010624071324,
"appeared": "2014-04-16t18:16:53z",
"type": "exchange",
"id": 281475329756178
},
{
"name": null,
"transacted": 0.004869785060921249,
"appeared": "2013-01-28t00:00:20z",
"type": "-",
"id": 281475073649929
},
{
"name": "known forum user",
"transacted": 0.0002557288141158989,
"appeared": "2013-04-11t14:39:21z",
"type": "forum user",
"id": 281475122556296
},
{
"name": "known exchange",
"transacted": 0.005189749542347697,
"appeared": "2013-06-27t04:16:39z",
"type": "exchange",
"id": 281475147815999
},
{
"name": "known exchange ",
"transacted": 0.0012812968020802379,
"appeared": "2013-12-16t16:35:11z",
"type": "exchange",
"id": 281475226888878
},
{
"name": null,
"transacted": 0.07832918215453194,
"appeared": "2013-06-12t23:22:34z",
"type": "-",
"id": 281475137979038
},
{
"name": "bitoomba",
"transacted": 0.0002786403323922734,
"appeared": "2013-07-30t08:14:29z",
"type": "gambling service",
"id": 281475154231430
},
{
"name": "bitcoin-24",
"transacted": 0.038463665512630016,
"appeared": "2012-04-17t10:36:14z",
"type": "exchange",
"id": 281475001126262
},
{
"name": "known forum user",
"transacted": 0.00024859570193164936,
"appeared": "2012-04-13t04:31:21z",
"type": "forum user",
"id": 281475001026620
},
{
"name": "cannabis road",
"transacted": 0.00032821482347696876,
"appeared": "2014-04-01t06:36:53z",
"type": "dark marketplace",
"id": 281475301113563
},
{
"name": "known exchange",
"transacted": 0.0027742581693907874,
"appeared": "2014-02-17t18:55:56z",
"type": "exchange",
"id": 281475261832442
},
{
"name": "known forum user",
"transacted": 0.00010479776236255573,
"appeared": "2011-06-08t05:49:08z",
"type": "forum user",
"id": 281475116276002
},
{
"name": null,
"transacted": 0.01011795411144131,
"appeared": "2012-06-19t06:54:06z",
"type": "-",
"id": 281475012633267
},
{
"name": null,
"transacted": 0.005596012527488856,
"appeared": "2012-06-05t11:26:09z",
"type": "-",
"id": 281475008442669
},
{
"name": "known exchange",
"transacted": 0.06996648618127785,
"appeared": "2012-10-09t09:22:57z",
"type": "exchange",
"id": 281475041010913
},
{
"name": null,
"transacted": 0.005758131823179791,
"appeared": "2012-05-12t16:15:52z",
"type": "-",
"id": 281475005616872
},
{
"name": null,
"transacted": 0.04145844575037148,
"appeared": "2011-11-07t22:45:20z",
"type": "-",
"id": 281474992550692
},
{
"name": "bitcoinica",
"transacted": 0.049988418142644875,
"appeared": "2011-09-17t03:54:40z",
"type": "exchange",
"id": 281474989852573
},
{
"name": null,
"transacted": 0.021315947815750372,
"appeared": "2011-06-10t23:25:12z",
"type": "-",
"id": 281475000272870
},
{
"name": null,
"transacted": 0.0014005510836552749,
"appeared": "2012-07-21t07:35:20z",
"type": "-",
"id": 281475019672659
},
{
"name": null,
"transacted": 0.01745632001485884,
"appeared": "2013-01-22t15:03:52z",
"type": "-",
"id": 281475071446658
},
{
"name": null,
"transacted": 0.010425790420505199,
"appeared": "2011-01-12t16:38:58z",
"type": "-",
"id": 281474978480860
},
{
"name": "scam",
"transacted": 0.0033276503283803864,
"appeared": "2013-04-15t15:53:58z",
"type": "scam",
"id": 281475110773635
},
{
"name": "ice-dice",
"transacted": 0.00022512859866270432,
"appeared": "2013-09-22t00:52:30z",
"type": "gambling service",
"id": 281475178680228
},
{
"name": null,
"transacted": 0.007223162120356613,
"appeared": "2012-10-13t01:45:15z",
"type": "-",
"id": 281475041976211
},
{
"name": "known forum user",
"transacted": 0.003748979291233284,
"appeared": "2010-08-12t15:58:33z",
"type": "forum user",
"id": 281474977584007
},
{
"name": null,
"transacted": 0.022471894457652304,
"appeared": "2013-10-01t23:58:26z",
"type": "-",
"id": 281475364591090
},
{
"name": null,
"transacted": 0.011363780169390788,
"appeared": "2012-10-25t07:37:06z",
"type": "-",
"id": 281475045344303
},
{
"name": null,
"transacted": 0.029592913893016343,
"appeared": "2011-10-16t01:14:32z",
"type": "-",
"id": 281474998815469
},
{
"name": "known exchange",
"transacted": 0.0005256493687964338,
"appeared": "2013-09-03t07:35:30z",
"type": "exchange",
"id": 281475174846335
},
{
"name": null,
"transacted": 0.0007575516748885587,
"appeared": "2013-03-06t02:11:30z",
"type": "-",
"id": 281475098444107
},
{
"name": "known exchange",
"transacted": 0.00007601980010401189,
"appeared": "2014-01-18t08:50:11z",
"type": "exchange",
"id": 281475246989482
},
{
"name": "known exchange",
"transacted": 0.0004278466897473997,
"appeared": "2013-12-21t16:49:23z",
"type": "exchange",
"id": 281475249528362
},
{
"name": "blackbank market",
"transacted": 0.00019215010104011888,
"appeared": "2014-02-25t00:32:53z",
"type": "dark marketplace",
"id": 281475285713389
},
{
"name": null,
"transacted": 0.05654975745913819,
"appeared": "2011-03-23t17:39:59z",
"type": "-",
"id": 281474979366073
},
{
"name": null,
"transacted": 0.006406659011887073,
"appeared": "2013-01-18t19:58:04z",
"type": "-",
"id": 281475070158230
},
{
"name": "known exchange",
"transacted": 0.0001940499176820208,
"appeared": "2014-05-06t08:07:06z",
"type": "exchange",
"id": 281475322856670
},
{
"name": null,
"transacted": 0.006015829112927191,
"appeared": "2012-09-23t10:18:19z",
"type": "-",
"id": 281475037494302
},
{
"name": "known exchange",
"transacted": 0.0001802445986627043,
"appeared": "2013-11-13t22:00:08z",
"type": "exchange",
"id": 281475205987727
},
{
"name": null,
"transacted": 0.011636159580980684,
"appeared": "2012-10-08t22:22:35z",
"type": null,
"id": 281475040893226
},
{
"name": null,
"transacted": 0.005984323906389302,
"appeared": "2012-10-07t08:36:12z",
"type": null,
"id": 281475040381559
},
{
"name": "dicebitco",
"transacted": 0.0030151670089153047,
"appeared": "2014-07-15t08:37:38z",
"type": "gambling service",
"id": 281475368705820
},
{
"name": null,
"transacted": 0.00531079933729569,
"appeared": "2012-08-31t08:40:30z",
"type": null,
"id": 281475197979212
},
{
"name": "anonibet",
"transacted": 0.00005414238848439821,
"appeared": "2013-11-20t23:59:05z",
"type": "gambling service",
"id": 281475297224296
},
{
"name": null,
"transacted": 0.005709612679049035,
"appeared": "2013-08-13t11:31:49z",
"type": null,
"id": 281475257011721
},
{
"name": "known exchange",
"transacted": 0.0004645626637444279,
"appeared": "2011-08-04t18:40:27z",
"type": "exchange",
"id": 281474990478282
},
{
"name": "known exchange",
"transacted": 0.0021046468320950968,
"appeared": "2014-08-15t17:59:12z",
"type": "exchange",
"id": 281475380996506
},
{
"name": null,
"transacted": 0.027258191515601785,
"appeared": "2012-02-11t16:33:40z",
"type": null,
"id": 281474997323759
},
{
"name": null,
"transacted": 0.05424428580980684,
"appeared": "2013-03-18t02:09:00z",
"type": null,
"id": 281475095852541
},
{
"name": "known wallet service",
"transacted": 0.04115787356612184,
"appeared": "2013-06-12t21:45:34z",
"type": "wallet",
"id": 281475137948530
},
{
"name": "bitcoinica",
"transacted": 0.019752459301634474,
"appeared": "2012-03-02t03:18:20z",
"type": "exchange",
"id": 281474998406040
},
{
"name": "satoshi-karoshi",
"transacted": 0.00006905620787518573,
"appeared": "2013-05-28t09:46:12z",
"type": "gambling service",
"id": 281475132186299
},
{
"name": null,
"transacted": 0.008837708151560179,
"appeared": "2011-05-09t06:14:50z",
"type": null,
"id": 281474980512415
},
{
"name": "known exchange",
"transacted": 0.00003172404699851412,
"appeared": "2013-11-21t06:35:05z",
"type": "exchange",
"id": 281475261675007
},
{
"name": null,
"transacted": 0.02354403796433878,
"appeared": "2012-05-01t01:35:19z",
"type": null,
"id": 281475007745745
},
{
"name": null,
"transacted": 0.04982754283803864,
"appeared": "2011-07-20t07:56:41z",
"type": null,
"id": 281474992690776
},
{
"name": null,
"transacted": 0.005358195502228826,
"appeared": "2012-09-27t04:20:13z",
"type": null,
"id": 281475096259732
},
{
"name": null,
"transacted": 0.01962934986627043,
"appeared": "2014-06-11t12:45:35z",
"type": null,
"id": 281475337347057
}
],
"links": [
{
"source": 281474994950401,
"target": 281475210091085,
"width": 1
},
{
"source": 281475234100993,
"target": 281475210091085,
"width": 4
},
{
"source": 281475253600611,
"target": 281475210091085,
"width": 1
},
{
"source": 281475265851748,
"target": 281475210091085,
"width": 1
},
{
"source": 281474987955397,
"target": 281475210091085,
"width": 1
},
{
"source": 281474987869318,
"target": 281475210091085,
"width": 4
},
{
"source": 281474988879238,
"target": 281475210091085,
"width": 7
},
{
"source": 281475129278567,
"target": 281475210091085,
"width": 4
},
{
"source": 281474993401991,
"target": 281475210091085,
"width": 1
},
{
"source": 281475026831048,
"target": 281475210091085,
"width": 7
},
{
"source": 281474997632233,
"target": 281475210091085,
"width": 4
},
{
"source": 281475260404909,
"target": 281475210091085,
"width": 4
},
{
"source": 281474984658672,
"target": 281475210091085,
"width": 7
},
{
"source": 281475113272497,
"target": 281475210091085,
"width": 1
},
{
"source": 281474997726930,
"target": 281475210091085,
"width": 4
},
{
"source": 281475012263700,
"target": 281475210091085,
"width": 10
},
{
"source": 281475091828341,
"target": 281475210091085,
"width": 4
},
{
"source": 281474985643606,
"target": 281475210091085,
"width": 7
},
{
"source": 281475180042200,
"target": 281475210091085,
"width": 7
},
{
"source": 281475009385593,
"target": 281475210091085,
"width": 1
},
{
"source": 281474990790137,
"target": 281475210091085,
"width": 4
},
{
"source": 281474980772798,
"target": 281475210091085,
"width": 4
},
{
"source": 281475202912575,
"target": 281475210091085,
"width": 4
},
{
"source": 281475219091935,
"target": 281475210091085,
"width": 4
},
{
"source": 281474987869318,
"target": 281475012263700,
"width": 4
},
{
"source": 281474993401991,
"target": 281475012263700,
"width": 4
},
{
"source": 281475210091085,
"target": 281475012263700,
"width": 4
},
{
"source": 281474980772798,
"target": 281475012263700,
"width": 4
},
{
"source": 281475133010629,
"target": 281474988879238,
"width": 4
},
{
"source": 281474987869318,
"target": 281474988879238,
"width": 4
},
{
"source": 281475147489673,
"target": 281474988879238,
"width": 1
},
{
"source": 281475210091085,
"target": 281474988879238,
"width": 7
},
{
"source": 281475012263700,
"target": 281474988879238,
"width": 4
},
{
"source": 281474993866807,
"target": 281474988879238,
"width": 1
},
{
"source": 281474993401991,
"target": 281475202912575,
"width": 7
},
{
"source": 281475026831048,
"target": 281475202912575,
"width": 4
},
{
"source": 281475210091085,
"target": 281475202912575,
"width": 7
},
{
"source": 281475219091935,
"target": 281475202912575,
"width": 4
},
{
"source": 281475187606240,
"target": 281475129278567,
"width": 1
},
{
"source": 281475253600611,
"target": 281475129278567,
"width": 7
},
{
"source": 281474987869318,
"target": 281475129278567,
"width": 4
},
{
"source": 281474988879238,
"target": 281475129278567,
"width": 10
},
{
"source": 281475026831048,
"target": 281475129278567,
"width": 1
},
{
"source": 281475270412585,
"target": 281475129278567,
"width": 4
},
{
"source": 281475240193197,
"target": 281475129278567,
"width": 1
},
{
"source": 281475116278995,
"target": 281475129278567,
"width": 1
},
{
"source": 281475155547156,
"target": 281475129278567,
"width": 1
},
{
"source": 281475246802390,
"target": 281475129278567,
"width": 4
},
{
"source": 281475180042200,
"target": 281475129278567,
"width": 4
},
{
"source": 281475113307130,
"target": 281475129278567,
"width": 1
},
{
"source": 281475183520613,
"target": 281475026831048,
"width": 4
},
{
"source": 281474987869318,
"target": 281475026831048,
"width": 1
},
{
"source": 281474988879238,
"target": 281475026831048,
"width": 7
},
{
"source": 281475129278567,
"target": 281475026831048,
"width": 4
},
{
"source": 281474993401991,
"target": 281475026831048,
"width": 4
},
{
"source": 281475037563976,
"target": 281475026831048,
"width": 4
},
{
"source": 281475147489673,
"target": 281475026831048,
"width": 1
},
{
"source": 281475215986089,
"target": 281475026831048,
"width": 4
},
{
"source": 281475210091085,
"target": 281475026831048,
"width": 4
},
{
"source": 281475201906447,
"target": 281475026831048,
"width": 4
},
{
"source": 281475211959472,
"target": 281475026831048,
"width": 1
},
{
"source": 281475151542740,
"target": 281475026831048,
"width": 4
},
{
"source": 281475012263700,
"target": 281475026831048,
"width": 7
},
{
"source": 281475281982646,
"target": 281475026831048,
"width": 4
},
{
"source": 281474985643606,
"target": 281475026831048,
"width": 4
},
{
"source": 281475180042200,
"target": 281475026831048,
"width": 1
},
{
"source": 281475295775581,
"target": 281475026831048,
"width": 4
},
{
"source": 281475202912575,
"target": 281475026831048,
"width": 10
},
{
"source": 281475219091935,
"target": 281475026831048,
"width": 7
},
{
"source": 281474987869318,
"target": 281474985643606,
"width": 1
},
{
"source": 281475210091085,
"target": 281474985643606,
"width": 1
},
{
"source": 281474988879238,
"target": 281475180042200,
"width": 7
},
{
"source": 281475129278567,
"target": 281475180042200,
"width": 4
},
{
"source": 281474993401991,
"target": 281475219091935,
"width": 7
},
{
"source": 281475026831048,
"target": 281475219091935,
"width": 4
},
{
"source": 281475210091085,
"target": 281475219091935,
"width": 7
},
{
"source": 281475202912575,
"target": 281475219091935,
"width": 4
},
{
"source": 281474988879238,
"target": 281474987869318,
"width": 7
},
{
"source": 281475129278567,
"target": 281474987869318,
"width": 4
},
{
"source": 281475037563976,
"target": 281474987869318,
"width": 4
},
{
"source": 281475005723784,
"target": 281474987869318,
"width": 1
},
{
"source": 281475026831048,
"target": 281474987869318,
"width": 4
},
{
"source": 281475210091085,
"target": 281474987869318,
"width": 7
},
{
"source": 281475012263700,
"target": 281474987869318,
"width": 4
},
{
"source": 281475202912575,
"target": 281474987869318,
"width": 4
},
{
"source": 281474984658672,
"target": 281474980772798,
"width": 4
},
{
"source": 281475012263700,
"target": 281474980772798,
"width": 7
},
{
"source": 281475210091085,
"target": 281474984658672,
"width": 7
},
{
"source": 281474980772798,
"target": 281474984658672,
"width": 1
},
{
"source": 281475265851748,
"target": 281475253600611,
"width": 1
},
{
"source": 281474988879238,
"target": 281475253600611,
"width": 4
},
{
"source": 281475129278567,
"target": 281475253600611,
"width": 4
},
{
"source": 281475292573256,
"target": 281475253600611,
"width": 4
},
{
"source": 281475270412585,
"target": 281475253600611,
"width": 7
},
{
"source": 281475236428593,
"target": 281475253600611,
"width": 1
},
{
"source": 281475246802390,
"target": 281475253600611,
"width": 4
},
{
"source": 281475253600611,
"target": 281475270412585,
"width": 4
},
{
"source": 281475265851748,
"target": 281475270412585,
"width": 4
},
{
"source": 281474988879238,
"target": 281475270412585,
"width": 1
},
{
"source": 281475129278567,
"target": 281475270412585,
"width": 1
},
{
"source": 281475292573256,
"target": 281475270412585,
"width": 1
},
{
"source": 281475246802390,
"target": 281475270412585,
"width": 4
},
{
"source": 281474988879238,
"target": 281474990790137,
"width": 1
},
{
"source": 281475012263700,
"target": 281474990790137,
"width": 7
},
{
"source": 281474985643606,
"target": 281474990790137,
"width": 7
},
{
"source": 281475253600611,
"target": 281475246802390,
"width": 4
},
{
"source": 281474988879238,
"target": 281475246802390,
"width": 1
},
{
"source": 281475129278567,
"target": 281475246802390,
"width": 1
},
{
"source": 281475270412585,
"target": 281475246802390,
"width": 4
},
{
"source": 281475026831048,
"target": 281475215986089,
"width": 1
},
{
"source": 281474988879238,
"target": 281475110926830,
"width": 1
},
{
"source": 281474988879238,
"target": 281475236428593,
"width": 4
},
{
"source": 281475129278567,
"target": 281475236428593,
"width": 1
},
{
"source": 281475264419261,
"target": 281475236428593,
"width": 4
},
{
"source": 281474988879238,
"target": 281475116278995,
"width": 4
},
{
"source": 281475129278567,
"target": 281475116278995,
"width": 1
},
{
"source": 281474985643606,
"target": 281475193922855,
"width": 7
},
{
"source": 281475202912575,
"target": 281475193922855,
"width": 4
},
{
"source": 281474988879238,
"target": 281475123155348,
"width": 4
},
{
"source": 281475170210314,
"target": 281475264419261,
"width": 7
},
{
"source": 281475236428593,
"target": 281475264419261,
"width": 4
},
{
"source": 281475016996696,
"target": 281475016972288,
"width": 1
},
{
"source": 281475256720206,
"target": 281475240193197,
"width": 7
},
{
"source": 281474988879238,
"target": 281475113307130,
"width": 4
},
{
"source": 281475129278567,
"target": 281475113307130,
"width": 1
},
{
"source": 281475256720206,
"target": 281475292573256,
"width": 7
},
{
"source": 281475098444107,
"target": 281475003395431,
"width": 1
},
{
"source": 281474978457429,
"target": 281475003395431,
"width": 4
},
{
"source": 281475026831048,
"target": 281475229250564,
"width": 1
},
{
"source": 281475210091085,
"target": 281475229250564,
"width": 1
},
{
"source": 281475253600611,
"target": 281475256720206,
"width": 1
},
{
"source": 281475129278567,
"target": 281475256720206,
"width": 4
},
{
"source": 281475012263700,
"target": 281475037563976,
"width": 4
},
{
"source": 281475202912575,
"target": 281475037563976,
"width": 1
},
{
"source": 281475210091085,
"target": 281475091828341,
"width": 4
},
{
"source": 281475265851748,
"target": 281475048031940,
"width": 1
},
{
"source": 281475153218308,
"target": 281475048031940,
"width": 1
},
{
"source": 281474987869318,
"target": 281475048031940,
"width": 4
},
{
"source": 281474988879238,
"target": 281475048031940,
"width": 4
},
{
"source": 281475210091085,
"target": 281475048031940,
"width": 4
},
{
"source": 281474988879238,
"target": 281475113272497,
"width": 4
},
{
"source": 281475016972288,
"target": 281475020670630,
"width": 1
},
{
"source": 281475003395431,
"target": 281474978457429,
"width": 4
},
{
"source": 281475058679082,
"target": 281475061970820,
"width": 1
},
{
"source": 281475016972288,
"target": 281475016996696,
"width": 4
},
{
"source": 281475012263700,
"target": 281475001343013,
"width": 1
},
{
"source": 281475180042200,
"target": 281475105016529,
"width": 1
},
{
"source": 281475136570761,
"target": 281475157743726,
"width": 4
},
{
"source": 281475016972288,
"target": 281475019672659,
"width": 1
},
{
"source": 281475003395431,
"target": 281475098444107,
"width": 1
}
]
}
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
},{}],2:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
function EventEmitter() {
this._events = this._events || {};
this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
EventEmitter.defaultMaxListeners = 10;
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function(n) {
if (!isNumber(n) || n < 0 || isNaN(n))
throw TypeError('n must be a positive number');
this._maxListeners = n;
return this;
};
EventEmitter.prototype.emit = function(type) {
var er, handler, len, args, i, listeners;
if (!this._events)
this._events = {};
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events.error ||
(isObject(this._events.error) && !this._events.error.length)) {
er = arguments[1];
if (er instanceof Error) {
throw er; // Unhandled 'error' event
}
throw TypeError('Uncaught, unspecified "error" event.');
}
}
handler = this._events[type];
if (isUndefined(handler))
return false;
if (isFunction(handler)) {
switch (arguments.length) {
// fast cases
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
len = arguments.length;
args = new Array(len - 1);
for (i = 1; i < len; i++)
args[i - 1] = arguments[i];
handler.apply(this, args);
}
} else if (isObject(handler)) {
len = arguments.length;
args = new Array(len - 1);
for (i = 1; i < len; i++)
args[i - 1] = arguments[i];
listeners = handler.slice();
len = listeners.length;
for (i = 0; i < len; i++)
listeners[i].apply(this, args);
}
return true;
};
EventEmitter.prototype.addListener = function(type, listener) {
var m;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events)
this._events = {};
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (this._events.newListener)
this.emit('newListener', type,
isFunction(listener.listener) ?
listener.listener : listener);
if (!this._events[type])
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
else if (isObject(this._events[type]))
// If we've already got an array, just append.
this._events[type].push(listener);
else
// Adding the second element, need to change to array.
this._events[type] = [this._events[type], listener];
// Check for listener leak
if (isObject(this._events[type]) && !this._events[type].warned) {
var m;
if (!isUndefined(this._maxListeners)) {
m = this._maxListeners;
} else {
m = EventEmitter.defaultMaxListeners;
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
if (typeof console.trace === 'function') {
// not supported in IE 10
console.trace();
}
}
}
return this;
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.once = function(type, listener) {
if (!isFunction(listener))
throw TypeError('listener must be a function');
var fired = false;
function g() {
this.removeListener(type, g);
if (!fired) {
fired = true;
listener.apply(this, arguments);
}
}
g.listener = listener;
this.on(type, g);
return this;
};
// emits a 'removeListener' event iff the listener was removed
EventEmitter.prototype.removeListener = function(type, listener) {
var list, position, length, i;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events || !this._events[type])
return this;
list = this._events[type];
length = list.length;
position = -1;
if (list === listener ||
(isFunction(list.listener) && list.listener === listener)) {
delete this._events[type];
if (this._events.removeListener)
this.emit('removeListener', type, listener);
} else if (isObject(list)) {
for (i = length; i-- > 0;) {
if (list[i] === listener ||
(list[i].listener && list[i].listener === listener)) {
position = i;
break;
}
}
if (position < 0)
return this;
if (list.length === 1) {
list.length = 0;
delete this._events[type];
} else {
list.splice(position, 1);
}
if (this._events.removeListener)
this.emit('removeListener', type, listener);
}
return this;
};
EventEmitter.prototype.removeAllListeners = function(type) {
var key, listeners;
if (!this._events)
return this;
// not listening for removeListener, no need to emit
if (!this._events.removeListener) {
if (arguments.length === 0)
this._events = {};
else if (this._events[type])
delete this._events[type];
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
for (key in this._events) {
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = {};
return this;
}
listeners = this._events[type];
if (isFunction(listeners)) {
this.removeListener(type, listeners);
} else {
// LIFO order
while (listeners.length)
this.removeListener(type, listeners[listeners.length - 1]);
}
delete this._events[type];
return this;
};
EventEmitter.prototype.listeners = function(type) {
var ret;
if (!this._events || !this._events[type])
ret = [];
else if (isFunction(this._events[type]))
ret = [this._events[type]];
else
ret = this._events[type].slice();
return ret;
};
EventEmitter.listenerCount = function(emitter, type) {
var ret;
if (!emitter._events || !emitter._events[type])
ret = 0;
else if (isFunction(emitter._events[type]))
ret = 1;
else
ret = emitter._events[type].length;
return ret;
};
function isFunction(arg) {
return typeof arg === 'function';
}
function isNumber(arg) {
return typeof arg === 'number';
}
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
function isUndefined(arg) {
return arg === void 0;
}
},{}],3:[function(require,module,exports){
(function (process){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// resolves . and .. elements in a path array with directory names there
// must be no slashes, empty elements, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray(parts, allowAboveRoot) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
var last = parts[i];
if (last === '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (allowAboveRoot) {
for (; up--; up) {
parts.unshift('..');
}
}
return parts;
}
// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe =
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
var splitPath = function(filename) {
return splitPathRe.exec(filename).slice(1);
};
// path.resolve([from ...], to)
// posix version
exports.resolve = function() {
var resolvedPath = '',
resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
var path = (i >= 0) ? arguments[i] : process.cwd();
// Skip empty and invalid entries
if (typeof path !== 'string') {
throw new TypeError('Arguments to path.resolve must be strings');
} else if (!path) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charAt(0) === '/';
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
return !!p;
}), !resolvedAbsolute).join('/');
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
};
// path.normalize(path)
// posix version
exports.normalize = function(path) {
var isAbsolute = exports.isAbsolute(path),
trailingSlash = substr(path, -1) === '/';
// Normalize the path
path = normalizeArray(filter(path.split('/'), function(p) {
return !!p;
}), !isAbsolute).join('/');
if (!path && !isAbsolute) {
path = '.';
}
if (path && trailingSlash) {
path += '/';
}
return (isAbsolute ? '/' : '') + path;
};
// posix version
exports.isAbsolute = function(path) {
return path.charAt(0) === '/';
};
// posix version
exports.join = function() {
var paths = Array.prototype.slice.call(arguments, 0);
return exports.normalize(filter(paths, function(p, index) {
if (typeof p !== 'string') {
throw new TypeError('Arguments to path.join must be strings');
}
return p;
}).join('/'));
};
// path.relative(from, to)
// posix version
exports.relative = function(from, to) {
from = exports.resolve(from).substr(1);
to = exports.resolve(to).substr(1);
function trim(arr) {
var start = 0;
for (; start < arr.length; start++) {
if (arr[start] !== '') break;
}
var end = arr.length - 1;
for (; end >= 0; end--) {
if (arr[end] !== '') break;
}
if (start > end) return [];
return arr.slice(start, end - start + 1);
}
var fromParts = trim(from.split('/'));
var toParts = trim(to.split('/'));
var length = Math.min(fromParts.length, toParts.length);
var samePartsLength = length;
for (var i = 0; i < length; i++) {
if (fromParts[i] !== toParts[i]) {
samePartsLength = i;
break;
}
}
var outputParts = [];
for (var i = samePartsLength; i < fromParts.length; i++) {
outputParts.push('..');
}
outputParts = outputParts.concat(toParts.slice(samePartsLength));
return outputParts.join('/');
};
exports.sep = '/';
exports.delimiter = ':';
exports.dirname = function(path) {
var result = splitPath(path),
root = result[0],
dir = result[1];
if (!root && !dir) {
// No dirname whatsoever
return '.';
}
if (dir) {
// It has a dirname, strip trailing slash
dir = dir.substr(0, dir.length - 1);
}
return root + dir;
};
exports.basename = function(path, ext) {
var f = splitPath(path)[2];
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};
exports.extname = function(path) {
return splitPath(path)[3];
};
function filter (xs, f) {
if (xs.filter) return xs.filter(f);
var res = [];
for (var i = 0; i < xs.length; i++) {
if (f(xs[i], i, xs)) res.push(xs[i]);
}
return res;
}
// String.prototype.substr - negative index don't work in IE8
var substr = 'ab'.substr(-1) === 'b'
? function (str, start, len) { return str.substr(start, len) }
: function (str, start, len) {
if (start < 0) start = str.length + start;
return str.substr(start, len);
}
;
}).call(this,require('_process'))
},{"_process":4}],4:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
var queue = [];
var draining = false;
function drainQueue() {
if (draining) {
return;
}
draining = true;
var currentQueue;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
var i = -1;
while (++i < len) {
currentQueue[i]();
}
len = queue.length;
}
draining = false;
}
process.nextTick = function (fun) {
queue.push(fun);
if (!draining) {
setTimeout(drainQueue, 0);
}
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
// TODO(shtylman)
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
},{}],5:[function(require,module,exports){
(function (global){
/*! http://mths.be/punycode v1.2.4 by @mathias */
;(function(root) {
/** Detect free variables */
var freeExports = typeof exports == 'object' && exports;
var freeModule = typeof module == 'object' && module &&
module.exports == freeExports && module;
var freeGlobal = typeof global == 'object' && global;
if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
root = freeGlobal;
}
/**
* The `punycode` object.
* @name punycode
* @type Object
*/
var punycode,
/** Highest positive signed 32-bit float value */
maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
/** Bootstring parameters */
base = 36,
tMin = 1,
tMax = 26,
skew = 38,
damp = 700,
initialBias = 72,
initialN = 128, // 0x80
delimiter = '-', // '\x2D'
/** Regular expressions */
regexPunycode = /^xn--/,
regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars
regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators
/** Error messages */
errors = {
'overflow': 'Overflow: input needs wider integers to process',
'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
'invalid-input': 'Invalid input'
},
/** Convenience shortcuts */
baseMinusTMin = base - tMin,
floor = Math.floor,
stringFromCharCode = String.fromCharCode,
/** Temporary variable */
key;
/*--------------------------------------------------------------------------*/
/**
* A generic error utility function.
* @private
* @param {String} type The error type.
* @returns {Error} Throws a `RangeError` with the applicable error message.
*/
function error(type) {
throw RangeError(errors[type]);
}
/**
* A generic `Array#map` utility function.
* @private
* @param {Array} array The array to iterate over.
* @param {Function} callback The function that gets called for every array
* item.
* @returns {Array} A new array of values returned by the callback function.
*/
function map(array, fn) {
var length = array.length;
while (length--) {
array[length] = fn(array[length]);
}
return array;
}
/**
* A simple `Array#map`-like wrapper to work with domain name strings.
* @private
* @param {String} domain The domain name.
* @param {Function} callback The function that gets called for every
* character.
* @returns {Array} A new string of characters returned by the callback
* function.
*/
function mapDomain(string, fn) {
return map(string.split(regexSeparators), fn).join('.');
}
/**
* Creates an array containing the numeric code points of each Unicode
* character in the string. While JavaScript uses UCS-2 internally,
* this function will convert a pair of surrogate halves (each of which
* UCS-2 exposes as separate characters) into a single code point,
* matching UTF-16.
* @see `punycode.ucs2.encode`
* @see <http://mathiasbynens.be/notes/javascript-encoding>
* @memberOf punycode.ucs2
* @name decode
* @param {String} string The Unicode input string (UCS-2).
* @returns {Array} The new array of code points.
*/
function ucs2decode(string) {
var output = [],
counter = 0,
length = string.length,
value,
extra;
while (counter < length) {
value = string.charCodeAt(counter++);
if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
// high surrogate, and there is a next character
extra = string.charCodeAt(counter++);
if ((extra & 0xFC00) == 0xDC00) { // low surrogate
output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
} else {
// unmatched surrogate; only append this code unit, in case the next
// code unit is the high surrogate of a surrogate pair
output.push(value);
counter--;
}
} else {
output.push(value);
}
}
return output;
}
/**
* Creates a string based on an array of numeric code points.
* @see `punycode.ucs2.decode`
* @memberOf punycode.ucs2
* @name encode
* @param {Array} codePoints The array of numeric code points.
* @returns {String} The new Unicode string (UCS-2).
*/
function ucs2encode(array) {
return map(array, function(value) {
var output = '';
if (value > 0xFFFF) {
value -= 0x10000;
output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
value = 0xDC00 | value & 0x3FF;
}
output += stringFromCharCode(value);
return output;
}).join('');
}
/**
* Converts a basic code point into a digit/integer.
* @see `digitToBasic()`
* @private
* @param {Number} codePoint The basic numeric code point value.
* @returns {Number} The numeric value of a basic code point (for use in
* representing integers) in the range `0` to `base - 1`, or `base` if
* the code point does not represent a value.
*/
function basicToDigit(codePoint) {
if (codePoint - 48 < 10) {
return codePoint - 22;
}
if (codePoint - 65 < 26) {
return codePoint - 65;
}
if (codePoint - 97 < 26) {
return codePoint - 97;
}
return base;
}
/**
* Converts a digit/integer into a basic code point.
* @see `basicToDigit()`
* @private
* @param {Number} digit The numeric value of a basic code point.
* @returns {Number} The basic code point whose value (when used for
* representing integers) is `digit`, which needs to be in the range
* `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
* used; else, the lowercase form is used. The behavior is undefined
* if `flag` is non-zero and `digit` has no uppercase form.
*/
function digitToBasic(digit, flag) {
// 0..25 map to ASCII a..z or A..Z
// 26..35 map to ASCII 0..9
return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
}
/**
* Bias adaptation function as per section 3.4 of RFC 3492.
* http://tools.ietf.org/html/rfc3492#section-3.4
* @private
*/
function adapt(delta, numPoints, firstTime) {
var k = 0;
delta = firstTime ? floor(delta / damp) : delta >> 1;
delta += floor(delta / numPoints);
for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
delta = floor(delta / baseMinusTMin);
}
return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
}
/**
* Converts a Punycode string of ASCII-only symbols to a string of Unicode
* symbols.
* @memberOf punycode
* @param {String} input The Punycode string of ASCII-only symbols.
* @returns {String} The resulting string of Unicode symbols.
*/
function decode(input) {
// Don't use UCS-2
var output = [],
inputLength = input.length,
out,
i = 0,
n = initialN,
bias = initialBias,
basic,
j,
index,
oldi,
w,
k,
digit,
t,
/** Cached calculation results */
baseMinusT;
// Handle the basic code points: let `basic` be the number of input code
// points before the last delimiter, or `0` if there is none, then copy
// the first basic code points to the output.
basic = input.lastIndexOf(delimiter);
if (basic < 0) {
basic = 0;
}
for (j = 0; j < basic; ++j) {
// if it's not a basic code point
if (input.charCodeAt(j) >= 0x80) {
error('not-basic');
}
output.push(input.charCodeAt(j));
}
// Main decoding loop: start just after the last delimiter if any basic code
// points were copied; start at the beginning otherwise.
for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
// `index` is the index of the next character to be consumed.
// Decode a generalized variable-length integer into `delta`,
// which gets added to `i`. The overflow checking is easier
// if we increase `i` as we go, then subtract off its starting
// value at the end to obtain `delta`.
for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
if (index >= inputLength) {
error('invalid-input');
}
digit = basicToDigit(input.charCodeAt(index++));
if (digit >= base || digit > floor((maxInt - i) / w)) {
error('overflow');
}
i += digit * w;
t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
if (digit < t) {
break;
}
baseMinusT = base - t;
if (w > floor(maxInt / baseMinusT)) {
error('overflow');
}
w *= baseMinusT;
}
out = output.length + 1;
bias = adapt(i - oldi, out, oldi == 0);
// `i` was supposed to wrap around from `out` to `0`,
// incrementing `n` each time, so we'll fix that now:
if (floor(i / out) > maxInt - n) {
error('overflow');
}
n += floor(i / out);
i %= out;
// Insert `n` at position `i` of the output
output.splice(i++, 0, n);
}
return ucs2encode(output);
}
/**
* Converts a string of Unicode symbols to a Punycode string of ASCII-only
* symbols.
* @memberOf punycode
* @param {String} input The string of Unicode symbols.
* @returns {String} The resulting Punycode string of ASCII-only symbols.
*/
function encode(input) {
var n,
delta,
handledCPCount,
basicLength,
bias,
j,
m,
q,
k,
t,
currentValue,
output = [],
/** `inputLength` will hold the number of code points in `input`. */
inputLength,
/** Cached calculation results */
handledCPCountPlusOne,
baseMinusT,
qMinusT;
// Convert the input in UCS-2 to Unicode
input = ucs2decode(input);
// Cache the length
inputLength = input.length;
// Initialize the state
n = initialN;
delta = 0;
bias = initialBias;
// Handle the basic code points
for (j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue < 0x80) {
output.push(stringFromCharCode(currentValue));
}
}
handledCPCount = basicLength = output.length;
// `handledCPCount` is the number of code points that have been handled;
// `basicLength` is the number of basic code points.
// Finish the basic string - if it is not empty - with a delimiter
if (basicLength) {
output.push(delimiter);
}
// Main encoding loop:
while (handledCPCount < inputLength) {
// All non-basic code points < n have been handled already. Find the next
// larger one:
for (m = maxInt, j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue >= n && currentValue < m) {
m = currentValue;
}
}
// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
// but guard against overflow
handledCPCountPlusOne = handledCPCount + 1;
if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
error('overflow');
}
delta += (m - n) * handledCPCountPlusOne;
n = m;
for (j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue < n && ++delta > maxInt) {
error('overflow');
}
if (currentValue == n) {
// Represent delta as a generalized variable-length integer
for (q = delta, k = base; /* no condition */; k += base) {
t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
if (q < t) {
break;
}
qMinusT = q - t;
baseMinusT = base - t;
output.push(
stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
);
q = floor(qMinusT / baseMinusT);
}
output.push(stringFromCharCode(digitToBasic(q, 0)));
bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
delta = 0;
++handledCPCount;
}
}
++delta;
++n;
}
return output.join('');
}
/**
* Converts a Punycode string representing a domain name to Unicode. Only the
* Punycoded parts of the domain name will be converted, i.e. it doesn't
* matter if you call it on a string that has already been converted to
* Unicode.
* @memberOf punycode
* @param {String} domain The Punycode domain name to convert to Unicode.
* @returns {String} The Unicode representation of the given Punycode
* string.
*/
function toUnicode(domain) {
return mapDomain(domain, function(string) {
return regexPunycode.test(string)
? decode(string.slice(4).toLowerCase())
: string;
});
}
/**
* Converts a Unicode string representing a domain name to Punycode. Only the
* non-ASCII parts of the domain name will be converted, i.e. it doesn't
* matter if you call it with a domain that's already in ASCII.
* @memberOf punycode
* @param {String} domain The domain name to convert, as a Unicode string.
* @returns {String} The Punycode representation of the given domain name.
*/
function toASCII(domain) {
return mapDomain(domain, function(string) {
return regexNonASCII.test(string)
? 'xn--' + encode(string)
: string;
});
}
/*--------------------------------------------------------------------------*/
/** Define the public API */
punycode = {
/**
* A string representing the current Punycode.js version number.
* @memberOf punycode
* @type String
*/
'version': '1.2.4',
/**
* An object of methods to convert from JavaScript's internal character
* representation (UCS-2) to Unicode code points, and back.
* @see <http://mathiasbynens.be/notes/javascript-encoding>
* @memberOf punycode
* @type Object
*/
'ucs2': {
'decode': ucs2decode,
'encode': ucs2encode
},
'decode': decode,
'encode': encode,
'toASCII': toASCII,
'toUnicode': toUnicode
};
/** Expose `punycode` */
// Some AMD build optimizers, like r.js, check for specific condition patterns
// like the following:
if (
typeof define == 'function' &&
typeof define.amd == 'object' &&
define.amd
) {
define('punycode', function() {
return punycode;
});
} else if (freeExports && !freeExports.nodeType) {
if (freeModule) { // in Node.js or RingoJS v0.8.0+
freeModule.exports = punycode;
} else { // in Narwhal or RingoJS v0.7.0-
for (key in punycode) {
punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
}
}
} else { // in Rhino or a web browser
root.punycode = punycode;
}
}(this));
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],6:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
// If obj.hasOwnProperty has been overridden, then calling
// obj.hasOwnProperty(prop) will break.
// See: https://github.com/joyent/node/issues/1707
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
module.exports = function(qs, sep, eq, options) {
sep = sep || '&';
eq = eq || '=';
var obj = {};
if (typeof qs !== 'string' || qs.length === 0) {
return obj;
}
var regexp = /\+/g;
qs = qs.split(sep);
var maxKeys = 1000;
if (options && typeof options.maxKeys === 'number') {
maxKeys = options.maxKeys;
}
var len = qs.length;
// maxKeys <= 0 means that we should not limit keys count
if (maxKeys > 0 && len > maxKeys) {
len = maxKeys;
}
for (var i = 0; i < len; ++i) {
var x = qs[i].replace(regexp, '%20'),
idx = x.indexOf(eq),
kstr, vstr, k, v;
if (idx >= 0) {
kstr = x.substr(0, idx);
vstr = x.substr(idx + 1);
} else {
kstr = x;
vstr = '';
}
k = decodeURIComponent(kstr);
v = decodeURIComponent(vstr);
if (!hasOwnProperty(obj, k)) {
obj[k] = v;
} else if (isArray(obj[k])) {
obj[k].push(v);
} else {
obj[k] = [obj[k], v];
}
}
return obj;
};
var isArray = Array.isArray || function (xs) {
return Object.prototype.toString.call(xs) === '[object Array]';
};
},{}],7:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
var stringifyPrimitive = function(v) {
switch (typeof v) {
case 'string':
return v;
case 'boolean':
return v ? 'true' : 'false';
case 'number':
return isFinite(v) ? v : '';
default:
return '';
}
};
module.exports = function(obj, sep, eq, name) {
sep = sep || '&';
eq = eq || '=';
if (obj === null) {
obj = undefined;
}
if (typeof obj === 'object') {
return map(objectKeys(obj), function(k) {
var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
if (isArray(obj[k])) {
return map(obj[k], function(v) {
return ks + encodeURIComponent(stringifyPrimitive(v));
}).join(sep);
} else {
return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
}
}).join(sep);
}
if (!name) return '';
return encodeURIComponent(stringifyPrimitive(name)) + eq +
encodeURIComponent(stringifyPrimitive(obj));
};
var isArray = Array.isArray || function (xs) {
return Object.prototype.toString.call(xs) === '[object Array]';
};
function map (xs, f) {
if (xs.map) return xs.map(f);
var res = [];
for (var i = 0; i < xs.length; i++) {
res.push(f(xs[i], i));
}
return res;
}
var objectKeys = Object.keys || function (obj) {
var res = [];
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
}
return res;
};
},{}],8:[function(require,module,exports){
'use strict';
exports.decode = exports.parse = require('./decode');
exports.encode = exports.stringify = require('./encode');
},{"./decode":6,"./encode":7}],9:[function(require,module,exports){
'use strict';
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };
exports.__esModule = true;
var _runtime = require('./handlebars.runtime');
var _runtime2 = _interopRequireWildcard(_runtime);
// Compiler imports
var _AST = require('./handlebars/compiler/ast');
var _AST2 = _interopRequireWildcard(_AST);
var _Parser$parse = require('./handlebars/compiler/base');
var _Compiler$compile$precompile = require('./handlebars/compiler/compiler');
var _JavaScriptCompiler = require('./handlebars/compiler/javascript-compiler');
var _JavaScriptCompiler2 = _interopRequireWildcard(_JavaScriptCompiler);
var _Visitor = require('./handlebars/compiler/visitor');
var _Visitor2 = _interopRequireWildcard(_Visitor);
var _noConflict = require('./handlebars/no-conflict');
var _noConflict2 = _interopRequireWildcard(_noConflict);
var _create = _runtime2['default'].create;
function create() {
var hb = _create();
hb.compile = function (input, options) {
return _Compiler$compile$precompile.compile(input, options, hb);
};
hb.precompile = function (input, options) {
return _Compiler$compile$precompile.precompile(input, options, hb);
};
hb.AST = _AST2['default'];
hb.Compiler = _Compiler$compile$precompile.Compiler;
hb.JavaScriptCompiler = _JavaScriptCompiler2['default'];
hb.Parser = _Parser$parse.parser;
hb.parse = _Parser$parse.parse;
return hb;
}
var inst = create();
inst.create = create;
_noConflict2['default'](inst);
inst.Visitor = _Visitor2['default'];
inst['default'] = inst;
exports['default'] = inst;
module.exports = exports['default'];
},{"./handlebars.runtime":10,"./handlebars/compiler/ast":12,"./handlebars/compiler/base":13,"./handlebars/compiler/compiler":15,"./handlebars/compiler/javascript-compiler":17,"./handlebars/compiler/visitor":20,"./handlebars/no-conflict":23}],10:[function(require,module,exports){
'use strict';
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };
exports.__esModule = true;
var _import = require('./handlebars/base');
var base = _interopRequireWildcard(_import);
// Each of these augment the Handlebars object. No need to setup here.
// (This is done to easily share code between commonjs and browse envs)
var _SafeString = require('./handlebars/safe-string');
var _SafeString2 = _interopRequireWildcard(_SafeString);
var _Exception = require('./handlebars/exception');
var _Exception2 = _interopRequireWildcard(_Exception);
var _import2 = require('./handlebars/utils');
var Utils = _interopRequireWildcard(_import2);
var _import3 = require('./handlebars/runtime');
var runtime = _interopRequireWildcard(_import3);
var _noConflict = require('./handlebars/no-conflict');
var _noConflict2 = _interopRequireWildcard(_noConflict);
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
function create() {
var hb = new base.HandlebarsEnvironment();
Utils.extend(hb, base);
hb.SafeString = _SafeString2['default'];
hb.Exception = _Exception2['default'];
hb.Utils = Utils;
hb.escapeExpression = Utils.escapeExpression;
hb.VM = runtime;
hb.template = function (spec) {
return runtime.template(spec, hb);
};
return hb;
}
var inst = create();
inst.create = create;
_noConflict2['default'](inst);
inst['default'] = inst;
exports['default'] = inst;
module.exports = exports['default'];
},{"./handlebars/base":11,"./handlebars/exception":22,"./handlebars/no-conflict":23,"./handlebars/runtime":24,"./handlebars/safe-string":25,"./handlebars/utils":26}],11:[function(require,module,exports){
'use strict';
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };
exports.__esModule = true;
exports.HandlebarsEnvironment = HandlebarsEnvironment;
exports.createFrame = createFrame;
var _import = require('./utils');
var Utils = _interopRequireWildcard(_import);
var _Exception = require('./exception');
var _Exception2 = _interopRequireWildcard(_Exception);
var VERSION = '3.0.1';
exports.VERSION = VERSION;
var COMPILER_REVISION = 6;
exports.COMPILER_REVISION = COMPILER_REVISION;
var REVISION_CHANGES = {
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
2: '== 1.0.0-rc.3',
3: '== 1.0.0-rc.4',
4: '== 1.x.x',
5: '== 2.0.0-alpha.x',
6: '>= 2.0.0-beta.1'
};
exports.REVISION_CHANGES = REVISION_CHANGES;
var isArray = Utils.isArray,
isFunction = Utils.isFunction,
toString = Utils.toString,
objectType = '[object Object]';
function HandlebarsEnvironment(helpers, partials) {
this.helpers = helpers || {};
this.partials = partials || {};
registerDefaultHelpers(this);
}
HandlebarsEnvironment.prototype = {
constructor: HandlebarsEnvironment,
logger: logger,
log: log,
registerHelper: function registerHelper(name, fn) {
if (toString.call(name) === objectType) {
if (fn) {
throw new _Exception2['default']('Arg not supported with multiple helpers');
}
Utils.extend(this.helpers, name);
} else {
this.helpers[name] = fn;
}
},
unregisterHelper: function unregisterHelper(name) {
delete this.helpers[name];
},
registerPartial: function registerPartial(name, partial) {
if (toString.call(name) === objectType) {
Utils.extend(this.partials, name);
} else {
if (typeof partial === 'undefined') {
throw new _Exception2['default']('Attempting to register a partial as undefined');
}
this.partials[name] = partial;
}
},
unregisterPartial: function unregisterPartial(name) {
delete this.partials[name];
}
};
function registerDefaultHelpers(instance) {
instance.registerHelper('helperMissing', function () {
if (arguments.length === 1) {
// A missing field in a {{foo}} constuct.
return undefined;
} else {
// Someone is actually trying to call something, blow up.
throw new _Exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"');
}
});
instance.registerHelper('blockHelperMissing', function (context, options) {
var inverse = options.inverse,
fn = options.fn;
if (context === true) {
return fn(this);
} else if (context === false || context == null) {
return inverse(this);
} else if (isArray(context)) {
if (context.length > 0) {
if (options.ids) {
options.ids = [options.name];
}
return instance.helpers.each(context, options);
} else {
return inverse(this);
}
} else {
if (options.data && options.ids) {
var data = createFrame(options.data);
data.contextPath = Utils.appendContextPath(options.data.contextPath, options.name);
options = { data: data };
}
return fn(context, options);
}
});
instance.registerHelper('each', function (context, options) {
if (!options) {
throw new _Exception2['default']('Must pass iterator to #each');
}
var fn = options.fn,
inverse = options.inverse,
i = 0,
ret = '',
data = undefined,
contextPath = undefined;
if (options.data && options.ids) {
contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
}
if (isFunction(context)) {
context = context.call(this);
}
if (options.data) {
data = createFrame(options.data);
}
function execIteration(field, index, last) {
if (data) {
data.key = field;
data.index = index;
data.first = index === 0;
data.last = !!last;
if (contextPath) {
data.contextPath = contextPath + field;
}
}
ret = ret + fn(context[field], {
data: data,
blockParams: Utils.blockParams([context[field], field], [contextPath + field, null])
});
}
if (context && typeof context === 'object') {
if (isArray(context)) {
for (var j = context.length; i < j; i++) {
execIteration(i, i, i === context.length - 1);
}
} else {
var priorKey = undefined;
for (var key in context) {
if (context.hasOwnProperty(key)) {
// We're running the iterations one step out of sync so we can detect
// the last iteration without have to scan the object twice and create
// an itermediate keys array.
if (priorKey) {
execIteration(priorKey, i - 1);
}
priorKey = key;
i++;
}
}
if (priorKey) {
execIteration(priorKey, i - 1, true);
}
}
}
if (i === 0) {
ret = inverse(this);
}
return ret;
});
instance.registerHelper('if', function (conditional, options) {
if (isFunction(conditional)) {
conditional = conditional.call(this);
}
// Default behavior is to render the positive path if the value is truthy and not empty.
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
if (!options.hash.includeZero && !conditional || Utils.isEmpty(conditional)) {
return options.inverse(this);
} else {
return options.fn(this);
}
});
instance.registerHelper('unless', function (conditional, options) {
return instance.helpers['if'].call(this, conditional, { fn: options.inverse, inverse: options.fn, hash: options.hash });
});
instance.registerHelper('with', function (context, options) {
if (isFunction(context)) {
context = context.call(this);
}
var fn = options.fn;
if (!Utils.isEmpty(context)) {
if (options.data && options.ids) {
var data = createFrame(options.data);
data.contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]);
options = { data: data };
}
return fn(context, options);
} else {
return options.inverse(this);
}
});
instance.registerHelper('log', function (message, options) {
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
instance.log(level, message);
});
instance.registerHelper('lookup', function (obj, field) {
return obj && obj[field];
});
}
var logger = {
methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
// State enum
DEBUG: 0,
INFO: 1,
WARN: 2,
ERROR: 3,
level: 1,
// Can be overridden in the host environment
log: function log(level, message) {
if (typeof console !== 'undefined' && logger.level <= level) {
var method = logger.methodMap[level];
(console[method] || console.log).call(console, message); // eslint-disable-line no-console
}
}
};
exports.logger = logger;
var log = logger.log;
exports.log = log;
function createFrame(object) {
var frame = Utils.extend({}, object);
frame._parent = object;
return frame;
}
/* [args, ]options */
},{"./exception":22,"./utils":26}],12:[function(require,module,exports){
'use strict';
exports.__esModule = true;
var AST = {
Program: function Program(statements, blockParams, strip, locInfo) {
this.loc = locInfo;
this.type = 'Program';
this.body = statements;
this.blockParams = blockParams;
this.strip = strip;
},
MustacheStatement: function MustacheStatement(path, params, hash, escaped, strip, locInfo) {
this.loc = locInfo;
this.type = 'MustacheStatement';
this.path = path;
this.params = params || [];
this.hash = hash;
this.escaped = escaped;
this.strip = strip;
},
BlockStatement: function BlockStatement(path, params, hash, program, inverse, openStrip, inverseStrip, closeStrip, locInfo) {
this.loc = locInfo;
this.type = 'BlockStatement';
this.path = path;
this.params = params || [];
this.hash = hash;
this.program = program;
this.inverse = inverse;
this.openStrip = openStrip;
this.inverseStrip = inverseStrip;
this.closeStrip = closeStrip;
},
PartialStatement: function PartialStatement(name, params, hash, strip, locInfo) {
this.loc = locInfo;
this.type = 'PartialStatement';
this.name = name;
this.params = params || [];
this.hash = hash;
this.indent = '';
this.strip = strip;
},
ContentStatement: function ContentStatement(string, locInfo) {
this.loc = locInfo;
this.type = 'ContentStatement';
this.original = this.value = string;
},
CommentStatement: function CommentStatement(comment, strip, locInfo) {
this.loc = locInfo;
this.type = 'CommentStatement';
this.value = comment;
this.strip = strip;
},
SubExpression: function SubExpression(path, params, hash, locInfo) {
this.loc = locInfo;
this.type = 'SubExpression';
this.path = path;
this.params = params || [];
this.hash = hash;
},
PathExpression: function PathExpression(data, depth, parts, original, locInfo) {
this.loc = locInfo;
this.type = 'PathExpression';
this.data = data;
this.original = original;
this.parts = parts;
this.depth = depth;
},
StringLiteral: function StringLiteral(string, locInfo) {
this.loc = locInfo;
this.type = 'StringLiteral';
this.original = this.value = string;
},
NumberLiteral: function NumberLiteral(number, locInfo) {
this.loc = locInfo;
this.type = 'NumberLiteral';
this.original = this.value = Number(number);
},
BooleanLiteral: function BooleanLiteral(bool, locInfo) {
this.loc = locInfo;
this.type = 'BooleanLiteral';
this.original = this.value = bool === 'true';
},
UndefinedLiteral: function UndefinedLiteral(locInfo) {
this.loc = locInfo;
this.type = 'UndefinedLiteral';
this.original = this.value = undefined;
},
NullLiteral: function NullLiteral(locInfo) {
this.loc = locInfo;
this.type = 'NullLiteral';
this.original = this.value = null;
},
Hash: function Hash(pairs, locInfo) {
this.loc = locInfo;
this.type = 'Hash';
this.pairs = pairs;
},
HashPair: function HashPair(key, value, locInfo) {
this.loc = locInfo;
this.type = 'HashPair';
this.key = key;
this.value = value;
},
// Public API used to evaluate derived attributes regarding AST nodes
helpers: {
// a mustache is definitely a helper if:
// * it is an eligible helper, and
// * it has at least one parameter or hash segment
helperExpression: function helperExpression(node) {
return !!(node.type === 'SubExpression' || node.params.length || node.hash);
},
scopedId: function scopedId(path) {
return /^\.|this\b/.test(path.original);
},
// an ID is simple if it only has one part, and that part is not
// `..` or `this`.
simpleId: function simpleId(path) {
return path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth;
}
}
};
// Must be exported as an object rather than the root of the module as the jison lexer
// must modify the object to operate properly.
exports['default'] = AST;
module.exports = exports['default'];
},{}],13:[function(require,module,exports){
'use strict';
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };
exports.__esModule = true;
exports.parse = parse;
var _parser = require('./parser');
var _parser2 = _interopRequireWildcard(_parser);
var _AST = require('./ast');
var _AST2 = _interopRequireWildcard(_AST);
var _WhitespaceControl = require('./whitespace-control');
var _WhitespaceControl2 = _interopRequireWildcard(_WhitespaceControl);
var _import = require('./helpers');
var Helpers = _interopRequireWildcard(_import);
var _extend = require('../utils');
exports.parser = _parser2['default'];
var yy = {};
_extend.extend(yy, Helpers, _AST2['default']);
function parse(input, options) {
// Just return if an already-compiled AST was passed in.
if (input.type === 'Program') {
return input;
}
_parser2['default'].yy = yy;
// Altering the shared object here, but this is ok as parser is a sync operation
yy.locInfo = function (locInfo) {
return new yy.SourceLocation(options && options.srcName, locInfo);
};
var strip = new _WhitespaceControl2['default']();
return strip.accept(_parser2['default'].parse(input));
}
},{"../utils":26,"./ast":12,"./helpers":16,"./parser":18,"./whitespace-control":21}],14:[function(require,module,exports){
'use strict';
exports.__esModule = true;
/*global define */
var _isArray = require('../utils');
var SourceNode = undefined;
try {
/* istanbul ignore next */
if (typeof define !== 'function' || !define.amd) {
// We don't support this in AMD environments. For these environments, we asusme that
// they are running on the browser and thus have no need for the source-map library.
var SourceMap = require('source-map');
SourceNode = SourceMap.SourceNode;
}
} catch (err) {}
/* istanbul ignore if: tested but not covered in istanbul due to dist build */
if (!SourceNode) {
SourceNode = function (line, column, srcFile, chunks) {
this.src = '';
if (chunks) {
this.add(chunks);
}
};
/* istanbul ignore next */
SourceNode.prototype = {
add: function add(chunks) {
if (_isArray.isArray(chunks)) {
chunks = chunks.join('');
}
this.src += chunks;
},
prepend: function prepend(chunks) {
if (_isArray.isArray(chunks)) {
chunks = chunks.join('');
}
this.src = chunks + this.src;
},
toStringWithSourceMap: function toStringWithSourceMap() {
return { code: this.toString() };
},
toString: function toString() {
return this.src;
}
};
}
function castChunk(chunk, codeGen, loc) {
if (_isArray.isArray(chunk)) {
var ret = [];
for (var i = 0, len = chunk.length; i < len; i++) {
ret.push(codeGen.wrap(chunk[i], loc));
}
return ret;
} else if (typeof chunk === 'boolean' || typeof chunk === 'number') {
// Handle primitives that the SourceNode will throw up on
return chunk + '';
}
return chunk;
}
function CodeGen(srcFile) {
this.srcFile = srcFile;
this.source = [];
}
CodeGen.prototype = {
prepend: function prepend(source, loc) {
this.source.unshift(this.wrap(source, loc));
},
push: function push(source, loc) {
this.source.push(this.wrap(source, loc));
},
merge: function merge() {
var source = this.empty();
this.each(function (line) {
source.add([' ', line, '\n']);
});
return source;
},
each: function each(iter) {
for (var i = 0, len = this.source.length; i < len; i++) {
iter(this.source[i]);
}
},
empty: function empty() {
var loc = arguments[0] === undefined ? this.currentLocation || { start: {} } : arguments[0];
return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
},
wrap: function wrap(chunk) {
var loc = arguments[1] === undefined ? this.currentLocation || { start: {} } : arguments[1];
if (chunk instanceof SourceNode) {
return chunk;
}
chunk = castChunk(chunk, this, loc);
return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk);
},
functionCall: function functionCall(fn, type, params) {
params = this.generateList(params);
return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']);
},
quotedString: function quotedString(str) {
return '"' + (str + '').replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
.replace(/\u2029/g, '\\u2029') + '"';
},
objectLiteral: function objectLiteral(obj) {
var pairs = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var value = castChunk(obj[key], this);
if (value !== 'undefined') {
pairs.push([this.quotedString(key), ':', value]);
}
}
}
var ret = this.generateList(pairs);
ret.prepend('{');
ret.add('}');
return ret;
},
generateList: function generateList(entries, loc) {
var ret = this.empty(loc);
for (var i = 0, len = entries.length; i < len; i++) {
if (i) {
ret.add(',');
}
ret.add(castChunk(entries[i], this, loc));
}
return ret;
},
generateArray: function generateArray(entries, loc) {
var ret = this.generateList(entries, loc);
ret.prepend('[');
ret.add(']');
return ret;
}
};
exports['default'] = CodeGen;
module.exports = exports['default'];
/* NOP */
},{"../utils":26,"source-map":28}],15:[function(require,module,exports){
'use strict';
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };
exports.__esModule = true;
exports.Compiler = Compiler;
exports.precompile = precompile;
exports.compile = compile;
var _Exception = require('../exception');
var _Exception2 = _interopRequireWildcard(_Exception);
var _isArray$indexOf = require('../utils');
var _AST = require('./ast');
var _AST2 = _interopRequireWildcard(_AST);
var slice = [].slice;
function Compiler() {}
// the foundHelper register will disambiguate helper lookup from finding a
// function in a context. This is necessary for mustache compatibility, which
// requires that context functions in blocks are evaluated by blockHelperMissing,
// and then proceed as if the resulting value was provided to blockHelperMissing.
Compiler.prototype = {
compiler: Compiler,
equals: function equals(other) {
var len = this.opcodes.length;
if (other.opcodes.length !== len) {
return false;
}
for (var i = 0; i < len; i++) {
var opcode = this.opcodes[i],
otherOpcode = other.opcodes[i];
if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) {
return false;
}
}
// We know that length is the same between the two arrays because they are directly tied
// to the opcode behavior above.
len = this.children.length;
for (var i = 0; i < len; i++) {
if (!this.children[i].equals(other.children[i])) {
return false;
}
}
return true;
},
guid: 0,
compile: function compile(program, options) {
this.sourceNode = [];
this.opcodes = [];
this.children = [];
this.options = options;
this.stringParams = options.stringParams;
this.trackIds = options.trackIds;
options.blockParams = options.blockParams || [];
// These changes will propagate to the other compiler components
var knownHelpers = options.knownHelpers;
options.knownHelpers = {
helperMissing: true,
blockHelperMissing: true,
each: true,
'if': true,
unless: true,
'with': true,
log: true,
lookup: true
};
if (knownHelpers) {
for (var _name in knownHelpers) {
if (_name in knownHelpers) {
options.knownHelpers[_name] = knownHelpers[_name];
}
}
}
return this.accept(program);
},
compileProgram: function compileProgram(program) {
var childCompiler = new this.compiler(),
// eslint-disable-line new-cap
result = childCompiler.compile(program, this.options),
guid = this.guid++;
this.usePartial = this.usePartial || result.usePartial;
this.children[guid] = result;
this.useDepths = this.useDepths || result.useDepths;
return guid;
},
accept: function accept(node) {
this.sourceNode.unshift(node);
var ret = this[node.type](node);
this.sourceNode.shift();
return ret;
},
Program: function Program(program) {
this.options.blockParams.unshift(program.blockParams);
var body = program.body,
bodyLength = body.length;
for (var i = 0; i < bodyLength; i++) {
this.accept(body[i]);
}
this.options.blockParams.shift();
this.isSimple = bodyLength === 1;
this.blockParams = program.blockParams ? program.blockParams.length : 0;
return this;
},
BlockStatement: function BlockStatement(block) {
transformLiteralToPath(block);
var program = block.program,
inverse = block.inverse;
program = program && this.compileProgram(program);
inverse = inverse && this.compileProgram(inverse);
var type = this.classifySexpr(block);
if (type === 'helper') {
this.helperSexpr(block, program, inverse);
} else if (type === 'simple') {
this.simpleSexpr(block);
// now that the simple mustache is resolved, we need to
// evaluate it by executing `blockHelperMissing`
this.opcode('pushProgram', program);
this.opcode('pushProgram', inverse);
this.opcode('emptyHash');
this.opcode('blockValue', block.path.original);
} else {
this.ambiguousSexpr(block, program, inverse);
// now that the simple mustache is resolved, we need to
// evaluate it by executing `blockHelperMissing`
this.opcode('pushProgram', program);
this.opcode('pushProgram', inverse);
this.opcode('emptyHash');
this.opcode('ambiguousBlockValue');
}
this.opcode('append');
},
PartialStatement: function PartialStatement(partial) {
this.usePartial = true;
var params = partial.params;
if (params.length > 1) {
throw new _Exception2['default']('Unsupported number of partial arguments: ' + params.length, partial);
} else if (!params.length) {
params.push({ type: 'PathExpression', parts: [], depth: 0 });
}
var partialName = partial.name.original,
isDynamic = partial.name.type === 'SubExpression';
if (isDynamic) {
this.accept(partial.name);
}
this.setupFullMustacheParams(partial, undefined, undefined, true);
var indent = partial.indent || '';
if (this.options.preventIndent && indent) {
this.opcode('appendContent', indent);
indent = '';
}
this.opcode('invokePartial', isDynamic, partialName, indent);
this.opcode('append');
},
MustacheStatement: function MustacheStatement(mustache) {
this.SubExpression(mustache); // eslint-disable-line new-cap
if (mustache.escaped && !this.options.noEscape) {
this.opcode('appendEscaped');
} else {
this.opcode('append');
}
},
ContentStatement: function ContentStatement(content) {
if (content.value) {
this.opcode('appendContent', content.value);
}
},
CommentStatement: function CommentStatement() {},
SubExpression: function SubExpression(sexpr) {
transformLiteralToPath(sexpr);
var type = this.classifySexpr(sexpr);
if (type === 'simple') {
this.simpleSexpr(sexpr);
} else if (type === 'helper') {
this.helperSexpr(sexpr);
} else {
this.ambiguousSexpr(sexpr);
}
},
ambiguousSexpr: function ambiguousSexpr(sexpr, program, inverse) {
var path = sexpr.path,
name = path.parts[0],
isBlock = program != null || inverse != null;
this.opcode('getContext', path.depth);
this.opcode('pushProgram', program);
this.opcode('pushProgram', inverse);
this.accept(path);
this.opcode('invokeAmbiguous', name, isBlock);
},
simpleSexpr: function simpleSexpr(sexpr) {
this.accept(sexpr.path);
this.opcode('resolvePossibleLambda');
},
helperSexpr: function helperSexpr(sexpr, program, inverse) {
var params = this.setupFullMustacheParams(sexpr, program, inverse),
path = sexpr.path,
name = path.parts[0];
if (this.options.knownHelpers[name]) {
this.opcode('invokeKnownHelper', params.length, name);
} else if (this.options.knownHelpersOnly) {
throw new _Exception2['default']('You specified knownHelpersOnly, but used the unknown helper ' + name, sexpr);
} else {
path.falsy = true;
this.accept(path);
this.opcode('invokeHelper', params.length, path.original, _AST2['default'].helpers.simpleId(path));
}
},
PathExpression: function PathExpression(path) {
this.addDepth(path.depth);
this.opcode('getContext', path.depth);
var name = path.parts[0],
scoped = _AST2['default'].helpers.scopedId(path),
blockParamId = !path.depth && !scoped && this.blockParamIndex(name);
if (blockParamId) {
this.opcode('lookupBlockParam', blockParamId, path.parts);
} else if (!name) {
// Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
this.opcode('pushContext');
} else if (path.data) {
this.options.data = true;
this.opcode('lookupData', path.depth, path.parts);
} else {
this.opcode('lookupOnContext', path.parts, path.falsy, scoped);
}
},
StringLiteral: function StringLiteral(string) {
this.opcode('pushString', string.value);
},
NumberLiteral: function NumberLiteral(number) {
this.opcode('pushLiteral', number.value);
},
BooleanLiteral: function BooleanLiteral(bool) {
this.opcode('pushLiteral', bool.value);
},
UndefinedLiteral: function UndefinedLiteral() {
this.opcode('pushLiteral', 'undefined');
},
NullLiteral: function NullLiteral() {
this.opcode('pushLiteral', 'null');
},
Hash: function Hash(hash) {
var pairs = hash.pairs,
i = 0,
l = pairs.length;
this.opcode('pushHash');
for (; i < l; i++) {
this.pushParam(pairs[i].value);
}
while (i--) {
this.opcode('assignToHash', pairs[i].key);
}
this.opcode('popHash');
},
// HELPERS
opcode: function opcode(name) {
this.opcodes.push({ opcode: name, args: slice.call(arguments, 1), loc: this.sourceNode[0].loc });
},
addDepth: function addDepth(depth) {
if (!depth) {
return;
}
this.useDepths = true;
},
classifySexpr: function classifySexpr(sexpr) {
var isSimple = _AST2['default'].helpers.simpleId(sexpr.path);
var isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]);
// a mustache is an eligible helper if:
// * its id is simple (a single part, not `this` or `..`)
var isHelper = !isBlockParam && _AST2['default'].helpers.helperExpression(sexpr);
// if a mustache is an eligible helper but not a definite
// helper, it is ambiguous, and will be resolved in a later
// pass or at runtime.
var isEligible = !isBlockParam && (isHelper || isSimple);
// if ambiguous, we can possibly resolve the ambiguity now
// An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
if (isEligible && !isHelper) {
var _name2 = sexpr.path.parts[0],
options = this.options;
if (options.knownHelpers[_name2]) {
isHelper = true;
} else if (options.knownHelpersOnly) {
isEligible = false;
}
}
if (isHelper) {
return 'helper';
} else if (isEligible) {
return 'ambiguous';
} else {
return 'simple';
}
},
pushParams: function pushParams(params) {
for (var i = 0, l = params.length; i < l; i++) {
this.pushParam(params[i]);
}
},
pushParam: function pushParam(val) {
var value = val.value != null ? val.value : val.original || '';
if (this.stringParams) {
if (value.replace) {
value = value.replace(/^(\.?\.\/)*/g, '').replace(/\//g, '.');
}
if (val.depth) {
this.addDepth(val.depth);
}
this.opcode('getContext', val.depth || 0);
this.opcode('pushStringParam', value, val.type);
if (val.type === 'SubExpression') {
// SubExpressions get evaluated and passed in
// in string params mode.
this.accept(val);
}
} else {
if (this.trackIds) {
var blockParamIndex = undefined;
if (val.parts && !_AST2['default'].helpers.scopedId(val) && !val.depth) {
blockParamIndex = this.blockParamIndex(val.parts[0]);
}
if (blockParamIndex) {
var blockParamChild = val.parts.slice(1).join('.');
this.opcode('pushId', 'BlockParam', blockParamIndex, blockParamChild);
} else {
value = val.original || value;
if (value.replace) {
value = value.replace(/^\.\//g, '').replace(/^\.$/g, '');
}
this.opcode('pushId', val.type, value);
}
}
this.accept(val);
}
},
setupFullMustacheParams: function setupFullMustacheParams(sexpr, program, inverse, omitEmpty) {
var params = sexpr.params;
this.pushParams(params);
this.opcode('pushProgram', program);
this.opcode('pushProgram', inverse);
if (sexpr.hash) {
this.accept(sexpr.hash);
} else {
this.opcode('emptyHash', omitEmpty);
}
return params;
},
blockParamIndex: function blockParamIndex(name) {
for (var depth = 0, len = this.options.blockParams.length; depth < len; depth++) {
var blockParams = this.options.blockParams[depth],
param = blockParams && _isArray$indexOf.indexOf(blockParams, name);
if (blockParams && param >= 0) {
return [depth, param];
}
}
}
};
function precompile(input, options, env) {
if (input == null || typeof input !== 'string' && input.type !== 'Program') {
throw new _Exception2['default']('You must pass a string or Handlebars AST to Handlebars.precompile. You passed ' + input);
}
options = options || {};
if (!('data' in options)) {
options.data = true;
}
if (options.compat) {
options.useDepths = true;
}
var ast = env.parse(input, options),
environment = new env.Compiler().compile(ast, options);
return new env.JavaScriptCompiler().compile(environment, options);
}
function compile(input, _x, env) {
var options = arguments[1] === undefined ? {} : arguments[1];
if (input == null || typeof input !== 'string' && input.type !== 'Program') {
throw new _Exception2['default']('You must pass a string or Handlebars AST to Handlebars.compile. You passed ' + input);
}
if (!('data' in options)) {
options.data = true;
}
if (options.compat) {
options.useDepths = true;
}
var compiled = undefined;
function compileInput() {
var ast = env.parse(input, options),
environment = new env.Compiler().compile(ast, options),
templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
return env.template(templateSpec);
}
// Template is only compiled on first use and cached after that point.
function ret(context, execOptions) {
if (!compiled) {
compiled = compileInput();
}
return compiled.call(this, context, execOptions);
}
ret._setup = function (setupOptions) {
if (!compiled) {
compiled = compileInput();
}
return compiled._setup(setupOptions);
};
ret._child = function (i, data, blockParams, depths) {
if (!compiled) {
compiled = compileInput();
}
return compiled._child(i, data, blockParams, depths);
};
return ret;
}
function argEquals(a, b) {
if (a === b) {
return true;
}
if (_isArray$indexOf.isArray(a) && _isArray$indexOf.isArray(b) && a.length === b.length) {
for (var i = 0; i < a.length; i++) {
if (!argEquals(a[i], b[i])) {
return false;
}
}
return true;
}
}
function transformLiteralToPath(sexpr) {
if (!sexpr.path.parts) {
var literal = sexpr.path;
// Casting to string here to make false and 0 literal values play nicely with the rest
// of the system.
sexpr.path = new _AST2['default'].PathExpression(false, 0, [literal.original + ''], literal.original + '', literal.loc);
}
}
},{"../exception":22,"../utils":26,"./ast":12}],16:[function(require,module,exports){
'use strict';
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };
exports.__esModule = true;
exports.SourceLocation = SourceLocation;
exports.id = id;
exports.stripFlags = stripFlags;
exports.stripComment = stripComment;
exports.preparePath = preparePath;
exports.prepareMustache = prepareMustache;
exports.prepareRawBlock = prepareRawBlock;
exports.prepareBlock = prepareBlock;
var _Exception = require('../exception');
var _Exception2 = _interopRequireWildcard(_Exception);
function SourceLocation(source, locInfo) {
this.source = source;
this.start = {
line: locInfo.first_line,
column: locInfo.first_column
};
this.end = {
line: locInfo.last_line,
column: locInfo.last_column
};
}
function id(token) {
if (/^\[.*\]$/.test(token)) {
return token.substr(1, token.length - 2);
} else {
return token;
}
}
function stripFlags(open, close) {
return {
open: open.charAt(2) === '~',
close: close.charAt(close.length - 3) === '~'
};
}
function stripComment(comment) {
return comment.replace(/^\{\{~?\!-?-?/, '').replace(/-?-?~?\}\}$/, '');
}
function preparePath(data, parts, locInfo) {
locInfo = this.locInfo(locInfo);
var original = data ? '@' : '',
dig = [],
depth = 0,
depthString = '';
for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i].part,
// If we have [] syntax then we do not treat path references as operators,
// i.e. foo.[this] resolves to approximately context.foo['this']
isLiteral = parts[i].original !== part;
original += (parts[i].separator || '') + part;
if (!isLiteral && (part === '..' || part === '.' || part === 'this')) {
if (dig.length > 0) {
throw new _Exception2['default']('Invalid path: ' + original, { loc: locInfo });
} else if (part === '..') {
depth++;
depthString += '../';
}
} else {
dig.push(part);
}
}
return new this.PathExpression(data, depth, dig, original, locInfo);
}
function prepareMustache(path, params, hash, open, strip, locInfo) {
// Must use charAt to support IE pre-10
var escapeFlag = open.charAt(3) || open.charAt(2),
escaped = escapeFlag !== '{' && escapeFlag !== '&';
return new this.MustacheStatement(path, params, hash, escaped, strip, this.locInfo(locInfo));
}
function prepareRawBlock(openRawBlock, content, close, locInfo) {
if (openRawBlock.path.original !== close) {
var errorNode = { loc: openRawBlock.path.loc };
throw new _Exception2['default'](openRawBlock.path.original + ' doesn\'t match ' + close, errorNode);
}
locInfo = this.locInfo(locInfo);
var program = new this.Program([content], null, {}, locInfo);
return new this.BlockStatement(openRawBlock.path, openRawBlock.params, openRawBlock.hash, program, undefined, {}, {}, {}, locInfo);
}
function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
// When we are chaining inverse calls, we will not have a close path
if (close && close.path && openBlock.path.original !== close.path.original) {
var errorNode = { loc: openBlock.path.loc };
throw new _Exception2['default'](openBlock.path.original + ' doesn\'t match ' + close.path.original, errorNode);
}
program.blockParams = openBlock.blockParams;
var inverse = undefined,
inverseStrip = undefined;
if (inverseAndProgram) {
if (inverseAndProgram.chain) {
inverseAndProgram.program.body[0].closeStrip = close.strip;
}
inverseStrip = inverseAndProgram.strip;
inverse = inverseAndProgram.program;
}
if (inverted) {
inverted = inverse;
inverse = program;
program = inverted;
}
return new this.BlockStatement(openBlock.path, openBlock.params, openBlock.hash, program, inverse, openBlock.strip, inverseStrip, close && close.strip, this.locInfo(locInfo));
}
},{"../exception":22}],17:[function(require,module,exports){
'use strict';
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };
exports.__esModule = true;
var _COMPILER_REVISION$REVISION_CHANGES = require('../base');
var _Exception = require('../exception');
var _Exception2 = _interopRequireWildcard(_Exception);
var _isArray = require('../utils');
var _CodeGen = require('./code-gen');
var _CodeGen2 = _interopRequireWildcard(_CodeGen);
function Literal(value) {
this.value = value;
}
function JavaScriptCompiler() {}
JavaScriptCompiler.prototype = {
// PUBLIC API: You can override these methods in a subclass to provide
// alternative compiled forms for name lookup and buffering semantics
nameLookup: function nameLookup(parent, name /* , type*/) {
if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
return [parent, '.', name];
} else {
return [parent, '[\'', name, '\']'];
}
},
depthedLookup: function depthedLookup(name) {
return [this.aliasable('this.lookup'), '(depths, "', name, '")'];
},
compilerInfo: function compilerInfo() {
var revision = _COMPILER_REVISION$REVISION_CHANGES.COMPILER_REVISION,
versions = _COMPILER_REVISION$REVISION_CHANGES.REVISION_CHANGES[revision];
return [revision, versions];
},
appendToBuffer: function appendToBuffer(source, location, explicit) {
// Force a source as this simplifies the merge logic.
if (!_isArray.isArray(source)) {
source = [source];
}
source = this.source.wrap(source, location);
if (this.environment.isSimple) {
return ['return ', source, ';'];
} else if (explicit) {
// This is a case where the buffer operation occurs as a child of another
// construct, generally braces. We have to explicitly output these buffer
// operations to ensure that the emitted code goes in the correct location.
return ['buffer += ', source, ';'];
} else {
source.appendToBuffer = true;
return source;
}
},
initializeBuffer: function initializeBuffer() {
return this.quotedString('');
},
// END PUBLIC API
compile: function compile(environment, options, context, asObject) {
this.environment = environment;
this.options = options;
this.stringParams = this.options.stringParams;
this.trackIds = this.options.trackIds;
this.precompile = !asObject;
this.name = this.environment.name;
this.isChild = !!context;
this.context = context || {
programs: [],
environments: []
};
this.preamble();
this.stackSlot = 0;
this.stackVars = [];
this.aliases = {};
this.registers = { list: [] };
this.hashes = [];
this.compileStack = [];
this.inlineStack = [];
this.blockParams = [];
this.compileChildren(environment, options);
this.useDepths = this.useDepths || environment.useDepths || this.options.compat;
this.useBlockParams = this.useBlockParams || environment.useBlockParams;
var opcodes = environment.opcodes,
opcode = undefined,
firstLoc = undefined,
i = undefined,
l = undefined;
for (i = 0, l = opcodes.length; i < l; i++) {
opcode = opcodes[i];
this.source.currentLocation = opcode.loc;
firstLoc = firstLoc || opcode.loc;
this[opcode.opcode].apply(this, opcode.args);
}
// Flush any trailing content that might be pending.
this.source.currentLocation = firstLoc;
this.pushSource('');
/* istanbul ignore next */
if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
throw new _Exception2['default']('Compile completed with content left on stack');
}
var fn = this.createFunctionContext(asObject);
if (!this.isChild) {
var ret = {
compiler: this.compilerInfo(),
main: fn
};
var programs = this.context.programs;
for (i = 0, l = programs.length; i < l; i++) {
if (programs[i]) {
ret[i] = programs[i];
}
}
if (this.environment.usePartial) {
ret.usePartial = true;
}
if (this.options.data) {
ret.useData = true;
}
if (this.useDepths) {
ret.useDepths = true;
}
if (this.useBlockParams) {
ret.useBlockParams = true;
}
if (this.options.compat) {
ret.compat = true;
}
if (!asObject) {
ret.compiler = JSON.stringify(ret.compiler);
this.source.currentLocation = { start: { line: 1, column: 0 } };
ret = this.objectLiteral(ret);
if (options.srcName) {
ret = ret.toStringWithSourceMap({ file: options.destName });
ret.map = ret.map && ret.map.toString();
} else {
ret = ret.toString();
}
} else {
ret.compilerOptions = this.options;
}
return ret;
} else {
return fn;
}
},
preamble: function preamble() {
// track the last context pushed into place to allow skipping the
// getContext opcode when it would be a noop
this.lastContext = 0;
this.source = new _CodeGen2['default'](this.options.srcName);
},
createFunctionContext: function createFunctionContext(asObject) {
var varDeclarations = '';
var locals = this.stackVars.concat(this.registers.list);
if (locals.length > 0) {
varDeclarations += ', ' + locals.join(', ');
}
// Generate minimizer alias mappings
//
// When using true SourceNodes, this will update all references to the given alias
// as the source nodes are reused in situ. For the non-source node compilation mode,
// aliases will not be used, but this case is already being run on the client and
// we aren't concern about minimizing the template size.
var aliasCount = 0;
for (var alias in this.aliases) {
// eslint-disable-line guard-for-in
var node = this.aliases[alias];
if (this.aliases.hasOwnProperty(alias) && node.children && node.referenceCount > 1) {
varDeclarations += ', alias' + ++aliasCount + '=' + alias;
node.children[0] = 'alias' + aliasCount;
}
}
var params = ['depth0', 'helpers', 'partials', 'data'];
if (this.useBlockParams || this.useDepths) {
params.push('blockParams');
}
if (this.useDepths) {
params.push('depths');
}
// Perform a second pass over the output to merge content when possible
var source = this.mergeSource(varDeclarations);
if (asObject) {
params.push(source);
return Function.apply(this, params);
} else {
return this.source.wrap(['function(', params.join(','), ') {\n ', source, '}']);
}
},
mergeSource: function mergeSource(varDeclarations) {
var isSimple = this.environment.isSimple,
appendOnly = !this.forceBuffer,
appendFirst = undefined,
sourceSeen = undefined,
bufferStart = undefined,
bufferEnd = undefined;
this.source.each(function (line) {
if (line.appendToBuffer) {
if (bufferStart) {
line.prepend(' + ');
} else {
bufferStart = line;
}
bufferEnd = line;
} else {
if (bufferStart) {
if (!sourceSeen) {
appendFirst = true;
} else {
bufferStart.prepend('buffer += ');
}
bufferEnd.add(';');
bufferStart = bufferEnd = undefined;
}
sourceSeen = true;
if (!isSimple) {
appendOnly = false;
}
}
});
if (appendOnly) {
if (bufferStart) {
bufferStart.prepend('return ');
bufferEnd.add(';');
} else if (!sourceSeen) {
this.source.push('return "";');
}
} else {
varDeclarations += ', buffer = ' + (appendFirst ? '' : this.initializeBuffer());
if (bufferStart) {
bufferStart.prepend('return buffer + ');
bufferEnd.add(';');
} else {
this.source.push('return buffer;');
}
}
if (varDeclarations) {
this.source.prepend('var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n'));
}
return this.source.merge();
},
// [blockValue]
//
// On stack, before: hash, inverse, program, value
// On stack, after: return value of blockHelperMissing
//
// The purpose of this opcode is to take a block of the form
// `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
// replace it on the stack with the result of properly
// invoking blockHelperMissing.
blockValue: function blockValue(name) {
var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
params = [this.contextName(0)];
this.setupHelperArgs(name, 0, params);
var blockName = this.popStack();
params.splice(1, 0, blockName);
this.push(this.source.functionCall(blockHelperMissing, 'call', params));
},
// [ambiguousBlockValue]
//
// On stack, before: hash, inverse, program, value
// Compiler value, before: lastHelper=value of last found helper, if any
// On stack, after, if no lastHelper: same as [blockValue]
// On stack, after, if lastHelper: value
ambiguousBlockValue: function ambiguousBlockValue() {
// We're being a bit cheeky and reusing the options value from the prior exec
var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
params = [this.contextName(0)];
this.setupHelperArgs('', 0, params, true);
this.flushInline();
var current = this.topStack();
params.splice(1, 0, current);
this.pushSource(['if (!', this.lastHelper, ') { ', current, ' = ', this.source.functionCall(blockHelperMissing, 'call', params), '}']);
},
// [appendContent]
//
// On stack, before: ...
// On stack, after: ...
//
// Appends the string value of `content` to the current buffer
appendContent: function appendContent(content) {
if (this.pendingContent) {
content = this.pendingContent + content;
} else {
this.pendingLocation = this.source.currentLocation;
}
this.pendingContent = content;
},
// [append]
//
// On stack, before: value, ...
// On stack, after: ...
//
// Coerces `value` to a String and appends it to the current buffer.
//
// If `value` is truthy, or 0, it is coerced into a string and appended
// Otherwise, the empty string is appended
append: function append() {
if (this.isInline()) {
this.replaceStack(function (current) {
return [' != null ? ', current, ' : ""'];
});
this.pushSource(this.appendToBuffer(this.popStack()));
} else {
var local = this.popStack();
this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']);
if (this.environment.isSimple) {
this.pushSource(['else { ', this.appendToBuffer('\'\'', undefined, true), ' }']);
}
}
},
// [appendEscaped]
//
// On stack, before: value, ...
// On stack, after: ...
//
// Escape `value` and append it to the buffer
appendEscaped: function appendEscaped() {
this.pushSource(this.appendToBuffer([this.aliasable('this.escapeExpression'), '(', this.popStack(), ')']));
},
// [getContext]
//
// On stack, before: ...
// On stack, after: ...
// Compiler value, after: lastContext=depth
//
// Set the value of the `lastContext` compiler value to the depth
getContext: function getContext(depth) {
this.lastContext = depth;
},
// [pushContext]
//
// On stack, before: ...
// On stack, after: currentContext, ...
//
// Pushes the value of the current context onto the stack.
pushContext: function pushContext() {
this.pushStackLiteral(this.contextName(this.lastContext));
},
// [lookupOnContext]
//
// On stack, before: ...
// On stack, after: currentContext[name], ...
//
// Looks up the value of `name` on the current context and pushes
// it onto the stack.
lookupOnContext: function lookupOnContext(parts, falsy, scoped) {
var i = 0;
if (!scoped && this.options.compat && !this.lastContext) {
// The depthed query is expected to handle the undefined logic for the root level that
// is implemented below, so we evaluate that directly in compat mode
this.push(this.depthedLookup(parts[i++]));
} else {
this.pushContext();
}
this.resolvePath('context', parts, i, falsy);
},
// [lookupBlockParam]
//
// On stack, before: ...
// On stack, after: blockParam[name], ...
//
// Looks up the value of `parts` on the given block param and pushes
// it onto the stack.
lookupBlockParam: function lookupBlockParam(blockParamId, parts) {
this.useBlockParams = true;
this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']);
this.resolvePath('context', parts, 1);
},
// [lookupData]
//
// On stack, before: ...
// On stack, after: data, ...
//
// Push the data lookup operator
lookupData: function lookupData(depth, parts) {
if (!depth) {
this.pushStackLiteral('data');
} else {
this.pushStackLiteral('this.data(data, ' + depth + ')');
}
this.resolvePath('data', parts, 0, true);
},
resolvePath: function resolvePath(type, parts, i, falsy) {
var _this = this;
if (this.options.strict || this.options.assumeObjects) {
this.push(strictLookup(this.options.strict, this, parts, type));
return;
}
var len = parts.length;
for (; i < len; i++) {
/*eslint-disable no-loop-func */
this.replaceStack(function (current) {
var lookup = _this.nameLookup(current, parts[i], type);
// We want to ensure that zero and false are handled properly if the context (falsy flag)
// needs to have the special handling for these values.
if (!falsy) {
return [' != null ? ', lookup, ' : ', current];
} else {
// Otherwise we can use generic falsy handling
return [' && ', lookup];
}
});
/*eslint-enable no-loop-func */
}
},
// [resolvePossibleLambda]
//
// On stack, before: value, ...
// On stack, after: resolved value, ...
//
// If the `value` is a lambda, replace it on the stack by
// the return value of the lambda
resolvePossibleLambda: function resolvePossibleLambda() {
this.push([this.aliasable('this.lambda'), '(', this.popStack(), ', ', this.contextName(0), ')']);
},
// [pushStringParam]
//
// On stack, before: ...
// On stack, after: string, currentContext, ...
//
// This opcode is designed for use in string mode, which
// provides the string value of a parameter along with its
// depth rather than resolving it immediately.
pushStringParam: function pushStringParam(string, type) {
this.pushContext();
this.pushString(type);
// If it's a subexpression, the string result
// will be pushed after this opcode.
if (type !== 'SubExpression') {
if (typeof string === 'string') {
this.pushString(string);
} else {
this.pushStackLiteral(string);
}
}
},
emptyHash: function emptyHash(omitEmpty) {
if (this.trackIds) {
this.push('{}'); // hashIds
}
if (this.stringParams) {
this.push('{}'); // hashContexts
this.push('{}'); // hashTypes
}
this.pushStackLiteral(omitEmpty ? 'undefined' : '{}');
},
pushHash: function pushHash() {
if (this.hash) {
this.hashes.push(this.hash);
}
this.hash = { values: [], types: [], contexts: [], ids: [] };
},
popHash: function popHash() {
var hash = this.hash;
this.hash = this.hashes.pop();
if (this.trackIds) {
this.push(this.objectLiteral(hash.ids));
}
if (this.stringParams) {
this.push(this.objectLiteral(hash.contexts));
this.push(this.objectLiteral(hash.types));
}
this.push(this.objectLiteral(hash.values));
},
// [pushString]
//
// On stack, before: ...
// On stack, after: quotedString(string), ...
//
// Push a quoted version of `string` onto the stack
pushString: function pushString(string) {
this.pushStackLiteral(this.quotedString(string));
},
// [pushLiteral]
//
// On stack, before: ...
// On stack, after: value, ...
//
// Pushes a value onto the stack. This operation prevents
// the compiler from creating a temporary variable to hold
// it.
pushLiteral: function pushLiteral(value) {
this.pushStackLiteral(value);
},
// [pushProgram]
//
// On stack, before: ...
// On stack, after: program(guid), ...
//
// Push a program expression onto the stack. This takes
// a compile-time guid and converts it into a runtime-accessible
// expression.
pushProgram: function pushProgram(guid) {
if (guid != null) {
this.pushStackLiteral(this.programExpression(guid));
} else {
this.pushStackLiteral(null);
}
},
// [invokeHelper]
//
// On stack, before: hash, inverse, program, params..., ...
// On stack, after: result of helper invocation
//
// Pops off the helper's parameters, invokes the helper,
// and pushes the helper's return value onto the stack.
//
// If the helper is not found, `helperMissing` is called.
invokeHelper: function invokeHelper(paramSize, name, isSimple) {
var nonHelper = this.popStack(),
helper = this.setupHelper(paramSize, name),
simple = isSimple ? [helper.name, ' || '] : '';
var lookup = ['('].concat(simple, nonHelper);
if (!this.options.strict) {
lookup.push(' || ', this.aliasable('helpers.helperMissing'));
}
lookup.push(')');
this.push(this.source.functionCall(lookup, 'call', helper.callParams));
},
// [invokeKnownHelper]
//
// On stack, before: hash, inverse, program, params..., ...
// On stack, after: result of helper invocation
//
// This operation is used when the helper is known to exist,
// so a `helperMissing` fallback is not required.
invokeKnownHelper: function invokeKnownHelper(paramSize, name) {
var helper = this.setupHelper(paramSize, name);
this.push(this.source.functionCall(helper.name, 'call', helper.callParams));
},
// [invokeAmbiguous]
//
// On stack, before: hash, inverse, program, params..., ...
// On stack, after: result of disambiguation
//
// This operation is used when an expression like `{{foo}}`
// is provided, but we don't know at compile-time whether it
// is a helper or a path.
//
// This operation emits more code than the other options,
// and can be avoided by passing the `knownHelpers` and
// `knownHelpersOnly` flags at compile-time.
invokeAmbiguous: function invokeAmbiguous(name, helperCall) {
this.useRegister('helper');
var nonHelper = this.popStack();
this.emptyHash();
var helper = this.setupHelper(0, name, helperCall);
var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
var lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')'];
if (!this.options.strict) {
lookup[0] = '(helper = ';
lookup.push(' != null ? helper : ', this.aliasable('helpers.helperMissing'));
}
this.push(['(', lookup, helper.paramsInit ? ['),(', helper.paramsInit] : [], '),', '(typeof helper === ', this.aliasable('"function"'), ' ? ', this.source.functionCall('helper', 'call', helper.callParams), ' : helper))']);
},
// [invokePartial]
//
// On stack, before: context, ...
// On stack after: result of partial invocation
//
// This operation pops off a context, invokes a partial with that context,
// and pushes the result of the invocation back.
invokePartial: function invokePartial(isDynamic, name, indent) {
var params = [],
options = this.setupParams(name, 1, params, false);
if (isDynamic) {
name = this.popStack();
delete options.name;
}
if (indent) {
options.indent = JSON.stringify(indent);
}
options.helpers = 'helpers';
options.partials = 'partials';
if (!isDynamic) {
params.unshift(this.nameLookup('partials', name, 'partial'));
} else {
params.unshift(name);
}
if (this.options.compat) {
options.depths = 'depths';
}
options = this.objectLiteral(options);
params.push(options);
this.push(this.source.functionCall('this.invokePartial', '', params));
},
// [assignToHash]
//
// On stack, before: value, ..., hash, ...
// On stack, after: ..., hash, ...
//
// Pops a value off the stack and assigns it to the current hash
assignToHash: function assignToHash(key) {
var value = this.popStack(),
context = undefined,
type = undefined,
id = undefined;
if (this.trackIds) {
id = this.popStack();
}
if (this.stringParams) {
type = this.popStack();
context = this.popStack();
}
var hash = this.hash;
if (context) {
hash.contexts[key] = context;
}
if (type) {
hash.types[key] = type;
}
if (id) {
hash.ids[key] = id;
}
hash.values[key] = value;
},
pushId: function pushId(type, name, child) {
if (type === 'BlockParam') {
this.pushStackLiteral('blockParams[' + name[0] + '].path[' + name[1] + ']' + (child ? ' + ' + JSON.stringify('.' + child) : ''));
} else if (type === 'PathExpression') {
this.pushString(name);
} else if (type === 'SubExpression') {
this.pushStackLiteral('true');
} else {
this.pushStackLiteral('null');
}
},
// HELPERS
compiler: JavaScriptCompiler,
compileChildren: function compileChildren(environment, options) {
var children = environment.children,
child = undefined,
compiler = undefined;
for (var i = 0, l = children.length; i < l; i++) {
child = children[i];
compiler = new this.compiler(); // eslint-disable-line new-cap
var index = this.matchExistingProgram(child);
if (index == null) {
this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
index = this.context.programs.length;
child.index = index;
child.name = 'program' + index;
this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile);
this.context.environments[index] = child;
this.useDepths = this.useDepths || compiler.useDepths;
this.useBlockParams = this.useBlockParams || compiler.useBlockParams;
} else {
child.index = index;
child.name = 'program' + index;
this.useDepths = this.useDepths || child.useDepths;
this.useBlockParams = this.useBlockParams || child.useBlockParams;
}
}
},
matchExistingProgram: function matchExistingProgram(child) {
for (var i = 0, len = this.context.environments.length; i < len; i++) {
var environment = this.context.environments[i];
if (environment && environment.equals(child)) {
return i;
}
}
},
programExpression: function programExpression(guid) {
var child = this.environment.children[guid],
programParams = [child.index, 'data', child.blockParams];
if (this.useBlockParams || this.useDepths) {
programParams.push('blockParams');
}
if (this.useDepths) {
programParams.push('depths');
}
return 'this.program(' + programParams.join(', ') + ')';
},
useRegister: function useRegister(name) {
if (!this.registers[name]) {
this.registers[name] = true;
this.registers.list.push(name);
}
},
push: function push(expr) {
if (!(expr instanceof Literal)) {
expr = this.source.wrap(expr);
}
this.inlineStack.push(expr);
return expr;
},
pushStackLiteral: function pushStackLiteral(item) {
this.push(new Literal(item));
},
pushSource: function pushSource(source) {
if (this.pendingContent) {
this.source.push(this.appendToBuffer(this.source.quotedString(this.pendingContent), this.pendingLocation));
this.pendingContent = undefined;
}
if (source) {
this.source.push(source);
}
},
replaceStack: function replaceStack(callback) {
var prefix = ['('],
stack = undefined,
createdStack = undefined,
usedLiteral = undefined;
/* istanbul ignore next */
if (!this.isInline()) {
throw new _Exception2['default']('replaceStack on non-inline');
}
// We want to merge the inline statement into the replacement statement via ','
var top = this.popStack(true);
if (top instanceof Literal) {
// Literals do not need to be inlined
stack = [top.value];
prefix = ['(', stack];
usedLiteral = true;
} else {
// Get or create the current stack name for use by the inline
createdStack = true;
var _name = this.incrStack();
prefix = ['((', this.push(_name), ' = ', top, ')'];
stack = this.topStack();
}
var item = callback.call(this, stack);
if (!usedLiteral) {
this.popStack();
}
if (createdStack) {
this.stackSlot--;
}
this.push(prefix.concat(item, ')'));
},
incrStack: function incrStack() {
this.stackSlot++;
if (this.stackSlot > this.stackVars.length) {
this.stackVars.push('stack' + this.stackSlot);
}
return this.topStackName();
},
topStackName: function topStackName() {
return 'stack' + this.stackSlot;
},
flushInline: function flushInline() {
var inlineStack = this.inlineStack;
this.inlineStack = [];
for (var i = 0, len = inlineStack.length; i < len; i++) {
var entry = inlineStack[i];
/* istanbul ignore if */
if (entry instanceof Literal) {
this.compileStack.push(entry);
} else {
var stack = this.incrStack();
this.pushSource([stack, ' = ', entry, ';']);
this.compileStack.push(stack);
}
}
},
isInline: function isInline() {
return this.inlineStack.length;
},
popStack: function popStack(wrapped) {
var inline = this.isInline(),
item = (inline ? this.inlineStack : this.compileStack).pop();
if (!wrapped && item instanceof Literal) {
return item.value;
} else {
if (!inline) {
/* istanbul ignore next */
if (!this.stackSlot) {
throw new _Exception2['default']('Invalid stack pop');
}
this.stackSlot--;
}
return item;
}
},
topStack: function topStack() {
var stack = this.isInline() ? this.inlineStack : this.compileStack,
item = stack[stack.length - 1];
/* istanbul ignore if */
if (item instanceof Literal) {
return item.value;
} else {
return item;
}
},
contextName: function contextName(context) {
if (this.useDepths && context) {
return 'depths[' + context + ']';
} else {
return 'depth' + context;
}
},
quotedString: function quotedString(str) {
return this.source.quotedString(str);
},
objectLiteral: function objectLiteral(obj) {
return this.source.objectLiteral(obj);
},
aliasable: function aliasable(name) {
var ret = this.aliases[name];
if (ret) {
ret.referenceCount++;
return ret;
}
ret = this.aliases[name] = this.source.wrap(name);
ret.aliasable = true;
ret.referenceCount = 1;
return ret;
},
setupHelper: function setupHelper(paramSize, name, blockHelper) {
var params = [],
paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
var foundHelper = this.nameLookup('helpers', name, 'helper');
return {
params: params,
paramsInit: paramsInit,
name: foundHelper,
callParams: [this.contextName(0)].concat(params)
};
},
setupParams: function setupParams(helper, paramSize, params) {
var options = {},
contexts = [],
types = [],
ids = [],
param = undefined;
options.name = this.quotedString(helper);
options.hash = this.popStack();
if (this.trackIds) {
options.hashIds = this.popStack();
}
if (this.stringParams) {
options.hashTypes = this.popStack();
options.hashContexts = this.popStack();
}
var inverse = this.popStack(),
program = this.popStack();
// Avoid setting fn and inverse if neither are set. This allows
// helpers to do a check for `if (options.fn)`
if (program || inverse) {
options.fn = program || 'this.noop';
options.inverse = inverse || 'this.noop';
}
// The parameters go on to the stack in order (making sure that they are evaluated in order)
// so we need to pop them off the stack in reverse order
var i = paramSize;
while (i--) {
param = this.popStack();
params[i] = param;
if (this.trackIds) {
ids[i] = this.popStack();
}
if (this.stringParams) {
types[i] = this.popStack();
contexts[i] = this.popStack();
}
}
if (this.trackIds) {
options.ids = this.source.generateArray(ids);
}
if (this.stringParams) {
options.types = this.source.generateArray(types);
options.contexts = this.source.generateArray(contexts);
}
if (this.options.data) {
options.data = 'data';
}
if (this.useBlockParams) {
options.blockParams = 'blockParams';
}
return options;
},
setupHelperArgs: function setupHelperArgs(helper, paramSize, params, useRegister) {
var options = this.setupParams(helper, paramSize, params, true);
options = this.objectLiteral(options);
if (useRegister) {
this.useRegister('options');
params.push('options');
return ['options=', options];
} else {
params.push(options);
return '';
}
}
};
(function () {
var reservedWords = ('break else new var' + ' case finally return void' + ' catch for switch while' + ' continue function this with' + ' default if throw' + ' delete in try' + ' do instanceof typeof' + ' abstract enum int short' + ' boolean export interface static' + ' byte extends long super' + ' char final native synchronized' + ' class float package throws' + ' const goto private transient' + ' debugger implements protected volatile' + ' double import public let yield await' + ' null true false').split(' ');
var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
for (var i = 0, l = reservedWords.length; i < l; i++) {
compilerWords[reservedWords[i]] = true;
}
})();
JavaScriptCompiler.isValidJavaScriptVariableName = function (name) {
return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name);
};
function strictLookup(requireTerminal, compiler, parts, type) {
var stack = compiler.popStack(),
i = 0,
len = parts.length;
if (requireTerminal) {
len--;
}
for (; i < len; i++) {
stack = compiler.nameLookup(stack, parts[i], type);
}
if (requireTerminal) {
return [compiler.aliasable('this.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ')'];
} else {
return stack;
}
}
exports['default'] = JavaScriptCompiler;
module.exports = exports['default'];
},{"../base":11,"../exception":22,"../utils":26,"./code-gen":14}],18:[function(require,module,exports){
"use strict";
exports.__esModule = true;
/* istanbul ignore next */
/* Jison generated parser */
var handlebars = (function () {
var parser = { trace: function trace() {},
yy: {},
symbols_: { error: 2, root: 3, program: 4, EOF: 5, program_repetition0: 6, statement: 7, mustache: 8, block: 9, rawBlock: 10, partial: 11, content: 12, COMMENT: 13, CONTENT: 14, openRawBlock: 15, END_RAW_BLOCK: 16, OPEN_RAW_BLOCK: 17, helperName: 18, openRawBlock_repetition0: 19, openRawBlock_option0: 20, CLOSE_RAW_BLOCK: 21, openBlock: 22, block_option0: 23, closeBlock: 24, openInverse: 25, block_option1: 26, OPEN_BLOCK: 27, openBlock_repetition0: 28, openBlock_option0: 29, openBlock_option1: 30, CLOSE: 31, OPEN_INVERSE: 32, openInverse_repetition0: 33, openInverse_option0: 34, openInverse_option1: 35, openInverseChain: 36, OPEN_INVERSE_CHAIN: 37, openInverseChain_repetition0: 38, openInverseChain_option0: 39, openInverseChain_option1: 40, inverseAndProgram: 41, INVERSE: 42, inverseChain: 43, inverseChain_option0: 44, OPEN_ENDBLOCK: 45, OPEN: 46, mustache_repetition0: 47, mustache_option0: 48, OPEN_UNESCAPED: 49, mustache_repetition1: 50, mustache_option1: 51, CLOSE_UNESCAPED: 52, OPEN_PARTIAL: 53, partialName: 54, partial_repetition0: 55, partial_option0: 56, param: 57, sexpr: 58, OPEN_SEXPR: 59, sexpr_repetition0: 60, sexpr_option0: 61, CLOSE_SEXPR: 62, hash: 63, hash_repetition_plus0: 64, hashSegment: 65, ID: 66, EQUALS: 67, blockParams: 68, OPEN_BLOCK_PARAMS: 69, blockParams_repetition_plus0: 70, CLOSE_BLOCK_PARAMS: 71, path: 72, dataName: 73, STRING: 74, NUMBER: 75, BOOLEAN: 76, UNDEFINED: 77, NULL: 78, DATA: 79, pathSegments: 80, SEP: 81, $accept: 0, $end: 1 },
terminals_: { 2: "error", 5: "EOF", 13: "COMMENT", 14: "CONTENT", 16: "END_RAW_BLOCK", 17: "OPEN_RAW_BLOCK", 21: "CLOSE_RAW_BLOCK", 27: "OPEN_BLOCK", 31: "CLOSE", 32: "OPEN_INVERSE", 37: "OPEN_INVERSE_CHAIN", 42: "INVERSE", 45: "OPEN_ENDBLOCK", 46: "OPEN", 49: "OPEN_UNESCAPED", 52: "CLOSE_UNESCAPED", 53: "OPEN_PARTIAL", 59: "OPEN_SEXPR", 62: "CLOSE_SEXPR", 66: "ID", 67: "EQUALS", 69: "OPEN_BLOCK_PARAMS", 71: "CLOSE_BLOCK_PARAMS", 74: "STRING", 75: "NUMBER", 76: "BOOLEAN", 77: "UNDEFINED", 78: "NULL", 79: "DATA", 81: "SEP" },
productions_: [0, [3, 2], [4, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [12, 1], [10, 3], [15, 5], [9, 4], [9, 4], [22, 6], [25, 6], [36, 6], [41, 2], [43, 3], [43, 1], [24, 3], [8, 5], [8, 5], [11, 5], [57, 1], [57, 1], [58, 5], [63, 1], [65, 3], [68, 3], [18, 1], [18, 1], [18, 1], [18, 1], [18, 1], [18, 1], [18, 1], [54, 1], [54, 1], [73, 2], [72, 1], [80, 3], [80, 1], [6, 0], [6, 2], [19, 0], [19, 2], [20, 0], [20, 1], [23, 0], [23, 1], [26, 0], [26, 1], [28, 0], [28, 2], [29, 0], [29, 1], [30, 0], [30, 1], [33, 0], [33, 2], [34, 0], [34, 1], [35, 0], [35, 1], [38, 0], [38, 2], [39, 0], [39, 1], [40, 0], [40, 1], [44, 0], [44, 1], [47, 0], [47, 2], [48, 0], [48, 1], [50, 0], [50, 2], [51, 0], [51, 1], [55, 0], [55, 2], [56, 0], [56, 1], [60, 0], [60, 2], [61, 0], [61, 1], [64, 1], [64, 2], [70, 1], [70, 2]],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {
var $0 = $$.length - 1;
switch (yystate) {
case 1:
return $$[$0 - 1];
break;
case 2:
this.$ = new yy.Program($$[$0], null, {}, yy.locInfo(this._$));
break;
case 3:
this.$ = $$[$0];
break;
case 4:
this.$ = $$[$0];
break;
case 5:
this.$ = $$[$0];
break;
case 6:
this.$ = $$[$0];
break;
case 7:
this.$ = $$[$0];
break;
case 8:
this.$ = new yy.CommentStatement(yy.stripComment($$[$0]), yy.stripFlags($$[$0], $$[$0]), yy.locInfo(this._$));
break;
case 9:
this.$ = new yy.ContentStatement($$[$0], yy.locInfo(this._$));
break;
case 10:
this.$ = yy.prepareRawBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
break;
case 11:
this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1] };
break;
case 12:
this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], false, this._$);
break;
case 13:
this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], true, this._$);
break;
case 14:
this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
break;
case 15:
this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
break;
case 16:
this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
break;
case 17:
this.$ = { strip: yy.stripFlags($$[$0 - 1], $$[$0 - 1]), program: $$[$0] };
break;
case 18:
var inverse = yy.prepareBlock($$[$0 - 2], $$[$0 - 1], $$[$0], $$[$0], false, this._$),
program = new yy.Program([inverse], null, {}, yy.locInfo(this._$));
program.chained = true;
this.$ = { strip: $$[$0 - 2].strip, program: program, chain: true };
break;
case 19:
this.$ = $$[$0];
break;
case 20:
this.$ = { path: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 2], $$[$0]) };
break;
case 21:
this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
break;
case 22:
this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
break;
case 23:
this.$ = new yy.PartialStatement($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], yy.stripFlags($$[$0 - 4], $$[$0]), yy.locInfo(this._$));
break;
case 24:
this.$ = $$[$0];
break;
case 25:
this.$ = $$[$0];
break;
case 26:
this.$ = new yy.SubExpression($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], yy.locInfo(this._$));
break;
case 27:
this.$ = new yy.Hash($$[$0], yy.locInfo(this._$));
break;
case 28:
this.$ = new yy.HashPair(yy.id($$[$0 - 2]), $$[$0], yy.locInfo(this._$));
break;
case 29:
this.$ = yy.id($$[$0 - 1]);
break;
case 30:
this.$ = $$[$0];
break;
case 31:
this.$ = $$[$0];
break;
case 32:
this.$ = new yy.StringLiteral($$[$0], yy.locInfo(this._$));
break;
case 33:
this.$ = new yy.NumberLiteral($$[$0], yy.locInfo(this._$));
break;
case 34:
this.$ = new yy.BooleanLiteral($$[$0], yy.locInfo(this._$));
break;
case 35:
this.$ = new yy.UndefinedLiteral(yy.locInfo(this._$));
break;
case 36:
this.$ = new yy.NullLiteral(yy.locInfo(this._$));
break;
case 37:
this.$ = $$[$0];
break;
case 38:
this.$ = $$[$0];
break;
case 39:
this.$ = yy.preparePath(true, $$[$0], this._$);
break;
case 40:
this.$ = yy.preparePath(false, $$[$0], this._$);
break;
case 41:
$$[$0 - 2].push({ part: yy.id($$[$0]), original: $$[$0], separator: $$[$0 - 1] });this.$ = $$[$0 - 2];
break;
case 42:
this.$ = [{ part: yy.id($$[$0]), original: $$[$0] }];
break;
case 43:
this.$ = [];
break;
case 44:
$$[$0 - 1].push($$[$0]);
break;
case 45:
this.$ = [];
break;
case 46:
$$[$0 - 1].push($$[$0]);
break;
case 53:
this.$ = [];
break;
case 54:
$$[$0 - 1].push($$[$0]);
break;
case 59:
this.$ = [];
break;
case 60:
$$[$0 - 1].push($$[$0]);
break;
case 65:
this.$ = [];
break;
case 66:
$$[$0 - 1].push($$[$0]);
break;
case 73:
this.$ = [];
break;
case 74:
$$[$0 - 1].push($$[$0]);
break;
case 77:
this.$ = [];
break;
case 78:
$$[$0 - 1].push($$[$0]);
break;
case 81:
this.$ = [];
break;
case 82:
$$[$0 - 1].push($$[$0]);
break;
case 85:
this.$ = [];
break;
case 86:
$$[$0 - 1].push($$[$0]);
break;
case 89:
this.$ = [$$[$0]];
break;
case 90:
$$[$0 - 1].push($$[$0]);
break;
case 91:
this.$ = [$$[$0]];
break;
case 92:
$$[$0 - 1].push($$[$0]);
break;
}
},
table: [{ 3: 1, 4: 2, 5: [2, 43], 6: 3, 13: [2, 43], 14: [2, 43], 17: [2, 43], 27: [2, 43], 32: [2, 43], 46: [2, 43], 49: [2, 43], 53: [2, 43] }, { 1: [3] }, { 5: [1, 4] }, { 5: [2, 2], 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: 10, 13: [1, 11], 14: [1, 18], 15: 16, 17: [1, 21], 22: 14, 25: 15, 27: [1, 19], 32: [1, 20], 37: [2, 2], 42: [2, 2], 45: [2, 2], 46: [1, 12], 49: [1, 13], 53: [1, 17] }, { 1: [2, 1] }, { 5: [2, 44], 13: [2, 44], 14: [2, 44], 17: [2, 44], 27: [2, 44], 32: [2, 44], 37: [2, 44], 42: [2, 44], 45: [2, 44], 46: [2, 44], 49: [2, 44], 53: [2, 44] }, { 5: [2, 3], 13: [2, 3], 14: [2, 3], 17: [2, 3], 27: [2, 3], 32: [2, 3], 37: [2, 3], 42: [2, 3], 45: [2, 3], 46: [2, 3], 49: [2, 3], 53: [2, 3] }, { 5: [2, 4], 13: [2, 4], 14: [2, 4], 17: [2, 4], 27: [2, 4], 32: [2, 4], 37: [2, 4], 42: [2, 4], 45: [2, 4], 46: [2, 4], 49: [2, 4], 53: [2, 4] }, { 5: [2, 5], 13: [2, 5], 14: [2, 5], 17: [2, 5], 27: [2, 5], 32: [2, 5], 37: [2, 5], 42: [2, 5], 45: [2, 5], 46: [2, 5], 49: [2, 5], 53: [2, 5] }, { 5: [2, 6], 13: [2, 6], 14: [2, 6], 17: [2, 6], 27: [2, 6], 32: [2, 6], 37: [2, 6], 42: [2, 6], 45: [2, 6], 46: [2, 6], 49: [2, 6], 53: [2, 6] }, { 5: [2, 7], 13: [2, 7], 14: [2, 7], 17: [2, 7], 27: [2, 7], 32: [2, 7], 37: [2, 7], 42: [2, 7], 45: [2, 7], 46: [2, 7], 49: [2, 7], 53: [2, 7] }, { 5: [2, 8], 13: [2, 8], 14: [2, 8], 17: [2, 8], 27: [2, 8], 32: [2, 8], 37: [2, 8], 42: [2, 8], 45: [2, 8], 46: [2, 8], 49: [2, 8], 53: [2, 8] }, { 18: 22, 66: [1, 32], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 18: 33, 66: [1, 32], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 4: 34, 6: 3, 13: [2, 43], 14: [2, 43], 17: [2, 43], 27: [2, 43], 32: [2, 43], 37: [2, 43], 42: [2, 43], 45: [2, 43], 46: [2, 43], 49: [2, 43], 53: [2, 43] }, { 4: 35, 6: 3, 13: [2, 43], 14: [2, 43], 17: [2, 43], 27: [2, 43], 32: [2, 43], 42: [2, 43], 45: [2, 43], 46: [2, 43], 49: [2, 43], 53: [2, 43] }, { 12: 36, 14: [1, 18] }, { 18: 38, 54: 37, 58: 39, 59: [1, 40], 66: [1, 32], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 5: [2, 9], 13: [2, 9], 14: [2, 9], 16: [2, 9], 17: [2, 9], 27: [2, 9], 32: [2, 9], 37: [2, 9], 42: [2, 9], 45: [2, 9], 46: [2, 9], 49: [2, 9], 53: [2, 9] }, { 18: 41, 66: [1, 32], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 18: 42, 66: [1, 32], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 18: 43, 66: [1, 32], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 31: [2, 73], 47: 44, 59: [2, 73], 66: [2, 73], 74: [2, 73], 75: [2, 73], 76: [2, 73], 77: [2, 73], 78: [2, 73], 79: [2, 73] }, { 21: [2, 30], 31: [2, 30], 52: [2, 30], 59: [2, 30], 62: [2, 30], 66: [2, 30], 69: [2, 30], 74: [2, 30], 75: [2, 30], 76: [2, 30], 77: [2, 30], 78: [2, 30], 79: [2, 30] }, { 21: [2, 31], 31: [2, 31], 52: [2, 31], 59: [2, 31], 62: [2, 31], 66: [2, 31], 69: [2, 31], 74: [2, 31], 75: [2, 31], 76: [2, 31], 77: [2, 31], 78: [2, 31], 79: [2, 31] }, { 21: [2, 32], 31: [2, 32], 52: [2, 32], 59: [2, 32], 62: [2, 32], 66: [2, 32], 69: [2, 32], 74: [2, 32], 75: [2, 32], 76: [2, 32], 77: [2, 32], 78: [2, 32], 79: [2, 32] }, { 21: [2, 33], 31: [2, 33], 52: [2, 33], 59: [2, 33], 62: [2, 33], 66: [2, 33], 69: [2, 33], 74: [2, 33], 75: [2, 33], 76: [2, 33], 77: [2, 33], 78: [2, 33], 79: [2, 33] }, { 21: [2, 34], 31: [2, 34], 52: [2, 34], 59: [2, 34], 62: [2, 34], 66: [2, 34], 69: [2, 34], 74: [2, 34], 75: [2, 34], 76: [2, 34], 77: [2, 34], 78: [2, 34], 79: [2, 34] }, { 21: [2, 35], 31: [2, 35], 52: [2, 35], 59: [2, 35], 62: [2, 35], 66: [2, 35], 69: [2, 35], 74: [2, 35], 75: [2, 35], 76: [2, 35], 77: [2, 35], 78: [2, 35], 79: [2, 35] }, { 21: [2, 36], 31: [2, 36], 52: [2, 36], 59: [2, 36], 62: [2, 36], 66: [2, 36], 69: [2, 36], 74: [2, 36], 75: [2, 36], 76: [2, 36], 77: [2, 36], 78: [2, 36], 79: [2, 36] }, { 21: [2, 40], 31: [2, 40], 52: [2, 40], 59: [2, 40], 62: [2, 40], 66: [2, 40], 69: [2, 40], 74: [2, 40], 75: [2, 40], 76: [2, 40], 77: [2, 40], 78: [2, 40], 79: [2, 40], 81: [1, 45] }, { 66: [1, 32], 80: 46 }, { 21: [2, 42], 31: [2, 42], 52: [2, 42], 59: [2, 42], 62: [2, 42], 66: [2, 42], 69: [2, 42], 74: [2, 42], 75: [2, 42], 76: [2, 42], 77: [2, 42], 78: [2, 42], 79: [2, 42], 81: [2, 42] }, { 50: 47, 52: [2, 77], 59: [2, 77], 66: [2, 77], 74: [2, 77], 75: [2, 77], 76: [2, 77], 77: [2, 77], 78: [2, 77], 79: [2, 77] }, { 23: 48, 36: 50, 37: [1, 52], 41: 51, 42: [1, 53], 43: 49, 45: [2, 49] }, { 26: 54, 41: 55, 42: [1, 53], 45: [2, 51] }, { 16: [1, 56] }, { 31: [2, 81], 55: 57, 59: [2, 81], 66: [2, 81], 74: [2, 81], 75: [2, 81], 76: [2, 81], 77: [2, 81], 78: [2, 81], 79: [2, 81] }, { 31: [2, 37], 59: [2, 37], 66: [2, 37], 74: [2, 37], 75: [2, 37], 76: [2, 37], 77: [2, 37], 78: [2, 37], 79: [2, 37] }, { 31: [2, 38], 59: [2, 38], 66: [2, 38], 74: [2, 38], 75: [2, 38], 76: [2, 38], 77: [2, 38], 78: [2, 38], 79: [2, 38] }, { 18: 58, 66: [1, 32], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 28: 59, 31: [2, 53], 59: [2, 53], 66: [2, 53], 69: [2, 53], 74: [2, 53], 75: [2, 53], 76: [2, 53], 77: [2, 53], 78: [2, 53], 79: [2, 53] }, { 31: [2, 59], 33: 60, 59: [2, 59], 66: [2, 59], 69: [2, 59], 74: [2, 59], 75: [2, 59], 76: [2, 59], 77: [2, 59], 78: [2, 59], 79: [2, 59] }, { 19: 61, 21: [2, 45], 59: [2, 45], 66: [2, 45], 74: [2, 45], 75: [2, 45], 76: [2, 45], 77: [2, 45], 78: [2, 45], 79: [2, 45] }, { 18: 65, 31: [2, 75], 48: 62, 57: 63, 58: 66, 59: [1, 40], 63: 64, 64: 67, 65: 68, 66: [1, 69], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 66: [1, 70] }, { 21: [2, 39], 31: [2, 39], 52: [2, 39], 59: [2, 39], 62: [2, 39], 66: [2, 39], 69: [2, 39], 74: [2, 39], 75: [2, 39], 76: [2, 39], 77: [2, 39], 78: [2, 39], 79: [2, 39], 81: [1, 45] }, { 18: 65, 51: 71, 52: [2, 79], 57: 72, 58: 66, 59: [1, 40], 63: 73, 64: 67, 65: 68, 66: [1, 69], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 24: 74, 45: [1, 75] }, { 45: [2, 50] }, { 4: 76, 6: 3, 13: [2, 43], 14: [2, 43], 17: [2, 43], 27: [2, 43], 32: [2, 43], 37: [2, 43], 42: [2, 43], 45: [2, 43], 46: [2, 43], 49: [2, 43], 53: [2, 43] }, { 45: [2, 19] }, { 18: 77, 66: [1, 32], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 4: 78, 6: 3, 13: [2, 43], 14: [2, 43], 17: [2, 43], 27: [2, 43], 32: [2, 43], 45: [2, 43], 46: [2, 43], 49: [2, 43], 53: [2, 43] }, { 24: 79, 45: [1, 75] }, { 45: [2, 52] }, { 5: [2, 10], 13: [2, 10], 14: [2, 10], 17: [2, 10], 27: [2, 10], 32: [2, 10], 37: [2, 10], 42: [2, 10], 45: [2, 10], 46: [2, 10], 49: [2, 10], 53: [2, 10] }, { 18: 65, 31: [2, 83], 56: 80, 57: 81, 58: 66, 59: [1, 40], 63: 82, 64: 67, 65: 68, 66: [1, 69], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 59: [2, 85], 60: 83, 62: [2, 85], 66: [2, 85], 74: [2, 85], 75: [2, 85], 76: [2, 85], 77: [2, 85], 78: [2, 85], 79: [2, 85] }, { 18: 65, 29: 84, 31: [2, 55], 57: 85, 58: 66, 59: [1, 40], 63: 86, 64: 67, 65: 68, 66: [1, 69], 69: [2, 55], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 18: 65, 31: [2, 61], 34: 87, 57: 88, 58: 66, 59: [1, 40], 63: 89, 64: 67, 65: 68, 66: [1, 69], 69: [2, 61], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 18: 65, 20: 90, 21: [2, 47], 57: 91, 58: 66, 59: [1, 40], 63: 92, 64: 67, 65: 68, 66: [1, 69], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 31: [1, 93] }, { 31: [2, 74], 59: [2, 74], 66: [2, 74], 74: [2, 74], 75: [2, 74], 76: [2, 74], 77: [2, 74], 78: [2, 74], 79: [2, 74] }, { 31: [2, 76] }, { 21: [2, 24], 31: [2, 24], 52: [2, 24], 59: [2, 24], 62: [2, 24], 66: [2, 24], 69: [2, 24], 74: [2, 24], 75: [2, 24], 76: [2, 24], 77: [2, 24], 78: [2, 24], 79: [2, 24] }, { 21: [2, 25], 31: [2, 25], 52: [2, 25], 59: [2, 25], 62: [2, 25], 66: [2, 25], 69: [2, 25], 74: [2, 25], 75: [2, 25], 76: [2, 25], 77: [2, 25], 78: [2, 25], 79: [2, 25] }, { 21: [2, 27], 31: [2, 27], 52: [2, 27], 62: [2, 27], 65: 94, 66: [1, 95], 69: [2, 27] }, { 21: [2, 89], 31: [2, 89], 52: [2, 89], 62: [2, 89], 66: [2, 89], 69: [2, 89] }, { 21: [2, 42], 31: [2, 42], 52: [2, 42], 59: [2, 42], 62: [2, 42], 66: [2, 42], 67: [1, 96], 69: [2, 42], 74: [2, 42], 75: [2, 42], 76: [2, 42], 77: [2, 42], 78: [2, 42], 79: [2, 42], 81: [2, 42] }, { 21: [2, 41], 31: [2, 41], 52: [2, 41], 59: [2, 41], 62: [2, 41], 66: [2, 41], 69: [2, 41], 74: [2, 41], 75: [2, 41], 76: [2, 41], 77: [2, 41], 78: [2, 41], 79: [2, 41], 81: [2, 41] }, { 52: [1, 97] }, { 52: [2, 78], 59: [2, 78], 66: [2, 78], 74: [2, 78], 75: [2, 78], 76: [2, 78], 77: [2, 78], 78: [2, 78], 79: [2, 78] }, { 52: [2, 80] }, { 5: [2, 12], 13: [2, 12], 14: [2, 12], 17: [2, 12], 27: [2, 12], 32: [2, 12], 37: [2, 12], 42: [2, 12], 45: [2, 12], 46: [2, 12], 49: [2, 12], 53: [2, 12] }, { 18: 98, 66: [1, 32], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 36: 50, 37: [1, 52], 41: 51, 42: [1, 53], 43: 100, 44: 99, 45: [2, 71] }, { 31: [2, 65], 38: 101, 59: [2, 65], 66: [2, 65], 69: [2, 65], 74: [2, 65], 75: [2, 65], 76: [2, 65], 77: [2, 65], 78: [2, 65], 79: [2, 65] }, { 45: [2, 17] }, { 5: [2, 13], 13: [2, 13], 14: [2, 13], 17: [2, 13], 27: [2, 13], 32: [2, 13], 37: [2, 13], 42: [2, 13], 45: [2, 13], 46: [2, 13], 49: [2, 13], 53: [2, 13] }, { 31: [1, 102] }, { 31: [2, 82], 59: [2, 82], 66: [2, 82], 74: [2, 82], 75: [2, 82], 76: [2, 82], 77: [2, 82], 78: [2, 82], 79: [2, 82] }, { 31: [2, 84] }, { 18: 65, 57: 104, 58: 66, 59: [1, 40], 61: 103, 62: [2, 87], 63: 105, 64: 67, 65: 68, 66: [1, 69], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 30: 106, 31: [2, 57], 68: 107, 69: [1, 108] }, { 31: [2, 54], 59: [2, 54], 66: [2, 54], 69: [2, 54], 74: [2, 54], 75: [2, 54], 76: [2, 54], 77: [2, 54], 78: [2, 54], 79: [2, 54] }, { 31: [2, 56], 69: [2, 56] }, { 31: [2, 63], 35: 109, 68: 110, 69: [1, 108] }, { 31: [2, 60], 59: [2, 60], 66: [2, 60], 69: [2, 60], 74: [2, 60], 75: [2, 60], 76: [2, 60], 77: [2, 60], 78: [2, 60], 79: [2, 60] }, { 31: [2, 62], 69: [2, 62] }, { 21: [1, 111] }, { 21: [2, 46], 59: [2, 46], 66: [2, 46], 74: [2, 46], 75: [2, 46], 76: [2, 46], 77: [2, 46], 78: [2, 46], 79: [2, 46] }, { 21: [2, 48] }, { 5: [2, 21], 13: [2, 21], 14: [2, 21], 17: [2, 21], 27: [2, 21], 32: [2, 21], 37: [2, 21], 42: [2, 21], 45: [2, 21], 46: [2, 21], 49: [2, 21], 53: [2, 21] }, { 21: [2, 90], 31: [2, 90], 52: [2, 90], 62: [2, 90], 66: [2, 90], 69: [2, 90] }, { 67: [1, 96] }, { 18: 65, 57: 112, 58: 66, 59: [1, 40], 66: [1, 32], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 5: [2, 22], 13: [2, 22], 14: [2, 22], 17: [2, 22], 27: [2, 22], 32: [2, 22], 37: [2, 22], 42: [2, 22], 45: [2, 22], 46: [2, 22], 49: [2, 22], 53: [2, 22] }, { 31: [1, 113] }, { 45: [2, 18] }, { 45: [2, 72] }, { 18: 65, 31: [2, 67], 39: 114, 57: 115, 58: 66, 59: [1, 40], 63: 116, 64: 67, 65: 68, 66: [1, 69], 69: [2, 67], 72: 23, 73: 24, 74: [1, 25], 75: [1, 26], 76: [1, 27], 77: [1, 28], 78: [1, 29], 79: [1, 31], 80: 30 }, { 5: [2, 23], 13: [2, 23], 14: [2, 23], 17: [2, 23], 27: [2, 23], 32: [2, 23], 37: [2, 23], 42: [2, 23], 45: [2, 23], 46: [2, 23], 49: [2, 23], 53: [2, 23] }, { 62: [1, 117] }, { 59: [2, 86], 62: [2, 86], 66: [2, 86], 74: [2, 86], 75: [2, 86], 76: [2, 86], 77: [2, 86], 78: [2, 86], 79: [2, 86] }, { 62: [2, 88] }, { 31: [1, 118] }, { 31: [2, 58] }, { 66: [1, 120], 70: 119 }, { 31: [1, 121] }, { 31: [2, 64] }, { 14: [2, 11] }, { 21: [2, 28], 31: [2, 28], 52: [2, 28], 62: [2, 28], 66: [2, 28], 69: [2, 28] }, { 5: [2, 20], 13: [2, 20], 14: [2, 20], 17: [2, 20], 27: [2, 20], 32: [2, 20], 37: [2, 20], 42: [2, 20], 45: [2, 20], 46: [2, 20], 49: [2, 20], 53: [2, 20] }, { 31: [2, 69], 40: 122, 68: 123, 69: [1, 108] }, { 31: [2, 66], 59: [2, 66], 66: [2, 66], 69: [2, 66], 74: [2, 66], 75: [2, 66], 76: [2, 66], 77: [2, 66], 78: [2, 66], 79: [2, 66] }, { 31: [2, 68], 69: [2, 68] }, { 21: [2, 26], 31: [2, 26], 52: [2, 26], 59: [2, 26], 62: [2, 26], 66: [2, 26], 69: [2, 26], 74: [2, 26], 75: [2, 26], 76: [2, 26], 77: [2, 26], 78: [2, 26], 79: [2, 26] }, { 13: [2, 14], 14: [2, 14], 17: [2, 14], 27: [2, 14], 32: [2, 14], 37: [2, 14], 42: [2, 14], 45: [2, 14], 46: [2, 14], 49: [2, 14], 53: [2, 14] }, { 66: [1, 125], 71: [1, 124] }, { 66: [2, 91], 71: [2, 91] }, { 13: [2, 15], 14: [2, 15], 17: [2, 15], 27: [2, 15], 32: [2, 15], 42: [2, 15], 45: [2, 15], 46: [2, 15], 49: [2, 15], 53: [2, 15] }, { 31: [1, 126] }, { 31: [2, 70] }, { 31: [2, 29] }, { 66: [2, 92], 71: [2, 92] }, { 13: [2, 16], 14: [2, 16], 17: [2, 16], 27: [2, 16], 32: [2, 16], 37: [2, 16], 42: [2, 16], 45: [2, 16], 46: [2, 16], 49: [2, 16], 53: [2, 16] }],
defaultActions: { 4: [2, 1], 49: [2, 50], 51: [2, 19], 55: [2, 52], 64: [2, 76], 73: [2, 80], 78: [2, 17], 82: [2, 84], 92: [2, 48], 99: [2, 18], 100: [2, 72], 105: [2, 88], 107: [2, 58], 110: [2, 64], 111: [2, 11], 123: [2, 70], 124: [2, 29] },
parseError: function parseError(str, hash) {
throw new Error(str);
},
parse: function parse(input) {
var self = this,
stack = [0],
vstack = [null],
lstack = [],
table = this.table,
yytext = "",
yylineno = 0,
yyleng = 0,
recovering = 0,
TERROR = 2,
EOF = 1;
this.lexer.setInput(input);
this.lexer.yy = this.yy;
this.yy.lexer = this.lexer;
this.yy.parser = this;
if (typeof this.lexer.yylloc == "undefined") this.lexer.yylloc = {};
var yyloc = this.lexer.yylloc;
lstack.push(yyloc);
var ranges = this.lexer.options && this.lexer.options.ranges;
if (typeof this.yy.parseError === "function") this.parseError = this.yy.parseError;
function popStack(n) {
stack.length = stack.length - 2 * n;
vstack.length = vstack.length - n;
lstack.length = lstack.length - n;
}
function lex() {
var token;
token = self.lexer.lex() || 1;
if (typeof token !== "number") {
token = self.symbols_[token] || token;
}
return token;
}
var symbol,
preErrorSymbol,
state,
action,
a,
r,
yyval = {},
p,
len,
newState,
expected;
while (true) {
state = stack[stack.length - 1];
if (this.defaultActions[state]) {
action = this.defaultActions[state];
} else {
if (symbol === null || typeof symbol == "undefined") {
symbol = lex();
}
action = table[state] && table[state][symbol];
}
if (typeof action === "undefined" || !action.length || !action[0]) {
var errStr = "";
if (!recovering) {
expected = [];
for (p in table[state]) if (this.terminals_[p] && p > 2) {
expected.push("'" + this.terminals_[p] + "'");
}
if (this.lexer.showPosition) {
errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
} else {
errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1 ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'");
}
this.parseError(errStr, { text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected });
}
}
if (action[0] instanceof Array && action.length > 1) {
throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
}
switch (action[0]) {
case 1:
stack.push(symbol);
vstack.push(this.lexer.yytext);
lstack.push(this.lexer.yylloc);
stack.push(action[1]);
symbol = null;
if (!preErrorSymbol) {
yyleng = this.lexer.yyleng;
yytext = this.lexer.yytext;
yylineno = this.lexer.yylineno;
yyloc = this.lexer.yylloc;
if (recovering > 0) recovering--;
} else {
symbol = preErrorSymbol;
preErrorSymbol = null;
}
break;
case 2:
len = this.productions_[action[1]][1];
yyval.$ = vstack[vstack.length - len];
yyval._$ = { first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column };
if (ranges) {
yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
}
r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
if (typeof r !== "undefined") {
return r;
}
if (len) {
stack = stack.slice(0, -1 * len * 2);
vstack = vstack.slice(0, -1 * len);
lstack = lstack.slice(0, -1 * len);
}
stack.push(this.productions_[action[1]][0]);
vstack.push(yyval.$);
lstack.push(yyval._$);
newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
stack.push(newState);
break;
case 3:
return true;
}
}
return true;
}
};
/* Jison generated lexer */
var lexer = (function () {
var lexer = { EOF: 1,
parseError: function parseError(str, hash) {
if (this.yy.parser) {
this.yy.parser.parseError(str, hash);
} else {
throw new Error(str);
}
},
setInput: function setInput(input) {
this._input = input;
this._more = this._less = this.done = false;
this.yylineno = this.yyleng = 0;
this.yytext = this.matched = this.match = "";
this.conditionStack = ["INITIAL"];
this.yylloc = { first_line: 1, first_column: 0, last_line: 1, last_column: 0 };
if (this.options.ranges) this.yylloc.range = [0, 0];
this.offset = 0;
return this;
},
input: function input() {
var ch = this._input[0];
this.yytext += ch;
this.yyleng++;
this.offset++;
this.match += ch;
this.matched += ch;
var lines = ch.match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno++;
this.yylloc.last_line++;
} else {
this.yylloc.last_column++;
}
if (this.options.ranges) this.yylloc.range[1]++;
this._input = this._input.slice(1);
return ch;
},
unput: function unput(ch) {
var len = ch.length;
var lines = ch.split(/(?:\r\n?|\n)/g);
this._input = ch + this._input;
this.yytext = this.yytext.substr(0, this.yytext.length - len - 1);
//this.yyleng -= len;
this.offset -= len;
var oldLines = this.match.split(/(?:\r\n?|\n)/g);
this.match = this.match.substr(0, this.match.length - 1);
this.matched = this.matched.substr(0, this.matched.length - 1);
if (lines.length - 1) this.yylineno -= lines.length - 1;
var r = this.yylloc.range;
this.yylloc = { first_line: this.yylloc.first_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.first_column,
last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len
};
if (this.options.ranges) {
this.yylloc.range = [r[0], r[0] + this.yyleng - len];
}
return this;
},
more: function more() {
this._more = true;
return this;
},
less: function less(n) {
this.unput(this.match.slice(n));
},
pastInput: function pastInput() {
var past = this.matched.substr(0, this.matched.length - this.match.length);
return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, "");
},
upcomingInput: function upcomingInput() {
var next = this.match;
if (next.length < 20) {
next += this._input.substr(0, 20 - next.length);
}
return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, "");
},
showPosition: function showPosition() {
var pre = this.pastInput();
var c = new Array(pre.length + 1).join("-");
return pre + this.upcomingInput() + "\n" + c + "^";
},
next: function next() {
if (this.done) {
return this.EOF;
}
if (!this._input) this.done = true;
var token, match, tempMatch, index, col, lines;
if (!this._more) {
this.yytext = "";
this.match = "";
}
var rules = this._currentRules();
for (var i = 0; i < rules.length; i++) {
tempMatch = this._input.match(this.rules[rules[i]]);
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
match = tempMatch;
index = i;
if (!this.options.flex) break;
}
}
if (match) {
lines = match[0].match(/(?:\r\n?|\n).*/g);
if (lines) this.yylineno += lines.length;
this.yylloc = { first_line: this.yylloc.last_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.last_column,
last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length };
this.yytext += match[0];
this.match += match[0];
this.matches = match;
this.yyleng = this.yytext.length;
if (this.options.ranges) {
this.yylloc.range = [this.offset, this.offset += this.yyleng];
}
this._more = false;
this._input = this._input.slice(match[0].length);
this.matched += match[0];
token = this.performAction.call(this, this.yy, this, rules[index], this.conditionStack[this.conditionStack.length - 1]);
if (this.done && this._input) this.done = false;
if (token) {
return token;
} else {
return;
}
}
if (this._input === "") {
return this.EOF;
} else {
return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { text: "", token: null, line: this.yylineno });
}
},
lex: function lex() {
var r = this.next();
if (typeof r !== "undefined") {
return r;
} else {
return this.lex();
}
},
begin: function begin(condition) {
this.conditionStack.push(condition);
},
popState: function popState() {
return this.conditionStack.pop();
},
_currentRules: function _currentRules() {
return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
},
topState: function topState() {
return this.conditionStack[this.conditionStack.length - 2];
},
pushState: function begin(condition) {
this.begin(condition);
} };
lexer.options = {};
lexer.performAction = function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {
function strip(start, end) {
return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng - end);
}
var YYSTATE = YY_START;
switch ($avoiding_name_collisions) {
case 0:
if (yy_.yytext.slice(-2) === "\\\\") {
strip(0, 1);
this.begin("mu");
} else if (yy_.yytext.slice(-1) === "\\") {
strip(0, 1);
this.begin("emu");
} else {
this.begin("mu");
}
if (yy_.yytext) {
return 14;
}break;
case 1:
return 14;
break;
case 2:
this.popState();
return 14;
break;
case 3:
yy_.yytext = yy_.yytext.substr(5, yy_.yyleng - 9);
this.popState();
return 16;
break;
case 4:
return 14;
break;
case 5:
this.popState();
return 13;
break;
case 6:
return 59;
break;
case 7:
return 62;
break;
case 8:
return 17;
break;
case 9:
this.popState();
this.begin("raw");
return 21;
break;
case 10:
return 53;
break;
case 11:
return 27;
break;
case 12:
return 45;
break;
case 13:
this.popState();return 42;
break;
case 14:
this.popState();return 42;
break;
case 15:
return 32;
break;
case 16:
return 37;
break;
case 17:
return 49;
break;
case 18:
return 46;
break;
case 19:
this.unput(yy_.yytext);
this.popState();
this.begin("com");
break;
case 20:
this.popState();
return 13;
break;
case 21:
return 46;
break;
case 22:
return 67;
break;
case 23:
return 66;
break;
case 24:
return 66;
break;
case 25:
return 81;
break;
case 26:
// ignore whitespace
break;
case 27:
this.popState();return 52;
break;
case 28:
this.popState();return 31;
break;
case 29:
yy_.yytext = strip(1, 2).replace(/\\"/g, "\"");return 74;
break;
case 30:
yy_.yytext = strip(1, 2).replace(/\\'/g, "'");return 74;
break;
case 31:
return 79;
break;
case 32:
return 76;
break;
case 33:
return 76;
break;
case 34:
return 77;
break;
case 35:
return 78;
break;
case 36:
return 75;
break;
case 37:
return 69;
break;
case 38:
return 71;
break;
case 39:
return 66;
break;
case 40:
return 66;
break;
case 41:
return "INVALID";
break;
case 42:
return 5;
break;
}
};
lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/, /^(?:[^\x00]+)/, /^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/, /^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/, /^(?:[^\x00]*?(?=(\{\{\{\{\/)))/, /^(?:[\s\S]*?--(~)?\}\})/, /^(?:\()/, /^(?:\))/, /^(?:\{\{\{\{)/, /^(?:\}\}\}\})/, /^(?:\{\{(~)?>)/, /^(?:\{\{(~)?#)/, /^(?:\{\{(~)?\/)/, /^(?:\{\{(~)?\^\s*(~)?\}\})/, /^(?:\{\{(~)?\s*else\s*(~)?\}\})/, /^(?:\{\{(~)?\^)/, /^(?:\{\{(~)?\s*else\b)/, /^(?:\{\{(~)?\{)/, /^(?:\{\{(~)?&)/, /^(?:\{\{(~)?!--)/, /^(?:\{\{(~)?![\s\S]*?\}\})/, /^(?:\{\{(~)?)/, /^(?:=)/, /^(?:\.\.)/, /^(?:\.(?=([=~}\s\/.)|])))/, /^(?:[\/.])/, /^(?:\s+)/, /^(?:\}(~)?\}\})/, /^(?:(~)?\}\})/, /^(?:"(\\["]|[^"])*")/, /^(?:'(\\[']|[^'])*')/, /^(?:@)/, /^(?:true(?=([~}\s)])))/, /^(?:false(?=([~}\s)])))/, /^(?:undefined(?=([~}\s)])))/, /^(?:null(?=([~}\s)])))/, /^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/, /^(?:as\s+\|)/, /^(?:\|)/, /^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/, /^(?:\[[^\]]*\])/, /^(?:.)/, /^(?:$)/];
lexer.conditions = { mu: { rules: [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42], inclusive: false }, emu: { rules: [2], inclusive: false }, com: { rules: [5], inclusive: false }, raw: { rules: [3, 4], inclusive: false }, INITIAL: { rules: [0, 1, 42], inclusive: true } };
return lexer;
})();
parser.lexer = lexer;
function Parser() {
this.yy = {};
}Parser.prototype = parser;parser.Parser = Parser;
return new Parser();
})();exports["default"] = handlebars;
module.exports = exports["default"];
},{}],19:[function(require,module,exports){
'use strict';
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };
exports.__esModule = true;
exports.print = print;
exports.PrintVisitor = PrintVisitor;
/*eslint-disable new-cap */
var _Visitor = require('./visitor');
var _Visitor2 = _interopRequireWildcard(_Visitor);
function print(ast) {
return new PrintVisitor().accept(ast);
}
function PrintVisitor() {
this.padding = 0;
}
PrintVisitor.prototype = new _Visitor2['default']();
PrintVisitor.prototype.pad = function (string) {
var out = '';
for (var i = 0, l = this.padding; i < l; i++) {
out = out + ' ';
}
out = out + string + '\n';
return out;
};
PrintVisitor.prototype.Program = function (program) {
var out = '',
body = program.body,
i = undefined,
l = undefined;
if (program.blockParams) {
var blockParams = 'BLOCK PARAMS: [';
for (i = 0, l = program.blockParams.length; i < l; i++) {
blockParams += ' ' + program.blockParams[i];
}
blockParams += ' ]';
out += this.pad(blockParams);
}
for (i = 0, l = body.length; i < l; i++) {
out = out + this.accept(body[i]);
}
this.padding--;
return out;
};
PrintVisitor.prototype.MustacheStatement = function (mustache) {
return this.pad('{{ ' + this.SubExpression(mustache) + ' }}');
};
PrintVisitor.prototype.BlockStatement = function (block) {
var out = '';
out = out + this.pad('BLOCK:');
this.padding++;
out = out + this.pad(this.SubExpression(block));
if (block.program) {
out = out + this.pad('PROGRAM:');
this.padding++;
out = out + this.accept(block.program);
this.padding--;
}
if (block.inverse) {
if (block.program) {
this.padding++;
}
out = out + this.pad('{{^}}');
this.padding++;
out = out + this.accept(block.inverse);
this.padding--;
if (block.program) {
this.padding--;
}
}
this.padding--;
return out;
};
PrintVisitor.prototype.PartialStatement = function (partial) {
var content = 'PARTIAL:' + partial.name.original;
if (partial.params[0]) {
content += ' ' + this.accept(partial.params[0]);
}
if (partial.hash) {
content += ' ' + this.accept(partial.hash);
}
return this.pad('{{> ' + content + ' }}');
};
PrintVisitor.prototype.ContentStatement = function (content) {
return this.pad('CONTENT[ \'' + content.value + '\' ]');
};
PrintVisitor.prototype.CommentStatement = function (comment) {
return this.pad('{{! \'' + comment.value + '\' }}');
};
PrintVisitor.prototype.SubExpression = function (sexpr) {
var params = sexpr.params,
paramStrings = [],
hash = undefined;
for (var i = 0, l = params.length; i < l; i++) {
paramStrings.push(this.accept(params[i]));
}
params = '[' + paramStrings.join(', ') + ']';
hash = sexpr.hash ? ' ' + this.accept(sexpr.hash) : '';
return this.accept(sexpr.path) + ' ' + params + hash;
};
PrintVisitor.prototype.PathExpression = function (id) {
var path = id.parts.join('/');
return (id.data ? '@' : '') + 'PATH:' + path;
};
PrintVisitor.prototype.StringLiteral = function (string) {
return '"' + string.value + '"';
};
PrintVisitor.prototype.NumberLiteral = function (number) {
return 'NUMBER{' + number.value + '}';
};
PrintVisitor.prototype.BooleanLiteral = function (bool) {
return 'BOOLEAN{' + bool.value + '}';
};
PrintVisitor.prototype.UndefinedLiteral = function () {
return 'UNDEFINED';
};
PrintVisitor.prototype.NullLiteral = function () {
return 'NULL';
};
PrintVisitor.prototype.Hash = function (hash) {
var pairs = hash.pairs,
joinedPairs = [];
for (var i = 0, l = pairs.length; i < l; i++) {
joinedPairs.push(this.accept(pairs[i]));
}
return 'HASH{' + joinedPairs.join(', ') + '}';
};
PrintVisitor.prototype.HashPair = function (pair) {
return pair.key + '=' + this.accept(pair.value);
};
/*eslint-enable new-cap */
},{"./visitor":20}],20:[function(require,module,exports){
'use strict';
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };
exports.__esModule = true;
var _Exception = require('../exception');
var _Exception2 = _interopRequireWildcard(_Exception);
var _AST = require('./ast');
var _AST2 = _interopRequireWildcard(_AST);
function Visitor() {
this.parents = [];
}
Visitor.prototype = {
constructor: Visitor,
mutating: false,
// Visits a given value. If mutating, will replace the value if necessary.
acceptKey: function acceptKey(node, name) {
var value = this.accept(node[name]);
if (this.mutating) {
// Hacky sanity check:
if (value && (!value.type || !_AST2['default'][value.type])) {
throw new _Exception2['default']('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type);
}
node[name] = value;
}
},
// Performs an accept operation with added sanity check to ensure
// required keys are not removed.
acceptRequired: function acceptRequired(node, name) {
this.acceptKey(node, name);
if (!node[name]) {
throw new _Exception2['default'](node.type + ' requires ' + name);
}
},
// Traverses a given array. If mutating, empty respnses will be removed
// for child elements.
acceptArray: function acceptArray(array) {
for (var i = 0, l = array.length; i < l; i++) {
this.acceptKey(array, i);
if (!array[i]) {
array.splice(i, 1);
i--;
l--;
}
}
},
accept: function accept(object) {
if (!object) {
return;
}
if (this.current) {
this.parents.unshift(this.current);
}
this.current = object;
var ret = this[object.type](object);
this.current = this.parents.shift();
if (!this.mutating || ret) {
return ret;
} else if (ret !== false) {
return object;
}
},
Program: function Program(program) {
this.acceptArray(program.body);
},
MustacheStatement: function MustacheStatement(mustache) {
this.acceptRequired(mustache, 'path');
this.acceptArray(mustache.params);
this.acceptKey(mustache, 'hash');
},
BlockStatement: function BlockStatement(block) {
this.acceptRequired(block, 'path');
this.acceptArray(block.params);
this.acceptKey(block, 'hash');
this.acceptKey(block, 'program');
this.acceptKey(block, 'inverse');
},
PartialStatement: function PartialStatement(partial) {
this.acceptRequired(partial, 'name');
this.acceptArray(partial.params);
this.acceptKey(partial, 'hash');
},
ContentStatement: function ContentStatement() {},
CommentStatement: function CommentStatement() {},
SubExpression: function SubExpression(sexpr) {
this.acceptRequired(sexpr, 'path');
this.acceptArray(sexpr.params);
this.acceptKey(sexpr, 'hash');
},
PathExpression: function PathExpression() {},
StringLiteral: function StringLiteral() {},
NumberLiteral: function NumberLiteral() {},
BooleanLiteral: function BooleanLiteral() {},
UndefinedLiteral: function UndefinedLiteral() {},
NullLiteral: function NullLiteral() {},
Hash: function Hash(hash) {
this.acceptArray(hash.pairs);
},
HashPair: function HashPair(pair) {
this.acceptRequired(pair, 'value');
}
};
exports['default'] = Visitor;
module.exports = exports['default'];
/* content */ /* comment */ /* path */ /* string */ /* number */ /* bool */ /* literal */ /* literal */
},{"../exception":22,"./ast":12}],21:[function(require,module,exports){
'use strict';
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };
exports.__esModule = true;
var _Visitor = require('./visitor');
var _Visitor2 = _interopRequireWildcard(_Visitor);
function WhitespaceControl() {}
WhitespaceControl.prototype = new _Visitor2['default']();
WhitespaceControl.prototype.Program = function (program) {
var isRoot = !this.isRootSeen;
this.isRootSeen = true;
var body = program.body;
for (var i = 0, l = body.length; i < l; i++) {
var current = body[i],
strip = this.accept(current);
if (!strip) {
continue;
}
var _isPrevWhitespace = isPrevWhitespace(body, i, isRoot),
_isNextWhitespace = isNextWhitespace(body, i, isRoot),
openStandalone = strip.openStandalone && _isPrevWhitespace,
closeStandalone = strip.closeStandalone && _isNextWhitespace,
inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
if (strip.close) {
omitRight(body, i, true);
}
if (strip.open) {
omitLeft(body, i, true);
}
if (inlineStandalone) {
omitRight(body, i);
if (omitLeft(body, i)) {
// If we are on a standalone node, save the indent info for partials
if (current.type === 'PartialStatement') {
// Pull out the whitespace from the final line
current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1];
}
}
}
if (openStandalone) {
omitRight((current.program || current.inverse).body);
// Strip out the previous content node if it's whitespace only
omitLeft(body, i);
}
if (closeStandalone) {
// Always strip the next node
omitRight(body, i);
omitLeft((current.inverse || current.program).body);
}
}
return program;
};
WhitespaceControl.prototype.BlockStatement = function (block) {
this.accept(block.program);
this.accept(block.inverse);
// Find the inverse program that is involed with whitespace stripping.
var program = block.program || block.inverse,
inverse = block.program && block.inverse,
firstInverse = inverse,
lastInverse = inverse;
if (inverse && inverse.chained) {
firstInverse = inverse.body[0].program;
// Walk the inverse chain to find the last inverse that is actually in the chain.
while (lastInverse.chained) {
lastInverse = lastInverse.body[lastInverse.body.length - 1].program;
}
}
var strip = {
open: block.openStrip.open,
close: block.closeStrip.close,
// Determine the standalone candiacy. Basically flag our content as being possibly standalone
// so our parent can determine if we actually are standalone
openStandalone: isNextWhitespace(program.body),
closeStandalone: isPrevWhitespace((firstInverse || program).body)
};
if (block.openStrip.close) {
omitRight(program.body, null, true);
}
if (inverse) {
var inverseStrip = block.inverseStrip;
if (inverseStrip.open) {
omitLeft(program.body, null, true);
}
if (inverseStrip.close) {
omitRight(firstInverse.body, null, true);
}
if (block.closeStrip.open) {
omitLeft(lastInverse.body, null, true);
}
// Find standalone else statments
if (isPrevWhitespace(program.body) && isNextWhitespace(firstInverse.body)) {
omitLeft(program.body);
omitRight(firstInverse.body);
}
} else if (block.closeStrip.open) {
omitLeft(program.body, null, true);
}
return strip;
};
WhitespaceControl.prototype.MustacheStatement = function (mustache) {
return mustache.strip;
};
WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = function (node) {
/* istanbul ignore next */
var strip = node.strip || {};
return {
inlineStandalone: true,
open: strip.open,
close: strip.close
};
};
function isPrevWhitespace(body, i, isRoot) {
if (i === undefined) {
i = body.length;
}
// Nodes that end with newlines are considered whitespace (but are special
// cased for strip operations)
var prev = body[i - 1],
sibling = body[i - 2];
if (!prev) {
return isRoot;
}
if (prev.type === 'ContentStatement') {
return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test(prev.original);
}
}
function isNextWhitespace(body, i, isRoot) {
if (i === undefined) {
i = -1;
}
var next = body[i + 1],
sibling = body[i + 2];
if (!next) {
return isRoot;
}
if (next.type === 'ContentStatement') {
return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test(next.original);
}
}
// Marks the node to the right of the position as omitted.
// I.e. {{foo}}' ' will mark the ' ' node as omitted.
//
// If i is undefined, then the first child will be marked as such.
//
// If mulitple is truthy then all whitespace will be stripped out until non-whitespace
// content is met.
function omitRight(body, i, multiple) {
var current = body[i == null ? 0 : i + 1];
if (!current || current.type !== 'ContentStatement' || !multiple && current.rightStripped) {
return;
}
var original = current.value;
current.value = current.value.replace(multiple ? /^\s+/ : /^[ \t]*\r?\n?/, '');
current.rightStripped = current.value !== original;
}
// Marks the node to the left of the position as omitted.
// I.e. ' '{{foo}} will mark the ' ' node as omitted.
//
// If i is undefined then the last child will be marked as such.
//
// If mulitple is truthy then all whitespace will be stripped out until non-whitespace
// content is met.
function omitLeft(body, i, multiple) {
var current = body[i == null ? body.length - 1 : i - 1];
if (!current || current.type !== 'ContentStatement' || !multiple && current.leftStripped) {
return;
}
// We omit the last node if it's whitespace only and not preceeded by a non-content node.
var original = current.value;
current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, '');
current.leftStripped = current.value !== original;
return current.leftStripped;
}
exports['default'] = WhitespaceControl;
module.exports = exports['default'];
},{"./visitor":20}],22:[function(require,module,exports){
'use strict';
exports.__esModule = true;
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
function Exception(message, node) {
var loc = node && node.loc,
line = undefined,
column = undefined;
if (loc) {
line = loc.start.line;
column = loc.start.column;
message += ' - ' + line + ':' + column;
}
var tmp = Error.prototype.constructor.call(this, message);
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
for (var idx = 0; idx < errorProps.length; idx++) {
this[errorProps[idx]] = tmp[errorProps[idx]];
}
if (Error.captureStackTrace) {
Error.captureStackTrace(this, Exception);
}
if (loc) {
this.lineNumber = line;
this.column = column;
}
}
Exception.prototype = new Error();
exports['default'] = Exception;
module.exports = exports['default'];
},{}],23:[function(require,module,exports){
(function (global){
'use strict';
exports.__esModule = true;
/*global window */
exports['default'] = function (Handlebars) {
/* istanbul ignore next */
var root = typeof global !== 'undefined' ? global : window,
$Handlebars = root.Handlebars;
/* istanbul ignore next */
Handlebars.noConflict = function () {
if (root.Handlebars === Handlebars) {
root.Handlebars = $Handlebars;
}
};
};
module.exports = exports['default'];
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],24:[function(require,module,exports){
'use strict';
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };
exports.__esModule = true;
exports.checkRevision = checkRevision;
// TODO: Remove this line and break up compilePartial
exports.template = template;
exports.wrapProgram = wrapProgram;
exports.resolvePartial = resolvePartial;
exports.invokePartial = invokePartial;
exports.noop = noop;
var _import = require('./utils');
var Utils = _interopRequireWildcard(_import);
var _Exception = require('./exception');
var _Exception2 = _interopRequireWildcard(_Exception);
var _COMPILER_REVISION$REVISION_CHANGES$createFrame = require('./base');
function checkRevision(compilerInfo) {
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
currentRevision = _COMPILER_REVISION$REVISION_CHANGES$createFrame.COMPILER_REVISION;
if (compilerRevision !== currentRevision) {
if (compilerRevision < currentRevision) {
var runtimeVersions = _COMPILER_REVISION$REVISION_CHANGES$createFrame.REVISION_CHANGES[currentRevision],
compilerVersions = _COMPILER_REVISION$REVISION_CHANGES$createFrame.REVISION_CHANGES[compilerRevision];
throw new _Exception2['default']('Template was precompiled with an older version of Handlebars than the current runtime. ' + 'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').');
} else {
// Use the embedded version info since the runtime doesn't know about this revision yet
throw new _Exception2['default']('Template was precompiled with a newer version of Handlebars than the current runtime. ' + 'Please update your runtime to a newer version (' + compilerInfo[1] + ').');
}
}
}
function template(templateSpec, env) {
/* istanbul ignore next */
if (!env) {
throw new _Exception2['default']('No environment passed to template');
}
if (!templateSpec || !templateSpec.main) {
throw new _Exception2['default']('Unknown template object: ' + typeof templateSpec);
}
// Note: Using env.VM references rather than local var references throughout this section to allow
// for external users to override these as psuedo-supported APIs.
env.VM.checkRevision(templateSpec.compiler);
function invokePartialWrapper(partial, context, options) {
if (options.hash) {
context = Utils.extend({}, context, options.hash);
}
partial = env.VM.resolvePartial.call(this, partial, context, options);
var result = env.VM.invokePartial.call(this, partial, context, options);
if (result == null && env.compile) {
options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);
result = options.partials[options.name](context, options);
}
if (result != null) {
if (options.indent) {
var lines = result.split('\n');
for (var i = 0, l = lines.length; i < l; i++) {
if (!lines[i] && i + 1 === l) {
break;
}
lines[i] = options.indent + lines[i];
}
result = lines.join('\n');
}
return result;
} else {
throw new _Exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode');
}
}
// Just add water
var container = {
strict: function strict(obj, name) {
if (!(name in obj)) {
throw new _Exception2['default']('"' + name + '" not defined in ' + obj);
}
return obj[name];
},
lookup: function lookup(depths, name) {
var len = depths.length;
for (var i = 0; i < len; i++) {
if (depths[i] && depths[i][name] != null) {
return depths[i][name];
}
}
},
lambda: function lambda(current, context) {
return typeof current === 'function' ? current.call(context) : current;
},
escapeExpression: Utils.escapeExpression,
invokePartial: invokePartialWrapper,
fn: function fn(i) {
return templateSpec[i];
},
programs: [],
program: function program(i, data, declaredBlockParams, blockParams, depths) {
var programWrapper = this.programs[i],
fn = this.fn(i);
if (data || depths || blockParams || declaredBlockParams) {
programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths);
} else if (!programWrapper) {
programWrapper = this.programs[i] = wrapProgram(this, i, fn);
}
return programWrapper;
},
data: function data(value, depth) {
while (value && depth--) {
value = value._parent;
}
return value;
},
merge: function merge(param, common) {
var obj = param || common;
if (param && common && param !== common) {
obj = Utils.extend({}, common, param);
}
return obj;
},
noop: env.VM.noop,
compilerInfo: templateSpec.compiler
};
function ret(context) {
var options = arguments[1] === undefined ? {} : arguments[1];
var data = options.data;
ret._setup(options);
if (!options.partial && templateSpec.useData) {
data = initData(context, data);
}
var depths = undefined,
blockParams = templateSpec.useBlockParams ? [] : undefined;
if (templateSpec.useDepths) {
depths = options.depths ? [context].concat(options.depths) : [context];
}
return templateSpec.main.call(container, context, container.helpers, container.partials, data, blockParams, depths);
}
ret.isTop = true;
ret._setup = function (options) {
if (!options.partial) {
container.helpers = container.merge(options.helpers, env.helpers);
if (templateSpec.usePartial) {
container.partials = container.merge(options.partials, env.partials);
}
} else {
container.helpers = options.helpers;
container.partials = options.partials;
}
};
ret._child = function (i, data, blockParams, depths) {
if (templateSpec.useBlockParams && !blockParams) {
throw new _Exception2['default']('must pass block params');
}
if (templateSpec.useDepths && !depths) {
throw new _Exception2['default']('must pass parent depths');
}
return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths);
};
return ret;
}
function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) {
function prog(context) {
var options = arguments[1] === undefined ? {} : arguments[1];
return fn.call(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), depths && [context].concat(depths));
}
prog.program = i;
prog.depth = depths ? depths.length : 0;
prog.blockParams = declaredBlockParams || 0;
return prog;
}
function resolvePartial(partial, context, options) {
if (!partial) {
partial = options.partials[options.name];
} else if (!partial.call && !options.name) {
// This is a dynamic partial that returned a string
options.name = partial;
partial = options.partials[partial];
}
return partial;
}
function invokePartial(partial, context, options) {
options.partial = true;
if (partial === undefined) {
throw new _Exception2['default']('The partial ' + options.name + ' could not be found');
} else if (partial instanceof Function) {
return partial(context, options);
}
}
function noop() {
return '';
}
function initData(context, data) {
if (!data || !('root' in data)) {
data = data ? _COMPILER_REVISION$REVISION_CHANGES$createFrame.createFrame(data) : {};
data.root = context;
}
return data;
}
},{"./base":11,"./exception":22,"./utils":26}],25:[function(require,module,exports){
'use strict';
exports.__esModule = true;
// Build out our basic SafeString type
function SafeString(string) {
this.string = string;
}
SafeString.prototype.toString = SafeString.prototype.toHTML = function () {
return '' + this.string;
};
exports['default'] = SafeString;
module.exports = exports['default'];
},{}],26:[function(require,module,exports){
'use strict';
exports.__esModule = true;
exports.extend = extend;
// Older IE versions do not directly support indexOf so we must implement our own, sadly.
exports.indexOf = indexOf;
exports.escapeExpression = escapeExpression;
exports.isEmpty = isEmpty;
exports.blockParams = blockParams;
exports.appendContextPath = appendContextPath;
var escape = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&#x27;',
'`': '&#x60;'
};
var badChars = /[&<>"'`]/g,
possible = /[&<>"'`]/;
function escapeChar(chr) {
return escape[chr];
}
function extend(obj /* , ...source */) {
for (var i = 1; i < arguments.length; i++) {
for (var key in arguments[i]) {
if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
obj[key] = arguments[i][key];
}
}
}
return obj;
}
var toString = Object.prototype.toString;
exports.toString = toString;
// Sourced from lodash
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
/*eslint-disable func-style, no-var */
var isFunction = function isFunction(value) {
return typeof value === 'function';
};
// fallback for older versions of Chrome and Safari
/* istanbul ignore next */
if (isFunction(/x/)) {
exports.isFunction = isFunction = function (value) {
return typeof value === 'function' && toString.call(value) === '[object Function]';
};
}
var isFunction;
exports.isFunction = isFunction;
/*eslint-enable func-style, no-var */
/* istanbul ignore next */
var isArray = Array.isArray || function (value) {
return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false;
};exports.isArray = isArray;
function indexOf(array, value) {
for (var i = 0, len = array.length; i < len; i++) {
if (array[i] === value) {
return i;
}
}
return -1;
}
function escapeExpression(string) {
if (typeof string !== 'string') {
// don't escape SafeStrings, since they're already safe
if (string && string.toHTML) {
return string.toHTML();
} else if (string == null) {
return '';
} else if (!string) {
return string + '';
}
// Force a string conversion as this will be done by the append regardless and
// the regex test will do this transparently behind the scenes, causing issues if
// an object's to string has escaped characters in it.
string = '' + string;
}
if (!possible.test(string)) {
return string;
}
return string.replace(badChars, escapeChar);
}
function isEmpty(value) {
if (!value && value !== 0) {
return true;
} else if (isArray(value) && value.length === 0) {
return true;
} else {
return false;
}
}
function blockParams(params, ids) {
params.path = ids;
return params;
}
function appendContextPath(contextPath, id) {
return (contextPath ? contextPath + '.' : '') + id;
}
},{}],27:[function(require,module,exports){
// USAGE:
// var handlebars = require('handlebars');
/* eslint-disable no-var */
// var local = handlebars.create();
var handlebars = require('../dist/cjs/handlebars')['default'];
var printer = require('../dist/cjs/handlebars/compiler/printer');
handlebars.PrintVisitor = printer.PrintVisitor;
handlebars.print = printer.print;
module.exports = handlebars;
// Publish a Node.js require() handler for .handlebars and .hbs files
function extension(module, filename) {
var fs = require('fs');
var templateString = fs.readFileSync(filename, 'utf8');
module.exports = handlebars.compile(templateString);
}
/* istanbul ignore else */
if (typeof require !== 'undefined' && require.extensions) {
require.extensions['.handlebars'] = extension;
require.extensions['.hbs'] = extension;
}
},{"../dist/cjs/handlebars":9,"../dist/cjs/handlebars/compiler/printer":19,"fs":1}],28:[function(require,module,exports){
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
exports.SourceMapGenerator = require('./source-map/source-map-generator').SourceMapGenerator;
exports.SourceMapConsumer = require('./source-map/source-map-consumer').SourceMapConsumer;
exports.SourceNode = require('./source-map/source-node').SourceNode;
},{"./source-map/source-map-consumer":34,"./source-map/source-map-generator":35,"./source-map/source-node":36}],29:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
var util = require('./util');
/**
* A data structure which is a combination of an array and a set. Adding a new
* member is O(1), testing for membership is O(1), and finding the index of an
* element is O(1). Removing elements from the set is not supported. Only
* strings are supported for membership.
*/
function ArraySet() {
this._array = [];
this._set = {};
}
/**
* Static method for creating ArraySet instances from an existing array.
*/
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
var set = new ArraySet();
for (var i = 0, len = aArray.length; i < len; i++) {
set.add(aArray[i], aAllowDuplicates);
}
return set;
};
/**
* Add the given string to this set.
*
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
var isDuplicate = this.has(aStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
this._set[util.toSetString(aStr)] = idx;
}
};
/**
* Is the given string a member of this set?
*
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
return Object.prototype.hasOwnProperty.call(this._set,
util.toSetString(aStr));
};
/**
* What is the index of the given string in the array?
*
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
if (this.has(aStr)) {
return this._set[util.toSetString(aStr)];
}
throw new Error('"' + aStr + '" is not in the set.');
};
/**
* What is the element at the given index?
*
* @param Number aIdx
*/
ArraySet.prototype.at = function ArraySet_at(aIdx) {
if (aIdx >= 0 && aIdx < this._array.length) {
return this._array[aIdx];
}
throw new Error('No element indexed by ' + aIdx);
};
/**
* Returns the array representation of this set (which has the proper indices
* indicated by indexOf). Note that this is a copy of the internal array used
* for storing the members so that no one can mess with internal state.
*/
ArraySet.prototype.toArray = function ArraySet_toArray() {
return this._array.slice();
};
exports.ArraySet = ArraySet;
});
},{"./util":37,"amdefine":38}],30:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*
* Based on the Base 64 VLQ implementation in Closure Compiler:
* https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
*
* Copyright 2011 The Closure Compiler Authors. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
var base64 = require('./base64');
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
// the next four bits are the actual value, and the 6th bit is the
// continuation bit. The continuation bit tells us whether there are more
// digits in this value following this digit.
//
// Continuation
// | Sign
// | |
// V V
// 101011
var VLQ_BASE_SHIFT = 5;
// binary: 100000
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
// binary: 011111
var VLQ_BASE_MASK = VLQ_BASE - 1;
// binary: 100000
var VLQ_CONTINUATION_BIT = VLQ_BASE;
/**
* Converts from a two-complement value to a value where the sign bit is
* placed in the least significant bit. For example, as decimals:
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
*/
function toVLQSigned(aValue) {
return aValue < 0
? ((-aValue) << 1) + 1
: (aValue << 1) + 0;
}
/**
* Converts to a two-complement value from a value where the sign bit is
* placed in the least significant bit. For example, as decimals:
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
*/
function fromVLQSigned(aValue) {
var isNegative = (aValue & 1) === 1;
var shifted = aValue >> 1;
return isNegative
? -shifted
: shifted;
}
/**
* Returns the base 64 VLQ encoded value.
*/
exports.encode = function base64VLQ_encode(aValue) {
var encoded = "";
var digit;
var vlq = toVLQSigned(aValue);
do {
digit = vlq & VLQ_BASE_MASK;
vlq >>>= VLQ_BASE_SHIFT;
if (vlq > 0) {
// There are still more digits in this value, so we must make sure the
// continuation bit is marked.
digit |= VLQ_CONTINUATION_BIT;
}
encoded += base64.encode(digit);
} while (vlq > 0);
return encoded;
};
/**
* Decodes the next base 64 VLQ value from the given string and returns the
* value and the rest of the string via the out parameter.
*/
exports.decode = function base64VLQ_decode(aStr, aOutParam) {
var i = 0;
var strLen = aStr.length;
var result = 0;
var shift = 0;
var continuation, digit;
do {
if (i >= strLen) {
throw new Error("Expected more digits in base 64 VLQ value.");
}
digit = base64.decode(aStr.charAt(i++));
continuation = !!(digit & VLQ_CONTINUATION_BIT);
digit &= VLQ_BASE_MASK;
result = result + (digit << shift);
shift += VLQ_BASE_SHIFT;
} while (continuation);
aOutParam.value = fromVLQSigned(result);
aOutParam.rest = aStr.slice(i);
};
});
},{"./base64":31,"amdefine":38}],31:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
var charToIntMap = {};
var intToCharMap = {};
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
.split('')
.forEach(function (ch, index) {
charToIntMap[ch] = index;
intToCharMap[index] = ch;
});
/**
* Encode an integer in the range of 0 to 63 to a single base 64 digit.
*/
exports.encode = function base64_encode(aNumber) {
if (aNumber in intToCharMap) {
return intToCharMap[aNumber];
}
throw new TypeError("Must be between 0 and 63: " + aNumber);
};
/**
* Decode a single base 64 digit to an integer.
*/
exports.decode = function base64_decode(aChar) {
if (aChar in charToIntMap) {
return charToIntMap[aChar];
}
throw new TypeError("Not a valid base 64 digit: " + aChar);
};
});
},{"amdefine":38}],32:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
/**
* Recursive implementation of binary search.
*
* @param aLow Indices here and lower do not contain the needle.
* @param aHigh Indices here and higher do not contain the needle.
* @param aNeedle The element being searched for.
* @param aHaystack The non-empty array being searched.
* @param aCompare Function which takes two elements and returns -1, 0, or 1.
*/
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare) {
// This function terminates when one of the following is true:
//
// 1. We find the exact element we are looking for.
//
// 2. We did not find the exact element, but we can return the index of
// the next closest element that is less than that element.
//
// 3. We did not find the exact element, and there is no next-closest
// element which is less than the one we are searching for, so we
// return -1.
var mid = Math.floor((aHigh - aLow) / 2) + aLow;
var cmp = aCompare(aNeedle, aHaystack[mid], true);
if (cmp === 0) {
// Found the element we are looking for.
return mid;
}
else if (cmp > 0) {
// aHaystack[mid] is greater than our needle.
if (aHigh - mid > 1) {
// The element is in the upper half.
return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare);
}
// We did not find an exact match, return the next closest one
// (termination case 2).
return mid;
}
else {
// aHaystack[mid] is less than our needle.
if (mid - aLow > 1) {
// The element is in the lower half.
return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare);
}
// The exact needle element was not found in this haystack. Determine if
// we are in termination case (2) or (3) and return the appropriate thing.
return aLow < 0 ? -1 : aLow;
}
}
/**
* This is an implementation of binary search which will always try and return
* the index of next lowest value checked if there is no exact hit. This is
* because mappings between original and generated line/col pairs are single
* points, and there is an implicit region between each of them, so a miss
* just means that you aren't on the very start of a region.
*
* @param aNeedle The element you are looking for.
* @param aHaystack The array that is being searched.
* @param aCompare A function which takes the needle and an element in the
* array and returns -1, 0, or 1 depending on whether the needle is less
* than, equal to, or greater than the element, respectively.
*/
exports.search = function search(aNeedle, aHaystack, aCompare) {
if (aHaystack.length === 0) {
return -1;
}
return recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare)
};
});
},{"amdefine":38}],33:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2014 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
var util = require('./util');
/**
* Determine whether mappingB is after mappingA with respect to generated
* position.
*/
function generatedPositionAfter(mappingA, mappingB) {
// Optimized for most common case
var lineA = mappingA.generatedLine;
var lineB = mappingB.generatedLine;
var columnA = mappingA.generatedColumn;
var columnB = mappingB.generatedColumn;
return lineB > lineA || lineB == lineA && columnB >= columnA ||
util.compareByGeneratedPositions(mappingA, mappingB) <= 0;
}
/**
* A data structure to provide a sorted view of accumulated mappings in a
* performance conscious manner. It trades a neglibable overhead in general
* case for a large speedup in case of mappings being added in order.
*/
function MappingList() {
this._array = [];
this._sorted = true;
// Serves as infimum
this._last = {generatedLine: -1, generatedColumn: 0};
}
/**
* Iterate through internal items. This method takes the same arguments that
* `Array.prototype.forEach` takes.
*
* NOTE: The order of the mappings is NOT guaranteed.
*/
MappingList.prototype.unsortedForEach =
function MappingList_forEach(aCallback, aThisArg) {
this._array.forEach(aCallback, aThisArg);
};
/**
* Add the given source mapping.
*
* @param Object aMapping
*/
MappingList.prototype.add = function MappingList_add(aMapping) {
var mapping;
if (generatedPositionAfter(this._last, aMapping)) {
this._last = aMapping;
this._array.push(aMapping);
} else {
this._sorted = false;
this._array.push(aMapping);
}
};
/**
* Returns the flat, sorted array of mappings. The mappings are sorted by
* generated position.
*
* WARNING: This method returns internal data without copying, for
* performance. The return value must NOT be mutated, and should be treated as
* an immutable borrow. If you want to take ownership, you must make your own
* copy.
*/
MappingList.prototype.toArray = function MappingList_toArray() {
if (!this._sorted) {
this._array.sort(util.compareByGeneratedPositions);
this._sorted = true;
}
return this._array;
};
exports.MappingList = MappingList;
});
},{"./util":37,"amdefine":38}],34:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
var util = require('./util');
var binarySearch = require('./binary-search');
var ArraySet = require('./array-set').ArraySet;
var base64VLQ = require('./base64-vlq');
/**
* A SourceMapConsumer instance represents a parsed source map which we can
* query for information about the original file positions by giving it a file
* position in the generated source.
*
* The only parameter is the raw source map (either as a JSON string, or
* already parsed to an object). According to the spec, source maps have the
* following attributes:
*
* - version: Which version of the source map spec this map is following.
* - sources: An array of URLs to the original source files.
* - names: An array of identifiers which can be referrenced by individual mappings.
* - sourceRoot: Optional. The URL root from which all sources are relative.
* - sourcesContent: Optional. An array of contents of the original source files.
* - mappings: A string of base64 VLQs which contain the actual mappings.
* - file: Optional. The generated file this source map is associated with.
*
* Here is an example source map, taken from the source map spec[0]:
*
* {
* version : 3,
* file: "out.js",
* sourceRoot : "",
* sources: ["foo.js", "bar.js"],
* names: ["src", "maps", "are", "fun"],
* mappings: "AA,AB;;ABCDE;"
* }
*
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
*/
function SourceMapConsumer(aSourceMap) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
}
var version = util.getArg(sourceMap, 'version');
var sources = util.getArg(sourceMap, 'sources');
// Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
// requires the array) to play nice here.
var names = util.getArg(sourceMap, 'names', []);
var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);
var mappings = util.getArg(sourceMap, 'mappings');
var file = util.getArg(sourceMap, 'file', null);
// Once again, Sass deviates from the spec and supplies the version as a
// string rather than a number, so we use loose equality checking here.
if (version != this._version) {
throw new Error('Unsupported version: ' + version);
}
// Some source maps produce relative source paths like "./foo.js" instead of
// "foo.js". Normalize these first so that future comparisons will succeed.
// See bugzil.la/1090768.
sources = sources.map(util.normalize);
// Pass `true` below to allow duplicate names and sources. While source maps
// are intended to be compressed and deduplicated, the TypeScript compiler
// sometimes generates source maps with duplicates in them. See Github issue
// #72 and bugzil.la/889492.
this._names = ArraySet.fromArray(names, true);
this._sources = ArraySet.fromArray(sources, true);
this.sourceRoot = sourceRoot;
this.sourcesContent = sourcesContent;
this._mappings = mappings;
this.file = file;
}
/**
* Create a SourceMapConsumer from a SourceMapGenerator.
*
* @param SourceMapGenerator aSourceMap
* The source map that will be consumed.
* @returns SourceMapConsumer
*/
SourceMapConsumer.fromSourceMap =
function SourceMapConsumer_fromSourceMap(aSourceMap) {
var smc = Object.create(SourceMapConsumer.prototype);
smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
smc.sourceRoot = aSourceMap._sourceRoot;
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
smc.sourceRoot);
smc.file = aSourceMap._file;
smc.__generatedMappings = aSourceMap._mappings.toArray().slice();
smc.__originalMappings = aSourceMap._mappings.toArray().slice()
.sort(util.compareByOriginalPositions);
return smc;
};
/**
* The version of the source mapping spec that we are consuming.
*/
SourceMapConsumer.prototype._version = 3;
/**
* The list of original sources.
*/
Object.defineProperty(SourceMapConsumer.prototype, 'sources', {
get: function () {
return this._sources.toArray().map(function (s) {
return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;
}, this);
}
});
// `__generatedMappings` and `__originalMappings` are arrays that hold the
// parsed mapping coordinates from the source map's "mappings" attribute. They
// are lazily instantiated, accessed via the `_generatedMappings` and
// `_originalMappings` getters respectively, and we only parse the mappings
// and create these arrays once queried for a source location. We jump through
// these hoops because there can be many thousands of mappings, and parsing
// them is expensive, so we only want to do it if we must.
//
// Each object in the arrays is of the form:
//
// {
// generatedLine: The line number in the generated code,
// generatedColumn: The column number in the generated code,
// source: The path to the original source file that generated this
// chunk of code,
// originalLine: The line number in the original source that
// corresponds to this chunk of generated code,
// originalColumn: The column number in the original source that
// corresponds to this chunk of generated code,
// name: The name of the original symbol which generated this chunk of
// code.
// }
//
// All properties except for `generatedLine` and `generatedColumn` can be
// `null`.
//
// `_generatedMappings` is ordered by the generated positions.
//
// `_originalMappings` is ordered by the original positions.
SourceMapConsumer.prototype.__generatedMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
get: function () {
if (!this.__generatedMappings) {
this.__generatedMappings = [];
this.__originalMappings = [];
this._parseMappings(this._mappings, this.sourceRoot);
}
return this.__generatedMappings;
}
});
SourceMapConsumer.prototype.__originalMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
get: function () {
if (!this.__originalMappings) {
this.__generatedMappings = [];
this.__originalMappings = [];
this._parseMappings(this._mappings, this.sourceRoot);
}
return this.__originalMappings;
}
});
SourceMapConsumer.prototype._nextCharIsMappingSeparator =
function SourceMapConsumer_nextCharIsMappingSeparator(aStr) {
var c = aStr.charAt(0);
return c === ";" || c === ",";
};
/**
* Parse the mappings in a string in to a data structure which we can easily
* query (the ordered arrays in the `this.__generatedMappings` and
* `this.__originalMappings` properties).
*/
SourceMapConsumer.prototype._parseMappings =
function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
var generatedLine = 1;
var previousGeneratedColumn = 0;
var previousOriginalLine = 0;
var previousOriginalColumn = 0;
var previousSource = 0;
var previousName = 0;
var str = aStr;
var temp = {};
var mapping;
while (str.length > 0) {
if (str.charAt(0) === ';') {
generatedLine++;
str = str.slice(1);
previousGeneratedColumn = 0;
}
else if (str.charAt(0) === ',') {
str = str.slice(1);
}
else {
mapping = {};
mapping.generatedLine = generatedLine;
// Generated column.
base64VLQ.decode(str, temp);
mapping.generatedColumn = previousGeneratedColumn + temp.value;
previousGeneratedColumn = mapping.generatedColumn;
str = temp.rest;
if (str.length > 0 && !this._nextCharIsMappingSeparator(str)) {
// Original source.
base64VLQ.decode(str, temp);
mapping.source = this._sources.at(previousSource + temp.value);
previousSource += temp.value;
str = temp.rest;
if (str.length === 0 || this._nextCharIsMappingSeparator(str)) {
throw new Error('Found a source, but no line and column');
}
// Original line.
base64VLQ.decode(str, temp);
mapping.originalLine = previousOriginalLine + temp.value;
previousOriginalLine = mapping.originalLine;
// Lines are stored 0-based
mapping.originalLine += 1;
str = temp.rest;
if (str.length === 0 || this._nextCharIsMappingSeparator(str)) {
throw new Error('Found a source and line, but no column');
}
// Original column.
base64VLQ.decode(str, temp);
mapping.originalColumn = previousOriginalColumn + temp.value;
previousOriginalColumn = mapping.originalColumn;
str = temp.rest;
if (str.length > 0 && !this._nextCharIsMappingSeparator(str)) {
// Original name.
base64VLQ.decode(str, temp);
mapping.name = this._names.at(previousName + temp.value);
previousName += temp.value;
str = temp.rest;
}
}
this.__generatedMappings.push(mapping);
if (typeof mapping.originalLine === 'number') {
this.__originalMappings.push(mapping);
}
}
}
this.__generatedMappings.sort(util.compareByGeneratedPositions);
this.__originalMappings.sort(util.compareByOriginalPositions);
};
/**
* Find the mapping that best matches the hypothetical "needle" mapping that
* we are searching for in the given "haystack" of mappings.
*/
SourceMapConsumer.prototype._findMapping =
function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,
aColumnName, aComparator) {
// To return the position we are searching for, we must first find the
// mapping for the given position and then return the opposite position it
// points to. Because the mappings are sorted, we can use binary search to
// find the best mapping.
if (aNeedle[aLineName] <= 0) {
throw new TypeError('Line must be greater than or equal to 1, got '
+ aNeedle[aLineName]);
}
if (aNeedle[aColumnName] < 0) {
throw new TypeError('Column must be greater than or equal to 0, got '
+ aNeedle[aColumnName]);
}
return binarySearch.search(aNeedle, aMappings, aComparator);
};
/**
* Compute the last column for each generated mapping. The last column is
* inclusive.
*/
SourceMapConsumer.prototype.computeColumnSpans =
function SourceMapConsumer_computeColumnSpans() {
for (var index = 0; index < this._generatedMappings.length; ++index) {
var mapping = this._generatedMappings[index];
// Mappings do not contain a field for the last generated columnt. We
// can come up with an optimistic estimate, however, by assuming that
// mappings are contiguous (i.e. given two consecutive mappings, the
// first mapping ends where the second one starts).
if (index + 1 < this._generatedMappings.length) {
var nextMapping = this._generatedMappings[index + 1];
if (mapping.generatedLine === nextMapping.generatedLine) {
mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;
continue;
}
}
// The last mapping for each line spans the entire line.
mapping.lastGeneratedColumn = Infinity;
}
};
/**
* Returns the original source, line, and column information for the generated
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
* - line: The line number in the generated source.
* - column: The column number in the generated source.
*
* and an object is returned with the following properties:
*
* - source: The original source file, or null.
* - line: The line number in the original source, or null.
* - column: The column number in the original source, or null.
* - name: The original identifier, or null.
*/
SourceMapConsumer.prototype.originalPositionFor =
function SourceMapConsumer_originalPositionFor(aArgs) {
var needle = {
generatedLine: util.getArg(aArgs, 'line'),
generatedColumn: util.getArg(aArgs, 'column')
};
var index = this._findMapping(needle,
this._generatedMappings,
"generatedLine",
"generatedColumn",
util.compareByGeneratedPositions);
if (index >= 0) {
var mapping = this._generatedMappings[index];
if (mapping.generatedLine === needle.generatedLine) {
var source = util.getArg(mapping, 'source', null);
if (source != null && this.sourceRoot != null) {
source = util.join(this.sourceRoot, source);
}
return {
source: source,
line: util.getArg(mapping, 'originalLine', null),
column: util.getArg(mapping, 'originalColumn', null),
name: util.getArg(mapping, 'name', null)
};
}
}
return {
source: null,
line: null,
column: null,
name: null
};
};
/**
* Returns the original source content. The only argument is the url of the
* original source file. Returns null if no original source content is
* availible.
*/
SourceMapConsumer.prototype.sourceContentFor =
function SourceMapConsumer_sourceContentFor(aSource) {
if (!this.sourcesContent) {
return null;
}
if (this.sourceRoot != null) {
aSource = util.relative(this.sourceRoot, aSource);
}
if (this._sources.has(aSource)) {
return this.sourcesContent[this._sources.indexOf(aSource)];
}
var url;
if (this.sourceRoot != null
&& (url = util.urlParse(this.sourceRoot))) {
// XXX: file:// URIs and absolute paths lead to unexpected behavior for
// many users. We can help them out when they expect file:// URIs to
// behave like it would if they were running a local HTTP server. See
// https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
var fileUriAbsPath = aSource.replace(/^file:\/\//, "");
if (url.scheme == "file"
&& this._sources.has(fileUriAbsPath)) {
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
}
if ((!url.path || url.path == "/")
&& this._sources.has("/" + aSource)) {
return this.sourcesContent[this._sources.indexOf("/" + aSource)];
}
}
throw new Error('"' + aSource + '" is not in the SourceMap.');
};
/**
* Returns the generated line and column information for the original source,
* line, and column positions provided. The only argument is an object with
* the following properties:
*
* - source: The filename of the original source.
* - line: The line number in the original source.
* - column: The column number in the original source.
*
* and an object is returned with the following properties:
*
* - line: The line number in the generated source, or null.
* - column: The column number in the generated source, or null.
*/
SourceMapConsumer.prototype.generatedPositionFor =
function SourceMapConsumer_generatedPositionFor(aArgs) {
var needle = {
source: util.getArg(aArgs, 'source'),
originalLine: util.getArg(aArgs, 'line'),
originalColumn: util.getArg(aArgs, 'column')
};
if (this.sourceRoot != null) {
needle.source = util.relative(this.sourceRoot, needle.source);
}
var index = this._findMapping(needle,
this._originalMappings,
"originalLine",
"originalColumn",
util.compareByOriginalPositions);
if (index >= 0) {
var mapping = this._originalMappings[index];
return {
line: util.getArg(mapping, 'generatedLine', null),
column: util.getArg(mapping, 'generatedColumn', null),
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
};
}
return {
line: null,
column: null,
lastColumn: null
};
};
/**
* Returns all generated line and column information for the original source
* and line provided. The only argument is an object with the following
* properties:
*
* - source: The filename of the original source.
* - line: The line number in the original source.
*
* and an array of objects is returned, each with the following properties:
*
* - line: The line number in the generated source, or null.
* - column: The column number in the generated source, or null.
*/
SourceMapConsumer.prototype.allGeneratedPositionsFor =
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
// When there is no exact match, SourceMapConsumer.prototype._findMapping
// returns the index of the closest mapping less than the needle. By
// setting needle.originalColumn to Infinity, we thus find the last
// mapping for the given line, provided such a mapping exists.
var needle = {
source: util.getArg(aArgs, 'source'),
originalLine: util.getArg(aArgs, 'line'),
originalColumn: Infinity
};
if (this.sourceRoot != null) {
needle.source = util.relative(this.sourceRoot, needle.source);
}
var mappings = [];
var index = this._findMapping(needle,
this._originalMappings,
"originalLine",
"originalColumn",
util.compareByOriginalPositions);
if (index >= 0) {
var mapping = this._originalMappings[index];
while (mapping && mapping.originalLine === needle.originalLine) {
mappings.push({
line: util.getArg(mapping, 'generatedLine', null),
column: util.getArg(mapping, 'generatedColumn', null),
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
});
mapping = this._originalMappings[--index];
}
}
return mappings.reverse();
};
SourceMapConsumer.GENERATED_ORDER = 1;
SourceMapConsumer.ORIGINAL_ORDER = 2;
/**
* Iterate over each mapping between an original source/line/column and a
* generated line/column in this source map.
*
* @param Function aCallback
* The function that is called with each mapping.
* @param Object aContext
* Optional. If specified, this object will be the value of `this` every
* time that `aCallback` is called.
* @param aOrder
* Either `SourceMapConsumer.GENERATED_ORDER` or
* `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
* iterate over the mappings sorted by the generated file's line/column
* order or the original's source/line/column order, respectively. Defaults to
* `SourceMapConsumer.GENERATED_ORDER`.
*/
SourceMapConsumer.prototype.eachMapping =
function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
var context = aContext || null;
var order = aOrder || SourceMapConsumer.GENERATED_ORDER;
var mappings;
switch (order) {
case SourceMapConsumer.GENERATED_ORDER:
mappings = this._generatedMappings;
break;
case SourceMapConsumer.ORIGINAL_ORDER:
mappings = this._originalMappings;
break;
default:
throw new Error("Unknown order of iteration.");
}
var sourceRoot = this.sourceRoot;
mappings.map(function (mapping) {
var source = mapping.source;
if (source != null && sourceRoot != null) {
source = util.join(sourceRoot, source);
}
return {
source: source,
generatedLine: mapping.generatedLine,
generatedColumn: mapping.generatedColumn,
originalLine: mapping.originalLine,
originalColumn: mapping.originalColumn,
name: mapping.name
};
}).forEach(aCallback, context);
};
exports.SourceMapConsumer = SourceMapConsumer;
});
},{"./array-set":29,"./base64-vlq":30,"./binary-search":32,"./util":37,"amdefine":38}],35:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
var base64VLQ = require('./base64-vlq');
var util = require('./util');
var ArraySet = require('./array-set').ArraySet;
var MappingList = require('./mapping-list').MappingList;
/**
* An instance of the SourceMapGenerator represents a source map which is
* being built incrementally. You may pass an object with the following
* properties:
*
* - file: The filename of the generated source.
* - sourceRoot: A root for all relative URLs in this source map.
*/
function SourceMapGenerator(aArgs) {
if (!aArgs) {
aArgs = {};
}
this._file = util.getArg(aArgs, 'file', null);
this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
this._sources = new ArraySet();
this._names = new ArraySet();
this._mappings = new MappingList();
this._sourcesContents = null;
}
SourceMapGenerator.prototype._version = 3;
/**
* Creates a new SourceMapGenerator based on a SourceMapConsumer
*
* @param aSourceMapConsumer The SourceMap.
*/
SourceMapGenerator.fromSourceMap =
function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
var sourceRoot = aSourceMapConsumer.sourceRoot;
var generator = new SourceMapGenerator({
file: aSourceMapConsumer.file,
sourceRoot: sourceRoot
});
aSourceMapConsumer.eachMapping(function (mapping) {
var newMapping = {
generated: {
line: mapping.generatedLine,
column: mapping.generatedColumn
}
};
if (mapping.source != null) {
newMapping.source = mapping.source;
if (sourceRoot != null) {
newMapping.source = util.relative(sourceRoot, newMapping.source);
}
newMapping.original = {
line: mapping.originalLine,
column: mapping.originalColumn
};
if (mapping.name != null) {
newMapping.name = mapping.name;
}
}
generator.addMapping(newMapping);
});
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
generator.setSourceContent(sourceFile, content);
}
});
return generator;
};
/**
* Add a single mapping from original source line and column to the generated
* source's line and column for this source map being created. The mapping
* object should have the following properties:
*
* - generated: An object with the generated line and column positions.
* - original: An object with the original line and column positions.
* - source: The original source file (relative to the sourceRoot).
* - name: An optional original token name for this mapping.
*/
SourceMapGenerator.prototype.addMapping =
function SourceMapGenerator_addMapping(aArgs) {
var generated = util.getArg(aArgs, 'generated');
var original = util.getArg(aArgs, 'original', null);
var source = util.getArg(aArgs, 'source', null);
var name = util.getArg(aArgs, 'name', null);
if (!this._skipValidation) {
this._validateMapping(generated, original, source, name);
}
if (source != null && !this._sources.has(source)) {
this._sources.add(source);
}
if (name != null && !this._names.has(name)) {
this._names.add(name);
}
this._mappings.add({
generatedLine: generated.line,
generatedColumn: generated.column,
originalLine: original != null && original.line,
originalColumn: original != null && original.column,
source: source,
name: name
});
};
/**
* Set the source content for a source file.
*/
SourceMapGenerator.prototype.setSourceContent =
function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
var source = aSourceFile;
if (this._sourceRoot != null) {
source = util.relative(this._sourceRoot, source);
}
if (aSourceContent != null) {
// Add the source content to the _sourcesContents map.
// Create a new _sourcesContents map if the property is null.
if (!this._sourcesContents) {
this._sourcesContents = {};
}
this._sourcesContents[util.toSetString(source)] = aSourceContent;
} else if (this._sourcesContents) {
// Remove the source file from the _sourcesContents map.
// If the _sourcesContents map is empty, set the property to null.
delete this._sourcesContents[util.toSetString(source)];
if (Object.keys(this._sourcesContents).length === 0) {
this._sourcesContents = null;
}
}
};
/**
* Applies the mappings of a sub-source-map for a specific source file to the
* source map being generated. Each mapping to the supplied source file is
* rewritten using the supplied source map. Note: The resolution for the
* resulting mappings is the minimium of this map and the supplied map.
*
* @param aSourceMapConsumer The source map to be applied.
* @param aSourceFile Optional. The filename of the source file.
* If omitted, SourceMapConsumer's file property will be used.
* @param aSourceMapPath Optional. The dirname of the path to the source map
* to be applied. If relative, it is relative to the SourceMapConsumer.
* This parameter is needed when the two source maps aren't in the same
* directory, and the source map to be applied contains relative source
* paths. If so, those relative source paths need to be rewritten
* relative to the SourceMapGenerator.
*/
SourceMapGenerator.prototype.applySourceMap =
function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
var sourceFile = aSourceFile;
// If aSourceFile is omitted, we will use the file property of the SourceMap
if (aSourceFile == null) {
if (aSourceMapConsumer.file == null) {
throw new Error(
'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
'or the source map\'s "file" property. Both were omitted.'
);
}
sourceFile = aSourceMapConsumer.file;
}
var sourceRoot = this._sourceRoot;
// Make "sourceFile" relative if an absolute Url is passed.
if (sourceRoot != null) {
sourceFile = util.relative(sourceRoot, sourceFile);
}
// Applying the SourceMap can add and remove items from the sources and
// the names array.
var newSources = new ArraySet();
var newNames = new ArraySet();
// Find mappings for the "sourceFile"
this._mappings.unsortedForEach(function (mapping) {
if (mapping.source === sourceFile && mapping.originalLine != null) {
// Check if it can be mapped by the source map, then update the mapping.
var original = aSourceMapConsumer.originalPositionFor({
line: mapping.originalLine,
column: mapping.originalColumn
});
if (original.source != null) {
// Copy mapping
mapping.source = original.source;
if (aSourceMapPath != null) {
mapping.source = util.join(aSourceMapPath, mapping.source)
}
if (sourceRoot != null) {
mapping.source = util.relative(sourceRoot, mapping.source);
}
mapping.originalLine = original.line;
mapping.originalColumn = original.column;
if (original.name != null) {
mapping.name = original.name;
}
}
}
var source = mapping.source;
if (source != null && !newSources.has(source)) {
newSources.add(source);
}
var name = mapping.name;
if (name != null && !newNames.has(name)) {
newNames.add(name);
}
}, this);
this._sources = newSources;
this._names = newNames;
// Copy sourcesContents of applied map.
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
if (aSourceMapPath != null) {
sourceFile = util.join(aSourceMapPath, sourceFile);
}
if (sourceRoot != null) {
sourceFile = util.relative(sourceRoot, sourceFile);
}
this.setSourceContent(sourceFile, content);
}
}, this);
};
/**
* A mapping can have one of the three levels of data:
*
* 1. Just the generated position.
* 2. The Generated position, original position, and original source.
* 3. Generated and original position, original source, as well as a name
* token.
*
* To maintain consistency, we validate that any new mapping being added falls
* in to one of these categories.
*/
SourceMapGenerator.prototype._validateMapping =
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
aName) {
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated.line > 0 && aGenerated.column >= 0
&& !aOriginal && !aSource && !aName) {
// Case 1.
return;
}
else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aOriginal && 'line' in aOriginal && 'column' in aOriginal
&& aGenerated.line > 0 && aGenerated.column >= 0
&& aOriginal.line > 0 && aOriginal.column >= 0
&& aSource) {
// Cases 2 and 3.
return;
}
else {
throw new Error('Invalid mapping: ' + JSON.stringify({
generated: aGenerated,
source: aSource,
original: aOriginal,
name: aName
}));
}
};
/**
* Serialize the accumulated mappings in to the stream of base 64 VLQs
* specified by the source map format.
*/
SourceMapGenerator.prototype._serializeMappings =
function SourceMapGenerator_serializeMappings() {
var previousGeneratedColumn = 0;
var previousGeneratedLine = 1;
var previousOriginalColumn = 0;
var previousOriginalLine = 0;
var previousName = 0;
var previousSource = 0;
var result = '';
var mapping;
var mappings = this._mappings.toArray();
for (var i = 0, len = mappings.length; i < len; i++) {
mapping = mappings[i];
if (mapping.generatedLine !== previousGeneratedLine) {
previousGeneratedColumn = 0;
while (mapping.generatedLine !== previousGeneratedLine) {
result += ';';
previousGeneratedLine++;
}
}
else {
if (i > 0) {
if (!util.compareByGeneratedPositions(mapping, mappings[i - 1])) {
continue;
}
result += ',';
}
}
result += base64VLQ.encode(mapping.generatedColumn
- previousGeneratedColumn);
previousGeneratedColumn = mapping.generatedColumn;
if (mapping.source != null) {
result += base64VLQ.encode(this._sources.indexOf(mapping.source)
- previousSource);
previousSource = this._sources.indexOf(mapping.source);
// lines are stored 0-based in SourceMap spec version 3
result += base64VLQ.encode(mapping.originalLine - 1
- previousOriginalLine);
previousOriginalLine = mapping.originalLine - 1;
result += base64VLQ.encode(mapping.originalColumn
- previousOriginalColumn);
previousOriginalColumn = mapping.originalColumn;
if (mapping.name != null) {
result += base64VLQ.encode(this._names.indexOf(mapping.name)
- previousName);
previousName = this._names.indexOf(mapping.name);
}
}
}
return result;
};
SourceMapGenerator.prototype._generateSourcesContent =
function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
return aSources.map(function (source) {
if (!this._sourcesContents) {
return null;
}
if (aSourceRoot != null) {
source = util.relative(aSourceRoot, source);
}
var key = util.toSetString(source);
return Object.prototype.hasOwnProperty.call(this._sourcesContents,
key)
? this._sourcesContents[key]
: null;
}, this);
};
/**
* Externalize the source map.
*/
SourceMapGenerator.prototype.toJSON =
function SourceMapGenerator_toJSON() {
var map = {
version: this._version,
sources: this._sources.toArray(),
names: this._names.toArray(),
mappings: this._serializeMappings()
};
if (this._file != null) {
map.file = this._file;
}
if (this._sourceRoot != null) {
map.sourceRoot = this._sourceRoot;
}
if (this._sourcesContents) {
map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
}
return map;
};
/**
* Render the source map being generated to a string.
*/
SourceMapGenerator.prototype.toString =
function SourceMapGenerator_toString() {
return JSON.stringify(this);
};
exports.SourceMapGenerator = SourceMapGenerator;
});
},{"./array-set":29,"./base64-vlq":30,"./mapping-list":33,"./util":37,"amdefine":38}],36:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
var SourceMapGenerator = require('./source-map-generator').SourceMapGenerator;
var util = require('./util');
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
// operating systems these days (capturing the result).
var REGEX_NEWLINE = /(\r?\n)/;
// Newline character code for charCodeAt() comparisons
var NEWLINE_CODE = 10;
// Private symbol for identifying `SourceNode`s when multiple versions of
// the source-map library are loaded. This MUST NOT CHANGE across
// versions!
var isSourceNode = "$$$isSourceNode$$$";
/**
* SourceNodes provide a way to abstract over interpolating/concatenating
* snippets of generated JavaScript source code while maintaining the line and
* column information associated with the original source code.
*
* @param aLine The original line number.
* @param aColumn The original column number.
* @param aSource The original source's filename.
* @param aChunks Optional. An array of strings which are snippets of
* generated JS, or other SourceNodes.
* @param aName The original identifier.
*/
function SourceNode(aLine, aColumn, aSource, aChunks, aName) {
this.children = [];
this.sourceContents = {};
this.line = aLine == null ? null : aLine;
this.column = aColumn == null ? null : aColumn;
this.source = aSource == null ? null : aSource;
this.name = aName == null ? null : aName;
this[isSourceNode] = true;
if (aChunks != null) this.add(aChunks);
}
/**
* Creates a SourceNode from generated code and a SourceMapConsumer.
*
* @param aGeneratedCode The generated code
* @param aSourceMapConsumer The SourceMap for the generated code
* @param aRelativePath Optional. The path that relative sources in the
* SourceMapConsumer should be relative to.
*/
SourceNode.fromStringWithSourceMap =
function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {
// The SourceNode we want to fill with the generated code
// and the SourceMap
var node = new SourceNode();
// All even indices of this array are one line of the generated code,
// while all odd indices are the newlines between two adjacent lines
// (since `REGEX_NEWLINE` captures its match).
// Processed fragments are removed from this array, by calling `shiftNextLine`.
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
var shiftNextLine = function() {
var lineContents = remainingLines.shift();
// The last line of a file might not have a newline.
var newLine = remainingLines.shift() || "";
return lineContents + newLine;
};
// We need to remember the position of "remainingLines"
var lastGeneratedLine = 1, lastGeneratedColumn = 0;
// The generate SourceNodes we need a code range.
// To extract it current and last mapping is used.
// Here we store the last mapping.
var lastMapping = null;
aSourceMapConsumer.eachMapping(function (mapping) {
if (lastMapping !== null) {
// We add the code from "lastMapping" to "mapping":
// First check if there is a new line in between.
if (lastGeneratedLine < mapping.generatedLine) {
var code = "";
// Associate first line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine());
lastGeneratedLine++;
lastGeneratedColumn = 0;
// The remaining code is added without mapping
} else {
// There is no new line in between.
// Associate the code between "lastGeneratedColumn" and
// "mapping.generatedColumn" with "lastMapping"
var nextLine = remainingLines[0];
var code = nextLine.substr(0, mapping.generatedColumn -
lastGeneratedColumn);
remainingLines[0] = nextLine.substr(mapping.generatedColumn -
lastGeneratedColumn);
lastGeneratedColumn = mapping.generatedColumn;
addMappingWithCode(lastMapping, code);
// No more remaining code, continue
lastMapping = mapping;
return;
}
}
// We add the generated code until the first mapping
// to the SourceNode without any mapping.
// Each line is added as separate string.
while (lastGeneratedLine < mapping.generatedLine) {
node.add(shiftNextLine());
lastGeneratedLine++;
}
if (lastGeneratedColumn < mapping.generatedColumn) {
var nextLine = remainingLines[0];
node.add(nextLine.substr(0, mapping.generatedColumn));
remainingLines[0] = nextLine.substr(mapping.generatedColumn);
lastGeneratedColumn = mapping.generatedColumn;
}
lastMapping = mapping;
}, this);
// We have processed all mappings.
if (remainingLines.length > 0) {
if (lastMapping) {
// Associate the remaining code in the current line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine());
}
// and add the remaining lines without any mapping
node.add(remainingLines.join(""));
}
// Copy sourcesContent into SourceNode
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
if (aRelativePath != null) {
sourceFile = util.join(aRelativePath, sourceFile);
}
node.setSourceContent(sourceFile, content);
}
});
return node;
function addMappingWithCode(mapping, code) {
if (mapping === null || mapping.source === undefined) {
node.add(code);
} else {
var source = aRelativePath
? util.join(aRelativePath, mapping.source)
: mapping.source;
node.add(new SourceNode(mapping.originalLine,
mapping.originalColumn,
source,
code,
mapping.name));
}
}
};
/**
* Add a chunk of generated JS to this source node.
*
* @param aChunk A string snippet of generated JS code, another instance of
* SourceNode, or an array where each member is one of those things.
*/
SourceNode.prototype.add = function SourceNode_add(aChunk) {
if (Array.isArray(aChunk)) {
aChunk.forEach(function (chunk) {
this.add(chunk);
}, this);
}
else if (aChunk[isSourceNode] || typeof aChunk === "string") {
if (aChunk) {
this.children.push(aChunk);
}
}
else {
throw new TypeError(
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
);
}
return this;
};
/**
* Add a chunk of generated JS to the beginning of this source node.
*
* @param aChunk A string snippet of generated JS code, another instance of
* SourceNode, or an array where each member is one of those things.
*/
SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {
if (Array.isArray(aChunk)) {
for (var i = aChunk.length-1; i >= 0; i--) {
this.prepend(aChunk[i]);
}
}
else if (aChunk[isSourceNode] || typeof aChunk === "string") {
this.children.unshift(aChunk);
}
else {
throw new TypeError(
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
);
}
return this;
};
/**
* Walk over the tree of JS snippets in this node and its children. The
* walking function is called once for each snippet of JS and is passed that
* snippet and the its original associated source's line/column location.
*
* @param aFn The traversal function.
*/
SourceNode.prototype.walk = function SourceNode_walk(aFn) {
var chunk;
for (var i = 0, len = this.children.length; i < len; i++) {
chunk = this.children[i];
if (chunk[isSourceNode]) {
chunk.walk(aFn);
}
else {
if (chunk !== '') {
aFn(chunk, { source: this.source,
line: this.line,
column: this.column,
name: this.name });
}
}
}
};
/**
* Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
* each of `this.children`.
*
* @param aSep The separator.
*/
SourceNode.prototype.join = function SourceNode_join(aSep) {
var newChildren;
var i;
var len = this.children.length;
if (len > 0) {
newChildren = [];
for (i = 0; i < len-1; i++) {
newChildren.push(this.children[i]);
newChildren.push(aSep);
}
newChildren.push(this.children[i]);
this.children = newChildren;
}
return this;
};
/**
* Call String.prototype.replace on the very right-most source snippet. Useful
* for trimming whitespace from the end of a source node, etc.
*
* @param aPattern The pattern to replace.
* @param aReplacement The thing to replace the pattern with.
*/
SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {
var lastChild = this.children[this.children.length - 1];
if (lastChild[isSourceNode]) {
lastChild.replaceRight(aPattern, aReplacement);
}
else if (typeof lastChild === 'string') {
this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
}
else {
this.children.push(''.replace(aPattern, aReplacement));
}
return this;
};
/**
* Set the source content for a source file. This will be added to the SourceMapGenerator
* in the sourcesContent field.
*
* @param aSourceFile The filename of the source file
* @param aSourceContent The content of the source file
*/
SourceNode.prototype.setSourceContent =
function SourceNode_setSourceContent(aSourceFile, aSourceContent) {
this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
};
/**
* Walk over the tree of SourceNodes. The walking function is called for each
* source file content and is passed the filename and source content.
*
* @param aFn The traversal function.
*/
SourceNode.prototype.walkSourceContents =
function SourceNode_walkSourceContents(aFn) {
for (var i = 0, len = this.children.length; i < len; i++) {
if (this.children[i][isSourceNode]) {
this.children[i].walkSourceContents(aFn);
}
}
var sources = Object.keys(this.sourceContents);
for (var i = 0, len = sources.length; i < len; i++) {
aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
}
};
/**
* Return the string representation of this source node. Walks over the tree
* and concatenates all the various snippets together to one string.
*/
SourceNode.prototype.toString = function SourceNode_toString() {
var str = "";
this.walk(function (chunk) {
str += chunk;
});
return str;
};
/**
* Returns the string representation of this source node along with a source
* map.
*/
SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {
var generated = {
code: "",
line: 1,
column: 0
};
var map = new SourceMapGenerator(aArgs);
var sourceMappingActive = false;
var lastOriginalSource = null;
var lastOriginalLine = null;
var lastOriginalColumn = null;
var lastOriginalName = null;
this.walk(function (chunk, original) {
generated.code += chunk;
if (original.source !== null
&& original.line !== null
&& original.column !== null) {
if(lastOriginalSource !== original.source
|| lastOriginalLine !== original.line
|| lastOriginalColumn !== original.column
|| lastOriginalName !== original.name) {
map.addMapping({
source: original.source,
original: {
line: original.line,
column: original.column
},
generated: {
line: generated.line,
column: generated.column
},
name: original.name
});
}
lastOriginalSource = original.source;
lastOriginalLine = original.line;
lastOriginalColumn = original.column;
lastOriginalName = original.name;
sourceMappingActive = true;
} else if (sourceMappingActive) {
map.addMapping({
generated: {
line: generated.line,
column: generated.column
}
});
lastOriginalSource = null;
sourceMappingActive = false;
}
for (var idx = 0, length = chunk.length; idx < length; idx++) {
if (chunk.charCodeAt(idx) === NEWLINE_CODE) {
generated.line++;
generated.column = 0;
// Mappings end at eol
if (idx + 1 === length) {
lastOriginalSource = null;
sourceMappingActive = false;
} else if (sourceMappingActive) {
map.addMapping({
source: original.source,
original: {
line: original.line,
column: original.column
},
generated: {
line: generated.line,
column: generated.column
},
name: original.name
});
}
} else {
generated.column++;
}
}
});
this.walkSourceContents(function (sourceFile, sourceContent) {
map.setSourceContent(sourceFile, sourceContent);
});
return { code: generated.code, map: map };
};
exports.SourceNode = SourceNode;
});
},{"./source-map-generator":35,"./util":37,"amdefine":38}],37:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
if (typeof define !== 'function') {
var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
/**
* This is a helper function for getting values from parameter/options
* objects.
*
* @param args The object we are extracting values from
* @param name The name of the property we are getting.
* @param defaultValue An optional value to return if the property is missing
* from the object. If this is not specified and the property is missing, an
* error will be thrown.
*/
function getArg(aArgs, aName, aDefaultValue) {
if (aName in aArgs) {
return aArgs[aName];
} else if (arguments.length === 3) {
return aDefaultValue;
} else {
throw new Error('"' + aName + '" is a required argument.');
}
}
exports.getArg = getArg;
var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
var match = aUrl.match(urlRegexp);
if (!match) {
return null;
}
return {
scheme: match[1],
auth: match[2],
host: match[3],
port: match[4],
path: match[5]
};
}
exports.urlParse = urlParse;
function urlGenerate(aParsedUrl) {
var url = '';
if (aParsedUrl.scheme) {
url += aParsedUrl.scheme + ':';
}
url += '//';
if (aParsedUrl.auth) {
url += aParsedUrl.auth + '@';
}
if (aParsedUrl.host) {
url += aParsedUrl.host;
}
if (aParsedUrl.port) {
url += ":" + aParsedUrl.port
}
if (aParsedUrl.path) {
url += aParsedUrl.path;
}
return url;
}
exports.urlGenerate = urlGenerate;
/**
* Normalizes a path, or the path portion of a URL:
*
* - Replaces consequtive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
* Based on code in the Node.js 'path' core module.
*
* @param aPath The path or url to normalize.
*/
function normalize(aPath) {
var path = aPath;
var url = urlParse(aPath);
if (url) {
if (!url.path) {
return aPath;
}
path = url.path;
}
var isAbsolute = (path.charAt(0) === '/');
var parts = path.split(/\/+/);
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
part = parts[i];
if (part === '.') {
parts.splice(i, 1);
} else if (part === '..') {
up++;
} else if (up > 0) {
if (part === '') {
// The first part is blank if the path is absolute. Trying to go
// above the root is a no-op. Therefore we can remove all '..' parts
// directly after the root.
parts.splice(i + 1, up);
up = 0;
} else {
parts.splice(i, 2);
up--;
}
}
}
path = parts.join('/');
if (path === '') {
path = isAbsolute ? '/' : '.';
}
if (url) {
url.path = path;
return urlGenerate(url);
}
return path;
}
exports.normalize = normalize;
/**
* Joins two paths/URLs.
*
* @param aRoot The root path or URL.
* @param aPath The path or URL to be joined with the root.
*
* - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
* scheme-relative URL: Then the scheme of aRoot, if any, is prepended
* first.
* - Otherwise aPath is a path. If aRoot is a URL, then its path portion
* is updated with the result and aRoot is returned. Otherwise the result
* is returned.
* - If aPath is absolute, the result is aPath.
* - Otherwise the two paths are joined with a slash.
* - Joining for example 'http://' and 'www.example.com' is also supported.
*/
function join(aRoot, aPath) {
if (aRoot === "") {
aRoot = ".";
}
if (aPath === "") {
aPath = ".";
}
var aPathUrl = urlParse(aPath);
var aRootUrl = urlParse(aRoot);
if (aRootUrl) {
aRoot = aRootUrl.path || '/';
}
// `join(foo, '//www.example.org')`
if (aPathUrl && !aPathUrl.scheme) {
if (aRootUrl) {
aPathUrl.scheme = aRootUrl.scheme;
}
return urlGenerate(aPathUrl);
}
if (aPathUrl || aPath.match(dataUrlRegexp)) {
return aPath;
}
// `join('http://', 'www.example.com')`
if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
aRootUrl.host = aPath;
return urlGenerate(aRootUrl);
}
var joined = aPath.charAt(0) === '/'
? aPath
: normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
if (aRootUrl) {
aRootUrl.path = joined;
return urlGenerate(aRootUrl);
}
return joined;
}
exports.join = join;
/**
* Make a path relative to a URL or another path.
*
* @param aRoot The root path or URL.
* @param aPath The path or URL to be made relative to aRoot.
*/
function relative(aRoot, aPath) {
if (aRoot === "") {
aRoot = ".";
}
aRoot = aRoot.replace(/\/$/, '');
// XXX: It is possible to remove this block, and the tests still pass!
var url = urlParse(aRoot);
if (aPath.charAt(0) == "/" && url && url.path == "/") {
return aPath.slice(1);
}
return aPath.indexOf(aRoot + '/') === 0
? aPath.substr(aRoot.length + 1)
: aPath;
}
exports.relative = relative;
/**
* Because behavior goes wacky when you set `__proto__` on objects, we
* have to prefix all the strings in our set with an arbitrary character.
*
* See https://github.com/mozilla/source-map/pull/31 and
* https://github.com/mozilla/source-map/issues/30
*
* @param String aStr
*/
function toSetString(aStr) {
return '$' + aStr;
}
exports.toSetString = toSetString;
function fromSetString(aStr) {
return aStr.substr(1);
}
exports.fromSetString = fromSetString;
function strcmp(aStr1, aStr2) {
var s1 = aStr1 || "";
var s2 = aStr2 || "";
return (s1 > s2) - (s1 < s2);
}
/**
* Comparator between two mappings where the original positions are compared.
*
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
* mappings with the same original source/line/column, but different generated
* line and column the same. Useful when searching for a mapping with a
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
var cmp;
cmp = strcmp(mappingA.source, mappingB.source);
if (cmp) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp || onlyCompareOriginal) {
return cmp;
}
cmp = strcmp(mappingA.name, mappingB.name);
if (cmp) {
return cmp;
}
cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp) {
return cmp;
}
return mappingA.generatedColumn - mappingB.generatedColumn;
};
exports.compareByOriginalPositions = compareByOriginalPositions;
/**
* Comparator between two mappings where the generated positions are
* compared.
*
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
* mappings with the same generated line and column, but different
* source/name/original line and column the same. Useful when searching for a
* mapping with a stubbed out mapping.
*/
function compareByGeneratedPositions(mappingA, mappingB, onlyCompareGenerated) {
var cmp;
cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp) {
return cmp;
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
if (cmp || onlyCompareGenerated) {
return cmp;
}
cmp = strcmp(mappingA.source, mappingB.source);
if (cmp) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp) {
return cmp;
}
return strcmp(mappingA.name, mappingB.name);
};
exports.compareByGeneratedPositions = compareByGeneratedPositions;
});
},{"amdefine":38}],38:[function(require,module,exports){
(function (process,__filename){
/** vim: et:ts=4:sw=4:sts=4
* @license amdefine 0.1.0 Copyright (c) 2011, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/amdefine for details
*/
/*jslint node: true */
/*global module, process */
'use strict';
/**
* Creates a define for node.
* @param {Object} module the "module" object that is defined by Node for the
* current module.
* @param {Function} [requireFn]. Node's require function for the current module.
* It only needs to be passed in Node versions before 0.5, when module.require
* did not exist.
* @returns {Function} a define function that is usable for the current node
* module.
*/
function amdefine(module, requireFn) {
'use strict';
var defineCache = {},
loaderCache = {},
alreadyCalled = false,
path = require('path'),
makeRequire, stringRequire;
/**
* Trims the . and .. from an array of path segments.
* It will keep a leading path segment if a .. will become
* the first path segment, to help with module name lookups,
* which act like paths, but can be remapped. But the end result,
* all paths that use this function should look normalized.
* NOTE: this method MODIFIES the input array.
* @param {Array} ary the array of path segments.
*/
function trimDots(ary) {
var i, part;
for (i = 0; ary[i]; i+= 1) {
part = ary[i];
if (part === '.') {
ary.splice(i, 1);
i -= 1;
} else if (part === '..') {
if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {
//End of the line. Keep at least one non-dot
//path segment at the front so it can be mapped
//correctly to disk. Otherwise, there is likely
//no path mapping for a path starting with '..'.
//This can still fail, but catches the most reasonable
//uses of ..
break;
} else if (i > 0) {
ary.splice(i - 1, 2);
i -= 2;
}
}
}
}
function normalize(name, baseName) {
var baseParts;
//Adjust any relative paths.
if (name && name.charAt(0) === '.') {
//If have a base name, try to normalize against it,
//otherwise, assume it is a top-level require that will
//be relative to baseUrl in the end.
if (baseName) {
baseParts = baseName.split('/');
baseParts = baseParts.slice(0, baseParts.length - 1);
baseParts = baseParts.concat(name.split('/'));
trimDots(baseParts);
name = baseParts.join('/');
}
}
return name;
}
/**
* Create the normalize() function passed to a loader plugin's
* normalize method.
*/
function makeNormalize(relName) {
return function (name) {
return normalize(name, relName);
};
}
function makeLoad(id) {
function load(value) {
loaderCache[id] = value;
}
load.fromText = function (id, text) {
//This one is difficult because the text can/probably uses
//define, and any relative paths and requires should be relative
//to that id was it would be found on disk. But this would require
//bootstrapping a module/require fairly deeply from node core.
//Not sure how best to go about that yet.
throw new Error('amdefine does not implement load.fromText');
};
return load;
}
makeRequire = function (systemRequire, exports, module, relId) {
function amdRequire(deps, callback) {
if (typeof deps === 'string') {
//Synchronous, single module require('')
return stringRequire(systemRequire, exports, module, deps, relId);
} else {
//Array of dependencies with a callback.
//Convert the dependencies to modules.
deps = deps.map(function (depName) {
return stringRequire(systemRequire, exports, module, depName, relId);
});
//Wait for next tick to call back the require call.
if (callback) {
process.nextTick(function () {
callback.apply(null, deps);
});
}
}
}
amdRequire.toUrl = function (filePath) {
if (filePath.indexOf('.') === 0) {
return normalize(filePath, path.dirname(module.filename));
} else {
return filePath;
}
};
return amdRequire;
};
//Favor explicit value, passed in if the module wants to support Node 0.4.
requireFn = requireFn || function req() {
return module.require.apply(module, arguments);
};
function runFactory(id, deps, factory) {
var r, e, m, result;
if (id) {
e = loaderCache[id] = {};
m = {
id: id,
uri: __filename,
exports: e
};
r = makeRequire(requireFn, e, m, id);
} else {
//Only support one define call per file
if (alreadyCalled) {
throw new Error('amdefine with no module ID cannot be called more than once per file.');
}
alreadyCalled = true;
//Use the real variables from node
//Use module.exports for exports, since
//the exports in here is amdefine exports.
e = module.exports;
m = module;
r = makeRequire(requireFn, e, m, module.id);
}
//If there are dependencies, they are strings, so need
//to convert them to dependency values.
if (deps) {
deps = deps.map(function (depName) {
return r(depName);
});
}
//Call the factory with the right dependencies.
if (typeof factory === 'function') {
result = factory.apply(m.exports, deps);
} else {
result = factory;
}
if (result !== undefined) {
m.exports = result;
if (id) {
loaderCache[id] = m.exports;
}
}
}
stringRequire = function (systemRequire, exports, module, id, relId) {
//Split the ID by a ! so that
var index = id.indexOf('!'),
originalId = id,
prefix, plugin;
if (index === -1) {
id = normalize(id, relId);
//Straight module lookup. If it is one of the special dependencies,
//deal with it, otherwise, delegate to node.
if (id === 'require') {
return makeRequire(systemRequire, exports, module, relId);
} else if (id === 'exports') {
return exports;
} else if (id === 'module') {
return module;
} else if (loaderCache.hasOwnProperty(id)) {
return loaderCache[id];
} else if (defineCache[id]) {
runFactory.apply(null, defineCache[id]);
return loaderCache[id];
} else {
if(systemRequire) {
return systemRequire(originalId);
} else {
throw new Error('No module with ID: ' + id);
}
}
} else {
//There is a plugin in play.
prefix = id.substring(0, index);
id = id.substring(index + 1, id.length);
plugin = stringRequire(systemRequire, exports, module, prefix, relId);
if (plugin.normalize) {
id = plugin.normalize(id, makeNormalize(relId));
} else {
//Normalize the ID normally.
id = normalize(id, relId);
}
if (loaderCache[id]) {
return loaderCache[id];
} else {
plugin.load(id, makeRequire(systemRequire, exports, module, relId), makeLoad(id), {});
return loaderCache[id];
}
}
};
//Create a define function specific to the module asking for amdefine.
function define(id, deps, factory) {
if (Array.isArray(id)) {
factory = deps;
deps = id;
id = undefined;
} else if (typeof id !== 'string') {
factory = id;
id = deps = undefined;
}
if (deps && !Array.isArray(deps)) {
factory = deps;
deps = undefined;
}
if (!deps) {
deps = ['require', 'exports', 'module'];
}
//Set up properties for this module. If an ID, then use
//internal cache. If no ID, then use the external variables
//for this node module.
if (id) {
//Put the module in deep freeze until there is a
//require call for it.
defineCache[id] = [id, deps, factory];
} else {
runFactory(id, deps, factory);
}
}
//define.require, which has access to all the values in the
//cache. Useful for AMD modules that all have IDs in the file,
//but need to finally export a value to node based on one of those
//IDs.
define.require = function (id) {
if (loaderCache[id]) {
return loaderCache[id];
}
if (defineCache[id]) {
runFactory.apply(null, defineCache[id]);
return loaderCache[id];
}
};
define.amd = {};
return define;
}
module.exports = amdefine;
}).call(this,require('_process'),"/node_modules/handlebars/node_modules/source-map/node_modules/amdefine/amdefine.js")
},{"_process":4,"path":3}],39:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var punycode = require('punycode');
exports.parse = urlParse;
exports.resolve = urlResolve;
exports.resolveObject = urlResolveObject;
exports.format = urlFormat;
exports.Url = Url;
function Url() {
this.protocol = null;
this.slashes = null;
this.auth = null;
this.host = null;
this.port = null;
this.hostname = null;
this.hash = null;
this.search = null;
this.query = null;
this.pathname = null;
this.path = null;
this.href = null;
}
// Reference: RFC 3986, RFC 1808, RFC 2396
// define these here so at least they only have to be
// compiled once on the first module load.
var protocolPattern = /^([a-z0-9.+-]+:)/i,
portPattern = /:[0-9]*$/,
// RFC 2396: characters reserved for delimiting URLs.
// We actually just auto-escape these.
delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
// RFC 2396: characters not allowed for various reasons.
unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
// Allowed by RFCs, but cause of XSS attacks. Always escape these.
autoEscape = ['\''].concat(unwise),
// Characters that are never ever allowed in a hostname.
// Note that any invalid chars are also handled, but these
// are the ones that are *expected* to be seen, so we fast-path
// them.
nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
hostEndingChars = ['/', '?', '#'],
hostnameMaxLen = 255,
hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/,
hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/,
// protocols that can allow "unsafe" and "unwise" chars.
unsafeProtocol = {
'javascript': true,
'javascript:': true
},
// protocols that never have a hostname.
hostlessProtocol = {
'javascript': true,
'javascript:': true
},
// protocols that always contain a // bit.
slashedProtocol = {
'http': true,
'https': true,
'ftp': true,
'gopher': true,
'file': true,
'http:': true,
'https:': true,
'ftp:': true,
'gopher:': true,
'file:': true
},
querystring = require('querystring');
function urlParse(url, parseQueryString, slashesDenoteHost) {
if (url && isObject(url) && url instanceof Url) return url;
var u = new Url;
u.parse(url, parseQueryString, slashesDenoteHost);
return u;
}
Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
if (!isString(url)) {
throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
}
var rest = url;
// trim before proceeding.
// This is to support parse stuff like " http://foo.com \n"
rest = rest.trim();
var proto = protocolPattern.exec(rest);
if (proto) {
proto = proto[0];
var lowerProto = proto.toLowerCase();
this.protocol = lowerProto;
rest = rest.substr(proto.length);
}
// figure out if it's got a host
// user@server is *always* interpreted as a hostname, and url
// resolution will treat //foo/bar as host=foo,path=bar because that's
// how the browser resolves relative URLs.
if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
var slashes = rest.substr(0, 2) === '//';
if (slashes && !(proto && hostlessProtocol[proto])) {
rest = rest.substr(2);
this.slashes = true;
}
}
if (!hostlessProtocol[proto] &&
(slashes || (proto && !slashedProtocol[proto]))) {
// there's a hostname.
// the first instance of /, ?, ;, or # ends the host.
//
// If there is an @ in the hostname, then non-host chars *are* allowed
// to the left of the last @ sign, unless some host-ending character
// comes *before* the @-sign.
// URLs are obnoxious.
//
// ex:
// http://a@b@c/ => user:a@b host:c
// http://a@b?@c => user:a host:c path:/?@c
// v0.12 TODO(isaacs): This is not quite how Chrome does things.
// Review our test case against browsers more comprehensively.
// find the first instance of any hostEndingChars
var hostEnd = -1;
for (var i = 0; i < hostEndingChars.length; i++) {
var hec = rest.indexOf(hostEndingChars[i]);
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
hostEnd = hec;
}
// at this point, either we have an explicit point where the
// auth portion cannot go past, or the last @ char is the decider.
var auth, atSign;
if (hostEnd === -1) {
// atSign can be anywhere.
atSign = rest.lastIndexOf('@');
} else {
// atSign must be in auth portion.
// http://a@b/c@d => host:b auth:a path:/c@d
atSign = rest.lastIndexOf('@', hostEnd);
}
// Now we have a portion which is definitely the auth.
// Pull that off.
if (atSign !== -1) {
auth = rest.slice(0, atSign);
rest = rest.slice(atSign + 1);
this.auth = decodeURIComponent(auth);
}
// the host is the remaining to the left of the first non-host char
hostEnd = -1;
for (var i = 0; i < nonHostChars.length; i++) {
var hec = rest.indexOf(nonHostChars[i]);
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
hostEnd = hec;
}
// if we still have not hit it, then the entire thing is a host.
if (hostEnd === -1)
hostEnd = rest.length;
this.host = rest.slice(0, hostEnd);
rest = rest.slice(hostEnd);
// pull out port.
this.parseHost();
// we've indicated that there is a hostname,
// so even if it's empty, it has to be present.
this.hostname = this.hostname || '';
// if hostname begins with [ and ends with ]
// assume that it's an IPv6 address.
var ipv6Hostname = this.hostname[0] === '[' &&
this.hostname[this.hostname.length - 1] === ']';
// validate a little.
if (!ipv6Hostname) {
var hostparts = this.hostname.split(/\./);
for (var i = 0, l = hostparts.length; i < l; i++) {
var part = hostparts[i];
if (!part) continue;
if (!part.match(hostnamePartPattern)) {
var newpart = '';
for (var j = 0, k = part.length; j < k; j++) {
if (part.charCodeAt(j) > 127) {
// we replace non-ASCII char with a temporary placeholder
// we need this to make sure size of hostname is not
// broken by replacing non-ASCII by nothing
newpart += 'x';
} else {
newpart += part[j];
}
}
// we test again with ASCII char only
if (!newpart.match(hostnamePartPattern)) {
var validParts = hostparts.slice(0, i);
var notHost = hostparts.slice(i + 1);
var bit = part.match(hostnamePartStart);
if (bit) {
validParts.push(bit[1]);
notHost.unshift(bit[2]);
}
if (notHost.length) {
rest = '/' + notHost.join('.') + rest;
}
this.hostname = validParts.join('.');
break;
}
}
}
}
if (this.hostname.length > hostnameMaxLen) {
this.hostname = '';
} else {
// hostnames are always lower case.
this.hostname = this.hostname.toLowerCase();
}
if (!ipv6Hostname) {
// IDNA Support: Returns a puny coded representation of "domain".
// It only converts the part of the domain name that
// has non ASCII characters. I.e. it dosent matter if
// you call it with a domain that already is in ASCII.
var domainArray = this.hostname.split('.');
var newOut = [];
for (var i = 0; i < domainArray.length; ++i) {
var s = domainArray[i];
newOut.push(s.match(/[^A-Za-z0-9_-]/) ?
'xn--' + punycode.encode(s) : s);
}
this.hostname = newOut.join('.');
}
var p = this.port ? ':' + this.port : '';
var h = this.hostname || '';
this.host = h + p;
this.href += this.host;
// strip [ and ] from the hostname
// the host field still retains them, though
if (ipv6Hostname) {
this.hostname = this.hostname.substr(1, this.hostname.length - 2);
if (rest[0] !== '/') {
rest = '/' + rest;
}
}
}
// now rest is set to the post-host stuff.
// chop off any delim chars.
if (!unsafeProtocol[lowerProto]) {
// First, make 100% sure that any "autoEscape" chars get
// escaped, even if encodeURIComponent doesn't think they
// need to be.
for (var i = 0, l = autoEscape.length; i < l; i++) {
var ae = autoEscape[i];
var esc = encodeURIComponent(ae);
if (esc === ae) {
esc = escape(ae);
}
rest = rest.split(ae).join(esc);
}
}
// chop off from the tail first.
var hash = rest.indexOf('#');
if (hash !== -1) {
// got a fragment string.
this.hash = rest.substr(hash);
rest = rest.slice(0, hash);
}
var qm = rest.indexOf('?');
if (qm !== -1) {
this.search = rest.substr(qm);
this.query = rest.substr(qm + 1);
if (parseQueryString) {
this.query = querystring.parse(this.query);
}
rest = rest.slice(0, qm);
} else if (parseQueryString) {
// no query string, but parseQueryString still requested
this.search = '';
this.query = {};
}
if (rest) this.pathname = rest;
if (slashedProtocol[lowerProto] &&
this.hostname && !this.pathname) {
this.pathname = '/';
}
//to support http.request
if (this.pathname || this.search) {
var p = this.pathname || '';
var s = this.search || '';
this.path = p + s;
}
// finally, reconstruct the href based on what has been validated.
this.href = this.format();
return this;
};
// format a parsed object into a url string
function urlFormat(obj) {
// ensure it's an object, and not a string url.
// If it's an obj, this is a no-op.
// this way, you can call url_format() on strings
// to clean up potentially wonky urls.
if (isString(obj)) obj = urlParse(obj);
if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
return obj.format();
}
Url.prototype.format = function() {
var auth = this.auth || '';
if (auth) {
auth = encodeURIComponent(auth);
auth = auth.replace(/%3A/i, ':');
auth += '@';
}
var protocol = this.protocol || '',
pathname = this.pathname || '',
hash = this.hash || '',
host = false,
query = '';
if (this.host) {
host = auth + this.host;
} else if (this.hostname) {
host = auth + (this.hostname.indexOf(':') === -1 ?
this.hostname :
'[' + this.hostname + ']');
if (this.port) {
host += ':' + this.port;
}
}
if (this.query &&
isObject(this.query) &&
Object.keys(this.query).length) {
query = querystring.stringify(this.query);
}
var search = this.search || (query && ('?' + query)) || '';
if (protocol && protocol.substr(-1) !== ':') protocol += ':';
// only the slashedProtocols get the //. Not mailto:, xmpp:, etc.
// unless they had them to begin with.
if (this.slashes ||
(!protocol || slashedProtocol[protocol]) && host !== false) {
host = '//' + (host || '');
if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
} else if (!host) {
host = '';
}
if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
if (search && search.charAt(0) !== '?') search = '?' + search;
pathname = pathname.replace(/[?#]/g, function(match) {
return encodeURIComponent(match);
});
search = search.replace('#', '%23');
return protocol + host + pathname + search + hash;
};
function urlResolve(source, relative) {
return urlParse(source, false, true).resolve(relative);
}
Url.prototype.resolve = function(relative) {
return this.resolveObject(urlParse(relative, false, true)).format();
};
function urlResolveObject(source, relative) {
if (!source) return relative;
return urlParse(source, false, true).resolveObject(relative);
}
Url.prototype.resolveObject = function(relative) {
if (isString(relative)) {
var rel = new Url();
rel.parse(relative, false, true);
relative = rel;
}
var result = new Url();
Object.keys(this).forEach(function(k) {
result[k] = this[k];
}, this);
// hash is always overridden, no matter what.
// even href="" will remove it.
result.hash = relative.hash;
// if the relative url is empty, then there's nothing left to do here.
if (relative.href === '') {
result.href = result.format();
return result;
}
// hrefs like //foo/bar always cut to the protocol.
if (relative.slashes && !relative.protocol) {
// take everything except the protocol from relative
Object.keys(relative).forEach(function(k) {
if (k !== 'protocol')
result[k] = relative[k];
});
//urlParse appends trailing / to urls like http://www.example.com
if (slashedProtocol[result.protocol] &&
result.hostname && !result.pathname) {
result.path = result.pathname = '/';
}
result.href = result.format();
return result;
}
if (relative.protocol && relative.protocol !== result.protocol) {
// if it's a known url protocol, then changing
// the protocol does weird things
// first, if it's not file:, then we MUST have a host,
// and if there was a path
// to begin with, then we MUST have a path.
// if it is file:, then the host is dropped,
// because that's known to be hostless.
// anything else is assumed to be absolute.
if (!slashedProtocol[relative.protocol]) {
Object.keys(relative).forEach(function(k) {
result[k] = relative[k];
});
result.href = result.format();
return result;
}
result.protocol = relative.protocol;
if (!relative.host && !hostlessProtocol[relative.protocol]) {
var relPath = (relative.pathname || '').split('/');
while (relPath.length && !(relative.host = relPath.shift()));
if (!relative.host) relative.host = '';
if (!relative.hostname) relative.hostname = '';
if (relPath[0] !== '') relPath.unshift('');
if (relPath.length < 2) relPath.unshift('');
result.pathname = relPath.join('/');
} else {
result.pathname = relative.pathname;
}
result.search = relative.search;
result.query = relative.query;
result.host = relative.host || '';
result.auth = relative.auth;
result.hostname = relative.hostname || relative.host;
result.port = relative.port;
// to support http.request
if (result.pathname || result.search) {
var p = result.pathname || '';
var s = result.search || '';
result.path = p + s;
}
result.slashes = result.slashes || relative.slashes;
result.href = result.format();
return result;
}
var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
isRelAbs = (
relative.host ||
relative.pathname && relative.pathname.charAt(0) === '/'
),
mustEndAbs = (isRelAbs || isSourceAbs ||
(result.host && relative.pathname)),
removeAllDots = mustEndAbs,
srcPath = result.pathname && result.pathname.split('/') || [],
relPath = relative.pathname && relative.pathname.split('/') || [],
psychotic = result.protocol && !slashedProtocol[result.protocol];
// if the url is a non-slashed url, then relative
// links like ../.. should be able
// to crawl up to the hostname, as well. This is strange.
// result.protocol has already been set by now.
// Later on, put the first path part into the host field.
if (psychotic) {
result.hostname = '';
result.port = null;
if (result.host) {
if (srcPath[0] === '') srcPath[0] = result.host;
else srcPath.unshift(result.host);
}
result.host = '';
if (relative.protocol) {
relative.hostname = null;
relative.port = null;
if (relative.host) {
if (relPath[0] === '') relPath[0] = relative.host;
else relPath.unshift(relative.host);
}
relative.host = null;
}
mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
}
if (isRelAbs) {
// it's absolute.
result.host = (relative.host || relative.host === '') ?
relative.host : result.host;
result.hostname = (relative.hostname || relative.hostname === '') ?
relative.hostname : result.hostname;
result.search = relative.search;
result.query = relative.query;
srcPath = relPath;
// fall through to the dot-handling below.
} else if (relPath.length) {
// it's relative
// throw away the existing file, and take the new path instead.
if (!srcPath) srcPath = [];
srcPath.pop();
srcPath = srcPath.concat(relPath);
result.search = relative.search;
result.query = relative.query;
} else if (!isNullOrUndefined(relative.search)) {
// just pull out the search.
// like href='?foo'.
// Put this after the other two cases because it simplifies the booleans
if (psychotic) {
result.hostname = result.host = srcPath.shift();
//occationaly the auth can get stuck only in host
//this especialy happens in cases like
//url.resolveObject('mailto:local1@domain1', 'local2@domain2')
var authInHost = result.host && result.host.indexOf('@') > 0 ?
result.host.split('@') : false;
if (authInHost) {
result.auth = authInHost.shift();
result.host = result.hostname = authInHost.shift();
}
}
result.search = relative.search;
result.query = relative.query;
//to support http.request
if (!isNull(result.pathname) || !isNull(result.search)) {
result.path = (result.pathname ? result.pathname : '') +
(result.search ? result.search : '');
}
result.href = result.format();
return result;
}
if (!srcPath.length) {
// no path at all. easy.
// we've already handled the other stuff above.
result.pathname = null;
//to support http.request
if (result.search) {
result.path = '/' + result.search;
} else {
result.path = null;
}
result.href = result.format();
return result;
}
// if a url ENDs in . or .., then it must get a trailing slash.
// however, if it ends in anything else non-slashy,
// then it must NOT get a trailing slash.
var last = srcPath.slice(-1)[0];
var hasTrailingSlash = (
(result.host || relative.host) && (last === '.' || last === '..') ||
last === '');
// strip single dots, resolve double dots to parent dir
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = srcPath.length; i >= 0; i--) {
last = srcPath[i];
if (last == '.') {
srcPath.splice(i, 1);
} else if (last === '..') {
srcPath.splice(i, 1);
up++;
} else if (up) {
srcPath.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (!mustEndAbs && !removeAllDots) {
for (; up--; up) {
srcPath.unshift('..');
}
}
if (mustEndAbs && srcPath[0] !== '' &&
(!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
srcPath.unshift('');
}
if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
srcPath.push('');
}
var isAbsolute = srcPath[0] === '' ||
(srcPath[0] && srcPath[0].charAt(0) === '/');
// put the host back
if (psychotic) {
result.hostname = result.host = isAbsolute ? '' :
srcPath.length ? srcPath.shift() : '';
//occationaly the auth can get stuck only in host
//this especialy happens in cases like
//url.resolveObject('mailto:local1@domain1', 'local2@domain2')
var authInHost = result.host && result.host.indexOf('@') > 0 ?
result.host.split('@') : false;
if (authInHost) {
result.auth = authInHost.shift();
result.host = result.hostname = authInHost.shift();
}
}
mustEndAbs = mustEndAbs || (result.host && srcPath.length);
if (mustEndAbs && !isAbsolute) {
srcPath.unshift('');
}
if (!srcPath.length) {
result.pathname = null;
result.path = null;
} else {
result.pathname = srcPath.join('/');
}
//to support request.http
if (!isNull(result.pathname) || !isNull(result.search)) {
result.path = (result.pathname ? result.pathname : '') +
(result.search ? result.search : '');
}
result.auth = relative.auth || result.auth;
result.slashes = result.slashes || relative.slashes;
result.href = result.format();
return result;
};
Url.prototype.parseHost = function() {
var host = this.host;
var port = portPattern.exec(host);
if (port) {
port = port[0];
if (port !== ':') {
this.port = port.substr(1);
}
host = host.substr(0, host.length - port.length);
}
if (host) this.hostname = host;
};
function isString(arg) {
return typeof arg === "string";
}
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
function isNull(arg) {
return arg === null;
}
function isNullOrUndefined(arg) {
return arg == null;
}
},{"punycode":5,"querystring":8}],40:[function(require,module,exports){
module.exports = Search;
var d3 = (window.d3);
var EventEmitter = require('events').EventEmitter;
var itemClass = 'node-search__list-item';
var selectedItemClass = 'node-search__list-item--selected';
var itemHeight = 35;
function Search(parentSelector) {
var api = {};
var data = [];
var key = '';
var eventEmitter = new EventEmitter();
var parent = d3.select(parentSelector);
var input = parent
.append('input')
.attr('type', 'input')
.classed('node-search__input', true);
var searchIcon = parent
.append('span')
.classed('icon icon-search node-search__icon', true);
var cancelIcon = parent
.append('span')
.classed('node-search__icon node-search__cancel', true)
.text('×')
.on('click', clearSearch);
var list = parent
.append('ul')
.classed('node-search__list', true);
input
.on('keyup', searchAutoComplete)
.on('click', stopPropagation);
api.data = function (newData) {
if (!newData) { return data; }
data = newData;
return api;
};
api.searchKey = function (newKey) {
if (!newKey) { return key; }
key = newKey;
return api;
};
api.emit = eventEmitter.emit;
api.on = eventEmitter.on;
api.clear = clearSearch;
function searchAutoComplete() {
var searchString = this.value.toLowerCase();
var selected = list.select('.' + selectedItemClass);
var index;
var matches = data.filter(function (d) {
var siteName = (d[key] || '').toLowerCase();
return (siteName.indexOf(searchString) !== -1) && (searchString !== '');
});
updateList(matches);
if (d3.event.which === 13) {
// select top item in list
api.emit('selected', selected.node() && selected.node().__data__);
clearSearch();
// searchAutoComplete.call(this);
} else if (d3.event.which === 38 || d3.event.which === 40) {
// move selection up
d3.event.preventDefault();
list
.selectAll('.' + itemClass)
.each(function (d, i) {
if (selected[0][0] === this) {
index = i;
}
});
selectItemWithIndex(index + (d3.event.which === 38 ? -1 : 1));
} else {
selectItemWithIndex(0);
}
}
function updateList(listItems) {
var li = list
.selectAll('.' + itemClass)
.data(listItems, getKey);
li
.enter()
.append('li')
.classed(itemClass, true)
.text(getKey)
.on('click', listItemClicked)
.on('mouseenter', listItemSelected);
li.exit().remove();
}
function listItemClicked(d) {
d3.event.stopPropagation();
api.emit('selected', d);
input.node().focus();
clearSearch();
}
function listItemSelected(d) {
list
.selectAll('.' + itemClass)
.classed(selectedItemClass, function (lid) {
return lid === d;
})
}
function clearSearch() {
input.node().value = '';
updateList([]);
}
function selectItemWithIndex(index) {
var listItems = list.selectAll('.' + itemClass);
var maxIndex = listItems[0].length - 1;
var listElement = list.node();
var listHeight = listElement.getBoundingClientRect().height;
var itemTop;
var itemBottom;
maxIndex = maxIndex < 0 ? 0 : maxIndex;
index = (index < 0) ? maxIndex : (index > maxIndex) ? 0 : index;
itemTop = itemHeight * index;
itemBottom = itemTop + itemHeight;
listItems
.classed(selectedItemClass, function (d, i) {
return i === index;
});
if (itemTop < listElement.scrollTop) {
listElement.scrollTop = itemTop;
} else if (itemBottom > (listElement.scrollTop + listHeight)) {
listElement.scrollTop = itemBottom - listHeight;
}
}
function selectFirst(d, i) {
return i === 0;
}
function getKey(d) {
return d[key];
}
function preventDefault() {
d3.event.preventDefault();
}
function stopPropagation() {
d3.event.stopPropagation();
}
return api;
}
},{"events":2}],41:[function(require,module,exports){
module.exports = Tooltip;
var handlebars = require('handlebars');
var d3 = (window.d3);
var common = require('./common');
var rawTemplate = "<h2>{{#titleCase}}{{name}}{{/titleCase}}</h2>\n<table>\n <tr>\n <th>Type</th>\n <td>{{#titleCase}}{{type}}{{/titleCase}}</td>\n </tr>\n</table>\n";
var instanceCounter = 0;
/*
convert text to title casing
*/
handlebars.registerHelper('titleCase', function (options) {
return common.toTitleCase(options.fn(this));
});
function Tooltip() {
this.template = handlebars.compile(rawTemplate);
this.rect;
this.tooltip = d3
.select(document.createElement('div'))
.classed('tooltip tooltip-' + instanceCounter, true);
}
Tooltip.prototype.appendTo = function (parent) {
parent.appendChild(this.tooltip.node());
return this;
};
Tooltip.prototype.render = function (context) {
this.tooltip.node().innerHTML = this.template(context);
this.rect = this.tooltip.node().getBoundingClientRect();
return this;
};
Tooltip.prototype.show = function (el) {
var rect = el.getBoundingClientRect();
var x = rect.left - (this.rect.width / 2);
var y = rect.top - this.rect.height - 20;
this.tooltip
.style('transform', 'translate(' + x + 'px,' + y + 'px)')
.classed('tooltip--show', true);
return this;
};
Tooltip.prototype.hide = function () {
this.tooltip.classed('tooltip--show', false);
return this;
};
Tooltip.prototype.classed = function () {
this.tooltip.classed.apply(this.tooltip, arguments);
return this;
};
},{"./common":42,"handlebars":27}],42:[function(require,module,exports){
function toTitleCase(string) {
string = string.replace(/_|-/, ' ');
return string.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
module.exports = {
toTitleCase: toTitleCase
};
},{}],43:[function(require,module,exports){
var d3 = (window.d3);
var pixi = (window.PIXI);
var url = require('url');
var timeForceDirected = require('./timeForceDirected');
var Tooltip = require('./Tooltip');
var Search = require('./Search');
var chart;
var nodeTooltip;
var informationButtons = d3.selectAll('.information-button-toggle');
var information = d3.select('.information');
var search;
var filteredNodes = [];
var filteredLinks = [];
var data;
var years = [];
var size;
var currentDateIndex = 1;
var lastYear;
var addNodeInterval;
var vizContainer = d3.select('.viz');
var textureAssets = [
'assets/images/arrow.png',
'assets/images/node.png',
'assets/images/axis/2009.png',
'assets/images/axis/2010.png',
'assets/images/axis/2011.png',
'assets/images/axis/2012.png',
'assets/images/axis/2013.png',
'assets/images/axis/2014.png',
'assets/images/axis/2015.png'
];
d3.select(window).on('resize', resize);
d3.json('data/data.json', function (response) {
data = response;
// console.log(data);
informationButtons.on('click', function () {
d3.event.stopPropagation();
information.classed('information--show', !information.classed('information--show'));
});
size = [window.innerWidth, window.innerHeight];
resize();
// get data ready for viz
processData();
var loader = new pixi.loaders.Loader();
textureAssets.forEach(function (url) {
loader.add(url, url);
});
loader.load();
loader.once('complete', function () {
nodeTooltip = new Tooltip();
nodeTooltip
.appendTo(document.body)
.render()
.classed('tooltip--show', true);
// init force layout, scales used etc.
chart = timeForceDirected
.parent(vizContainer)
.years(years)
.calcScales(data.nodes, data.links)
.nodes(filteredNodes)
.links(filteredLinks)
.start()
.on('focussedOnNode', function (d) {
nodeTooltip
.render(d)
.classed('tooltip--show', true);
search.clear();
});
search = Search('.node-search');
search
.searchKey('name')
.data(data.nodes)
.on('selected', chart.focusOn);
// size the svg container and layout
resize();
addNodeInterval = setInterval(filterDataByTime, 10);
});
});
function resize() {
size[0] = window.innerWidth;
size[1] = window.innerHeight;
chart && chart.resize();
}
function filterDataByTime() {
var chartSize = chart.size();
var currentDate = dates[currentDateIndex];
var currentYear = currentDate.getFullYear();
if (lastYear !== currentYear) {
chart.highlightYear(currentYear);
}
lastYear = currentYear;
filteredNodes.length = 0;
filteredLinks.length = 0;
// add node to filtered dataset
data.nodes.forEach(function (node) {
if (node.appeared <= currentDate) {
node.x = node.x || (chartSize[0] / 2);
node.y = node.y || (chartSize[1] / 2);
filteredNodes.push(node);
}
});
// add all relevant links to filtered list
data.links.forEach(function (link) {
if (filteredNodes.indexOf(link.target) !== -1 && filteredNodes.indexOf(link.source) !== -1) {
filteredLinks.push(link);
}
});
// if last node was added then clear interval
if (currentDateIndex < (dates.length - 1)) {
currentDateIndex += 1;
} else {
clearInterval(addNodeInterval);
setTimeout(chart.bangFinished, 2000);
}
chart
.nodes(filteredNodes)
.links(filteredLinks);
// kick layout up the arse
chart.start();
}
function processData() {
// turn date strings into actual dates
data.nodes.forEach(function (node) {
node.appeared = new Date(node.appeared.substr(0, 10));
node.year = parseFloat(node.appeared.getUTCFullYear());
node.month = parseFloat(node.appeared.getMonth());
years.push(node.year);
});
// turn link source/target ids into references to nodes
data.links.forEach(function (link) {
link.target = getNodeFromId(link.target);
link.source = getNodeFromId(link.source);
});
// tally the number of links attached to each node
data.links.forEach(function (link) {
link.source.connections = link.source.connections || 0;
link.target.connections = link.target.connections || 0;
link.source.connections += 1;
link.target.connections += 1;
});
// get list of dates
dates = data.nodes
.map(function (node) { return node.appeared; })
.sort(function (a, b) { return a - b; });
// set up scales/maps used to position nodes based on their year
years = d3.set(years).values();
years = years.map(function (yearString) { return new Date(yearString); });
}
// get node from id
function getNodeFromId(id) {
return data.nodes.filter(function (node) {
return node.id === id;
})[0];
}
function formatDateDisplay(date) {
return moment(date).format('MMM Mo \'YY');
}
function formatSiteDisplay(siteUrl) {
var parsedUrl = url.parse(siteUrl || '');
var href = (siteUrl && ('http://www.' + siteUrl)) || '';
var value = !href ? '' : '<a href="' + href + '" target="__blank__"><span class="icon icon-link"></span> ' + siteUrl + '</a>';
return value;
}
},{"./Search":40,"./Tooltip":41,"./timeForceDirected":45,"url":39}],44:[function(require,module,exports){
var d3 = (window.d3);
var pixi = (window.PIXI);
var EventEmitter = require('events').EventEmitter;
var common = require('./common');
var isMobile = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent)
|| /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4));
var eventEmitter = new EventEmitter();
var currentYear;
var highlightedNode;
var nodeInFocus;
var nodeClicked = false; // @TODO ugly solution, work out event bubbling
var years = [];
var links = [];
var nodes = [];
var scaleLimit = [1, 4];
var layoutSize = [1000, 1000];
var canvasSize = [1000, 1000];
var renderSettings = {antialias: true, transparent: true, interactive: true, resolution: 1};
var renderer = pixi.autoDetectRenderer(canvasSize[0], canvasSize[1], renderSettings);
var stage = new pixi.Container();
var world = new pixi.Container();
var nodeTexture = pixi.Texture.fromImage('assets/images/node.png');
var axisContainer = new pixi.Container();
var nodeContainer = new pixi.Container();
var linkContainer = new pixi.Container();
var labelContainer = new pixi.Container();
var debugGraphic = new pixi.Graphics();
var nodeSprites = [];
var ease = d3.ease('cubic-in-out');
var linkWidth = d3.scale.linear().range([2, 10]);
var nodeSize = d3.scale.log().base(10).range([1, 8]);
var dateRadius;
var colors = [
'rgb(255, 235, 238)', // #FFEBEE
// 'rgb(255, 238, 88)', // #FFEE58
'rgb(17, 187, 218)', // #11bbda
// 'rgb(144, 164, 174)', // #90A4AE
'rgb(131, 133, 133)', // #838585
// 'rgb(255, 143, 0)', // #FF8F00
'rgb(215, 189, 43)', // #D7BD2B
'rgb(192, 40, 66)' // #C02842
];
var colorMap = {
'dark marketplace': colors[4],
'tumbler': colors[4],
'scam': colors[4],
'exchange': colors[1],
'wallet': colors[1],
'lending service': colors[1],
'faucet': colors[1],
'forum user': colors[1],
'mining pool': colors[1],
'payment processor': colors[1],
'charity': colors[1],
'gambling service': colors[3],
'creator': colors[0],
'-': colors[2]
};
var zoom = d3.behavior.zoom()
.scaleExtent([1, 8])
.on("zoomstart", function () {
world.originalX = world.position.x;
world.originalY = world.position.y;
world.originalScale = world.scale.x;
})
.on("zoom", function () {
var x = d3.event.translate[0] + world.xOffset;
var y = d3.event.translate[1] + world.yOffset;
updateWorldPosition(x, y, d3.event.scale);
})
.on("zoomend", function () {
// console.log(d3.event);
});
// populate world
stage.addChild(world);
world.addChild(axisContainer);
world.addChild(linkContainer);
world.addChild(nodeContainer);
world.addChild(labelContainer);
world.addChild(debugGraphic);
// size canvas
resize();
resetCamera();
// attach events
renderer.view.addEventListener('click', viewClicked);
// apply zoom + pan behaviour
if(isMobile) {
d3
.select(renderer.view)
.call(zoom);
}
requestAnimationFrame(render);
/*
draw the visualisation
*/
function draw() {
var i;
drawLinks();
drawNodes();
// update axis opacity to current year
for (i = 0; i < years.length; i++) {
years[i].alpha += (((years[i].year === currentYear) ? 1 : 0.2) - years[i].alpha) * 0.05;
}
}
/*
getter/setter for canvas width
*/
draw.width = function (newWidth) {
if (!newWidth) return canvasSize[0];
canvasSize[0] = newWidth;
return draw;
};
/*
getter/setter for canvas height
*/
draw.height = function (newHeight) {
if (!newHeight) return canvasSize[1];
canvasSize[1] = newHeight;
return draw;
};
/*
getter for canvas element
*/
draw.canvas = function () {
return renderer.view;
};
/*
get/set links data
*/
draw.links = function (newLinks) {
if (!newLinks) return links;
links = newLinks;
return draw;
};
/*
get/set node data
*/
draw.nodes = function (newNodes) {
if (!newNodes) return nodes;
nodes = newNodes;
return draw;
};
/*
update scales used for visuals based on data
*/
draw.updateScales = function (nodes, links) {
linkWidth.domain(d3.extent(links, function (link) {
return link.width;
}));
// set domain for node size scale
nodeSize.domain(d3.extent(nodes, function (node) {
return node.transacted;
}));
createSpriteAxis();
};
draw.focusOnNodesNetwork = function (d) {
var network = getNodesNetwork(d);
var networkBox = getNetworkBox(network);
if (!d || Math.abs(networkBox.width) === Infinity) {
resetCamera(true);
return;
}
nodeInFocus = d;
highlightNodesNetwork(d, network);
eventEmitter.emit('focussedOnNode', d);
zoomToBox(networkBox);
};
draw.layoutSize = function (newLayoutSize) {
if (!newLayoutSize) return layoutSize;
layoutSize = newLayoutSize;
return draw;
};
/*
window resize handler
*/
draw.resize = resize;
function resize() {
var canvasScale;
var canvasWidth;
var canvasHeight;
if (window.innerWidth < window.innerHeight) {
canvasScale = window.innerHeight / window.innerWidth;
canvasWidth = layoutSize[0];
canvasHeight = layoutSize[1] * canvasScale;
} else {
canvasScale = window.innerWidth / window.innerHeight;
canvasWidth = layoutSize[0] * canvasScale;
canvasHeight = layoutSize[1];
}
canvasSize[0] = canvasWidth;
canvasSize[1] = canvasHeight;
renderer.resize(canvasWidth, canvasHeight);
resetCamera();
}
/*
get/set currentYear
*/
draw.currentYear = function (newCurrentYear) {
if (!newCurrentYear) return currentYear;
currentYear = newCurrentYear;
return draw;
};
/*
called when
*/
draw.bangFinished = function () {
var i;
if (!isMobile) {
// attach events to axis rings
for (i = 0; i < years.length; i++) {
years[i].interactive = true;
years[i].alpha = 0.2;
years[i].mouseover = yearMouseover;
years[i].mouseout = yearMouseout;
}
}
};
draw.dateRadius = function (newDateRadius) {
dateRadius = newDateRadius;
return draw;
};
/*
visually highlight a nodes network
*/
function highlightNodesNetwork(d, network) {
highlightedNode = d;
network = network || getNodesNetwork(d);
links.forEach(function (link) {
link.highlighted = (network.links.indexOf(link) !== -1);
link.desiredColor = (link.target === d) ? 0xE42A2A : (link.source === d) ? rgbToHex(116, 239, 0) : 0xFFFFFF;
});
nodes.forEach(function (node) {
node.highlighted = (network.nodes.indexOf(node) !== -1);
if (node.label) {
node.label.desiredAlpha = node.highlighted ? 1 : 0;
}
});
}
function createSpriteAxis() {
var year;
var yearSprite;
var radius;
var diameter;
var label;
for (year = 2015; year >= 2009; year--) {
yearSprite = new pixi.Sprite(pixi.Texture.fromImage('assets/images/axis/' + year + '.png'));
yearSprite.anchor.x = 0.5;
yearSprite.anchor.y = 0.5;
yearSprite.position.x = layoutSize[0] / 2;
yearSprite.position.y = layoutSize[1] / 2;
yearSprite.year = year;
radius = dateRadius(new Date((yearSprite.year + 1) + ''));
diameter = radius * 2;
yearSprite.scale.x = diameter / yearSprite.texture.width;
yearSprite.scale.y = diameter / yearSprite.texture.height;
axisContainer.addChild(yearSprite);
years.push(yearSprite);
}
}
function yearMouseover(e) {
currentYear = this.year;
}
function yearMouseout(e) {
currentYear = currentYear < 2015 ? currentYear++ : 2015;
}
/*
expose event emitter methods
*/
draw.on = function (eventName, handler) {
eventEmitter.on(eventName, handler);
return draw;
};
draw.nodeHighlighted = function () {
return !!highlightedNode;
};
/*
render to canvas using pixi
*/
var then = Date.now();
var fpsInterval = 1000 / 60;
function render() {
draw();
var now = Date.now();
var elapsed = now - then;
if (elapsed > fpsInterval){
then = now - (elapsed % fpsInterval);
renderer.render(stage);
}
requestAnimationFrame(render);
}
function nodeColor(d) {
var type = d.type || '-';
return rgbToHex(colorMap[type]);
}
/*
draw the links to a pixi graphics instance
*/
function drawLinks() {
var i;
var desiredAlpha;
var desiredColor;
var link;
var linkGraphic;
var width;
var arrowPos;
for (i = 0; i < links.length; i++) {
link = links[i];
linkGraphic = link.graphic;
if (!linkGraphic) {
linkGraphic = link.graphic = createLinkGraphic();
}
calcLinkQuadControlPoint(link);
width = linkWidth(link.width);
desiredAlpha = (!highlightedNode) ? 0.05 : (link.highlighted) ? 0.4 : 0.02;
desiredColor = (!highlightedNode || !link.desiredColor) ? 0xFFFFFF : link.desiredColor;
linkGraphic.clear()
linkGraphic.lineStyle(width, desiredColor, 1);
linkGraphic.moveTo(link.source.x, link.source.y);
linkGraphic.quadraticCurveTo(link.controlPoint[0], link.controlPoint[1], link.target.x, link.target.y);
linkGraphic.alpha += (desiredAlpha - linkGraphic.alpha) * 0.1;
if (highlightedNode && link.highlighted) {
arrowPos = getPointOnCurve(link.source.x, link.source.y, link.controlPoint[0], link.controlPoint[1], link.target.x, link.target.y, 0.5);
linkGraphic.arrow.alpha = 0.5;
linkGraphic.arrow.position.x = arrowPos[0];
linkGraphic.arrow.position.y = arrowPos[1];
linkGraphic.arrow.rotation = arrowPos[2];
linkGraphic.arrow.scale.x = (width / 10);
linkGraphic.arrow.scale.x = linkGraphic.arrow.scale.x < 0.3 ? linkGraphic.arrow.scale.x : 0.3;
linkGraphic.arrow.scale.y = linkGraphic.arrow.scale.x;
linkGraphic.arrow.tint = desiredColor;
} else {
linkGraphic.arrow.alpha = 0;
}
}
}
/*
function which creates a graphic instance to draw a link to
*/
function createLinkGraphic(d) {
var linkGraphic = new pixi.Graphics();
var arrow = pixi.Sprite.fromImage('assets/images/arrow.png');
linkGraphic.datum = d;
linkGraphic.arrow = arrow;
arrow.alpha = 0;
arrow.anchor.x = 0.5;
arrow.anchor.y = 0.5;
arrow.scale.x = 0.25;
arrow.scale.y = 0.25;
linkContainer.addChild(linkGraphic);
linkContainer.addChild(arrow);
return linkGraphic;
}
/*
draw/position pixi sprites for nodes
*/
function drawNodes() {
var i;
var node;
var nodeSprite;
for (i = 0; i < nodes.length; i++) {
node = nodes[i];
nodeSprite = node.sprite;
if (!nodeSprite) {
nodeSprite = node.sprite = createNode(node);
nodeSprites.push(nodeSprite);
}
nodeSprite.position.x = node.x;
nodeSprite.position.y = node.y;
nodeSprite.alpha += (((node.highlighted || !highlightedNode) ? 1 : 0.2) - nodeSprite.alpha) * 0.1;
if (node.label) {
node.label.position.x = node.x;
node.label.position.y = node.y - 10;
node.label.alpha += (node.label.desiredAlpha - node.label.alpha) * 0.1;
}
}
}
/*
utility function to create a nodes sprite and label
*/
function createNode(d) {
var nodeSprite = new pixi.Sprite(nodeTexture);
var nodeLabel;
var scale = nodeSize(d.transacted) / (nodeTexture.width / 2);
nodeSprite.datum = d;
nodeSprite.anchor.x = 0.5;
nodeSprite.anchor.y = 0.5;
nodeSprite.scale.x = scale;
nodeSprite.scale.y = scale;
nodeSprite.tint = nodeColor(d);
nodeSprite.interactive = true;
nodeSprite.mouseover = nodeMouseover;
nodeSprite.mouseout = nodeMouseout;
nodeSprite.click = nodeSprite.tap = nodeClick;
nodeContainer.addChild(nodeSprite);
if (d.name) {
nodeLabel = new pixi.Text(common.toTitleCase(d.name), {font: '48px sans-serif', align: 'center', fill: 'white', stroke: 'rgba(24, 52, 87, 0.5)', strokeThickness: 10});
nodeLabel.scale.x = 0.3;
nodeLabel.scale.y = 0.3;
nodeLabel.anchor.x = 0.5;
nodeLabel.anchor.y = 1;
nodeLabel.alpha = 0;
nodeLabel.desiredAlpha = 1;
labelContainer.addChild(nodeLabel);
d.label = nodeLabel;
// @TODO some other method for this
setTimeout(function () {
nodeLabel.desiredAlpha = 0;
}, 1000);
}
return nodeSprite;
}
function nodeMouseover() {
if (!highlightedNode) highlightNodesNetwork(this.datum);
}
function nodeMouseout() {
if (!nodeInFocus) unhighlightNode();
}
function unhighlightNode() {
nodeInFocus = null;
highlightedNode = null;
nodes.forEach(function (node) {
node.highlighted = false;
if (node.label) {
node.label.desiredAlpha = 0;
}
});
eventEmitter.emit('nodeUnhighlighted');
}
function nodeClick(e) {
nodeClicked = true;
setTimeout(function () { nodeClicked = false; }, 50);
draw.focusOnNodesNetwork(this.datum);
}
function viewClicked(e) {
if (nodeClicked) return;
unhighlightNode();
resetCameraTimeout = setTimeout(resetCamera.bind(null, true), 200);
}
/*
zoom world camera to given bounding box
*/
function zoomToBox(box) {
var ratioX = (canvasSize[0] / box.width);
var ratioY = (canvasSize[1] / box.height);
var scale = (ratioX < ratioY ? ratioX : ratioY) * 0.8;
scale = (scale < scaleLimit[0]) ? scaleLimit[0] : (scale > scaleLimit[1]) ? scaleLimit[1] : scale;
var xOffset = -(box.left * scale) + ((canvasSize[0] - (box.width * scale)) / 2);
var yOffset = -(box.top * scale) + ((canvasSize[1] - (box.height * scale)) / 2);
animateWorld(xOffset, yOffset, scale);
}
/*
animate world "camera" to a given position and scale
*/
function animateWorld(x, y, scale) {
var xLerp = d3.interpolate(world.position.x, x);
var yLerp = d3.interpolate(world.position.y, y);
var scaleLerp = d3.interpolate(world.scale.x, scale);
animate(function (t) {
updateWorldPosition(xLerp(t), yLerp(t), scaleLerp(t));
updateZoomState();
}, 1000);
};
/*
function used to update world position and scale
*/
function updateWorldPosition(x, y, scale) {
scale = (scale !== undefined) ? scale : world.scale.y;
world.position.x = x;
world.position.y = y;
world.scale.x = scale;
world.scale.y = scale;
eventEmitter.emit('positionChanged', x, y, scale);
}
/*
utility function for creating custom d3 animations
*/
function animate(tick, duration) {
d3.timer(function (t) {
var delta = t / duration;
delta = delta > 1 ? 1 : delta < 0 ? 0 : delta;
tick(ease(delta));
return (duration < t);
});
}
function getNodesNetwork(d) {
var connectedNodes = d ? [d] : [];
var connectedNodes;
var connectedLinks = links.filter(function (ld) {
return ld.source === d || ld.target === d;
});
// get connected nodes
connectedLinks.forEach(function (ld) {
if (connectedNodes.indexOf(ld.target) === -1) {
connectedNodes.push(ld.target);
}
if (connectedNodes.indexOf(ld.source) === -1) {
connectedNodes.push(ld.source);
}
});
return {
links: connectedLinks,
nodes: connectedNodes
};
}
function getNetworkBox(network) {
var charToPixelCoe = 4;
var longestLabelLength = 0;
var labelPadding;
var box = {
top: Infinity,
right: -Infinity,
bottom: -Infinity,
left: Infinity,
center: {x:0, y: 0}
};
network.nodes.forEach(function (d) {
box.left = (d.x < box.left) ? d.x : box.left;
box.right = (d.x > box.right) ? d.x : box.right;
box.top = (d.y < box.top) ? d.y : box.top;
box.bottom = (d.y > box.bottom) ? d.y : box.bottom;
if ((d.name || '').length > longestLabelLength) {
longestLabelLength = d.name.length;
}
});
// edgecase - if only one node exists in selection create box for it
if (network.nodes.length === 1) {
box.top -= 100;
box.right += 100;
box.bottom += 100;
box.left -= 100;
} else {
labelPadding = longestLabelLength * charToPixelCoe;
box.left -= labelPadding;
box.right += labelPadding;
box.top -= 20;
box.bottom += 10;
}
box.width = box.right - box.left;
box.height = box.bottom - box.top;
box.center.x = box.left + (box.width / 2);
box.center.y = box.top + (box.height / 2);
return box;
}
/*
takes in either three numbers for rgb or an rgb string and returns the colour as a HEX number
*/
function rgbToHex(r,g,b) {
var parsedColor;
if (typeof r === 'string') {
parsedColor = d3.rgb(r);
r = parsedColor.r;
g = parsedColor.g;
b = parsedColor.b;
}
r = numToHexString(r);
g = numToHexString(g);
b = numToHexString(b);
return parseInt('0x' + r + g + b, 16);
}
/*
takes in number and returns hex string. eg 255 -> "FF"
*/
function numToHexString(num) {
var hex = num.toString(16);
return hex.length > 1 ? hex : ('0' + hex);
}
function resetCamera(animate) {
var xOffset = ((canvasSize[0] / 2) - (layoutSize[0] / 2));
var yOffset = ((canvasSize[1] / 2) - (layoutSize[1] / 2));
if (!animate) {
updateWorldPosition(xOffset, yOffset);
updateZoomState();
} else {
animateWorld(xOffset, yOffset, 1);
}
world.xOffset = xOffset;
world.yOffset = yOffset;
unhighlightNode();
}
function debugRect(x, y, width, height) {
debugGraphic.clear();
debugGraphic.lineStyle(2, 0xFF0000, 0.5);
debugGraphic.drawCircle(x, y, width, height);
}
function debugPoint(x, y) {
debugGraphic.lineStyle(2, 0xFF0000, 1);
debugGraphic.drawRect(x, y, 5);
}
function updateZoomState() {
zoom
.scale(world.scale.x)
.translate([world.position.x - world.xOffset, world.position.y - world.yOffset]);
}
/*
calculate the bezier control point for the link
*/
function calcLinkQuadControlPoint(d) {
var controlPoint = [];
var dx = d.source.x - d.target.x;
var dy = d.source.y - d.target.y;
var dir = (dx > 0) ? 1 : -1;
var h = Math.sqrt((dx * dx) + (dy * dy));
// find intermediate point
controlPoint[0] = (d.source.x + d.target.x) / 2;
controlPoint[1] = (d.source.y + d.target.y) / 2;
// store point if it doesnt exist
d.controlPoint = d.controlPoint || controlPoint.slice();
// change the direction of the curve (so that links dont overlap)
controlPoint[0] += h * 0.2 * dir;
controlPoint[1] += h * 0.2 * dir;
// ease intermediate point
d.controlPoint[0] += (controlPoint[0] - d.controlPoint[0]) * 0.01;
d.controlPoint[1] += (controlPoint[1] - d.controlPoint[1]) * 0.01;
}
/*
get point along quadratic curve
*/
function getPt(n1, n2, i) {
var diff = n2 - n1;
return n1 + (diff * i);
}
function getPointOnCurve(sx, sy, cx, cy, tx, ty, i) {
var xa = getPt( sx , cx , i );
var ya = getPt( sy , cy , i );
var xb = getPt( cx , tx , i );
var yb = getPt( cy , ty , i );
var x = getPt( xa , xb , i );
var y = getPt( ya , yb , i );
var angle = Math.atan2(ya - yb, xa - xb);
return [x, y, angle];
}
module.exports = draw;
},{"./common":42,"events":2}],45:[function(require,module,exports){
var d3 = (window.d3);
var pixi = (window.PIXI);
var EventEmitter = require('events').EventEmitter;
var eventEmitter = new EventEmitter();
var TIME_MODE = 0;
var FORCE_MODE = 1;
var XMLNS = 'http://www.w3.org/2000/svg';
var nodes = [];
var links = [];
var years = [];
var padding = {top: 0, right: 0, bottom: 20, left: 0};
var size = [1000, 1000];
var radius = (size[0] < size[1] ? size[0] : size[1]) * 0.44;
var layout;
var parent;
var draw = require('./timeForceDirected.draw.js');
var canvas = draw.canvas();
var linkDistance = d3.scale.linear().range([50, 200]);
var dateRadius = d3.scale.linear().range([0, radius]);
var resumeMovementTimeout;
var nodeInFocus = null;
var mode = TIME_MODE;
layout = d3.layout
.force()
.size(size)
.nodes(nodes)
.links(links)
.linkDistance(getLinkDistance)
.linkStrength(0)
.chargeDistance(0)
.charge(0)
.on('tick', update);
draw
.links(links)
.nodes(nodes)
.layoutSize(size)
.dateRadius(dateRadius)
.on('nodeUnhighlighted', resumeMovement)
.on('focussedOnNode', focussedOnNode);
resize();
/*
callback for force directed layout tick
*/
function update(e) {
// prevent force directed from stopping
if (e.alpha !== 0.099 ) {
layout.alpha(0.099);
}
// constrain nodes position based on time
if (mode === TIME_MODE) {
calcNodesDatePos();
constrainNodesByTime(e.alpha);
}
}
// event methods
update.on = eventEmitter.on;
update.emit = eventEmitter.emit;
/*
reference to allow layout to be started externally
*/
update.start = function () {
layout.start();
return update;
};
/*
get/set parent container
*/
update.parent = function (newParent) {
parent = newParent;
parent.node().appendChild(canvas);
return update;
};
/*
get/set size of layout
*/
update.size = function (newSize) {
if (!newSize) { return size; }
size = newSize;
return update;
};
/*
get/set years array
*/
update.years = function (newYears) {
if (!newYears) { return years; }
years = newYears;
return update;
};
/*
calculate scale used. Propogate scale update to drawing layer
*/
update.calcScales = function (allNodes, allLinks) {
updateScales(allNodes, allLinks);
draw.updateScales(allNodes, allLinks);
return update;
};
/*
get/set nodes
*/
update.nodes = function (newNodes) {
var i;
if (newNodes) {
nodes.length = 0;
for (i = 0; i < newNodes.length; i++) {
nodes.push(newNodes[i]);
}
return update;
}
return nodes;
};
/*
get/set links
*/
update.links = function (newLinks) {
var i;
if (newLinks) {
links.length = 0;
for (i = 0; i < newLinks.length; i++) {
links.push(newLinks[i]);
}
return update;
}
return links;
};
/*
highlight a given year ring on the axis
*/
update.highlightYear = function (year) {
draw.currentYear(year);
};
/*
change mode from time to force directed or vice versa
*/
update.changeMode = function () {
if (mode === FORCE_MODE) {
enterTimeMode();
} else {
enterForceDirectedMode();
}
};
/*
focus on a given node datum
*/
update.focusOn = function (d) {
draw.focusOnNodesNetwork(d);
pauseMovement();
};
/*
resize draw layer
*/
update.resize = resize;
function resize() {
draw.resize();
return update;
};
/*
callback for when the initial animation has finished
*/
update.bangFinished = function () {
draw.bangFinished();
d3
.select(window)
.on('mousemove', pauseMovement);
};
/*
emit event when node has been focussed on
*/
function focussedOnNode(d) {
update.emit('focussedOnNode', d);
}
/*
enter force directed mode
*/
function enterForceDirectedMode() {
mode = FORCE_MODE;
var balanceExtent = d3.extent(nodes, function (d) {
return d.balance;
});
balanceExtent[0] += 0.0001;
var chargeScale = d3.scale.log().base(10).domain(balanceExtent).range([0, -200]).clamp(true);
layout
.chargeDistance(3000)
.charge(-50)
.friction(0.7)
.start();
}
/*
enter time mode
*/
function enterTimeMode() {
mode = TIME_MODE;
layout
.chargeDistance(0)
.charge(0)
.friction(0.9)
.linkStrength(0)
.start();
}
/*
pause movement of nodes for a short period of time
*/
function pauseMovement() {
layout.stop();
clearTimeout(resumeMovementTimeout);
if (!draw.nodeHighlighted() && !(d3.event.target.parentNode.classList && d3.event.target.parentNode.classList.contains('node'))) {
resumeMovementTimeout = setTimeout(resumeMovement, 1500);
}
}
/*
resume nodes animation
*/
function resumeMovement() {
layout.resume();
}
/*
work out the nodes desired position based on its appearance date
*/
function calcNodesDatePos() {
var i;
var node;
var cx = size[0] / 2;
var cy = size[1] / 2;
for (i = 0; i < nodes.length; i++) {
node = nodes[i];
if (node.dx === undefined && node.dy === undefined) {
node.radius = dateRadius(node.appeared);;
node.angle = Math.random() * Math.PI * 2;
node.av = 0.0005 - (Math.random() * 0.001);
} else {
node.angle += node.av;
}
node.dx = cx + node.radius * Math.cos(node.angle);
node.dy = cy + node.radius * Math.sin(node.angle);
}
}
/*
constrain the position of nodes based on their calculated position base on appearance date
*/
function constrainNodesByTime(alpha) {
var node;
for (i = 0; i < nodes.length; i++) {
node = nodes[i];
node.x += (node.x - node.dx) * (0.05 * alpha)
node.y += (node.y - node.dy) * (0.05 * alpha)
}
}
/*
update scales used
*/
function updateScales(nodes, links) {
dateRadius.domain(d3.extent(dates));
linkDistance.domain(d3.extent(nodes, function (node) {
return node.connections;
}));
}
/*
accessor for node key
*/
function getNodeKey(d) {
return d.id;
}
/*
accessor for link key
*/
function getLinkKey(d) {
return d.source.id + ':' + d.target.id;
}
/*
get links distance, used in force directed mode (@TODO have a look at this)
*/
function getLinkDistance(d) {
var sourceConnections = linkDistance(d.source.connections);
var targetConnections = linkDistance(d.target.connections);
var numOfConnections = d.source.connections > d.target.connections ? d.source.connections : d.target.connections;
return (sourceConnections + targetConnections) * 1.5;
}
module.exports = update;
},{"./timeForceDirected.draw.js":44,"events":2}]},{},[43]);
/* line 1, ../src/scss/partials/_reset.scss */
* {
box-sizing: border-box;
}
/* line 5, ../src/scss/partials/_reset.scss */
html,
body {
margin: 0;
padding: 0;
height: 100%;
font-family: "Open Sans", sans-serif;
}
/* line 13, ../src/scss/partials/_reset.scss */
body {
font-size: 62.5%;
background-color: #183457;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
}
/* line 1, ../src/scss/partials/_tooltip.scss */
.tooltip {
opacity: 0;
position: absolute;
/*top: 0;
left: 0;*/
width: 280px;
border: 1px solid #11BBDA;
border-radius: 0px 0px 3px 3px;
background: #183457;
padding: 10px;
color: white;
font-size: 16px;
pointer-events: none;
transition: opacity 0.2s ease-in-out;
/*top: initial;*/
bottom: 30px;
right: 30px;
/*left: initial;*/
}
/* line 22, ../src/scss/partials/_tooltip.scss */
.tooltip.tooltip--show {
opacity: 1;
}
/* line 26, ../src/scss/partials/_tooltip.scss */
.tooltip:before, .tooltip:after {
display: block;
position: absolute;
bottom: -19px;
left: calc(50% - 6px);
border: 10px solid #0f0f0f;
border-left-color: transparent;
border-right-color: transparent;
border-bottom-color: transparent;
}
/* line 40, ../src/scss/partials/_tooltip.scss */
.tooltip:before {
border-top-color: #11BBDA;
bottom: -20px;
}
/* line 45, ../src/scss/partials/_tooltip.scss */
.tooltip h2 {
min-height: 28px;
font-size: 18px;
font-weight: normal;
margin: 0 0 5px 0;
padding-bottom: 5px;
text-align: right;
border-bottom: 1px solid #11BBDA;
white-space: pre;
}
/* line 55, ../src/scss/partials/_tooltip.scss */
.tooltip h2:empty:after {
content: "N/A";
}
/* line 60, ../src/scss/partials/_tooltip.scss */
.tooltip table {
border-collapse: collapse;
color: inherit;
font-size: inherit;
width: 100%;
}
/* line 66, ../src/scss/partials/_tooltip.scss */
.tooltip table th {
color: #11BBDA;
font-weight: normal;
}
/* line 70, ../src/scss/partials/_tooltip.scss */
.tooltip table th:after {
content: ": ";
}
/* line 75, ../src/scss/partials/_tooltip.scss */
.tooltip table th {
text-align: left;
}
/* line 79, ../src/scss/partials/_tooltip.scss */
.tooltip table td {
padding: 0 5px;
text-align: right;
}
/* line 2, ../src/scss/partials/_viz.scss */
.viz canvas {
display: block;
margin: 0 auto;
width: auto;
height: 100%;
}
/* line 10, ../src/scss/partials/_viz.scss */
.node {
fill: white;
transition: opacity 0.2s ease-in-out;
cursor: pointer;
}
/* line 15, ../src/scss/partials/_viz.scss */
.highlight-mode .node {
opacity: 0.15;
}
/* line 19, ../src/scss/partials/_viz.scss */
.node.node--highlight {
opacity: 1;
}
/* line 24, ../src/scss/partials/_viz.scss */
.node__label {
font-size: 14;
text-anchor: middle;
fill: white;
opacity: 0;
pointer-events: none;
transition: opacity 0.2s ease-in-out;
}
/* line 32, ../src/scss/partials/_viz.scss */
.node--show-label .node__label, .node--highlight .node__label {
opacity: 1;
}
/* line 38, ../src/scss/partials/_viz.scss */
.link {
stroke: white;
fill: none;
opacity: 0.05;
transition: opacity 0.5s ease-in-out;
}
/* line 44, ../src/scss/partials/_viz.scss */
.highlight-mode .link {
opacity: 0.025;
}
/* line 48, ../src/scss/partials/_viz.scss */
.link.link--highlight {
opacity: 0.5;
}
/* line 52, ../src/scss/partials/_viz.scss */
.link.link--transfer-to, .link.link--transfer-fro {
stroke-dasharray: 10 2;
stroke-dashoffset: 0;
}
/* line 58, ../src/scss/partials/_viz.scss */
.link.link--transfer-to {
stroke: #E42A2A;
animation: transfer-to 5s linear infinite;
-webkit-animation: transfer-to 5s linear infinite;
}
/* line 64, ../src/scss/partials/_viz.scss */
.link.link--transfer-fro {
stroke: #50fa00;
animation: transfer-fro 5s linear infinite;
-webkit-animation: transfer-fro 5s linear infinite;
}
/* line 71, ../src/scss/partials/_viz.scss */
.year {
opacity: 0.3;
transition: opacity 0.2s ease-in-out;
}
/* line 75, ../src/scss/partials/_viz.scss */
.year.year--highlight {
opacity: 1;
}
/* line 79, ../src/scss/partials/_viz.scss */
.axis--hidden .year {
opacity: 0;
}
/* line 83, ../src/scss/partials/_viz.scss */
.year .label {
font-size: 1.8em;
}
/* line 88, ../src/scss/partials/_viz.scss */
.ring {
stroke: #11BBDA;
stroke-width: 2;
stroke-dasharray: 20;
fill: transparent;
}
/* line 95, ../src/scss/partials/_viz.scss */
.label {
fill: #11BBDA;
text-anchor: middle;
}
/* line 100, ../src/scss/partials/_viz.scss */
text {
font-family: "Open Sans", sans-serif;
fill: #888;
}
/* line 107, ../src/scss/partials/_viz.scss */
.size-legend circle {
fill: white;
}
/* line 111, ../src/scss/partials/_viz.scss */
.size-legend line {
stroke: white;
}
/* line 117, ../src/scss/partials/_viz.scss */
.slow-motion .node {
transition: opacity 0.4s ease-in-out;
}
/* line 121, ../src/scss/partials/_viz.scss */
.slow-motion .node__label {
transition: opacity 0.6s ease-in-out;
}
/* line 125, ../src/scss/partials/_viz.scss */
.slow-motion .link {
transition: opacity 1s ease-in-out;
}
/* line 129, ../src/scss/partials/_viz.scss */
.slow-motion .year {
transition: opacity 1s ease-in-out;
}
@-webkit-keyframes transfer-to {
from {
stroke-dashoffset: -100;
}
to {
stroke-dashoffset: 0;
}
}
@-webkit-keyframes transfer-fro {
from {
stroke-dashoffset: 0;
}
to {
stroke-dashoffset: 100;
}
}
/* line 2, ../src/scss/partials/_switch.scss */
.mode-switch {
position: absolute;
left: 80px;
bottom: 80px;
width: 100px;
}
/* line 9, ../src/scss/partials/_switch.scss */
.mode-switch__icon {
position: absolute;
top: 5px;
color: #11253d;
font-size: 40px;
transition: color 0.5s ease-in-out;
}
/* line 16, ../src/scss/partials/_switch.scss */
.mode-switch__icon.mode-switch__icon-first {
left: -50px;
color: #11BBDA;
}
/* line 21, ../src/scss/partials/_switch.scss */
.mode-switch__icon.mode-switch__icon-second {
right: -50px;
}
/* line 26, ../src/scss/partials/_switch.scss */
.mode-switch__checkbox {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 50px;
cursor: pointer;
}
/* line 35, ../src/scss/partials/_switch.scss */
.mode-switch__toggle {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 50px;
border-radius: 25px;
background-color: #11253d;
pointer-events: none;
}
/* line 45, ../src/scss/partials/_switch.scss */
.mode-switch__toggle:after {
position: absolute;
top: 3px;
left: 3px;
content: "";
display: block;
width: 44px;
height: 44px;
border-radius: 22px;
background-color: #11BBDA;
transition: transform 0.5s ease-in-out;
}
/* line 60, ../src/scss/partials/_switch.scss */
.mode-switch__checkbox:checked + div .mode-switch__toggle:after {
transform: translate(50px, 0);
}
/* line 65, ../src/scss/partials/_switch.scss */
.mode-switch__checkbox:checked + div .mode-switch__icon.mode-switch__icon-first {
color: #11253d;
}
/* line 69, ../src/scss/partials/_switch.scss */
.mode-switch__checkbox:checked + div .mode-switch__icon.mode-switch__icon-second {
color: #11BBDA;
}
/* line 1, ../src/scss/partials/_search.scss */
.node-search {
position: absolute;
right: 30px;
bottom: 100px;
width: 280px;
}
/* line 8, ../src/scss/partials/_search.scss */
.node-search__input {
background: #183457;
border: 1px solid #11BBDA;
border-radius: 3px 3px 0px 0px;
color: white;
display: block;
width: 100%;
padding: 10px 35px 10px 35px;
font-size: 1.6em;
}
/* line 19, ../src/scss/partials/_search.scss */
.node-search__cancel,
.node-search__icon {
position: absolute;
top: 11px;
left: 11px;
color: white;
font-size: 16px;
pointer-events: none;
}
/* line 29, ../src/scss/partials/_search.scss */
.node-search__cancel {
left: initial;
top: 7px;
right: 14px;
font-size: 20px;
cursor: pointer;
pointer-events: all;
}
/* line 38, ../src/scss/partials/_search.scss */
.node-search__list {
padding: 0;
margin-top: 0;
list-style: none;
max-height: 300px;
overflow: auto;
-moz-transition: height 0.5s ease-in-out;
-o-transition: height 0.5s ease-in-out;
-webkit-transition: height 0.5s ease-in-out;
transition: height 0.5s ease-in-out;
}
/* line 47, ../src/scss/partials/_search.scss */
.node-search__list-item {
box-sizing: border-box;
padding: 5px;
font-family: "Open Sans", sans-serif;
font-size: 16px;
color: white;
border-top: #11BBDA 1px solid;
height: 35px;
white-space: pre;
overflow: hidden;
cursor: pointer;
background: #11253d;
}
/* line 60, ../src/scss/partials/_search.scss */
.node-search__list-item.node-search__list-item--selected {
background-color: white;
color: black;
}
/* line 65, ../src/scss/partials/_search.scss */
.node-search__list-item:first-child {
border-top: none;
}
/* line 1, ../src/scss/partials/_information.scss */
header {
position: absolute;
top: 25px;
left: 30px;
font-family: "Open Sans", sans-serif;
color: white;
padding: 0;
}
/* line 9, ../src/scss/partials/_information.scss */
header h1 {
display: inline-block;
letter-spacing: 0.3em;
text-transform: uppercase;
margin: 0;
}
footer {
position: fixed;
bottom: 25px;
left: 30px;
font-family: "Open Sans", sans-serif;
color: white;
padding: 0;
}
/* line 17, ../src/scss/partials/_information.scss */
.information-button-toggle {
display: block;
float: left;
width: 40px;
height: 40px;
border: 2px solid white;
border-radius: 50%;
font-size: 25px;
text-align: center;
color: white;
cursor: pointer;
margin: 7px 15px 0 0;
-moz-transition: all 0.2s ease-in-out;
-o-transition: all 0.2s ease-in-out;
-webkit-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
}
/* line 31, ../src/scss/partials/_information.scss */
.information-button-toggle.information-button-toggle--show {
line-height: 1.15em;
font-size: 30px;
font-family: "Open Sans", sans-serif;
}
/* line 38, ../src/scss/partials/_information.scss */
.information-button-toggle.information-button-toggle--hide {
line-height: 1.4em;
display: block;
position: absolute;
top: 25px;
left: 30px;
background-color: #183457;
}
/* line 47, ../src/scss/partials/_information.scss */
.information-button-toggle:hover {
background-color: white;
color: #183457;
}
/* line 53, ../src/scss/partials/_information.scss */
.information {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(24, 52, 87, 0.95);
color: white;
font-family: "Open Sans", sans-serif;
pointer-events: none;
opacity: 0;
z-index: 10;
-moz-transform: scale(1.2);
-ms-transform: scale(1.2);
-webkit-transform: scale(1.2);
transform: scale(1.2);
-moz-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
-webkit-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
}
/* line 68, ../src/scss/partials/_information.scss */
.information__scrollable-box {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow-y: auto;
padding-bottom: 6%;
z-index: -1;
}
/* line 78, ../src/scss/partials/_information.scss */
.information__scrollable-box > h1 {
margin: 0 auto;
max-width: 600px;
padding: 0 20px;
text-align: center;
text-transform: uppercase;
margin-top: 6%;
margin-bottom: 30px;
letter-spacing: 0.3em;
font-weight: initial;
font-size: 3em;
color: white;
}
@media (max-width: 768px) {
/* line 78, ../src/scss/partials/_information.scss */
.information__scrollable-box > h1 {
text-align: left;
padding: 0 70px 0 90px;
font-size: 2em;
}
}
/* line 98, ../src/scss/partials/_information.scss */
.information__scrollable-box > hr {
border-width: 1px;
margin: 30px auto;
max-width: 400px;
border-color: white;
}
/* line 105, ../src/scss/partials/_information.scss */
.information__scrollable-box > p {
text-align: justify;
margin: 20px auto;
max-width: 600px;
padding: 0 30px;
font-size: 1.6em;
color: white;
}
/* line 114, ../src/scss/partials/_information.scss */
.information__scrollable-box > img {
display: block;
margin: 0 auto;
max-width: 100%;
}
/* line 121, ../src/scss/partials/_information.scss */
.information.information--show {
opacity: 1;
pointer-events: all;
-moz-transform: scale(1);
-ms-transform: scale(1);
-webkit-transform: scale(1);
transform: scale(1);
}
/* line 128, ../src/scss/partials/_information.scss */
.color-key {
font-size: 16px;
max-width: 600px;
margin: 0 auto;
}
@media (max-width: 768px) {
/* line 128, ../src/scss/partials/_information.scss */
.color-key {
margin-left: 30px;
}
}
/* line 137, ../src/scss/partials/_information.scss */
.color-key__row {
display: block;
margin-top: -2px;
float: left;
}
/* line 142, ../src/scss/partials/_information.scss */
.color-key__row th {
padding-right: 5px;
vertical-align: top;
}
/* line 147, ../src/scss/partials/_information.scss */
.color-key__row td {
padding-left: 5px;
border-left-width: 2px;
border-left-style: solid;
color: white;
font-family: "Open Sans", sans-serif;
}
/* line 154, ../src/scss/partials/_information.scss */
.color-key__row td p {
font-size: 12px;
margin: 0;
}
@media (max-width: 768px) {
/* line 154, ../src/scss/partials/_information.scss */
.color-key__row td p {
font-size: 10px;
}
}
/* line 165, ../src/scss/partials/_information.scss */
.color-key__row--yellow td {
border-left-color: #FFEBEE;
}
/* line 169, ../src/scss/partials/_information.scss */
.color-key__row--yellow .color-key__node {
background-color: #FFEBEE;
}
/* line 175, ../src/scss/partials/_information.scss */
.color-key__row--green td {
border-left-color: #11bbda;
}
/* line 179, ../src/scss/partials/_information.scss */
.color-key__row--green .color-key__node {
background-color: #11bbda;
}
/* line 185, ../src/scss/partials/_information.scss */
.color-key__row--red td {
border-left-color: #C02842;
}
/* line 189, ../src/scss/partials/_information.scss */
.color-key__row--red .color-key__node {
background-color: #C02842;
}
/* line 195, ../src/scss/partials/_information.scss */
.color-key__row--orange td {
border-left-color: #D7BD2B;
}
/* line 199, ../src/scss/partials/_information.scss */
.color-key__row--orange .color-key__node {
background-color: #D7BD2B;
}
/* line 205, ../src/scss/partials/_information.scss */
.color-key__row--white td {
border-left-color: #838585;
}
/* line 209, ../src/scss/partials/_information.scss */
.color-key__row--white .color-key__node {
background-color: #838585;
}
/* line 215, ../src/scss/partials/_information.scss */
.color-key__node {
margin-top: 3px;
width: 10px;
height: 10px;
border-radius: 50%;
}
/* line 34, ../src/scss/style.scss */
.elliptic-link .elliptic-link__logo {
position: absolute;
top: 30px;
right: 30px;
width: 130px;
}
@media (max-width: 768px) {
/* line 44, ../src/scss/style.scss */
.tooltip,
.elliptic-link,
.node-search {
display: none;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment