diff --git a/BVAM-schema.md b/BVAM-schema.md new file mode 100644 index 0000000..f2e1da9 --- /dev/null +++ b/BVAM-schema.md @@ -0,0 +1,65 @@ +``` +{ + "asset": "A11160532403717707375", + "issuer": [ + { + "name": "", + "email": "", + "phone": "", + "pgpsig": "", + "twitter": "", + "location": [ + { + address: "", + city: "", + state: "", + zip: "", + country: "" + } + ] + } + ], + "token": [ + { + "name": "", + "description": "This is a description", + "expiration": "", + "image": [ + { + url: "", + hash: "", + role: "icon" + }, + { + url: "", + hash: "", + role: "background" + }, + { + url: "", + hash: "", + role: "banner" + }, + ], + "website": [ + { + url: "", + role: "information" + }, + { + url: "", + role: "redeem" + }, + { + url: "", + role: "vend" + }, + { + url: "", + role: "terms" + } + ] + } + ] +} +``` diff --git a/BVAM.md b/BVAM.md new file mode 100644 index 0000000..a5fd429 --- /dev/null +++ b/BVAM.md @@ -0,0 +1,60 @@ +## Blockchain Validated Asset Metadata + +_Note: The terms 'asset' and 'token' can be used interchangeably_ + +Blockchain Validated Asset Metadata (BVAM) is a method which allows [Counterparty](http://counterparty.io) Asset metadata to be stored off-blockchain as JSON data, yet still be verifiable and inalterable by storing the hash of the JSON data in the Counterparty Asset description. + +BVAM must define, at a minimum, the 'asset' element within the JSON data. This conforms to the current Counterparty Enhanced Asset Info [documentation](http://counterparty.io/docs/enhanced_asset_info/). Additional elements can also be customized to meet the needs of each wallet provider. Elements should be listed in alphabetical order to ensure repeatability of the JSON data hash. + +There are two methods for storing BVAM JSON data which are recognized by the Pockets wallet, server method (via [xcp.ninja](http://xcp.ninja)) and p2p method (via [Webtorrent](http://webtorrent.io) protocol) + +Example BVAM json, http://xcp.ninja/hash/TB2rTB5FdLtqYu31wTmKgy54TYeZSqJgr3.json + +Referenced Counterparty Asset, https://counterpartychain.io/asset/A11161111624187815485 + +### Server Method + +1. A third party service(s) hosts a JSON file with Enhanced Asset info (this is inline with the current protocol). For Tokenly Pockets, this is currently limited to [xcp.ninja](http://xcp.ninja) only. + +2. When issuing a new asset in Counterparty, the asset description references the hash of the stringify'd enhanced asset JSON data (instead of referencing the URL of the JSON file in the asset description). To save space, the SHA256 hash is encoded, similar to a bitcoin public key but with the version numbered altered to display a "T" as the first character instead of a "1". + + *Example BVAM hash: TB2rTB5FdLtqYu31wTmKgy54TYeZSqJgr3* + + var jsondata = '{"ownername":"ABC Inc.","ownertwitter":"@abcinc","owneraddress":"1GcFhAQGFZVDAr4jiR2tKwisHcgNUjhGNC","asset":"A11161111624187815485","assetname":"Widget","assetdescription":"Good for one widget.","assetwebsite":"http://abcwidgets.com"}' + + var firstSHA = Crypto.SHA256(jsondata) + + var hash160 = Crypto.RIPEMD160(Crypto.util.hexToBytes(firstSHA)) + var version = 0x41 // "T" + var hashAndBytes = Crypto.util.hexToBytes(hash160) + hashAndBytes.unshift(version) + + var doubleSHA = Crypto.SHA256(Crypto.util.hexToBytes(Crypto.SHA256(hashAndBytes))) + var addressChecksum = doubleSHA.substr(0,8) + + var unencodedAddress = "41" + hash160 + addressChecksum + + var address = Bitcoin.Base58.encode(Crypto.util.hexToBytes(unencodedAddress)) + + http://jsfiddle.net/k0jk49km/ + + +3. The hash is prefixed in the asset description with "TOKNID-" for wallet software to identify that an asset has associated BVAM. This represents a 41-byte asset description. + + *Example Asset Description: TOKNID-TB2rTB5FdLtqYu31wTmKgy54TYeZSqJgr3* + +4. Wallet software can query any third party service and trust that the data is valid without the need to trust the source. This is accomplished by independently verifying the data hash within the wallet using the method in Step 2. + +### p2p Method + +BVAM via Webtorrent can be enabled in the Wallet Settings tab of Tokenly Pockets. Once downloaded, Pockets caches BVAM locally for future reference. + +1. Token issuers seed BVAM JSON files with Enhanced Asset info via Webtorrent. BVAM creation and seeding is currently available at [xcp.ninja](http://xcp.ninja). _Token issuance, BVAM creation and seeding (via Webtorrent Control Panel) is available in the current Repository v0.2.1_ + +2. When issuing a new asset in Counterparty, the asset description references the Webtorrent infohash of the enhanced asset JSON file named BVAMWT.json which contains BVAM unique to that asset. To save space, the Webtorrent infohash is Base58 encoded. + +3. The hash is prefixed in the asset description with "BVAMWT-" for wallet software to identify that an asset has an associated BVAM Webtorrent. + + *Example Asset Description: BVAMWT-4SL14zw8RoTco96bTwtdKwnXGXcZ* + +4. Wallet software can Base58 decode the infohash and query Webtorrent peers to download BVAM. diff --git a/Chrome Extension/funddev-icon.png b/Chrome Extension/funddev-icon.png new file mode 100644 index 0000000..dfe6a46 Binary files /dev/null and b/Chrome Extension/funddev-icon.png differ diff --git a/Chrome Extension/glidera-icon.png b/Chrome Extension/glidera-icon.png new file mode 100644 index 0000000..33936c7 Binary files /dev/null and b/Chrome Extension/glidera-icon.png differ diff --git a/Chrome Extension/glidera.css b/Chrome Extension/glidera.css new file mode 100644 index 0000000..1dda4f8 --- /dev/null +++ b/Chrome Extension/glidera.css @@ -0,0 +1,37 @@ +input.glideraNumber[type=number]::-webkit-inner-spin-button, +input.glideraNumber[type=number]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} + +.glideraloadinggif +{ + background: url('loader.gif') no-repeat left center !important; + background-size: 20px 20px !important; + background-position-x: 7px !important; +} + +.glidera-modal-header { + min-height: 33px; + border-bottom: 1px solid #E5E5E5; + background: no-repeat scroll 0px 0px #475564; + color: #FFF; + font-size: 18px; + padding: 6px 12px 4px 39px; + background-size: 20px auto; + background-position: 10px 7px; +} + +.glidera-modal-body { + position: relative; + padding: 7px; + background: #ebebeb; + font-family: 'Source Sans Pro', sans-serif; +} + +.glidera-modal-footer { + background: no-repeat scroll 0px 0px #ebebeb; + border-top: 1px solid #E5E5E5; + border-radius: 10px; + margin-top: 0px !important; +} \ No newline at end of file diff --git a/Chrome Extension/glidera.png b/Chrome Extension/glidera.png new file mode 100644 index 0000000..a2f7d3a Binary files /dev/null and b/Chrome Extension/glidera.png differ diff --git a/Chrome Extension/glideraRegister.html b/Chrome Extension/glideraRegister.html new file mode 100644 index 0000000..6329485 --- /dev/null +++ b/Chrome Extension/glideraRegister.html @@ -0,0 +1,48 @@ + + + +Glidera Registration + + + + + + + + + + + +
+ + + +
+
+
Close
+
+
+
+ + diff --git a/Chrome Extension/images/bank-icon.png b/Chrome Extension/images/bank-icon.png new file mode 100644 index 0000000..6686e91 Binary files /dev/null and b/Chrome Extension/images/bank-icon.png differ diff --git a/Chrome Extension/images/expand-icon.png b/Chrome Extension/images/expand-icon.png new file mode 100644 index 0000000..cb20e4b Binary files /dev/null and b/Chrome Extension/images/expand-icon.png differ diff --git a/Chrome Extension/images/help-icon.png b/Chrome Extension/images/help-icon.png new file mode 100644 index 0000000..2f06eed Binary files /dev/null and b/Chrome Extension/images/help-icon.png differ diff --git a/Chrome Extension/images/network-icon.png b/Chrome Extension/images/network-icon.png new file mode 100644 index 0000000..25b4989 Binary files /dev/null and b/Chrome Extension/images/network-icon.png differ diff --git a/Chrome Extension/images/ninja-icon.png b/Chrome Extension/images/ninja-icon.png new file mode 100644 index 0000000..3ee3df0 Binary files /dev/null and b/Chrome Extension/images/ninja-icon.png differ diff --git a/Chrome Extension/images/paywithpockets-blue.png b/Chrome Extension/images/paywithpockets-blue.png new file mode 100644 index 0000000..bf2fd8c Binary files /dev/null and b/Chrome Extension/images/paywithpockets-blue.png differ diff --git a/Chrome Extension/images/paywithpockets-green.png b/Chrome Extension/images/paywithpockets-green.png new file mode 100644 index 0000000..4ae6c79 Binary files /dev/null and b/Chrome Extension/images/paywithpockets-green.png differ diff --git a/Chrome Extension/images/paywithpockets-yellow.png b/Chrome Extension/images/paywithpockets-yellow.png new file mode 100644 index 0000000..509a69a Binary files /dev/null and b/Chrome Extension/images/paywithpockets-yellow.png differ diff --git a/Chrome Extension/images/tutorial_splash.png b/Chrome Extension/images/tutorial_splash.png new file mode 100644 index 0000000..08b6f14 Binary files /dev/null and b/Chrome Extension/images/tutorial_splash.png differ diff --git a/Chrome Extension/images/tutorial_splash2.png b/Chrome Extension/images/tutorial_splash2.png new file mode 100644 index 0000000..32e02bd Binary files /dev/null and b/Chrome Extension/images/tutorial_splash2.png differ diff --git a/Chrome Extension/issue-tx-wt.html b/Chrome Extension/issue-tx-wt.html new file mode 100644 index 0000000..993d853 --- /dev/null +++ b/Chrome Extension/issue-tx-wt.html @@ -0,0 +1,64 @@ + + + + + + Review Token Information + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Review Token Information
+
+ + + + \ No newline at end of file diff --git a/Chrome Extension/issue-tx.html b/Chrome Extension/issue-tx.html new file mode 100644 index 0000000..58350c5 --- /dev/null +++ b/Chrome Extension/issue-tx.html @@ -0,0 +1,64 @@ + + + + + + Review Token Information + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Review Token Information
+
+ + + + \ No newline at end of file diff --git a/Chrome Extension/issueticker-wt.js b/Chrome Extension/issueticker-wt.js new file mode 100644 index 0000000..20987a2 --- /dev/null +++ b/Chrome Extension/issueticker-wt.js @@ -0,0 +1,242 @@ +function ajaxissue(url, data, rawtx) { + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + console.log(xhr.responseText); + + $("#content").hide(); + //$("#sendtokenbutton").prop('disabled', true); + + var newTxid = rawtotxid(rawtx); + + console.log(newTxid); + + var hash = $("body").data("hash"); + + //$("#yourtxid").html("View Transaction"); + //$("#issuefromwallet").html("View Transaction"); + $("#issuefromwallet").html("
Token Issued!
Token will appear in wallet after one confirmation
"); + + + xhr.close; + } + } + xhr.open(data ? "POST" : "GET", url, true); + if (data) xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + xhr.send(data); +} + + +function sendBTCissue(hextx) { +// url = 'http://blockchain.info/pushtx'; +// postdata = 'tx=' + hextx; + + url = 'https://chain.so/api/v2/send_tx/BTC'; + postdata = 'tx_hex=' + hextx; + + if (url != null && url != "") + { + ajaxissue(url, postdata, hextx); + } +} + + + +function getExtStorage() +{ + chrome.storage.local.get(["passphrase", "encrypted", "firstopen"], function (data) + { + if ( data.firstopen == false ) { + + if ( data.encrypted == false) { + + $("#pinsplash").hide(); + + $("#issuefromwallet").show(); + $("#content").show(); + + $("body").data('pp', data.passphrase); + + } else if ( data.encrypted == true) { + + + $("#pinsplash").show(); + + $("#issuefromwallet").hide(); + $("#content").hide(); + + } + + } else { + + $("#issuefromwallet").html("
Click on the Tokenly Pockets icon to the right of your browser address bar to set up your wallet.
"); + + } + }); +} + + + +function padprefix(str, max) { + + str = str.toString(); + return str.length < max ? padprefix('0' + str, max) : str; + +} + + +var bitcore = require('bitcore'); +var INSIGHT_SERVER = getInsightServer(); + + +$( document ).ready(function() { + + var thisurl = window.location.href; + var datafromurl = parseURLParams(thisurl); + + getExtStorage(); + + var JsonFormatter = { + stringify: function (cipherParams) { + // create json object with ciphertext + var jsonObj = { + ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64) + }; + + return JSON.stringify(jsonObj); + }, + + parse: function (jsonStr) { + // parse json string + var jsonObj = JSON.parse(jsonStr); + + // extract ciphertext from json object, and create cipher params object + var cipherParams = CryptoJS.lib.CipherParams.create({ + ciphertext: CryptoJS.enc.Base64.parse(jsonObj.ct) + }); + + return cipherParams; + } + }; + + $("form").submit(function (e) { + e.preventDefault(); + //}; + + // $("#pinButton").click(function () { + + var pin = $("#inputPin").val(); + + $("#inputPin").val(""); + + chrome.storage.local.get(["passphrase"], function (data) + { + var decrypted = CryptoJS.AES.decrypt(data.passphrase, pin, { format: JsonFormatter }); + var decrypted_passphrase = decrypted.toString(CryptoJS.enc.Utf8); + + //console.log(decrypted_passphrase.length); + + if (decrypted_passphrase.length > 0) { + + $("#pinsplash").hide(); + $("#issuefromwallet").show(); + $("#content").show(); + //$(".hideEncrypted").show(); + //$("#acceptedbox").hide(); + + $("body").data('pp', decrypted.toString(CryptoJS.enc.Utf8)); + + } + }); + }); + + + + if (datafromurl["address"][0] !== "undefined" && datafromurl["divisible"][0] !== "undefined" && datafromurl["asset"][0] !== "undefined" && datafromurl["description"][0] !== "undefined" && datafromurl["amount"][0] !== "undefined") { + + + var address = datafromurl["address"][0]; + var asset = datafromurl["asset"][0]; + var divisible = datafromurl["divisible"][0]; + var amount = datafromurl["amount"][0]; + var description = datafromurl["description"][0]; + + $("#content").html("
Issuing Address:
"+address+"
Asset ID:
"+asset+"
Divisible:
"+divisible+"
Amount to be Issued:
"+amount+"
Description:
"+description+"
BVAM json:
Loading...
BVAM link:
Webtorrent Magnet link:
"); + + var hash = description.substr(7); + + $("body").data({hash: hash}); + + var filename_base58_decode = Crypto.util.bytesToHex(Bitcoin.Base58.decode(hash)); + + console.log(filename_base58_decode); + + var success = false; + + var bvamlink = "http://xcp.ninja/p2p/infohash/"+filename_base58_decode+"/BVAMWT.json"; + + var magnetUri = 'magnet:?xt=urn:btih:'+filename_base58_decode; + + $.getJSON(bvamlink, function(data) { + + success = true; + + var jsonform = JSON.stringify(data); + + var regex = new RegExp(',', 'g'); + + //replace via regex + jsonform = jsonform.replace(regex, '
'); + + $("#bvamjson").html(jsonform); + $("#bvamlink").html(""+bvamlink+""); + $("#magnetlink").html(""+magnetUri+""); + + //$("#issuefromwallet").show(); + + }); + + setTimeout(function() { + if (!success) + { + // Handle error accordingly + $("#bvamjson").html("Error"); + $("#bvamlink").html("Error"); + } + }, 5000); + + } else { + $("#content").html("Error"); + } + + $("#issuebutton").click(function(){ + + $("#issuebutton").prop('disabled', true); + $("#issuebutton").html('Issuing...'); + + console.log(asset); + + var mnemonic = $('body').data('pp'); + + var add_from = address; // sending address + var assetidval = asset; // receiving address + + var quantity = amount; + + var btc_total = 0.0000547; //total btc to receiving address + var msig_total = 0.000078; //total btc to multisig output (returned to sender) + + var transfee = 0.0001; //bitcoin tx fee + + var msig_outputs = 2; + + if(description.length <= 41) { + + createIssuance(add_from, assetidval, quantity, divisible, description, msig_total, transfee, mnemonic, msig_outputs); + + } + + + }); + +}); \ No newline at end of file diff --git a/Chrome Extension/issueticker.js b/Chrome Extension/issueticker.js new file mode 100644 index 0000000..e427e6c --- /dev/null +++ b/Chrome Extension/issueticker.js @@ -0,0 +1,243 @@ +function ajaxissue(url, data, rawtx) { + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + console.log(xhr.responseText); + + var checksuccess = jQuery.parseJSON(xhr.responseText); + + $("#content").hide(); + //$("#sendtokenbutton").prop('disabled', true); + + var newTxid = rawtotxid(rawtx); + + console.log(newTxid); + + + if (checksuccess.status != "success") { + + $("#issuefromwallet").html("
Token Issuance Failed!
Something is wrong, please try again later.
"); + + } else { + + //$("#yourtxid").html("View Transaction"); + //$("#issuefromwallet").html("View Transaction"); + $("#issuefromwallet").html("
Token Issued!
Token will appear in wallet after one confirmation

"); + } + + xhr.close; + } + } + xhr.open(data ? "POST" : "GET", url, true); + if (data) xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + xhr.send(data); +} + + +function sendBTCissue(hextx) { +// url = 'http://blockchain.info/pushtx'; +// postdata = 'tx=' + hextx; + + url = 'https://chain.so/api/v2/send_tx/BTC'; + postdata = 'tx_hex=' + hextx; + + if (url != null && url != "") + { + ajaxissue(url, postdata, hextx); + } +} + + + +function getExtStorage() +{ + chrome.storage.local.get(["passphrase", "encrypted", "firstopen"], function (data) + { + if ( data.firstopen == false ) { + + if ( data.encrypted == false) { + + $("#pinsplash").hide(); + + $("#issuefromwallet").show(); + $("#content").show(); + + $("body").data('pp', data.passphrase); + + } else if ( data.encrypted == true) { + + + $("#pinsplash").show(); + + $("#issuefromwallet").hide(); + $("#content").hide(); + + } + + } else { + + $("#issuefromwallet").html("
Click on the Tokenly Pockets icon to the right of your browser address bar to set up your wallet.
"); + + } + }); +} + + + +function padprefix(str, max) { + + str = str.toString(); + return str.length < max ? padprefix('0' + str, max) : str; + +} + + +var bitcore = require('bitcore'); +var INSIGHT_SERVER = getInsightServer(); + +$( document ).ready(function() { + + var thisurl = window.location.href; + var datafromurl = parseURLParams(thisurl); + + getExtStorage(); + + var JsonFormatter = { + stringify: function (cipherParams) { + // create json object with ciphertext + var jsonObj = { + ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64) + }; + + return JSON.stringify(jsonObj); + }, + + parse: function (jsonStr) { + // parse json string + var jsonObj = JSON.parse(jsonStr); + + // extract ciphertext from json object, and create cipher params object + var cipherParams = CryptoJS.lib.CipherParams.create({ + ciphertext: CryptoJS.enc.Base64.parse(jsonObj.ct) + }); + + return cipherParams; + } + }; + + $("form").submit(function (e) { + e.preventDefault(); + //}; + + // $("#pinButton").click(function () { + + var pin = $("#inputPin").val(); + + $("#inputPin").val(""); + + chrome.storage.local.get(["passphrase"], function (data) + { + var decrypted = CryptoJS.AES.decrypt(data.passphrase, pin, { format: JsonFormatter }); + var decrypted_passphrase = decrypted.toString(CryptoJS.enc.Utf8); + + //console.log(decrypted_passphrase.length); + + if (decrypted_passphrase.length > 0) { + + $("#pinsplash").hide(); + $("#issuefromwallet").show(); + $("#content").show(); + //$(".hideEncrypted").show(); + //$("#acceptedbox").hide(); + + $("body").data('pp', decrypted.toString(CryptoJS.enc.Utf8)); + + } + }); + }); + + + + if (datafromurl["address"][0] !== "undefined" && datafromurl["divisible"][0] !== "undefined" && datafromurl["asset"][0] !== "undefined" && datafromurl["description"][0] !== "undefined" && datafromurl["amount"][0] !== "undefined") { + + + + var address = datafromurl["address"][0]; + var asset = datafromurl["asset"][0]; + var divisible = datafromurl["divisible"][0]; + var amount = datafromurl["amount"][0]; + var description = datafromurl["description"][0]; + + $("#content").html("
Issuing Address:
"+address+"
Asset ID:
"+asset+"
Divisible:
"+divisible+"
Amount to be Issued:
"+amount+"
Description:
"+description+"
BVAM json:
Loading...
BVAM link:
"); + + var hash = description.substr(7); + + console.log(hash); + + var success = false; + + var bvamlink = "http://xcp.ninja/hash/"+hash+".json"; + + $.getJSON(bvamlink, function(data) { + + success = true; + + var jsonform = JSON.stringify(data); + + var regex = new RegExp(',', 'g'); + + //replace via regex + jsonform = jsonform.replace(regex, '
'); + + $("#bvamjson").html(jsonform); + $("#bvamlink").html(""+bvamlink+""); + + + //$("#issuefromwallet").show(); + + }); + + setTimeout(function() { + if (!success) + { + // Handle error accordingly + $("#bvamjson").html("Error"); + $("#bvamlink").html("Error"); + } + }, 5000); + + } else { + $("#content").html("Error"); + } + + $("#issuebutton").click(function(){ + + $("#issuebutton").prop('disabled', true); + $("#issuebutton").html('Issuing...'); + + console.log(asset); + + var mnemonic = $('body').data('pp'); + + var add_from = address; // sending address + var assetidval = asset; // receiving address + + var quantity = amount; + + var btc_total = 0.0000547; //total btc to receiving address + var msig_total = 0.000078; //total btc to multisig output (returned to sender) + + var transfee = 0.0001; //bitcoin tx fee + + var msig_outputs = 2; + + if(description.length == 41) { + + createIssuance(add_from, assetidval, quantity, divisible, description, msig_total, transfee, mnemonic, msig_outputs); + + } + + + }); + +}); \ No newline at end of file diff --git a/Chrome Extension/js/apiserver.js b/Chrome Extension/js/apiserver.js new file mode 100644 index 0000000..f84f92a --- /dev/null +++ b/Chrome Extension/js/apiserver.js @@ -0,0 +1,87 @@ +function getInsightServer() { + var INSIGHT_SERVER = "insight.bitpay.com"; + + console.log("Insight Server: "+INSIGHT_SERVER); + + return INSIGHT_SERVER; + +// $.getJSON( "https://"+INSIGHT_SERVER+"/api/peer", function( data ) { +// +// //console.log(data.connected); +// +// if (data.connected != true) { +// +// INSIGHT_SERVER = "chain.localbitcoins.com"; +// +// $.getJSON( "https://"+INSIGHT_SERVER+"/api/peer", function( data ) { +// +// if (data.connected != true) { +// +// INSIGHT_SERVER = "search.bitaccess.ca"; +// console.log("Active Insight Server: "+INSIGHT_SERVER); +// +// return INSIGHT_SERVER; +// +// } else { +// +// console.log("Active Insight Server: "+INSIGHT_SERVER); +// +// return INSIGHT_SERVER; +// +// } +// +// }); +// +// } else { +// +// console.log("Active Insight Server: "+INSIGHT_SERVER); +// +// return INSIGHT_SERVER; +// +// } +// +// }); +} + +//function getInsightServerCallback(callback) { +// var INSIGHT_SERVER = "insight.bitpay.com"; +// +// $.getJSON( "https://"+INSIGHT_SERVER+"/api/peer", function( data ) { +// +// console.log(data.connected); +// +// if (data.connected != true) { +// +// INSIGHT_SERVER = "chain.localbitcoins.com"; +// +// $.getJSON( "https://"+INSIGHT_SERVER+"/api/peer", function( data ) { +// +// if (data.connected != true) { +// +// INSIGHT_SERVER = "search.bitaccess.ca"; +// console.log("Insight Server: "+INSIGHT_SERVER); +// +// callback(INSIGHT_SERVER); +// +// } else { +// +// console.log("Insight Server: "+INSIGHT_SERVER); +// +// callback(INSIGHT_SERVER); +// +// } +// +// }); +// +// } else { +// +// console.log("Insight Server: "+INSIGHT_SERVER); +// +// callback(INSIGHT_SERVER); +// +// } +// +// }); +//} +// +// diff --git a/Chrome Extension/js/bitcoinjs-min.js b/Chrome Extension/js/bitcoinjs-min.js index 5124d8d..015117b 100644 --- a/Chrome Extension/js/bitcoinjs-min.js +++ b/Chrome Extension/js/bitcoinjs-min.js @@ -22,7 +22,8 @@ Bitcoin.Address=function(e){"string"==typeof e&&(e=Bitcoin.Address.decodeString( function integerToBytes(e,t){var n=e.toByteArrayUnsigned();if(tn.length)n.unshift(0);return n}function dmp(e){return e instanceof BigInteger||(e=e.toBigInteger()),Crypto.util.bytesToHex(e.toByteArrayUnsigned())}ECFieldElementFp.prototype.getByteLength=function(){return Math.floor((this.toBigInteger().bitLength()+7)/8)},ECPointFp.prototype.getEncoded=function(e){var t=this.getX().toBigInteger(),n=this.getY().toBigInteger(),r=integerToBytes(t,32);return e?n.isEven()?r.unshift(2):r.unshift(3):(r.unshift(4),r=r.concat(integerToBytes(n,32))),r},ECPointFp.decodeFrom=function(e,t){var n=t[0],r=t.length-1,i=t.slice(1,1+r/2),s=t.slice(1+r/2,1+r);i.unshift(0),s.unshift(0);var o=new BigInteger(i),u=new BigInteger(s);return new ECPointFp(e,e.fromBigInteger(o),e.fromBigInteger(u))},ECPointFp.prototype.add2D=function(e){if(this.isInfinity())return e;if(e.isInfinity())return this;if(this.x.equals(e.x))return this.y.equals(e.y)?this.twice():this.curve.getInfinity();var t=e.x.subtract(this.x),n=e.y.subtract(this.y),r=n.divide(t),i=r.square().subtract(this.x).subtract(e.x),s=r.multiply(this.x.subtract(i)).subtract(this.y);return new ECPointFp(this.curve,i,s)},ECPointFp.prototype.twice2D=function(){if(this.isInfinity())return this;if(this.y.toBigInteger().signum()==0)return this.curve.getInfinity();var e=this.curve.fromBigInteger(BigInteger.valueOf(2)),t=this.curve.fromBigInteger(BigInteger.valueOf(3)),n=this.x.square().multiply(t).add(this.curve.a).divide(this.y.multiply(e)),r=n.square().subtract(this.x.multiply(e)),i=n.multiply(this.x.subtract(r)).subtract(this.y);return new ECPointFp(this.curve,r,i)},ECPointFp.prototype.multiply2D=function(e){if(this.isInfinity())return this;if(e.signum()==0)return this.curve.getInfinity();var t=e,n=t.multiply(new BigInteger("3")),r=this.negate(),i=this,s;for(s=n.bitLength()-2;s>0;--s){i=i.twice();var o=n.testBit(s),u=t.testBit(s);o!=u&&(i=i.add2D(o?this:r))}return i},ECPointFp.prototype.isOnCurve=function(){var e=this.getX().toBigInteger(),t=this.getY().toBigInteger(),n=this.curve.getA().toBigInteger(),r=this.curve.getB().toBigInteger(),i=this.curve.getQ(),s=t.multiply(t).mod(i),o=e.multiply(e).multiply(e).add(n.multiply(e)).add(r).mod(i);return s.equals(o)},ECPointFp.prototype.toString=function(){return"("+this.getX().toBigInteger().toString()+","+this.getY().toBigInteger().toString()+")"},ECPointFp.prototype.validate=function(){var e=this.curve.getQ();if(this.isInfinity())throw new Error("Point is at infinity.");var t=this.getX().toBigInteger(),n=this.getY().toBigInteger();if(t.compareTo(BigInteger.ONE)<0||t.compareTo(e.subtract(BigInteger.ONE))>0)throw new Error("x coordinate out of bounds");if(n.compareTo(BigInteger.ONE)<0||n.compareTo(e.subtract(BigInteger.ONE))>0)throw new Error("y coordinate out of bounds");if(!this.isOnCurve())throw new Error("Point is not on the curve.");if(this.multiply(e).isInfinity())throw new Error("Point is not a scalar multiple of G.");return!0},Bitcoin.ECDSA=function(){function r(e,t,n,r){var i=Math.max(t.bitLength(),r.bitLength()),s=e.add2D(n),o=e.curve.getInfinity();for(var u=i-1;u>=0;--u)o=o.twice2D(),o.z=BigInteger.ONE,t.testBit(u)?r.testBit(u)?o=o.add2D(s):o=o.add2D(e):r.testBit(u)&&(o=o.add2D(n));return o}var e=getSECCurveByName("secp256k1"),t=new SecureRandom,n=null,i={getBigRandom:function(e){return(new BigInteger(e.bitLength(),t)).mod(e.subtract(BigInteger.ONE)).add(BigInteger.ONE)},sign:function(t,n){var r=n,s=e.getN(),o=BigInteger.fromByteArrayUnsigned(t);do var u=i.getBigRandom(s),a=e.getG(),f=a.multiply(u),l=f.getX().toBigInteger().mod(s);while(l.compareTo(BigInteger.ZERO)<=0);var c=u.modInverse(s).multiply(o.add(r.multiply(l))).mod(s);return i.serializeSig(l,c)},verify:function(t,n,r){var s,o;if(Bitcoin.Util.isArray(n)){var u=i.parseSig(n);s=u.r,o=u.s}else{if("object"!=typeof n||!n.r||!n.s)throw"Invalid value for signature";s=n.r,o=n.s}var a;if(r instanceof ECPointFp)a=r;else{if(!Bitcoin.Util.isArray(r))throw"Invalid format for pubkey value, must be byte array or ECPointFp";a=ECPointFp.decodeFrom(e.getCurve(),r)}var f=BigInteger.fromByteArrayUnsigned(t);return i.verifyRaw(f,s,o,a)},verifyRaw:function(t,n,r,i){var s=e.getN(),o=e.getG();if(n.compareTo(BigInteger.ONE)<0||n.compareTo(s)>=0)return!1;if(r.compareTo(BigInteger.ONE)<0||r.compareTo(s)>=0)return!1;var u=r.modInverse(s),a=t.multiply(u).mod(s),f=n.multiply(u).mod(s),l=o.multiply(a).add(i.multiply(f)),c=l.getX().toBigInteger().mod(s);return c.equals(n)},serializeSig:function(e,t){var n=e.toByteArraySigned(),r=t.toByteArraySigned(),i=[];return i.push(2),i.push(n.length),i=i.concat(n),i.push(2),i.push(r.length),i=i.concat(r),i.unshift(i.length),i.unshift(48),i},parseSig:function(e){var t;if(e[0]!=48)throw new Error("Signature not a valid DERSequence");t=2;if(e[t]!=2)throw new Error("First element in signature must be a DERInteger");var n=e.slice(t+2,t+2+e[t+1]);t+=2+e[t+1];if(e[t]!=2)throw new Error("Second element in signature must be a DERInteger");var r=e.slice(t+2,t+2+e[t+1]);t+=2+e[t+1];var i=BigInteger.fromByteArrayUnsigned(n),s=BigInteger.fromByteArrayUnsigned(r);return{r:i,s:s}},parseSigCompact:function(t){if(t.length!==65)throw"Signature has the wrong length";var n=t[0]-27;if(n<0||n>7)throw"Invalid signature type";var r=e.getN(),i=BigInteger.fromByteArrayUnsigned(t.slice(1,33)).mod(r),s=BigInteger.fromByteArrayUnsigned(t.slice(33,65)).mod(r);return{r:i,s:s,i:n}},recoverPubKey:function(t,s,o,u){u&=3;var a=u&1,f=u>>1,l=e.getN(),c=e.getG(),h=e.getCurve(),p=h.getQ(),d=h.getA().toBigInteger(),v=h.getB().toBigInteger();n||(n=p.add(BigInteger.ONE).divide(BigInteger.valueOf(4)));var m=f?t.add(l):t,g=m.multiply(m).multiply(m).add(d.multiply(m)).add(v).mod(p),y=g.modPow(n,p),b=y.isEven()?u%2:(u+1)%2,w=(y.isEven()?!a:a)?y:p.subtract(y),E=new ECPointFp(h,h.fromBigInteger(m),h.fromBigInteger(w));E.validate();var S=BigInteger.fromByteArrayUnsigned(o),x=BigInteger.ZERO.subtract(S).mod(l),T=t.modInverse(l),N=r(E,s,c,x).multiply(T);console.log("G.x: ",Crypto.util.bytesToHex(c.x.toBigInteger().toByteArrayUnsigned())),console.log("G.y: ",Crypto.util.bytesToHex(c.y.toBigInteger().toByteArrayUnsigned())),console.log("s: ",Crypto.util.bytesToHex(T.toByteArrayUnsigned())),console.log("Q.x: ",Crypto.util.bytesToHex(N.x.toBigInteger().toByteArrayUnsigned())),console.log("Q.y: ",Crypto.util.bytesToHex(N.y.toBigInteger().toByteArrayUnsigned())),N.validate();if(!i.verifyRaw(S,t,s,N))throw"Pubkey recovery unsuccessful";var C=new Bitcoin.ECKey;return C.pub=N,C},calcPubkeyRecoveryParam:function(e,t,n,r){for(var i=0;i<4;i++)try{var s=Bitcoin.ECDSA.recoverPubKey(t,n,r,i);if(s.getBitcoinAddress().toString()==e)return i}catch(o){}throw"Unable to find valid recovery factor"}};return i}(); Bitcoin.ECKey=function(){var e=Bitcoin.ECDSA,t=getSECCurveByName("secp256k1"),n=new SecureRandom,r=function(n){if(!n){var i=t.getN();this.priv=e.getBigRandom(i)}else n instanceof BigInteger?this.priv=n:Bitcoin.Util.isArray(n)?this.priv=BigInteger.fromByteArrayUnsigned(n):"string"==typeof n&&(n.length==51&&n[0]=="5"?this.priv=BigInteger.fromByteArrayUnsigned(r.decodeString(n)):this.priv=BigInteger.fromByteArrayUnsigned(Crypto.util.base64ToBytes(n)));this.compressed=!!r.compressByDefault};return r.compressByDefault=!1,r.prototype.setCompressed=function(e){this.compressed=!!e},r.prototype.getPub=function(){return this.getPubPoint().getEncoded(this.compressed)},r.prototype.getPubPoint=function(){return this.pub||(this.pub=t.getG().multiply(this.priv)),this.pub},r.prototype.getPubKeyHash=function(){return this.pubKeyHash?this.pubKeyHash:this.pubKeyHash=Bitcoin.Util.sha256ripe160(this.getPub())},r.prototype.getBitcoinAddress=function(){var e=this.getPubKeyHash(),t=new Bitcoin.Address(e);return t},r.prototype.getExportedPrivateKey=function(){var e=this.priv.toByteArrayUnsigned();while(e.length<32)e.unshift(0);e.unshift(128);var t=Crypto.SHA256(Crypto.SHA256(e,{asBytes:!0}),{asBytes:!0}),n=e.concat(t.slice(0,4));return Bitcoin.Base58.encode(n)},r.prototype.setPub=function(e){this.pub=ECPointFp.decodeFrom(t.getCurve(),e)},r.prototype.toString=function(e){return e==="base64"?Crypto.util.bytesToBase64(this.priv.toByteArrayUnsigned()):Crypto.util.bytesToHex(this.priv.toByteArrayUnsigned())},r.prototype.sign=function(t){return e.sign(t,this.priv)},r.prototype.verify=function(t,n){return e.verify(t,n,this.getPub())},r.decodeString=function(e){var t=Bitcoin.Base58.decode(e),n=t.slice(0,33),r=Crypto.SHA256(Crypto.SHA256(n,{asBytes:!0}),{asBytes:!0});if(r[0]!=t[33]||r[1]!=t[34]||r[2]!=t[35]||r[3]!=t[36])throw"Checksum validation failed!";var i=n.shift();if(i!=128)throw"Version "+i+" not supported!";return n},r}(); (function(){var e=Bitcoin.Opcode=function(e){this.code=e};e.prototype.toString=function(){return e.reverseMap[this.code]},e.map={OP_0:0,OP_FALSE:0,OP_PUSHDATA1:76,OP_PUSHDATA2:77,OP_PUSHDATA4:78,OP_1NEGATE:79,OP_RESERVED:80,OP_1:81,OP_TRUE:81,OP_2:82,OP_3:83,OP_4:84,OP_5:85,OP_6:86,OP_7:87,OP_8:88,OP_9:89,OP_10:90,OP_11:91,OP_12:92,OP_13:93,OP_14:94,OP_15:95,OP_16:96,OP_NOP:97,OP_VER:98,OP_IF:99,OP_NOTIF:100,OP_VERIF:101,OP_VERNOTIF:102,OP_ELSE:103,OP_ENDIF:104,OP_VERIFY:105,OP_RETURN:106,OP_TOALTSTACK:107,OP_FROMALTSTACK:108,OP_2DROP:109,OP_2DUP:110,OP_3DUP:111,OP_2OVER:112,OP_2ROT:113,OP_2SWAP:114,OP_IFDUP:115,OP_DEPTH:116,OP_DROP:117,OP_DUP:118,OP_NIP:119,OP_OVER:120,OP_PICK:121,OP_ROLL:122,OP_ROT:123,OP_SWAP:124,OP_TUCK:125,OP_CAT:126,OP_SUBSTR:127,OP_LEFT:128,OP_RIGHT:129,OP_SIZE:130,OP_INVERT:131,OP_AND:132,OP_OR:133,OP_XOR:134,OP_EQUAL:135,OP_EQUALVERIFY:136,OP_RESERVED1:137,OP_RESERVED2:138,OP_1ADD:139,OP_1SUB:140,OP_2MUL:141,OP_2DIV:142,OP_NEGATE:143,OP_ABS:144,OP_NOT:145,OP_0NOTEQUAL:146,OP_ADD:147,OP_SUB:148,OP_MUL:149,OP_DIV:150,OP_MOD:151,OP_LSHIFT:152,OP_RSHIFT:153,OP_BOOLAND:154,OP_BOOLOR:155,OP_NUMEQUAL:156,OP_NUMEQUALVERIFY:157,OP_NUMNOTEQUAL:158,OP_LESSTHAN:159,OP_GREATERTHAN:160,OP_LESSTHANOREQUAL:161,OP_GREATERTHANOREQUAL:162,OP_MIN:163,OP_MAX:164,OP_WITHIN:165,OP_RIPEMD160:166,OP_SHA1:167,OP_SHA256:168,OP_HASH160:169,OP_HASH256:170,OP_CODESEPARATOR:171,OP_CHECKSIG:172,OP_CHECKSIGVERIFY:173,OP_CHECKMULTISIG:174,OP_CHECKMULTISIGVERIFY:175,OP_NOP1:176,OP_NOP2:177,OP_NOP3:178,OP_NOP4:179,OP_NOP5:180,OP_NOP6:181,OP_NOP7:182,OP_NOP8:183,OP_NOP9:184,OP_NOP10:185,OP_PUBKEYHASH:253,OP_PUBKEY:254,OP_INVALIDOPCODE:255},e.reverseMap=[];for(var t in e.map)e.reverseMap[e.map[t]]=t})(); -(function(){var Opcode=Bitcoin.Opcode;for(var i in Opcode.map)eval("var "+i+" = "+Opcode.map[i]+";");var Script=Bitcoin.Script=function(e){if(!e)this.buffer=[];else if("string"==typeof e)this.buffer=Crypto.util.base64ToBytes(e);else if(Bitcoin.Util.isArray(e))this.buffer=e;else{if(!(e instanceof Script))throw new Error("Invalid script");this.buffer=e.buffer}this.parse()};Script.prototype.parse=function(){function n(n){e.chunks.push(e.buffer.slice(t,t+n)),t+=n}var e=this;this.chunks=[];var t=0;while(t=240&&(r=r<<8|this.buffer[t++]);var i;r>0&&r>>8&255)):(this.buffer.push(OP_PUSHDATA4),this.buffer.push(e.length&255),this.buffer.push(e.length>>>8&255),this.buffer.push(e.length>>>16&255),this.buffer.push(e.length>>>24&255)),this.buffer=this.buffer.concat(e),this.chunks.push(e)},Script.createOutputScript=function(e){var t=new Script;return t.writeOp(OP_DUP),t.writeOp(OP_HASH160),t.writeBytes(e.hash),t.writeOp(OP_EQUALVERIFY),t.writeOp(OP_CHECKSIG),t},Script.prototype.extractAddresses=function(e){switch(this.getOutType()){case"Address":return e.push(new Address(this.chunks[2])),1;case"Pubkey":return e.push(new Address(Util.sha256ripe160(this.chunks[0]))),1;case"Multisig":for(var t=1;t=240&&(r=r<<8|this.buffer[t++]);var i;r>0&&r>>8&255)):(this.buffer.push(OP_PUSHDATA4),this.buffer.push(e.length&255),this.buffer.push(e.length>>>8&255),this.buffer.push(e.length>>>16&255),this.buffer.push(e.length>>>24&255)),this.buffer=this.buffer.concat(e),this.chunks.push(e)},Script.createOutputScript=function(e){var t=new Script;return t.writeOp(OP_DUP),t.writeOp(OP_HASH160),t.writeBytes(e.hash),t.writeOp(OP_EQUALVERIFY),t.writeOp(OP_CHECKSIG),t},Script.prototype.extractAddresses=function(e){switch(this.getOutType()){case"Address":return e.push(new Address(this.chunks[2])),1;case"Pubkey":return e.push(new Address(Util.sha256ripe160(this.chunks[0]))),1;case"Multisig":for(var t=1;t=0;o--){var u=this.outs[o],a=u.script.simpleOutPubKeyHash();e.hasHash(a)?i=a:n=!1,r=a}for(var o=this.ins.length-1;o>=0;o--){var f=this.ins[o];s=f.script.simpleInPubKeyHash();if(!e.hasHash(s)){t=!1;break}}var l=this.calcImpact(e),c={};return c.impact=l,l.sign>0&&l.value.compareTo(BigInteger.ZERO)>0?(c.type="recv",c.addr=new Bitcoin.Address(i)):t&&n?c.type="self":t?(c.type="sent",c.addr=new Bitcoin.Address(r)):c.type="other",c}return null},t.prototype.getDescription=function(e){var t=this.analyze(e);if(!t)return"";switch(t.type){case"recv":return"Received with "+t.addr;case"sent":return"Payment to "+t.addr;case"self":return"Payment to yourself";case"other":default:return""}},t.prototype.getTotalOutValue=function(){var e=BigInteger.ZERO;for(var t=0;t=0?{sign:1,value:t.subtract(s)}:{sign:-1,value:s.subtract(t)}}return BigInteger.ZERO};var u=Bitcoin.TransactionIn=function(t){this.outpoint=t.outpoint,t.script instanceof e?this.script=t.script:this.script=new e(t.script),this.sequence=t.sequence};u.prototype.clone=function(){var e=new u({outpoint:{hash:this.outpoint.hash,index:this.outpoint.index},script:this.script.clone(),sequence:this.sequence});return e};var a=Bitcoin.TransactionOut=function(t){t.script instanceof e?this.script=t.script:this.script=new e(t.script);if(Bitcoin.Util.isArray(t.value))this.value=t.value;else if("string"==typeof t.value){var n=(new BigInteger(t.value,10)).toString(16);while(n.length<16)n="0"+n;this.value=Crypto.util.hexToBytes(n)}};a.prototype.clone=function(){var e=new a({script:this.script.clone(),value:this.value.slice(0)});return e}})(); Bitcoin.Wallet=function(){var e=Bitcoin.Script,t=Bitcoin.TransactionIn,n=Bitcoin.TransactionOut,r=function(){var e=[];this.addressHashes=[],this.txIndex={},this.unspentOuts=[],this.addressPointer=0,this.addKey=function(t,n){t instanceof Bitcoin.ECKey||(t=new Bitcoin.ECKey(t)),e.push(t),n&&("string"==typeof n&&(n=Crypto.util.base64ToBytes(n)),t.setPub(n)),this.addressHashes.push(t.getBitcoinAddress().getHashBase64())},this.addKeys=function(e,t){"string"==typeof e&&(e=e.split(",")),"string"==typeof t&&(t=t.split(","));var n;if(Array.isArray(t)&&e.length==t.length)for(n=0;n=0)break}if(o.compareTo(s)<0)throw new Error("Insufficient funds.");var a=o.subtract(s),f=new Bitcoin.Transaction;for(u=0;u0&&f.addOutput(this.getNextAddress(),a);var l=1;for(u=0;u= 2) { + newurl += "?" + urlAndQs[1]; +} +chrome.extension.sendMessage({redirect: newurl}); +chrome.extension.onMessage.addListener(function(request, sender) { + + if(sender.tab != undefined){ + chrome.tabs.update(sender.tab.id, {url: request.redirect}); + } + + if(request.bvamwt == "create_seed_tab") { + var seedurl = chrome.extension.getURL('seedbvam.html'); + chrome.tabs.create({url : seedurl}, function(tab) {}); + } + +}); \ No newline at end of file diff --git a/Chrome Extension/js/detect.js b/Chrome Extension/js/detect.js new file mode 100644 index 0000000..dff96c7 --- /dev/null +++ b/Chrome Extension/js/detect.js @@ -0,0 +1,488 @@ + + + + +chrome.storage.local.get(function(data) { + + data["chainso_detect"]; + + if(data["chainso_detect"] == 'yes') { + + $('kbd').each(function(i, obj) { + + if (i == 0) { + + console.log($(this).text()); + + var txid = $(this).text(); + + get_xcp_encoded_opreturn(txid, function(utxo_hash, data_chunk, sendaddress, confirmation_text){ + + console.log(utxo_hash); + + //$("#arc").html(data_chunk); + // check for 'CNTRPRTY' + var counterparty_prefix = data_chunk.substring(2, 18); + if (counterparty_prefix != '434e545250525459') { return; } + + // check for a send (action type 00000000) + var action_type = data_chunk.substring(18, 26); + if (action_type != '00000000') { return; } + + var asset = data_chunk.substring(26, 42); + var amount = data_chunk.substring(42, 58); + + //var asset_dec = parseInt(asset, 16); + var asset_dec = hexToDec(asset); + + console.log(asset_dec); + var amount_dec = hexToDec(amount) / 100000000; + console.log("asset id: "+asset_dec); + + var numeric_lowerlimit = Math.pow(26, 12) + 1; + + console.log(numeric_lowerlimit); + + if (asset_dec > numeric_lowerlimit) { + + var assetnamed = "A"+asset_dec; + + } else { + + var assetnamed = assetname(asset_dec); + + } + + console.log(assetnamed); + + var source_html = "https://counterpartychain.io/api/asset/"+assetnamed; + + loadBvam(function(bvamdata, hashname, hashhash){ + + $.getJSON( source_html, function( data ) { + + if (data.divisible == 0) { amount_dec = Math.round(amount_dec * 100000000); } + + if (assetnamed.substr(0,1) == "A") { + + var checkprefix = (data.description).substr(0,6); + + var hash = (data.description).substr(7); + + console.log(hash); + + var assetnamedisplay = assetnamed; + + console.log(bvamdata); + + if(checkprefix == "TOKNID" || checkprefix == "BVAMWT") { + + console.log(hashhash); + + if (typeof(hashname[assetnamed]) !== 'undefined') { + + if(hashhash[assetnamed] == hash) { + +// for (var i = 0; i < bvamdata.length; i++) { +// +// if (bvamdata[i]["hash"] == hash) { +// +// var storeddata = bvamdata[i]["data"]; +// +// console.log(storeddata); + +// if(storeddata["asset"] == assetnamed) { + +// assetnamedisplay = storeddata["assetname"] + "
" + assetnamed + "
"; + +// } else { +// +// assetnamedisplay = assetnamed; +// +// } + +// } +// +// } + + assetnamedisplay = hashname[assetnamed] + "
" + assetnamed + "
"; + + $( "
Token Transaction Detected!
"+confirmation_text+"

Token:

"+assetnamedisplay+"

Amount Sent:

"+amount_dec+"

Sent to: "+sendaddress+"

Counterparty Data parsed by Tokenly Pockets
" ).insertAfter( ".row:first" ); + + } + + } else { + + assetnamedisplay = assetnamed; + +// $.getJSON("http://xcp.ninja/hash/"+hash+".json", function(data) { +// +// var isvaliddata = validateEnhancedAssetJSON(data); +// +// console.log("Calculated Remote JSON Hash: "+isvaliddata); +// console.log("Stored Remote JSON Hash: "+hash); +// +// if(isvaliddata == hash && data.asset == assetnamed) { +// +// var time_date = new Date(); +// var time_unix = time_date.getTime(); +// +// var newbvam = {hash: hash, data: data, added: time_unix}; +// +// addBvam(allbvamdata); +// console.log(allbvamdata); +// +// assetnamedisplay = data.assetname + "
" + assetnamed + "
"; + + $( "
Token Transaction Detected!
"+confirmation_text+"

Token:

"+assetnamedisplay+"

Amount Sent:

"+amount_dec+"

Sent to: "+sendaddress+"

Counterparty Data parsed by Tokenly Pockets
" ).insertAfter( ".row:first" ); + +// } +// }) + + } + + } else { + + $( "
Token Transaction Detected!
"+confirmation_text+"

Token:

"+assetnamedisplay+"

Amount Sent:

"+amount_dec+"

Sent to: "+sendaddress+"

Counterparty Data parsed by Tokenly Pockets
" ).insertAfter( ".row:first" ); + + } + + + } else { + + $( "
Token Transaction Detected!
"+confirmation_text+"

Token:

"+assetnamed+"

Amount Sent:

"+amount_dec+"

Sent to: "+sendaddress+"

Counterparty Data parsed by Tokenly Pockets
" ).insertAfter( ".row:first" ); + + } + }); + }); + }); + + + + } + }); + + } +}); + + +function get_xcp_encoded_opreturn(tx_id, callback) { + + + var source_html = "https://chain.so/api/v2/get_tx/BTC/"+tx_id; + //var source_html = "https://blockchain.info/rawtx/"+tx_id+"?format=json&cors=true"; + + var target_tx = new Array(); + + $.getJSON( source_html, function( target_tx ) { + + var tx_index = target_tx.data.inputs[0].from_output.txid; + //var tx_index = target_tx.inputs[0].prev_out.tx_index; + + //console.log(tx_index); + + var target_address = target_tx.data.outputs[0].address; + + var confirmations = target_tx.data.confirmations; + + if (confirmations == 0) { + var confirmation_text = "Unconfirmed"; + } else if (confirmations == 1) { + var confirmation_text = "1 confirmation"; + } else { + var confirmation_text = confirmations + " confirmations"; + } + + $.each(target_tx.data.outputs, function(i, item) { + + + + if ((target_tx.data.outputs[i].address == "nonstandard")){ + var target_script = target_tx.data.outputs[i].script; + var xcp_pubkey_data = target_script.substring(10); + + + + var source_html_tx_index = "https://chain.so/api/v2/get_tx/BTC/"+tx_index; + + $.getJSON( source_html_tx_index, xcp_pubkey_data, function( data ) { + + //console.log(data.hash); + //console.log(xcp_pubkey_data); + + var xcp_decoded = xcp_rc4(data.data.txid, xcp_pubkey_data); + + xcp_decoded = "1c"+xcp_decoded; //add first byte to simulate OP_CHECKMULTISIG + + callback(data.data.txid, xcp_decoded, target_address, confirmation_text); + + }); + + } + + + }); + + }); + +} + +function rc4(key, str) { + + //https://gist.github.com/farhadi/2185197 + + var s = [], j = 0, x, res = ''; + for (var i = 0; i < 256; i++) { + s[i] = i; + } + for (i = 0; i < 256; i++) { + j = (j + s[i] + key.charCodeAt(i % key.length)) % 256; + x = s[i]; + s[i] = s[j]; + s[j] = x; + } + i = 0; + j = 0; + for (var y = 0; y < str.length; y++) { + i = (i + 1) % 256; + j = (j + s[i]) % 256; + x = s[i]; + s[i] = s[j]; + s[j] = x; + res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]); + } + return res; + +} + + +function xcp_rc4(key, datachunk) { + + return bin2hex(rc4(hex2bin(key), hex2bin(datachunk))); + +} + +function hex2bin(hex) { + + var bytes = []; + var str; + + for (var i = 0; i < hex.length - 1; i += 2) { + + var ch = parseInt(hex.substr(i, 2), 16); + bytes.push(ch); + + } + + str = String.fromCharCode.apply(String, bytes); + return str; + +}; + +function bin2hex(s) { + + // http://kevin.vanzonneveld.net + + var i, l, o = "", + n; + + s += ""; + + for (i = 0, l = s.length; i < l; i++) { + n = s.charCodeAt(i).toString(16); + o += n.length < 2 ? "0" + n : n; + } + + return o; + +}; + +function assetname(assetid) { + + if(assetid != 1){ + + var b26_digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + var letter_array = b26_digits.split(""); + var asset_name = ""; + var div; + var rem; + + var rem_bigint; + var div_bigint; + var div_bigint_parsed; + var rem_bigint_parsed; + + + while (assetid > 0) { + +// if (assetid >= 9007199254740992) { + + + + // console.log(BigIntegerSM.toJSValue(BigIntegerSM.divideAndRemainder(57044491945578590, 26))); + + var assetid_bigint = BigIntegerSM(assetid); + + div_bigint = BigIntegerSM(assetid_bigint).divide(26); +// div_bigint_parsed = div_bigint.toString(16); +//// console.log(div_bigint_parsed); +// div = parseInt(div_bigint_parsed); + div = Math.floor(BigIntegerSM.toJSValue(div_bigint)); + + // console.log(div); + + rem_bigint = BigIntegerSM(assetid_bigint).remainder(26); +// rem_bigint_parsed = rem_bigint.toString(16); +// rem = parseInt(rem_bigint_parsed); + rem = BigIntegerSM.toJSValue(rem_bigint); + + // console.log(rem); + +// } else { +// +// div = assetid/26); +// rem = assetid % 26; +// +// } + + assetid = div; + + asset_name = asset_name + letter_array[rem]; + + } + + var final_name = asset_name.split("").reverse().join(""); + + } else { + + var final_name = "XCP"; + + } + + return final_name; + +} + +function validateEnhancedAssetJSON(jsondata) { + + var jsonstring = JSON.stringify(jsondata); + + console.log(jsonstring); + + var firstSHA = Crypto.SHA256(jsonstring) + + var hash160 = Crypto.RIPEMD160(Crypto.util.hexToBytes(firstSHA)) + var version = 0x41 // "T" + var hashAndBytes = Crypto.util.hexToBytes(hash160) + hashAndBytes.unshift(version) + + var doubleSHA = Crypto.SHA256(Crypto.util.hexToBytes(Crypto.SHA256(hashAndBytes))) + var addressChecksum = doubleSHA.substr(0,8) + + var unencodedAddress = "41" + hash160 + addressChecksum + + var address = Bitcoin.Base58.encode(Crypto.util.hexToBytes(unencodedAddress)) + + return address + +} + +//function loadBvam(callback) { +// +// chrome.storage.local.get(function(data) { +// +// if(typeof(data["bvam"]) !== 'undefined') { +// +// var hashname = new Array(); +// +// var allbvam = data["bvam"]; +// +// for (var i = 0; i < allbvam.length; i++) { +// +// var asset = allbvam[i]["data"]["asset"]; +// var name = allbvam[i]["data"]["assetname"]; +// +// hashname[asset] = name; +// +// } +// +// } else { +// +// var allbvam = ""; +// +// } +// +// console.log(hashname); +// +// callback(allbvam, hashname); +// +// }); +// +//} + +function loadBvam(callback) { + + chrome.storage.local.get(function(data) { + + if(typeof(data["bvam"]) !== 'undefined') { + + var hashname = new Array(); + var hashhash = new Array(); + + var allbvam = data["bvam"]; + + for (var i = 0; i < allbvam.length; i++) { + + var asset = allbvam[i]["data"]["asset"]; + var name = allbvam[i]["data"]["assetname"]; + var hash = allbvam[i]["hash"]; + + hashname[asset] = name; + + hashhash[asset] = hash; + + } + + } else { + + var allbvam = ""; + var hashname = ""; + var hashhash = ""; + + } + + console.log(hashname); + console.log(hashhash); + + callback(allbvam, hashname, hashhash); + + }); + +} + +function addBvam(newbvamdata) { + + chrome.storage.local.get(function(data) { + + if(typeof(data["bvam"]) === 'undefined') { + + var allbvam = new Array(); + + } else { + + var allbvam = data["bvam"]; + + } + + allbvam = allbvam.concat(newbvamdata); + + chrome.storage.local.set( + { + + 'bvam': allbvam + + }, function (){}); + + }); + +} diff --git a/Chrome Extension/js/glidera.js b/Chrome Extension/js/glidera.js new file mode 100644 index 0000000..1984b39 --- /dev/null +++ b/Chrome Extension/js/glidera.js @@ -0,0 +1,765 @@ +document.addEventListener('DOMContentLoaded', function() { + $("#glideraSetupIframe").load(function() { + $('#loadingGif').hide(); + $('#glideraSetupIframe').show(); + }); + $("#glideraTransactionsIframe").load(function() { + $('#loadingGif').hide(); + $('#glideraTransactionsIframe').show(); + }); +}); + +$(document).on('click', '.glideralink', function(event) { + $('#glideraNavBar').removeClass('in'); + glidera.showGlideraTab($(event.target).data('glideratab')); +}); +$(document).on('click', '#buysellTab', function() { + loadAddresslist(); +}); +$(document).on('click', '#glideraButton', function() { + glidera.checkOAuthCredentials(); +}); +$(document).on('click', '#glideraLoginButton', function() { + glidera.loginOrRegister(); +}); +$(document).on('click', '#glideraSignUpButton', function() { + glidera.loginOrRegister(); +}); +$(document).on('keyup mouseup', '.buyInput', function(event) { + glidera.updateBuyPrice(event.target); +}); +$(document).on('click', '#btnBuy2FA', function() { + glidera.buyPrecheck(); +}); +$(document).on('click', '#btnBuyBTC', function() { + glidera.buy(); +}); +$(document).on('keyup mouseup', '.sellInput', function(event) { + glidera.updateSellPrice(event.target); +}); +$(document).on('click', '#btnSell2FA', function() { + glidera.sellPrecheck(); +}); +$(document).on('click', '#btnSellBTC', function() { + glidera.sell(); +}); + +//TESTNET CREDENTIALS +//var GLIDERA_URL = 'https://localhost:8181'; +//var TOKENLY_CLIENT_ID = '6d030d594df17e9e2bceb4b7cd95b858'; +//var TOKENLY_SECRET = '092a99d7c01e2bd30d218d971e062639'; + +//SANDBOX CREDENTIALS +//var GLIDERA_URL = 'https://sandbox.glidera.io'; +//var TOKENLY_CLIENT_ID = '6b1c4f1bf968f49ae0017a2165fc1e29'; +//var TOKENLY_SECRET = '9ecb432a0403baa274b91393c09e93e9'; + +//PRODUCTION CREDENTIALS +var GLIDERA_URL = 'https://www.glidera.io'; +var TOKENLY_CLIENT_ID = '3d57e15259393ba79be5c88e5acee0e5'; +var TOKENLY_SECRET = '52a72c5038848c04daeb8d9860346e93'; + +var GLIDERA_STORAGE_KEY = 'glideraStorageKey'; +var GLIDERA_API_URL = GLIDERA_URL + '/api/v1/'; +var REDIRECT_URI = GLIDERA_URL + "/blank"; + +var INSIGHT_SERVER = "insight.bitpay.com"; + +if (!glidera) { + var glidera = { + buyQuote: '', + buyTimer: undefined, + sellQuote: '', + sellTimer: undefined, + sellTransaction: undefined, + updateAddressListWithBalance: function() { + $('.glideraAddressList > option').each(function(index, element) { + var bitpayUtxos = "https://" + (getNetwork().name === 'testnet' ? 'test-' : '') + INSIGHT_SERVER + "/api/addr/" + $(element).text() + "/utxo"; + $.getJSON(bitpayUtxos, function(utxoData) { + var totalSeen = 0; + $.each(utxoData, function(index, utxo) { + totalSeen += utxo.amount * 100000000; + }); + + totalSeen = totalSeen / 100000000; + + $(element).attr('label', $(element).attr('label').replace(/\(\d*\.?\d*\WBTC\)/g, '') + ' (' + totalSeen + ' BTC)'); + }); + }); + }, + showGlideraTab: function(elementId) { + //console.log("showGlideraTab"); + glidera.removeAllMessages(); + glidera.removeAllUncloseableMessages(); + var targetPage = $('#' + elementId); + if (targetPage !== undefined && targetPage !== null) { + $('.glideratab').hide(); + $('#loadingGif').show(); + glidera.getGlideraStorage(function(glideraStorage) { + $('li>.glideralink').parent().removeClass('active'); + $('.glideralink[data-glideratab=' + elementId + ']').parent().addClass('active'); + var accessToken = glideraStorage['accessToken']; + if (accessToken !== undefined) { + if (elementId === 'glideraSetup') { + var glideraSetupIframe = $('#glideraSetupIframe'); + glideraSetupIframe.hide(); + $('#loadingGif').show(); + glideraSetupIframe.attr('src', GLIDERA_URL + "/user/setup?access_token=" + accessToken); + } else if (elementId === 'glideraTransactions') { + var glideraTransactionsIframe = $('#glideraTransactionsIframe'); + glideraTransactionsIframe.hide(); + $('#loadingGif').show(); + glideraTransactionsIframe.attr('src', GLIDERA_URL + "/user/transactions?access_token=" + accessToken); + } else { + $('#loadingGif').hide(); + if (elementId === 'glideraSell') { + glidera.updateAddressListWithBalance(); + } + if (elementId === 'glideraSell' || elementId === 'glideraBuy') { + glidera.glideraAPIEndpoint('user/status', 'GET', function(data) { + if (data !== undefined && data !== null && data['userCanTransact'] !== undefined && data['userCanTransact'] === true) { + $('#btnSell2FA').removeProp('disabled'); + $('#btnBuy2FA').removeProp('disabled'); + } else { + glidera.addUncloseableMessage('alert-warning', null, 'Complete setup to enable buy/sell.'); + $('#btnSell2FA').prop('disabled', true); + $('#btnBuy2FA').prop('disabled', true); + } + }, function() { + glidera.addUncloseableMessage('alert-warning', null, 'Complete setup to enable buy/sell.'); + $('#btnSell2FA').prop('disabled', true); + $('#btnBuy2FA').prop('disabled', true); + }); + } + } + } else { + $('#loadingGif').hide(); + } + if (elementId === 'glideraRegister') { + $('#glideraNavBarButton').hide(); + } else { + $('#glideraNavBarButton').show(); + } + var pageTitle = targetPage.data('pagetitle'); + var pageTitleElement = $('#glideraPageTitle'); + if (pageTitle !== undefined) { + pageTitleElement.text(pageTitle); + pageTitleElement.show(); + } else { + pageTitleElement.hide(); + pageTitleElement.text(''); + } + targetPage.show(); + }); + } + }, + checkOAuthCredentials: function() { + //console.log("checkOAuthCredentials"); + $('.glideratab').hide(); + $('#loadingGif').show(); + glidera.getGlideraStorage(function(glideraStorage) { + if (glideraStorage['accessToken'] !== undefined) { + //console.log("checkOAuthCredentials access token found"); + glidera.validateAccessToken(glideraStorage['accessToken']); + } else { + //console.log("checkOAuthCredentials no credentials found"); + glidera.showOAuthPage(); + } + }); + }, + showOAuthPage: function() { + //console.log("showOAuthPage"); + glidera.showGlideraTab('glideraRegister'); + }, + showBuySell: function() { + //console.log("showBuySell"); + glidera.showGlideraTab('glideraBuy'); + }, + showSetup: function() { + //console.log("showSetup"); + glidera.showGlideraTab('glideraSetup'); + }, + loginOrRegister: function() { + //console.log("loginOrRegister"); + chrome.windows.create({ + 'url': GLIDERA_URL + '/oauth2/auth?client_id=' + TOKENLY_CLIENT_ID + '&response_type=code&scope=personal_info&required_scope=transact transaction_history&redirect_uri=' + REDIRECT_URI, + 'type': 'popup', + 'width': 400, + 'height': 615 + }, function(window) {}); + }, + validateAccessToken: function() { + //console.log("validateAccessToken"); + glidera.glideraAPIEndpoint('oauth/token', 'GET', function() { + glidera.checkSetup(); + }, function() { + glidera.removeKey('accessToken', glidera.showOAuthPage); + }); + }, + checkSetup: function() { + //console.log("checkSetup"); + glidera.glideraAPIEndpoint('user/status', 'GET', function(data) { + if (data !== undefined && data !== null && data['userCanTransact'] !== undefined && data['userCanTransact'] === true) { + glidera.showBuySell(); + } else { + glidera.showSetup(); + } + }, function() { + glidera.showSetup(); + }); + }, + getGlideraStorage: function(fCallback) { + //console.log("getGlideraStorage"); + chrome.storage.local.get(GLIDERA_STORAGE_KEY, function(data) { + if ($.isEmptyObject(data) || !data.hasOwnProperty(GLIDERA_STORAGE_KEY)) { + fCallback({}); + } else { + fCallback(data[GLIDERA_STORAGE_KEY]); + } + }); + }, + glideraAPIEndpoint: function(endpoint, type, fSuccess, fError, data, twoFactorAuthentication) { + //console.log("glideraAPIEndpoint: " + type + " " + endpoint); + glidera.getGlideraStorage(function(glideraStorage) { + var ajaxObject = { + url: GLIDERA_API_URL + endpoint, + type: type, + headers: { + 'Authorization': 'Bearer ' + glideraStorage['accessToken'] + }, + success: function(data) { + if (fSuccess !== undefined && fSuccess !== null) { + fSuccess(data); + } + }, + error: function(data) { + if (fError !== undefined && fError !== null) { + fError(data); + } + } + }; + if (data !== undefined) { + ajaxObject.dataType = 'json'; + ajaxObject.contentType = 'application/json'; + ajaxObject.data = JSON.stringify(data); + } + if (twoFactorAuthentication !== undefined && twoFactorAuthentication !== '') { + ajaxObject.headers['2FA_CODE'] = twoFactorAuthentication; + } + $.ajax(ajaxObject); + }); + }, + addKey: function(key, value, fCallback) { + //console.log("save: [" + key + "]=" + value); + glidera.getGlideraStorage(function(glideraStorage) { + glideraStorage[key] = value; + var saveObject = {}; + saveObject[GLIDERA_STORAGE_KEY] = glideraStorage; + chrome.storage.local.set(saveObject, function() { + if (fCallback !== undefined && fCallback !== null) { + fCallback(); + } + }); + }); + }, + removeKey: function(key, fCallback) { + //console.log("delete: [" + key + "]"); + glidera.getGlideraStorage(function(glideraStorage) { + delete glideraStorage[key]; + var saveObject = {}; + saveObject[GLIDERA_STORAGE_KEY] = glideraStorage; + chrome.storage.local.set(saveObject, function() { + if (fCallback !== undefined && fCallback !== null) { + fCallback(); + } + }); + }); + }, + addMessage: function(styleClass, strongMessage, message) { + glidera.removeAllMessages(); + var div = $(''); + $("#glideraMessage").append(div); + }, + addUncloseableMessage: function(styleClass, strongMessage, message) { + glidera.removeAllMessages(); + var div = $(''); + $("#glideraUncloseableMessage").append(div); + }, + removeAllMessages: function() { + $("#glideraMessage").empty(); + }, + removeAllUncloseableMessages: function() { + $("#glideraUncloseableMessage").empty(); + }, + formatBTC: function(value) { + var theAmount = parseFloat(value); + if (isNaN(theAmount)) { + return ""; + } else { + var aAmount = theAmount.toString().split("."); + var bitcoin = ""; + if (aAmount.length == 2 && aAmount[1].length > 4) { + return "" + bitcoin + theAmount.toFixed(Math.max(4, (theAmount.toString().split('.')[1] || []).length)) + ""; + } else { + return "" + bitcoin + theAmount + ""; + } + } + }, + formatUSD: function(price) { + if (isNaN(parseFloat(price))) { + return ""; + } else { + return "" + parseFloat(price).toFixed(2) + ""; + } + }, + formatDate: function(date) { + var formattedDate = new Date(date); + var month = formattedDate.getMonth() + 1; + var day = formattedDate.getDate(); + var year = formattedDate.getFullYear().toString().substr(2, 2); + return month + "/" + day + "/" + year; + }, + updateBuyPrice: function(element) { + //console.log("updateBuyPrice"); + var updateBasedOnUSD; + if ($(element).attr('id') === 'buyUSD') { + updateBasedOnUSD = true; + } else if ($(element).attr('id') === 'buyBTC') { + updateBasedOnUSD = false; + } + var ajaxData = {}; + if (updateBasedOnUSD) { + var fiat = $('#buyUSD').val(); + var fiatFloat = parseFloat(fiat); + if (!isNaN(fiatFloat) && fiatFloat >= 0.01) { + ajaxData['fiat'] = fiat; + glidera.startLoadingInput($('#buyBTC')); + } else { + $('#buyBTC').val(''); + $('#buySummaryBitcoin').html(''); + $('#buySummarySubtotal').html(''); + $('#buySummaryFee').html(''); + $('#buySummaryTotal').html(''); + return; + } + } else { + var qty = $('#buyBTC').val(); + var qtytFloat = parseFloat(qty); + if (!isNaN(qtytFloat) && qtytFloat >= 0.00000001) { + ajaxData['qty'] = qty; + glidera.startLoadingInput($('#buyUSD')); + } else { + $('#buyUSD').val(''); + $('#buySummaryBitcoin').html(''); + $('#buySummarySubtotal').html(''); + $('#buySummaryFee').html(''); + $('#buySummaryTotal').html(''); + return; + } + } + glidera.glideraAPIEndpoint('prices/buy', 'POST', function(data) { + //console.log("getBuyPrice success: " + JSON.stringify(data)); + glidera.removeAllMessages(); + glidera.endLoadingInput($('#buyBTC')); + glidera.endLoadingInput($('#buyUSD')); + $('.glideraNumber').removeClass('glideraloadinggif'); + if (updateBasedOnUSD) { + $('#buyBTC').val(data['qty']); + } else { + $('#buyUSD').val(data['subtotal']); + } + $('#buySummaryBitcoin').html(glidera.formatBTC(data['qty'])); + $('#buySummarySubtotal').html(glidera.formatUSD(data['subtotal'])); + $('#buySummaryFee').html(glidera.formatUSD(data['fees'])); + $('#buySummaryTotal').html(glidera.formatUSD(data['total'])); + $('#ltbPriceFlipped').html('$'+data['price']); + glidera.buyQuote = data['priceUuid']; + + if( glidera.buyTimer !== undefined) { + clearTimeout(glidera.buyTimer); + } + + glidera.buyTimer = setTimeout(function() { + if($('#buyUSD').is(":visible") && glidera.buyQuote === data['priceUuid'] ) { + glidera.updateBuyPrice(); + } + }, new Date(data['expires']) - new Date() - 15000); + + glidera.glideraAPIEndpoint('user/limits', 'GET', function(limitsData) { + //console.log("user/limits success: " + JSON.stringify(limitsData)); + if (limitsData['transactDisabledPendingFirstTransaction']) { + glidera.addMessage('alert-warning', null, "Your first transaction is currently pending. " + "The first transaction must clear before you can transact again."); + } else if (limitsData !== undefined && limitsData['dailySellRemaining'] !== undefined && data['subtotal'] > limitsData['dailyBuyRemaining']) { + glidera.addMessage('alert-warning', null, "Your buy is over your remaining daily limit of " + glidera.formatUSD(limitsData['dailyBuyRemaining'])); + } + }); + }, function(data) { + //console.log("getBuyPrice failure: " + JSON.stringify(data)); + glidera.endLoadingInput($('#buyBTC')); + glidera.endLoadingInput($('#buyUSD')); + if (data !== undefined && data['status'] == 400 && data['responseJSON'] !== undefined && data['responseJSON.code'] == 1101) { + glidera.addMessage('alert-danger', null, "The purchase amount is too large, try a smaller amount."); + } else { + glidera.addMessage('alert-danger', null, "An error occured while getting a quote for your purchase, please try again."); + } + }, ajaxData); + }, + startLoadingInput: function(element) { + $(element).val(''); + $(element).removeAttr('placeholder'); + $(element).addClass('glideraloadinggif'); + }, + endLoadingInput: function(element) { + $(element).removeClass('glideraloadinggif'); + $(element).attr('placeholder', '0.00'); + }, + buyPrecheck: function() { + //console.log("buyPrecheck"); + glidera.removeAllMessages(); + var errorMessage = ''; + var usd = $('#buyUSD').val(); + var btc = $('#buyBTC').val(); + var address = $('#glideraBuyAddress').val(); + if (isNaN(parseFloat(usd)) && isNaN(parseFloat(btc))) { + errorMessage += "Please enter an amount to purchase"; + } else if (isNaN(parseFloat(usd))) { + errorMessage += "Please enter a valid USD amount"; + } else if (isNaN(parseFloat(btc))) { + errorMessage += "Please enter a valid BTC amount"; + } else if (address === undefined || address === '') { + errorMessage += "Please select an address"; + } else if (parseFloat(usd) <= 0 || parseFloat(btc) <= 0) { + errorMessage += "Purchase amount is too small"; + } + if (errorMessage !== '') { + glidera.addMessage('alert-danger', null, errorMessage); + } else { + glidera.glideraAPIEndpoint('user/limits', 'GET', function(data) { + //console.log("user/limits success: " + JSON.stringify(data)); + if (data !== undefined && data['dailyBuyRemaining'] !== undefined) { + if (data['transactDisabledPendingFirstTransaction']) { + glidera.addMessage('alert-danger', null, "Your first transaction is currently pending. " + "The first transaction must clear before you can transact again."); + } else if (parseFloat(usd) > data['dailyBuyRemaining']) { + glidera.addMessage('alert-danger', null, "Your purchase is over your remaining daily limit of " + glidera.formatUSD(data['dailyBuyRemaining'])); + } else { + glidera.sendBuy2FA(); + $('#buy2FABTC').html(glidera.formatBTC(btc)); + $('#buy2FAUSD').html(glidera.formatUSD(usd)); + $('#buy2FA').modal('show'); + } + } else { + glidera.addMessage('alert-danger', null, "An error occured while preparing your purchase, please try again"); + } + }, function(data) { + //console.log("user/limits error: " + JSON.stringify(data)); + glidera.addMessage('alert-danger', null, "An error occured while preparing your purchase, please try again."); + }); + } + }, + buy: function() { + //console.log("buy"); + $('#btnBuyBTC').prop('disabled', true); + var ajaxData = {}; + ajaxData['destinationAddress'] = $('#glideraBuyAddress').val(); + ajaxData['qty'] = $('#buyBTC').val(); + ajaxData['priceUuid'] = glidera.buyQuote; + ajaxData['useCurrentPrice'] = false; + var buy2FACode = $('#buy2FACode'); + glidera.glideraAPIEndpoint('buy', 'POST', function(data) { + //console.log("buy success: " + JSON.stringify(data)); + glidera.addMessage('alert-info', "Success!", "Your bitcoin should be delivered on " + glidera.formatDate(data['estimatedDeliveryDate'])); + $('#btnBuyBTC').prop('disabled', false); + $('#buyUSD').val(''); + $('#buyBTC').val(''); + glidera.updateBuyPrice(); + }, function(data) { + //console.log("buy failure: " + JSON.stringify(data)); + if (data !== undefined && data['responseJSON'] !== undefined && data['responseJSON']['code'] == 2006) { + glidera.addMessage('alert-danger', null, "Invalid 2FA code, please try again."); + } else if (data !== undefined && data['responseJSON'] !== undefined && data['responseJSON']['code'] == 3114) { + glidera.addMessage('alert-danger', null, "The market demand for Bitcoin is too high. Please try again later."); + } else { + glidera.addMessage('alert-danger', null, "An error occured while processing your purchase, please try again."); + } + $('#btnBuyBTC').prop('disabled', false); + }, ajaxData, buy2FACode.val()); + buy2FACode.val(''); + $('#buy2FA').modal('hide'); + }, + updateSellPrice: function(element) { + //console.log("updateSellPrice"); + var updateBasedOnUSD; + if ($(element).attr('id') === 'sellUSD') { + updateBasedOnUSD = true; + } else if ($(element).attr('id') === 'sellBTC') { + updateBasedOnUSD = false; + } + var ajaxData = {}; + if (updateBasedOnUSD) { + var fiat = $('#sellUSD').val(); + var fiatFloat = parseFloat(fiat); + if (!isNaN(fiatFloat) && fiatFloat >= 0.01) { + glidera.startLoadingInput($('#sellBTC')); + ajaxData['fiat'] = fiat; + } else { + $('#sellBTC').val(''); + $('#sellSummaryBitcoin').html(''); + $('#sellSummarySubtotal').html(''); + $('#sellSummaryFee').html(''); + $('#sellSummaryTotal').html(''); + return; + } + } else { + var qty = $('#sellBTC').val(); + var qtytFloat = parseFloat(qty); + if (!isNaN(qtytFloat) && qtytFloat >= 0.00000001) { + glidera.startLoadingInput($('#sellUSD')); + ajaxData['qty'] = qty; + } else { + $('#sellUSD').val(''); + $('#sellSummaryBitcoin').html(''); + $('#sellSummarySubtotal').html(''); + $('#sellSummaryFee').html(''); + $('#sellSummaryTotal').html(''); + return; + } + } + glidera.glideraAPIEndpoint('prices/sell', 'POST', function(data) { + //console.log("getSellPrice success: " + JSON.stringify(data)); + glidera.removeAllMessages(); + glidera.endLoadingInput($('#sellBTC')); + glidera.endLoadingInput($('#sellUSD')); + if (updateBasedOnUSD) { + $('#sellBTC').val(data['qty']); + } else { + $('#sellUSD').val(data['subtotal']); + } + $('#sellSummaryBitcoin').html(glidera.formatBTC(data['qty'])); + $('#sellSummarySubtotal').html(glidera.formatUSD(data['subtotal'])); + $('#sellSummaryFee').html(glidera.formatUSD(data['fees'])); + $('#sellSummaryTotal').html(glidera.formatUSD(data['total'])); + $('#ltbPriceFlipped').html('$'+data['price']); + glidera.sellQuote = data['priceUuid']; + + if( glidera.sellTimer !== undefined) { + clearTimeout(glidera.sellTimer); + } + + glidera.sellTimer = setTimeout(function() { + if($('#sellUSD').is(":visible") && glidera.sellQuote === data['priceUuid'] ) { + glidera.updateSellPrice(); + } + }, new Date(data['expires']) - new Date() - 15000); + + glidera.glideraAPIEndpoint('user/limits', 'GET', function(limitsData) { + //console.log("user/limits success: " + JSON.stringify(limitsData)); + if (limitsData['transactDisabledPendingFirstTransaction']) { + glidera.addMessage('alert-warning', null, "Your first transaction is currently pending. " + "The first transaction must clear before you can transact again."); + } else if (limitsData !== undefined && limitsData['dailySellRemaining'] !== undefined && data['subtotal'] > limitsData['dailySellRemaining']) { + glidera.addMessage('alert-warning', null, "Your sell is over your remaining daily limit of " + glidera.formatUSD(limitsData['dailySellRemaining'])); + } else { + var fromAddress = $('#glideraSellAddress').val(); + var bitpayUtxos = "https://" + (getNetwork().name === 'testnet' ? 'test-' : '') + INSIGHT_SERVER + "/api/addr/" + fromAddress + "/utxo"; + $.getJSON(bitpayUtxos, function(utxoData) { + //console.log(utxoData); + var totalSeen = 0; + $.each(utxoData, function(index, utxo) { + totalSeen += utxo.amount; + }); + if (totalSeen < data['qty']) { + glidera.addMessage('alert-warning', null, "This address has insufficient funds to sell " + glidera.formatBTC(data['qty']) + ", current balance is " + glidera.formatBTC(totalSeen)); + } + }); + } + }); + }, function(data) { + //console.log("getSellPrice failure: " + JSON.stringify(data)); + glidera.endLoadingInput($('#sellBTC')); + glidera.endLoadingInput($('#sellUSD')); + if (data !== undefined && data['status'] == 400 && data['responseJSON'] !== undefined && data['responseJSON']['code'] == 1101) { + glidera.addMessage('alert-danger', null, "The sell amount is too large, try a smaller amount."); + } else { + glidera.addMessage('alert-danger', null, "An error occured while getting a quote for your sell, please try again."); + } + }, ajaxData); + }, + sellPrecheck: function() { + //console.log("sellPrecheck"); + glidera.removeAllMessages(); + var errorMessage = ''; + var usd = $('#sellUSD').val(); + var btc = $('#sellBTC').val(); + var address = $('#glideraSellAddress').val(); + if (isNaN(parseFloat(usd)) && isNaN(parseFloat(btc))) { + errorMessage += "Please enter an amount to sell"; + } else if (isNaN(parseFloat(usd))) { + errorMessage += "Please enter a valid USD amount"; + } else if (isNaN(parseFloat(btc))) { + errorMessage += "Please enter a valid BTC amount"; + } else if (address === undefined || address === '') { + errorMessage += "Please select an address"; + } else if (parseFloat(usd) <= 0 || parseFloat(btc) <= 0) { + errorMessage += "Sell amount is too small"; + } + if (errorMessage !== '') { + glidera.addMessage('alert-danger', null, errorMessage); + } else { + glidera.glideraAPIEndpoint('user/limits', 'GET', function(data) { + //console.log("user/limits success: " + JSON.stringify(data)); + if (data !== undefined && data['dailySellRemaining'] !== undefined) { + if (data['transactDisabledPendingFirstTransaction']) { + glidera.addMessage('alert-danger', null, "Your first transaction is currently pending. " + "The first transaction must clear before you can transact again."); + } else if (parseFloat(usd) > data['dailySellRemaining']) { + glidera.addMessage('alert-danger', null, "Your sell is over your remaining daily limit of " + glidera.formatUSD(data['dailySellRemaining'])); + } else { + //All the prechecks look good, try creating the transaction + glidera.createTransaction(btc, address, function(sellTransaction) { + glidera.sellTransaction = sellTransaction; + glidera.sendSell2FA(); + $('#sell2FABTC').html(glidera.formatBTC(btc)); + $('#sell2FAUSD').html(glidera.formatUSD(usd)); + $('#sell2FA').modal('show'); + }); + } + } else { + glidera.addMessage('alert-danger', null, "An error occured while preparing your sell, please try again"); + } + }, function(data) { + //console.log("user/limits error: " + JSON.stringify(data)); + glidera.addMessage('alert-danger', null, "An error occured while preparing your sell, please try again."); + }); + } + }, + createTransaction: function(amountToSend, fromAddress, fSuccess) { + //console.log("createTransaction from " + fromAddress); + glidera.glideraAPIEndpoint('user/create_sell_address', 'GET', function(data) { + if (data !== undefined && data['sellAddress'] !== undefined) { + //Successful created sell address + //console.log("user/create_sell_address success: " + JSON.stringify(data)); + var transaction = new bitcore.Transaction().to(data['sellAddress'], bitcore.Unit.fromBTC(amountToSend).toSatoshis()).change(fromAddress); + if (transaction._hasDustOutputs()) { + glidera.addMessage('alert-danger', null, "The bitcoin amount is too small, you must sell at least " + glidera.formatBTC(0.00000547)); + return; + } + var bitpayUtxo = "https://" + (getNetwork().name === 'testnet' ? 'test-' : '') + INSIGHT_SERVER + "/api/addr/" + fromAddress + "/utxo"; + $.getJSON(bitpayUtxo, function(data) { + //console.log(data); + data.sort(function(a, b) { + return b.amount - a.amount; + }); + + var totalSeen = 0; + $.each(data, function(index, utxo) { + totalSeen += bitcore.Unit.fromBTC(utxo.amount).toSatoshis(); + var change = transaction._getUnspentValue() - transaction.getFee(); + if (transaction._getUnspentValue() >= transaction.getFee() && !transaction._hasDustOutputs() && (change === 0 || change > bitcore.Transaction.DUST_AMOUNT)) { + //We already have enough + return; + } + transaction.from(utxo); + //console.log("found " + (utxo.amount * 100000000) + " satoshis, still missing " + (0 - transaction._getUnspentValue()) + " satoshis"); + }); + + var change = transaction._getUnspentValue() - transaction.getFee(); + if (transaction._getUnspentValue() < 0) { + //Insufficient funds gatherered + var total = bitcore.Unit.fromSatoshis(totalSeen).toBTC(); + glidera.addMessage('alert-danger', null, "This address has insufficient funds to sell " + glidera.formatBTC(amountToSend) + ", current balance is " + glidera.formatBTC(total)); + } else if (transaction._getUnspentValue() < transaction.getFee()) { + //Sufficient funds gathered for output, but not for fee + var fee = bitcore.Unit.fromSatoshis(transaction.getFee()).toBTC(); + glidera.addMessage('alert-danger', null, "A transaction fee of " + glidera.formatBTC(fee) + " is required, try selling a lower amount."); + } else if (transaction._hasDustOutputs() ) { + //Output results in dust + glidera.addMessage('alert-danger', null, "The amount to sell is below the minimum threshold."); + } else if (change !== 0 && change <= bitcore.Transaction.DUST_AMOUNT) { + //change results in dust + glidera.addMessage('alert-danger', null, "The change from this sell is below the minimum threshold."); + } else { + //We have collected enough bitcoin + transaction.sign(getprivkey(fromAddress, $("#newpassphrase").html())); + if (fSuccess !== undefined) { + fSuccess(transaction); + } + } + }).fail(function(jqxhr, textStatus, error) { + glidera.addMessage('alert-danger', null, "An error occured while confirming your balance, please try again."); + }); + } else { + //No sell address was returned + //console.log("user/create_sell_address error: " + JSON.stringify(data)); + glidera.addMessage('alert-danger', null, "An error occured while preparing your sell, please try again"); + } + }, function(data) { + //An error happened while requesting sell address + //console.log("user/create_sell_address error: " + JSON.stringify(data)); + glidera.addMessage('alert-danger', null, "An error occured while preparing your sell, please try again"); + }); + }, + sell: function() { + //console.log("sell"); + $('#btnSellBTC').prop('disabled', true); + var refundAddress = $('#glideraSellAddress').val(); + if (glidera.sellTransaction === undefined) { + glidera.addMessage('alert-danger', null, "An error occured while preparing your sell, please try again"); + } + var signedTransaction = glidera.sellTransaction.serialize(false); + var ajaxData = {}; + ajaxData['refundAddress'] = refundAddress; + ajaxData['signedTransaction'] = signedTransaction; + ajaxData['priceUuid'] = glidera.sellQuote; + ajaxData['useCurrentPrice'] = false; + var sell2FACode = $('#sell2FACode'); + glidera.glideraAPIEndpoint('sell', 'POST', function(data) { + //console.log("sell success: " + JSON.stringify(data)); + glidera.addMessage('alert-info', "Success!", "Your USD should be delivered on " + glidera.formatDate(data['estimatedDeliveryDate'])); + $('#btnSellBTC').prop('disabled', false); + $('#sellUSD').val(''); + $('#sellBTC').val(''); + glidera.updateSellPrice(); + glidera.updateAddressListWithBalance(); + }, function(data) { + //console.log("sell failure: " + JSON.stringify(data)); + if (data !== undefined && data['responseJSON'] !== undefined && data['responseJSON']['code'] == 2006) { + glidera.addMessage('alert-danger', null, "Invalid 2FA code, please try again."); + } else if (data !== undefined && data['responseJSON'] !== undefined && data['responseJSON']['code'] == 5002) { + glidera.addMessage('alert-danger', null, "An error occured while publishing your transaction, please try again."); + } else { + glidera.addMessage('alert-danger', null, "An error occured while processing your sell, please try again."); + } + $('#btnBuyBTC').prop('disabled', false); + $('#btnSellBTC').prop('disabled', false); + }, ajaxData, sell2FACode.val()); + sell2FACode.val(''); + $('#sell2FA').modal('hide'); + }, + sendBuy2FA: function() { + $('#buy2FASMS').hide(); + $('#buy2FAAuthenticator').hide(); + glidera.glideraAPIEndpoint('authentication/get2faCode', 'GET', function(data) { + //console.log(data); + if (data['mode'] === "SMS") { + $('#buy2FASMS').show(); + } else if (data['mode'] === "AUTHENTICATOR") { + $('#buy2FAAuthenticator').show(); + } + }, function() { + glidera.addMessage('alert-danger', null, "An error occured while preparing your purchase, please try again"); + }); + }, + sendSell2FA: function() { + $('#sell2FASMS').hide(); + $('#sell2FAAuthenticator').hide(); + glidera.glideraAPIEndpoint('authentication/get2faCode', 'GET', function(data) { + //console.log(data); + if (data['mode'] === "SMS") { + $('#sell2FASMS').show(); + } else if (data['mode'] === "AUTHENTICATOR") { + $('#sell2FAAuthenticator').show(); + } + }, function() { + glidera.addMessage('alert-danger', null, "An error occured while preparing your sell, please try again"); + }); + } + }; +} \ No newline at end of file diff --git a/Chrome Extension/js/glideraRegister.js b/Chrome Extension/js/glideraRegister.js new file mode 100644 index 0000000..f549128 --- /dev/null +++ b/Chrome Extension/js/glideraRegister.js @@ -0,0 +1,82 @@ +window.addEventListener('load', onLoad); + +function onLoad() { + var parameters = [], hash; + var querystring = document.URL.split('?')[1]; + if (querystring !== undefined) { + querystring = querystring.split('&'); + for (var i = 0; i < querystring.length; i++) { + hash = querystring[i].split('='); + parameters.push(hash[1]); + parameters[hash[0]] = hash[1]; + } + } + + console.log(JSON.stringify(parameters)); + + var grantCode = parameters['code']; + + if (grantCode !== undefined) { + tradeGrantCodeForAccessToken(grantCode); + } else if (parameters['error'] === 'access_denied') { + self.close(); + $('#denied').show(); + } else { + $('#error').show(); + } + + $(document).on('click', '.btn', function() { + self.close(); + }); + +} + +function tradeGrantCodeForAccessToken(grantCode) { + console.log("tradeGrantCodeForAccessToken"); + + accessTokenRequest(grantCode, REDIRECT_URI, function(data) { + // chrome.extension.sendRequest({ + // redirect: 'popup.html' + // }); + $('#success').show(); + }, function(data) { + $('#error').show(); + }); +} + +function accessTokenRequest(grantCode, redirect_uri, fSuccess, fError) { + $.ajax({ + url : GLIDERA_API_URL + "oauth/token", + type : 'POST', + dataType : 'json', + contentType : 'application/json', + data : JSON.stringify({ + "grant_type" : "authorization_code", + "code" : grantCode, + "redirect_uri" : redirect_uri, + "client_id" : TOKENLY_CLIENT_ID, + "client_secret" : TOKENLY_SECRET + }), + success : function(data) { + console.log("tradeGrantCodeForAccessToken success" + + JSON.stringify(data)); + glidera.addKey("accessToken", data.access_token, function() { + if (fSuccess !== undefined && fSuccess !== null) { + fSuccess(data); + } + }); + }, + error : function(data) { + console.log("tradeGrantCodeForAccessToken failure: " + + JSON.stringify(data)); + glidera.removeKey("accessToken", function() { + glidera.removeKey("grantCode", function() { + if (fError !== undefined && fError !== null) { + fError(data); + } + }); + }); + + } + }); +} \ No newline at end of file diff --git a/Chrome Extension/js/hex2dec-cs.js b/Chrome Extension/js/hex2dec-cs.js new file mode 100644 index 0000000..f30d641 --- /dev/null +++ b/Chrome Extension/js/hex2dec-cs.js @@ -0,0 +1,93 @@ +/** + * A function for converting hex <-> dec w/o loss of precision. + * + * The problem is that parseInt("0x12345...") isn't precise enough to convert + * 64-bit integers correctly. + * + * Internally, this uses arrays to encode decimal digits starting with the least + * significant: + * 8 = [8] + * 16 = [6, 1] + * 1024 = [4, 2, 0, 1] + */ + +// Adds two arrays for the given base (10 or 16), returning the result. +// This turns out to be the only "primitive" operation we need. +function add(x, y, base) { + var z = []; + var n = Math.max(x.length, y.length); + var carry = 0; + var i = 0; + while (i < n || carry) { + var xi = i < x.length ? x[i] : 0; + var yi = i < y.length ? y[i] : 0; + var zi = carry + xi + yi; + z.push(zi % base); + carry = Math.floor(zi / base); + i++; + } + return z; +} + +// Returns a*x, where x is an array of decimal digits and a is an ordinary +// JavaScript number. base is the number base of the array x. +function multiplyByNumber(num, x, base) { + if (num < 0) return null; + if (num == 0) return []; + + var result = []; + var power = x; + while (true) { + if (num & 1) { + result = add(result, power, base); + } + num = num >> 1; + if (num === 0) break; + power = add(power, power, base); + } + + return result; +} + +function parseToDigitsArray(str, base) { + var digits = str.split(''); + var ary = []; + for (var i = digits.length - 1; i >= 0; i--) { + var n = parseInt(digits[i], base); + if (isNaN(n)) return null; + ary.push(n); + } + return ary; +} + +function convertBase(str, fromBase, toBase) { + var digits = parseToDigitsArray(str, fromBase); + if (digits === null) return null; + + var outArray = []; + var power = [1]; + for (var i = 0; i < digits.length; i++) { + // invariant: at this point, fromBase^i = power + if (digits[i]) { + outArray = add(outArray, multiplyByNumber(digits[i], power, toBase), toBase); + } + power = multiplyByNumber(fromBase, power, toBase); + } + + var out = ''; + for (var i = outArray.length - 1; i >= 0; i--) { + out += outArray[i].toString(toBase); + } + return out; +} + +function decToHex(decStr) { + var hex = convertBase(decStr, 10, 16); + return hex ? '0x' + hex : null; +} + +function hexToDec(hexStr) { + if (hexStr.substring(0, 2) === '0x') hexStr = hexStr.substring(2); + hexStr = hexStr.toLowerCase(); + return convertBase(hexStr, 16, 10); +} \ No newline at end of file diff --git a/Chrome Extension/js/import_addresses.js b/Chrome Extension/js/import_addresses.js new file mode 100644 index 0000000..b131637 --- /dev/null +++ b/Chrome Extension/js/import_addresses.js @@ -0,0 +1,42 @@ +var fileChooser = document.createElement("input"); +fileChooser.type = 'file'; +fileChooser.style.margin = "0 0 0 -3000px"; + +fileChooser.addEventListener('change', function (evt) { + var f = evt.target.files[0]; + + var extension = f.name.split('.').pop().toLowerCase(); + + + if(f && extension == "json") { + var reader = new FileReader(); + reader.onload = function(e) { + + + + var contents = e.target.result; + + var jsonObj = JSON.parse( contents ); + + chrome.storage.local.set( + { + 'imported_labels': jsonObj + }, function () { + + window.alert("Addresses Imported! You must re-open Tokenly Pockets."); + + + }); + + } + reader.readAsText(f); + } else { + + window.alert("Error! You must import a valid JSON file."); + + } +}); + +document.body.appendChild(fileChooser); + +fileChooser.click(); diff --git a/Chrome Extension/js/issuancebutton.js b/Chrome Extension/js/issuancebutton.js new file mode 100644 index 0000000..8b31147 --- /dev/null +++ b/Chrome Extension/js/issuancebutton.js @@ -0,0 +1,44 @@ +//var address = $(".companion-tip-address").text(); + +var iconpath = chrome.extension.getURL('pockets-48.png'); +var tipsplash = chrome.extension.getURL('issue-tx.html'); +var tipsplashwt = chrome.extension.getURL('issue-tx-wt.html'); + +$('.issue-button').html(tipsplash); + +$('.issue-webtorrent-button').html(tipsplashwt); + +$('.issue-image').html(iconpath); + + + +//function loadAddressIssuance() { +// +// var string = $('body').data('pp'); +// var array = string.split(" "); +// m = new Mnemonic(array); +// +// var HDPrivateKey = bitcore.HDPrivateKey.fromSeed(m.toHex(), bitcore.Networks.livenet); +// +// +// chrome.storage.local.get(function(data) { +// +// var addresslabels = data.addressinfo; +// +// +// +// +// for (var i = 0; i <= addresslabels.length; i++) { +// +// var derived = HDPrivateKey.derive("m/0'/0/" + i); +// var address1 = new bitcore.Address(derived.publicKey, bitcore.Networks.livenet); +// +// var pubkey = address1.toString(); +// +// //$(".addressselect").append(""); +// +// $(".addressselectnoadd").append(""); +// } +// +// }); +//}; \ No newline at end of file diff --git a/Chrome Extension/js/tipbutton.js b/Chrome Extension/js/tipbutton.js index 0fd8341..b468aeb 100644 --- a/Chrome Extension/js/tipbutton.js +++ b/Chrome Extension/js/tipbutton.js @@ -1,22 +1,50 @@ //var address = $(".companion-tip-address").text(); -var iconpath = chrome.extension.getURL('pockets-48.png'); +var iconpathicon = chrome.extension.getURL('pockets-48.png'); +var iconpathblue = chrome.extension.getURL('images/paywithpockets-blue.png'); +var iconpathyellow = chrome.extension.getURL('images/paywithpockets-yellow.png'); +var iconpathgreen = chrome.extension.getURL('images/paywithpockets-green.png'); var tipsplash = chrome.extension.getURL('tipsplash.html'); -$('.companionurl').html(tipsplash); -$('.companionimage').html(iconpath); - -$('.companion-tip-button').each(function(i, obj) { +$('.pockets-url').html(tipsplash); +$('.pockets-image').html(iconpathblue); +$('.pockets-image-blue').html(iconpathblue); +$('.pockets-image-yellow').html(iconpathyellow); +$('.pockets-image-green').html(iconpathgreen); +$('.pockets-image-icon').html(iconpathicon); + +$('.pockets-payment-button').each(function(i, obj) { + + var buttoncolor = $(this).attr("data-color"); + + if (buttoncolor == "yellow") { + var iconcolor = "yellow"; + var iconwidth = 160; + iconpath = chrome.extension.getURL('images/paywithpockets-'+iconcolor+'.png'); + } else if (buttoncolor == "green") { + var iconcolor = "green"; + var iconwidth = 160; + iconpath = chrome.extension.getURL('images/paywithpockets-'+iconcolor+'.png'); + } else if (buttoncolor == "icon") { + var iconcolor = "icon"; + var iconwidth = 24; + iconpath = chrome.extension.getURL('pockets-48.png'); + } else { + var iconcolor = "blue"; + var iconwidth = 160; + iconpath = chrome.extension.getURL('images/paywithpockets-'+iconcolor+'.png'); + } var address = $(this).attr("data-address"); var label = $(this).attr("data-label"); // var isxcp = $(this).attr("data-isxcp"); var tokens = $(this).attr("data-tokens"); + var amount = $(this).attr("data-amount"); var labelurl = encodeURIComponent(label).replace(/[!'()*]/g, escape); var tokensurl = encodeURIComponent(tokens); - var tipbutton = "
"; + var tipbutton = "
"; //"&isxcp="+isxcp+ @@ -24,227 +52,6 @@ $('.companion-tip-button').each(function(i, obj) { }); -if (document.location.hostname == "chain.so") { - - $('kbd').each(function(i, obj) { - - if (i == 0) { - - console.log($(this).text()); - - var txid = $(this).text(); - - get_xcp_encoded_opreturn(txid, function(utxo_hash, data_chunk, sendaddress, confirmation_text){ - - console.log(utxo_hash); - - //$("#arc").html(data_chunk); - var asset = data_chunk.substring(42, 26); - var amount = data_chunk.substring(58, 42); - var asset_dec = parseInt(asset, 16); - console.log(asset_dec); - var amount_dec = parseInt(amount, 16) / 100000000; - console.log(amount_dec); - var assetnamed = assetname(asset_dec); - - console.log(assetnamed); - - - var source_html = "https://counterpartychain.io/api/asset/"+assetnamed; - - $.getJSON( source_html, function( data ) { - - if (data.divisible == 0) { amount_dec = Math.round(amount_dec * 100000000); } - - - $( "
Counterparty Data Detected!
"+confirmation_text+"

Counterparty Asset:

"+assetnamed+"

Amount Sent:

"+amount_dec+"

Sent to: "+sendaddress+"

Data parsed by Tokenly Pockets
" ).insertAfter( ".row:first" ); - }); - }); - - - - } - }); -} - -function get_xcp_encoded_opreturn(tx_id, callback) { - - - var source_html = "https://chain.so/api/v2/get_tx/BTC/"+tx_id; - //var source_html = "https://blockchain.info/rawtx/"+tx_id+"?format=json&cors=true"; - - var target_tx = new Array(); - - $.getJSON( source_html, function( target_tx ) { - - var tx_index = target_tx.data.inputs[0].from_output.txid; - //var tx_index = target_tx.inputs[0].prev_out.tx_index; - - //console.log(tx_index); - - var target_address = target_tx.data.outputs[0].address; - - var confirmations = target_tx.data.confirmations; - - if (confirmations == 0) { - var confirmation_text = "Unconfirmed"; - } else if (confirmations == 1) { - var confirmation_text = "1 confirmation"; - } else { - var confirmation_text = confirmations + " confirmations"; - } - - $.each(target_tx.data.outputs, function(i, item) { - - - - if ((target_tx.data.outputs[i].address == "nonstandard")){ - var target_script = target_tx.data.outputs[i].script; - var xcp_pubkey_data = target_script.substring(10); - - - - var source_html_tx_index = "https://chain.so/api/v2/get_tx/BTC/"+tx_index; - - $.getJSON( source_html_tx_index, xcp_pubkey_data, function( data ) { - - //console.log(data.hash); - //console.log(xcp_pubkey_data); - - var xcp_decoded = xcp_rc4(data.data.txid, xcp_pubkey_data); - - xcp_decoded = "1c"+xcp_decoded; //add first byte to simulate OP_CHECKMULTISIG - - callback(data.data.txid, xcp_decoded, target_address, confirmation_text); - - }); - - } - - - }); - - }); - -} - -function rc4(key, str) { - - //https://gist.github.com/farhadi/2185197 - - var s = [], j = 0, x, res = ''; - for (var i = 0; i < 256; i++) { - s[i] = i; - } - for (i = 0; i < 256; i++) { - j = (j + s[i] + key.charCodeAt(i % key.length)) % 256; - x = s[i]; - s[i] = s[j]; - s[j] = x; - } - i = 0; - j = 0; - for (var y = 0; y < str.length; y++) { - i = (i + 1) % 256; - j = (j + s[i]) % 256; - x = s[i]; - s[i] = s[j]; - s[j] = x; - res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]); - } - return res; - -} - - -function xcp_rc4(key, datachunk) { - - return bin2hex(rc4(hex2bin(key), hex2bin(datachunk))); - -} - -function hex2bin(hex) { - - var bytes = []; - var str; - - for (var i = 0; i < hex.length - 1; i += 2) { - - var ch = parseInt(hex.substr(i, 2), 16); - bytes.push(ch); - - } - - str = String.fromCharCode.apply(String, bytes); - return str; - -}; - -function bin2hex(s) { - - // http://kevin.vanzonneveld.net - - var i, l, o = "", - n; - - s += ""; - - for (i = 0, l = s.length; i < l; i++) { - n = s.charCodeAt(i).toString(16); - o += n.length < 2 ? "0" + n : n; - } - - return o; - -}; - - -function assetname(assetid) { - - if(assetid != 1){ - - var b26_digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - var letter_array = b26_digits.split(""); - var asset_name = ""; - var div; - var rem; - - while (assetid > 0) { - - div = Math.floor(assetid/26); - rem = assetid % 26; - - assetid = div; - - asset_name = asset_name + letter_array[rem]; - - } - - var final_name = asset_name.split("").reverse().join(""); - - } else { - - var final_name = "XCP"; - - } - - return final_name; - -} -//var address = $("companion-tip-button").attr("data-address"); -//var label = $("#companion-tip-button").attr("data-label"); -// -//var labelurl = encodeURIComponent(label); -// -//var iconpath = chrome.extension.getURL('ltb-icon-orange-48.png'); -// -//var tipsplash = chrome.extension.getURL('tipsplash.html'); -// -//var tipbutton = "
"; -// -// -// -//$("#companion-tip-button").html(tipbutton); diff --git a/Chrome Extension/js/utxo.js b/Chrome Extension/js/utxo.js index f16650e..e103844 100644 --- a/Chrome Extension/js/utxo.js +++ b/Chrome Extension/js/utxo.js @@ -1,3 +1,16 @@ +function txfailedDisplay(){ + + $("#sendtokenbutton").html("Refresh to continue..."); + + $("#freezeUnconfirmed").css("display", "block"); + $("#mainDisplay").css("display", "none"); + //$("#yourtxid").html("View Transaction"); + $("#yourtxid").html("Transaction Failed!"); + $("#txsendstatus").html("Something is wrong, please try again later"); + $(".tipsendcomplete").html("
Transaction Failed!
Something is wrong, please try again later.
"); + +} + function ajax(url, data, rawtx) { var xhr = new XMLHttpRequest(); @@ -5,21 +18,40 @@ function ajax(url, data, rawtx) { if (xhr.readyState == 4) { console.log(xhr.responseText); - $("#sendtokenbutton").html("Sent! Refresh to continue..."); - //$("#sendtokenbutton").prop('disabled', true); + var checksuccess = jQuery.parseJSON(xhr.responseText); - var newTxid = rawtotxid(rawtx); + console.log(checksuccess.status); - console.log(newTxid); - $("#freezeUnconfirmed").css("display", "block"); - $("#mainDisplay").css("display", "none"); - //$("#yourtxid").html("View Transaction"); - $("#yourtxid").html("View Transaction"); - $(".tipsendcomplete").html("
Send Complete!
Token balances update in wallet after one confirmation

"); + if (checksuccess.status != "success") { + + txfailedDisplay(); + + } else { + + $("#sendtokenbutton").html("Sent! Refresh to continue..."); + //$("#sendtokenbutton").prop('disabled', true); + + var newTxid = rawtotxid(rawtx); + + console.log(newTxid); + $("#freezeUnconfirmed").css("display", "block"); + $("#mainDisplay").css("display", "none"); + //$("#yourtxid").html("View Transaction"); + $("#yourtxid").html("View Transaction"); + $("#txsendstatus").html("Balance will update after one confirmation"); + $(".tipsendcomplete").html("
Send Complete!
Token balances update in wallet after one confirmation

"); + + } xhr.close; } } + + xhr.onerror = function() { + console.log("onerror function"); + txfailedDisplay(); + }; + xhr.open(data ? "POST" : "GET", url, true); if (data) xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xhr.send(data); @@ -42,7 +74,7 @@ function sendBTCpush(hextx) { function sendBTC(add_from, add_to, sendtotal, transfee) { - var source_html = "https://insight.bitpay.com/api/addr/"+add_from+"/utxo"; + var source_html = "https://"+INSIGHT_SERVER+"/api/addr/"+add_from+"/utxo"; //var source_html = "https://chain.localbitcoins.com/api/addr/"+add_from+"/utxo"; diff --git a/Chrome Extension/js/webtorrent/bvam-p2p.js b/Chrome Extension/js/webtorrent/bvam-p2p.js new file mode 100644 index 0000000..d85f9c2 --- /dev/null +++ b/Chrome Extension/js/webtorrent/bvam-p2p.js @@ -0,0 +1,197 @@ +function decodeUtf8(arrayBuffer) { + var result = ""; + var i = 0; + var c = 0; + var c1 = 0; + var c2 = 0; + + var data = new Uint8Array(arrayBuffer); + + // If we have a BOM skip it + if (data.length >= 3 && data[0] === 0xef && data[1] === 0xbb && data[2] === 0xbf) { + i = 3; + } + + while (i < data.length) { + c = data[i]; + + if (c < 128) { + result += String.fromCharCode(c); + i++; + } else if (c > 191 && c < 224) { + if( i+1 >= data.length ) { + throw "UTF-8 Decode failed. Two byte character was truncated."; + } + c2 = data[i+1]; + result += String.fromCharCode( ((c&31)<<6) | (c2&63) ); + i += 2; + } else { + if (i+2 >= data.length) { + throw "UTF-8 Decode failed. Multi byte character was truncated."; + } + c2 = data[i+1]; + c3 = data[i+2]; + result += String.fromCharCode( ((c&15)<<12) | ((c2&63)<<6) | (c3&63) ); + i += 3; + } + } + return result; +} + + +function getBvamWT(bvamhasharray, callback) { + + chrome.storage.local.get(function(data) { + + if(typeof(data["bvam"]) === 'undefined') { + + var allbvam = new Array(); + + } else { + + var allbvam = data["bvam"]; + + } + + + + for(var j = 0; j < allbvam.length; j++){ + + for(var k = 0; k < bvamhasharray.length; k++){ + + if (allbvam[j]["type"] == "BVAMWT" && allbvam[j]["hash"] == bvamhasharray[k]["hash"]) { + + displayBvamWTasset(bvamhasharray[k]["asset"], bvamhasharray[k]["amount"], allbvam[j]["data"]["assetname"]) + + bvamhasharray.splice(k, 1) + + } + + } + + } + + + console.log(bvamhasharray); + + checkBvamwtEnabled(function() { + + console.log("BVAM via webtorrent is on!"); + +// var client = new WebTorrent(); + + console.log(client); + + var datacount = bvamhasharray.length; + + if(bvamhasharray.length != 0) { + + console.log("looking for BVAM webtorrents..."); + + $.each(bvamhasharray, function(m, item) { + + loadingBvamWTasset(bvamhasharray[m]["asset"]); + + var filename_base58_decode = Bitcoin.Base58.decode(bvamhasharray[m]["hash"]) + var infohash = Crypto.util.bytesToHex(filename_base58_decode) + + var magnetUri = 'magnet:?xt=urn:btih:'+infohash; + + console.log(magnetUri); + + client.add(magnetUri, function (torrent) { + + torrent.files.forEach(function (file) { + + console.log(file.length); + + if (file.length < 1500) { + + file.getBuffer(function (err, buffer) { + if (!err) { + + var jsonstring = decodeUtf8(buffer); + var jsondata = JSON.parse(jsonstring) + + console.log(jsondata); + + var assetname = bvamhasharray[m]["asset"] + var assetbalance = bvamhasharray[m]["amount"] + var hash = bvamhasharray[m]["hash"]; + + if(assetname == jsondata["asset"]) { + + displayBvamWTasset(assetname, assetbalance, jsondata["assetname"]); + + var time_date = new Date(); + var time_unix = time_date.getTime(); + + var bvamdataforstorage = {hash: hash, type: "BVAMWT", data: jsondata, added: time_unix}; + + addBvam(bvamdataforstorage); + + } + + + torrent.destroy(function(){ + + console.log(infohash + " destroyed!"); + + console.log(client.torrents); + + }) + + } + + }) + + } + + + }) + + + }) + + + }) + + console.log(client.torrents); + console.log(client.torrents.length); + + window.setTimeout(function() { + + if(client.torrents.length > 0) { + + do { + + var l = client.torrents.length; + + window.client.torrents[l-1].destroy(function(){ + + console.log("destroyed!"); + + console.log(client); + + }); + + } while (l > 1); + + } + + + }, 30000); + + + } + + + }) + + + }); + + + +} + diff --git a/Chrome Extension/js/webtorrent/bvam-seed.js b/Chrome Extension/js/webtorrent/bvam-seed.js new file mode 100644 index 0000000..814f700 --- /dev/null +++ b/Chrome Extension/js/webtorrent/bvam-seed.js @@ -0,0 +1,233 @@ +// function bulkSeed (files, callback) { +// var index = 0 +// function seeder () { +// client.seed(files[index], function onseed (torrent) { +// // do something with torrent +// if (index < files.lenght) { +// seeder() +// index ++ +// } +// else callback() +// }) +// } +// } + +//"scripts": [ "js/content.js", "js/jquery.min.js", "js/bitcoinjs-min.js", "js/webtorrent/webtorrent.min.js", "js/webtorrent/bvam-seed.js" ] + + + + + + +function startWebTorrents() { + + chrome.storage.local.get(function(data) { + + var enabled = data["bvamwt_enabled"]; + + if (enabled == "yes") { + + //$("#seedinfo").append("
calculating local bvam infohashes..."); + + chrome.storage.local.get(function(data) { + + if(typeof(data["bvam"]) !== 'undefined') { + + var jsontoseed = new Array(); + + var allbvam = data["bvam"]; + + var k = 0; + + for (var i = 0; i < allbvam.length; i++) { + + var type = allbvam[i]["type"]; + + if (type == "BVAMWT") { + + var filename_base58 = allbvam[i]["hash"]; + + var filename_base58_decode = Bitcoin.Base58.decode(filename_base58) + var hash = Crypto.util.bytesToHex(filename_base58_decode) + + //$("#seedinfo").append("
"+hash); + + var assetid = allbvam[i]["data"]["asset"]; + var assetname = allbvam[i]["data"]["assetname"]; + var assetdesc = allbvam[i]["data"]["assetdescription"]; + var assetweb = allbvam[i]["data"]["assetwebsite"]; + + var ownername = allbvam[i]["data"]["ownername"]; + var ownertwitter = allbvam[i]["data"]["ownertwitter"]; + var owneraddress = allbvam[i]["data"]["owneraddress"]; + + var prejsonform = {ownername: ownername, ownertwitter: ownertwitter, owneraddress: owneraddress, asset: assetid, assetname: assetname, assetdescription: assetdesc, assetwebsite: assetweb}; + + //var filename = "BVAMWT.json"; + + var jsonstring = JSON.stringify(prejsonform); + + + jsontoseed[k] = jsonstring; + + k++; + + } + + } + + //$("#seedinfo").append(jsontoseed); + + (function TorrentLoop (i) { + + torrentfunc = setTimeout(function () { + + jsonstring = jsontoseed[i-1]; + + var jsondata = JSON.parse(jsonstring); + + console.log(jsondata); + + var asset = jsondata["asset"]; + var assetname = jsondata["assetname"]; + + var blob = new Blob([jsonstring], {type: "application/json"}); + + client.seed(blob, {name: "BVAMWT.json"}, function (torrent) { + + $("#seedinfo").append('
Client is seeding ' + asset + " - " + assetname + " - " + torrent.infoHash + "
"); + + + torrent.on('wire', function (wire, addr) { + $("#seedinfo").append('
' + torrent.infoHash + ' connected to peer with address ' + addr); + }) + + }) + + if (--i) TorrentLoop(i); + + }, 250) + })(jsontoseed.length); + + + $("#seedinfo").append("
start seeding!"); + + + + } + + + + }) + + + } + + }) + +} + +function seedNewTorrent(bvam){ + + var jsondata = JSON.parse(bvam); + + var asset = jsondata["asset"]; + var assetname = jsondata["assetname"]; + + var blob = new Blob([bvam], {type: "application/json"}); + + client.seed(blob, {name: "BVAMWT.json"}, function (torrent) { + + $("#seedinfo").append('
Client is seeding ' + asset + " - " + assetname + " - " + torrent.infoHash + "
"); + + torrent.on('wire', function (wire, addr) { + $("#seedinfo").append('
' + torrent.infoHash + ' connected to peer with address ' + addr); + }) + + }) + +} + + + +chrome.runtime.onMessage.addListener( + function(request) { + + if (request.bvamwt == "seed_new") { + + //$("#seedinfo").append(request.bvamjson); + + var newbvam = request.bvamjson; + + var jsondata = JSON.stringify(newbvam); + + seedNewTorrent(jsondata); + + } + + if (request.bvamwt == "end") { + + if (typeof(client) !== undefined) { + + clearTimeout(torrentfunc); + + //$("#seedinfo").append(client.torrents); + + client.destroy(function () { + + $("#seedinfo").append("
client destroyed!"); + + }) + + } + + } + + } +); + + + +var client = new WebTorrent(); + +startWebTorrents(); + +setTimeout(function(){ + + chrome.tabs.getCurrent(function(tab) { + chrome.tabs.reload(tab.id, function() { }); + }); + + + + }, 60000); + +$( document ).ready(function() { + + $(document).on("click", 'a', function (event) + { + event.preventDefault(); + chrome.tabs.create({url: $(this).attr('href')}); + + }) + + +}); + +//setInterval(function(){ +// +// chrome.tabs.getCurrent(function(tab) { +// +// chrome.processes.getProcessIdForTab(tab.id, function(processId) { +// +// chrome.processes.getProcessInfo(processId, function(processes) { +// +// console.log(processes); +// +// }); +// +// }); +// +// }); +// +// }, 5000); \ No newline at end of file diff --git a/Chrome Extension/js/webtorrent/webtorrent.min.js b/Chrome Extension/js/webtorrent/webtorrent.min.js new file mode 100644 index 0000000..5367760 --- /dev/null +++ b/Chrome Extension/js/webtorrent/webtorrent.min.js @@ -0,0 +1,17 @@ +(function(e){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=e()}else if(typeof define==="function"&&define.amd){define([],e)}else{var t;if(typeof window!=="undefined"){t=window}else if(typeof global!=="undefined"){t=global}else if(typeof self!=="undefined"){t=self}else{t=this}t.WebTorrent=e()}})(function(){var e,t,r;return function n(e,t,r){function i(s,o){if(!t[s]){if(!e[s]){var f=typeof require=="function"&&require;if(!o&&f)return f(s,!0);if(a)return a(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var l=t[s]={exports:{}};e[s][0].call(l.exports,function(t){var r=e[s][1][t];return i(r?r:t)},l,l.exports,n,e,t,r)}return t[s].exports}var a=typeof require=="function"&&require;for(var s=0;s=0)_();else if(c.indexOf(g)>=0)w();else if(p.indexOf(g)>=0)x();else if(d.indexOf(g)>=0)k();else v(r,new Error('Unsupported file type "'+g+'": Cannot append to DOM'));function _(){if(!h){return v(r,new Error("Video/audio streaming is not supported in your browser. You can still share "+"or download "+e.name+" (once it's fully downloaded). Use Chrome for "+"MediaSource support."))}var a=f.indexOf(g)>=0?"video":"audio";if(o.indexOf(g)>=0)l();else c();function l(){i("Use `videostream` package for "+e.name);_();u.addEventListener("error",d);u.addEventListener("playing",b);s(e,u)}function c(){i("Use MediaSource API for "+e.name);_();u.addEventListener("error",m);u.addEventListener("playing",b);e.createReadStream().pipe(new n(u,{extname:g}));if(y)u.currentTime=y}function p(){i("Use Blob URL for "+e.name);_();u.addEventListener("error",S);u.addEventListener("playing",b);e.getBlobURL(function(e,t){if(e)return S(e);u.src=t;if(y)u.currentTime=y})}function d(e){i("videostream error: fallback to MediaSource API: %o",e.message||e);u.removeEventListener("error",d);u.removeEventListener("playing",b);c()}function m(e){i("MediaSource API error: fallback to Blob URL: %o",e.message||e);u.removeEventListener("error",m);u.removeEventListener("playing",b);p()}function _(e){if(!u){u=document.createElement(a);u.controls=true;u.autoplay=true;u.play();u.addEventListener("progress",function(){y=u.currentTime});t.appendChild(u)}}}function b(){u.removeEventListener("playing",b);r(null,u)}function w(){u=document.createElement("audio");u.controls=true;u.autoplay=true;t.appendChild(u);e.getBlobURL(function(e,t){if(e)return S(e);u.addEventListener("error",S);u.addEventListener("playing",b);u.src=t;u.play()})}function x(){e.getBlobURL(function(i,n){if(i)return S(i);u=document.createElement("img");u.src=n;u.alt=e.name;t.appendChild(u);r(null)})}function k(){e.getBlobURL(function(e,i){if(e)return S(e);u=document.createElement("iframe");u.src=i;if(g!==".pdf")u.sandbox="allow-forms allow-scripts";t.appendChild(u);r(null)})}function S(t){if(u)u.remove();t.message='Error appending file "'+e.name+'" to DOM: '+t.message;i(t.message);if(r)r(t)}};function m(){}function v(e,t,i){r.nextTick(function(){if(e)e(t,i)})}}).call(this,e("_process"))},{_process:48,debug:120,mediasource:129,path:47,videostream:179}],2:[function(e,t,r){t.exports=s;var i=e("debug")("webtorrent:file-stream");var n=e("inherits");var a=e("stream");n(s,a.Readable);function s(e,t){a.Readable.call(this,t);this.destroyed=false;this._torrent=e._torrent;var r=t&&t.start||0;var i=t&&t.end||e.length-1;var n=e._torrent.pieceLength;this._startPiece=(r+e.offset)/n|0;this._endPiece=(i+e.offset)/n|0;this._piece=this._startPiece;this._offset=r+e.offset-this._startPiece*n;this._missing=i-r+1;this._reading=false;this._notifying=false;this._criticalLength=Math.min(1024*1024/n|0,2)}s.prototype._read=function(){if(this._reading)return;this._reading=true;this._notify()};s.prototype._notify=function(){var e=this;if(!e._reading||e._missing===0)return;if(!e._torrent.bitfield.get(e._piece)){return e._torrent.critical(e._piece,e._piece+e._criticalLength)}if(e._notifying)return;e._notifying=true;var t=e._piece;e._torrent.store.get(t,function(r,n){e._notifying=false;if(e.destroyed)return;if(r)return e.destroy(r);i("read %s (length %s) (err %s)",t,n.length,r&&r.message);if(e._offset){n=n.slice(e._offset);e._offset=0}if(e._missing0){return r[Math.random()*r.length|0]}else{return-1}}},{}],6:[function(e,t,r){t.exports=u;var i=e("debug")("webtorrent:server");var n=e("http");var a=e("mime");var s=e("pump");var o=e("range-parser");var f=e("url");function u(e,t){var r=n.createServer(t);var u=[];r.on("connection",function(e){e.setTimeout(36e6);u.push(e);e.on("close",function(){var t=u.indexOf(e);if(t>=0)u.splice(t,1)})});r.destroy=function(e){u.forEach(function(e){e.destroy()});r.close(e)};r.on("request",function(t,r){i("onRequest");if(t.method==="OPTIONS"&&t.headers["access-control-request-headers"]){r.setHeader("Access-Control-Allow-Methods","POST, GET, OPTIONS");r.setHeader("Access-Control-Allow-Headers",t.headers["access-control-request-headers"]);r.setHeader("Access-Control-Max-Age","1728000");return r.end()}if(t.headers.origin){r.setHeader("Access-Control-Allow-Origin",t.headers.origin)}var n=f.parse(t.url).pathname;if(n==="/favicon.ico")return r.end();if(e.ready)u();else e.once("ready",u);function u(){if(n==="/"){r.setHeader("Content-Type","text/html");var f=e.files.map(function(e,t){return'
  • '+e.name+"
  • "}).join("
    ");return r.end("

    WebTorrent

      "+f+"
    ")}var u=Number(n.slice(1));if(Number.isNaN(u)||u>=e.files.length){r.statusCode=404;return r.end("404 Not Found")}var l=e.files[u];r.setHeader("Accept-Ranges","bytes");r.setHeader("Content-Type",a.lookup(l.name));r.statusCode=200;r.setHeader("transferMode.dlna.org","Streaming");r.setHeader("contentFeatures.dlna.org","DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000");var c;if(t.headers.range){r.statusCode=206;c=o(l.length,t.headers.range)[0];i("range %s",JSON.stringify(c));r.setHeader("Content-Range","bytes "+c.start+"-"+c.end+"/"+l.length);r.setHeader("Content-Length",c.end-c.start+1)}else{r.setHeader("Content-Length",l.length)}if(t.method==="HEAD")r.end();s(l.createReadStream(c),r)}});return r}},{debug:120,http:67,mime:131,pump:148,"range-parser":152,url:77}],7:[function(e,t,r){(function(r,i){t.exports=H;var n=e("addr-to-ip-port");var a=e("bitfield");var s=e("chunk-store-stream/write");var o=e("create-torrent");var f=e("debug")("webtorrent:torrent");var u=e("torrent-discovery");var l=e("events").EventEmitter;var c=e("xtend/mutable");var p=e("fs-chunk-store");var d=e("immediate-chunk-store");var h=e("inherits");var m=e("multistream");var v=e("os");var g=e("run-parallel");var y=e("parse-torrent");var _=e("path");var b=e("path-exists");var w=e("torrent-piece");var x=e("pump");var k=e("random-iterate");var S=e("re-emitter");var E=e("simple-sha1");var A=e("bittorrent-swarm");var U=e("uniq");var I=e("ut_metadata");var T=e("ut_pex");var L=e("./file");var B=e("./rarity-map");var C=e("./server");var R=128*1024;var P=3e4;var z=5e3;var O=3*w.BLOCK_LENGTH;var F=.5;var M=1;var j=1e4;var D=2;var N=_.join(b.sync("/tmp")?"/tmp":v.tmpDir(),"webtorrent");h(H,l);function H(e,t){var r=this;l.call(r);if(!f.enabled)r.setMaxListeners(0);f("new torrent");r.client=t.client;r.announce=t.announce;r.urlList=t.urlList;r.path=t.path;r._store=t.store||p;r.strategy=t.strategy||"sequential";r._rechokeNumSlots=t.uploads===false||t.uploads===0?0:+t.uploads||10;r._rechokeOptimisticWire=null;r._rechokeOptimisticTime=0;r._rechokeIntervalId=null;r.ready=false;r.destroyed=false;r.metadata=null;r.store=null;r.numBlockedPeers=0;r.files=null;r.done=false;r._amInterested=false;r._selections=[];r._critical=[];r._servers=[];if(e)r._onTorrentId(e)}Object.defineProperty(H.prototype,"timeRemaining",{get:function(){if(this.swarm.downloadSpeed()===0)return Infinity;else return(this.length-this.downloaded)/this.swarm.downloadSpeed()*1e3}});Object.defineProperty(H.prototype,"downloaded",{get:function(){var e=0;for(var t=0,r=this.pieces.length;tt||e<0||t>=n.pieces.length){throw new Error("invalid selection ",e,":",t)}r=Number(r)||0;f("select %s-%s (priority %s)",e,t,r);n._selections.push({from:e,to:t,offset:0,priority:r,notify:i||W});n._selections.sort(function(e,t){return t.priority-e.priority});n._updateSelections()};H.prototype.deselect=function(e,t,r){var i=this;r=Number(r)||0;f("deselect %s-%s (priority %s)",e,t,r);for(var n=0;n2*(t.swarm.numConns-t.swarm.numPeers)&&e.amInterested){e.destroy()}else{r=setTimeout(i,z);if(r.unref)r.unref()}}var n=0;function a(){if(e.peerPieces.length!==t.pieces.length)return;for(;nR){return e.destroy()}if(t.pieces[r])return;t.store.get(r,{offset:i,length:n},a)});e.bitfield(t.bitfield);e.interested();r=setTimeout(i,z);if(r.unref)r.unref();e.isSeeder=false;a()};H.prototype._updateSelections=function(){var e=this;if(!e.swarm||e.destroyed)return;if(!e.metadata)return e.once("metadata",e._updateSelections.bind(e));r.nextTick(e._gcSelections.bind(e));e._updateInterest();e._update()};H.prototype._gcSelections=function(){var e=this;for(var t=0;t=r)return;var i=q(e,M);f(false)||f(true);function n(t,r,i,n){return function(a){return a>=t&&a<=r&&!(a in i)&&e.peerPieces.get(a)&&(!n||n(a))}}function a(){if(e.requests.length)return;for(var r=t._selections.length;r--;){var i=t._selections[r];var a;if(t.strategy==="rarest"){var s=i.from+i.offset;var o=i.to;var f=o-s+1;var u={};var l=0;var c=n(s,o,u);while(l=i.from+i.offset;--a){if(!e.peerPieces.get(a))continue;if(t._request(e,a,false))return}}}}function s(){var r=e.downloadSpeed()||1;if(r>O)return function(){return true};var i=Math.max(1,e.requests.length)*w.BLOCK_LENGTH/r;var n=10;var a=0;return function(e){if(!n||t.bitfield.get(e))return true;var s=t.pieces[e].missing;for(;a0)continue;n--;return false}return true}}function o(e){var r=e;for(var i=e;i=i)return true;var a=s();for(var f=0;f0)e._rechokeOptimisticTime-=1;else e._rechokeOptimisticWire=null;var t=[];e.swarm.wires.forEach(function(r){if(!r.isSeeder&&r!==e._rechokeOptimisticWire){t.push({wire:r,downloadSpeed:r.downloadSpeed(),uploadSpeed:r.uploadSpeed(),salt:Math.random(),isChoked:true})}});t.sort(s);var r=0;var i=0;for(;i=O)continue;if(2*u>i||u>a)continue;s=f;a=u}if(!s)return false;for(o=0;o=s)return false;var o=n.pieces[t];var u=o.reserve();if(u===-1&&i&&n._hotswap(e,t)){u=o.reserve()}if(u===-1)return false;var l=n._reservations[t];if(!l)l=n._reservations[t]=[];var c=l.indexOf(null);if(c===-1)c=l.length;l[c]=e;var p=o.chunkOffset(u);var d=o.chunkLength(u);e.request(t,p,d,function m(r,i){if(!n.ready)return n.once("ready",function(){m(r,i)});if(l[c]===e)l[c]=null;if(o!==n.pieces[t])return h();if(r){f("error getting piece %s (offset: %s length: %s) from %s: %s",t,p,d,e.remoteAddress+":"+e.remotePort,r.message);o.cancel(u);h();return}f("got piece %s (offset: %s length: %s) from %s",t,p,d,e.remoteAddress+":"+e.remotePort);if(!o.set(u,i,e))return h();var a=o.flush();E(a,function(e){if(e===n._hashes[t]){if(!n.pieces[t])return;f("piece verified %s",t);n.pieces[t]=null;n._reservations[t]=null;n.bitfield.set(t,true);n.store.put(t,a);n.swarm.wires.forEach(function(e){e.have(t)});n._checkDone()}else{n.pieces[t]=new w(o.length);n.emit("warning",new Error("Piece "+t+" failed verification"))}h()})});function h(){r.nextTick(function(){n._update()})}return true};H.prototype._checkDone=function(){var e=this;if(e.destroyed)return;e.files.forEach(function(t){if(t.done)return;for(var r=t._startPiece;r<=t._endPiece;++r){if(!e.bitfield.get(r))return}t.done=true;t.emit("done");f("file done: "+t.name)});if(e.files.every(function(e){return e.done})){e.done=true;e.emit("done");f("torrent done: "+e.infoHash);if(e.discovery.tracker)e.discovery.tracker.complete()}e._gcSelections()};H.prototype.load=function(e,t){var r=this;if(!Array.isArray(e))e=[e];if(!t)t=W;var i=new m(e);var n=new s(r.store,r.pieceLength);x(i,n,function(e){if(e)return t(e);r.pieces.forEach(function(e,t){r.pieces[t]=null;r._reservations[t]=null;r.bitfield.set(t,true)});r._checkDone();t(null)})};H.prototype.createServer=function(e){var t=this;if(typeof C!=="function")return;var r=new C(t,e);t._servers.push(r);return r};H.prototype._onError=function(e){var t=this;f("torrent error: %s",e.message||e);t.emit("error",e);t.destroy()};function q(e,t){return Math.ceil(2+t*e.downloadSpeed()/w.BLOCK_LENGTH)}function G(e){return Math.random()*e|0}function W(){}}).call(this,e("_process"),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./file":3,"./rarity-map":5,"./server":6,_process:48,"addr-to-ip-port":8,bitfield:9,"bittorrent-swarm":10,"chunk-store-stream/write":89,"create-torrent":90,debug:120,events:43,"fs-chunk-store":130,"immediate-chunk-store":127,inherits:128,multistream:133,os:46,"parse-torrent":134,path:47,"path-exists":147,pump:148,"random-iterate":151,"re-emitter":153,"run-parallel":154,"simple-sha1":162,"torrent-discovery":165,"torrent-piece":166,uniq:167,ut_metadata:168,ut_pex:38,"xtend/mutable":181}],8:[function(e,t,r){var i=/^\[?([^\]]+)\]?:(\d+)$/;var n={};var a=0;t.exports=function s(e){if(a===1e5)n={};if(!n[e]){var t=i.exec(e);if(!t)throw new Error("invalid addr: "+e);n[e]=[t[1],Number(t[2])];a+=1}return n[e]};t.exports.reset=function o(){n={}}},{}],9:[function(e,t,r){(function(e){var r=typeof e!=="undefined"?e:typeof Int8Array!=="undefined"?Int8Array:function(e){var t=new Array(e);for(var r=0;r>3;if(e%8!==0)t++;return t}i.prototype.get=function(e){var t=e>>3;return t>e%8)};i.prototype.set=function(e,t){var r=e>>3;if(t||arguments.length===1){if(this.buffer.length>e%8}else if(r>e%8)}};i.prototype._grow=function(e){if(this.buffer.length=e.maxConns){return}a("drain (%s queued, %s/%s peers)",e.numQueued,e.numPeers,e.maxConns);var t=e._queue.shift();if(!t)return;a("tcp connect attempt to %s",t.addr);var r=n(t.addr);var i={host:r[0],port:r[1]};if(e._hostname)i.localAddress=e._hostname;var s=t.conn=u.connect(i);s.once("connect",function(){t.onConnect()});s.once("error",function(e){t.destroy(e)});t.setConnectTimeout();s.on("close",function(){if(e.destroyed)return;if(t.retries>=h.length){a("conn %s closed: will not re-add (max %s attempts)",t.addr,h.length);return}var r=h[t.retries];a("conn %s closed: will re-add to queue in %sms (attempt %s)",t.addr,r,t.retries+1);var i=setTimeout(function n(){var r=e._addPeer(t.addr);if(r)r.retries=t.retries+1},r);if(i.unref)i.unref()})};m.prototype._onError=function(e){var t=this;t.emit("error",e);t.destroy()};m.prototype._validAddr=function(e){var t=this;var r=n(e);var i=r[0];var a=r[1];return a>0&&a<65535&&!(i==="127.0.0.1"&&a===t._port)}}).call(this,e("_process"),e("buffer").Buffer)},{"./lib/peer":11,"./lib/tcp-pool":12,_process:48,"addr-to-ip-port":38,buffer:39,debug:120,dezalgo:19,events:43,inherits:128,net:38,speedometer:164}],11:[function(e,t,r){var i=e("debug")("bittorrent-swarm:peer");var n=e("./webconn");var a=e("bittorrent-protocol");var s=25e3;var o=25e3;r.createWebRTCPeer=function(e,t){var r=new f(e.id);r.conn=e;r.swarm=t;if(r.conn.connected){r.onConnect()}else{r.conn.once("connect",function(){r.onConnect()});r.conn.once("error",function(e){r.destroy(e)});r.setConnectTimeout()}return r};r.createIncomingTCPPeer=function(e){var t=e.remoteAddress+":"+e.remotePort;var r=new f(t);r.conn=e;r.addr=t;r.onConnect();return r};r.createOutgoingTCPPeer=function(e,t){var r=new f(e);r.addr=e;r.swarm=t;return r};r.createWebPeer=function(e,t,r){var i=new f(e);i.swarm=r;i.conn=new n(e,t);i.onConnect();return i};function f(e){var t=this;t.id=e;i("new Peer %s",e);t.addr=null;t.conn=null;t.swarm=null;t.wire=null;t.connected=false;t.destroyed=false;t.timeout=null;t.retries=0;t.sentHandshake=false}f.prototype.onConnect=function(){var e=this;if(e.destroyed)return;e.connected=true;i("Peer %s connected",e.id);clearTimeout(e.connectTimeout);var t=e.conn;t.once("end",function(){e.destroy()});t.once("close",function(){e.destroy()});t.once("finish",function(){e.destroy()});t.once("error",function(t){e.destroy(t)});var r=e.wire=new a;r.once("end",function(){e.destroy()});r.once("close",function(){e.destroy()});r.once("finish",function(){e.destroy()});r.once("error",function(t){e.destroy(t)});r.once("handshake",function(t,r){e.onHandshake(t,r)});e.setHandshakeTimeout();t.pipe(r).pipe(t);if(e.swarm&&!e.sentHandshake)e.handshake()};f.prototype.onHandshake=function(e,t){var r=this;if(!r.swarm)return;var n=e.toString("hex");var a=t.toString("hex");if(r.swarm.destroyed)return r.destroy(new Error("swarm already destroyed"));if(n!==r.swarm.infoHashHex){return r.destroy(new Error("unexpected handshake info hash for this swarm"))}if(a===r.swarm.peerIdHex){return r.destroy(new Error("refusing to handshake with self"))}i("Peer %s got handshake %s",r.id,n);clearTimeout(r.handshakeTimeout);r.retries=0;r.wire.on("download",function(e){if(r.destroyed)return;r.swarm.downloaded+=e;r.swarm.downloadSpeed(e);r.swarm.emit("download",e)});r.wire.on("upload",function(e){if(r.destroyed)return;r.swarm.uploaded+=e;r.swarm.uploadSpeed(e);r.swarm.emit("upload",e)});if(!r.sentHandshake)r.handshake();r.swarm.wires.push(r.wire);var s=r.addr;if(!s&&r.conn.remoteAddress){s=r.conn.remoteAddress+":"+r.conn.remotePort}r.swarm.emit("wire",r.wire,s)};f.prototype.handshake=function(){var e=this;e.wire.handshake(e.swarm.infoHash,e.swarm.peerId,e.swarm.handshakeOpts);e.sentHandshake=true};f.prototype.setConnectTimeout=function(){var e=this;clearTimeout(e.connectTimeout);e.connectTimeout=setTimeout(function(){e.destroy(new Error("connect timeout"))},s);if(e.connectTimeout.unref)e.connectTimeout.unref()};f.prototype.setHandshakeTimeout=function(){var e=this;clearTimeout(e.handshakeTimeout);e.handshakeTimeout=setTimeout(function(){e.destroy(new Error("handshake timeout"))},o);if(e.handshakeTimeout.unref)e.handshakeTimeout.unref()};f.prototype.destroy=function(e){var t=this;if(t.destroyed)return;t.destroyed=true;t.connected=false;i("destroy %s (error: %s)",t.id,e&&(e.message||e));clearTimeout(t.connectTimeout);clearTimeout(t.handshakeTimeout);var r=t.swarm;var n=t.conn;var a=t.wire;t.conn=null;t.swarm=null;t.wire=null;if(r&&a){var s=r.wires.indexOf(a);if(s>=0)r.wires.splice(s,1)}if(n)n.destroy();if(a)a.destroy();if(r)r.removePeer(t.id)}},{"./webconn":13,"bittorrent-protocol":14,debug:120}],12:[function(e,t,r){(function(r){t.exports=f;var i=e("debug")("bittorrent-swarm:tcp-pool");var n=e("dezalgo");var a=e("net");var s=e("./peer");var o={};function f(e,t){var r=this;r.port=e;r.listening=false;r.swarms={};i("new TCPPool (port: %s, hostname: %s)",e,t);r.pendingConns=[];r.server=a.createServer();r.server.on("connection",function(e){r._onConnection(e)});r.server.on("error",function(e){r._onError(e)});r.server.on("listening",function(){r._onListening()});r.server.listen(r.port,t)}f.addSwarm=function(e){var t=o[e._port];if(!t)t=o[e._port]=new f(e._port,e._hostname);t.addSwarm(e);return t};f.removeSwarm=function(e,t){var i=o[e._port];if(!i)return t();i.removeSwarm(e);var n=0;for(var a in i.swarms){var s=i.swarms[a];if(s)n+=1}if(n===0)i.destroy(t);else r.nextTick(t)};f.getDefaultListenPort=function(e){for(var t in o){var r=o[t];if(r&&!r.swarms[e])return r.port}return 0};f.prototype.addSwarm=function(e){var t=this;if(t.swarms[e.infoHashHex]){r.nextTick(function(){e._onError(new Error("There is already a swarm with info hash "+e.infoHashHex+" "+"listening on port "+e._port))});return}t.swarms[e.infoHashHex]=e;if(t.listening){r.nextTick(function(){e._onListening(t.port)})}i("add swarm %s to tcp pool %s",e.infoHashHex,t.port)};f.prototype.removeSwarm=function(e){var t=this;i("remove swarm %s from tcp pool %s",e.infoHashHex,t.port);t.swarms[e.infoHashHex]=null};f.prototype.destroy=function(e){var t=this;if(e)e=n(e);i("destroy tcp pool %s",t.port);t.listening=false;t.pendingConns.forEach(function(e){e.destroy()});o[t.port]=null;try{t.server.close(e)}catch(r){if(e)e(null)}};f.prototype._onListening=function(){var e=this;var t=e.server.address()||{port:0};var r=t.port;i("tcp pool listening on %s",r);if(r!==e.port){o[e.port]=null;e.port=r;o[e.port]=e}e.listening=true;for(var n in e.swarms){var a=e.swarms[n];if(a)a._onListening(e.port)}};f.prototype._onConnection=function(e){var t=this;t.pendingConns.push(e);e.once("close",r);function r(){t.pendingConns.splice(t.pendingConns.indexOf(e))}var i=s.createIncomingTCPPeer(e);i.wire.once("handshake",function(n,a){var s=n.toString("hex");r();e.removeListener("close",r);var o=t.swarms[s];if(o){i.swarm=o;o._addIncomingPeer(i);i.onHandshake(n,a)}else{var f=new Error("Unexpected info hash "+s+" from incoming peer "+i.id+": destroying peer");i.destroy(f)}})};f.prototype._onError=function(e){var t=this;t.destroy();for(var r in t.swarms){var i=t.swarms[r];if(i){t.removeSwarm(i);i._onError(e)}}}}).call(this,e("_process"))},{"./peer":11,_process:48,debug:120,dezalgo:19,net:38}],13:[function(e,t,r){(function(r){t.exports=f;var i=e("bitfield");var n=e("debug")("bittorrent-swarm:webconn");var a=e("simple-get");var s=e("inherits");var o=e("bittorrent-protocol");s(f,o);function f(e,t){var a=this;o.call(this);a.url=e;a.parsedTorrent=t;a.setKeepAlive(true);a.on("handshake",function(t,n){a.handshake(t,new r(20).fill(e));var s=a.parsedTorrent.pieces.length;var o=new i(s);for(var f=0;f<=s;f++){o.set(f,true)}a.bitfield(o)});a.on("choke",function(){n("choke")});a.on("unchoke",function(){n("unchoke")});a.once("interested",function(){n("interested");a.unchoke()});a.on("uninterested",function(){n("uninterested")});a.on("bitfield",function(){n("bitfield")});a.on("request",function(e,t,r,i){n("request pieceIndex=%d offset=%d length=%d",e,t,r);a.httpRequest(e,t,r,i)})}f.prototype.httpRequest=function(e,t,r,i){var s=this;var o=e*s.parsedTorrent.pieceLength;var f=o+t;var u=f+r-1;n("Requesting pieceIndex=%d offset=%d length=%d start=%d end=%d",e,t,r,f,u);var l={url:s.url,method:"GET",headers:{"user-agent":"WebTorrent (http://webtorrent.io)",range:"bytes="+f+"-"+u}};a.concat(l,function(e,t,r){if(e)return i(e);if(r.statusCode<200||r.statusCode>=300){return i(new Error("Unexpected HTTP status code "+r.statusCode))}n("Got data of length %d",t.length);i(null,t)})}}).call(this,e("buffer").Buffer)},{bitfield:9,"bittorrent-protocol":14,buffer:39,debug:120,inherits:128,"simple-get":159}],14:[function(e,t,r){(function(r){t.exports=w;var i=e("bencode");var n=e("bitfield");var a=e("debug")("bittorrent-protocol");var s=e("xtend");var o=e("hat");var f=e("inherits");var u=e("speedometer");var l=e("stream");var c=4e5;var p=new r("BitTorrent protocol");var d=new r([0,0,0,0]);var h=new r([0,0,0,1,0]);var m=new r([0,0,0,1,1]);var v=new r([0,0,0,1,2]);var g=new r([0,0,0,1,3]);var y=[0,0,0,0,0,0,0,0];var _=[0,0,0,3,9,0,0];function b(e,t,r,i){this.piece=e;this.offset=t;this.length=r;this.callback=i}f(w,l.Duplex);function w(){if(!(this instanceof w))return new w;l.Duplex.call(this);this._debugId=o(32);this._debug("new wire");this.amChoking=true;this.amInterested=false;this.peerChoking=true;this.peerInterested=false;this.peerPieces=new n(0,{grow:c});this.peerExtensions={};this.requests=[];this.peerRequests=[];this.extendedMapping={};this.peerExtendedMapping={};this.extendedHandshake={};this.peerExtendedHandshake={};this._ext={};this._nextExt=1;this.uploaded=0;this.downloaded=0;this.uploadSpeed=u();this.downloadSpeed=u();this._keepAliveInterval=null;this._timeout=null;this._timeoutMs=0;this.destroyed=false;this._finished=false;this._buffer=[];this._bufferSize=0;this._parser=null;this._parserSize=0;this.on("finish",this._onfinish);this._parseHandshake()}w.prototype.setKeepAlive=function(e){this._debug("setKeepAlive %s",e);clearInterval(this._keepAliveInterval);if(e===false)return;this._keepAliveInterval=setInterval(this.keepAlive.bind(this),6e4)};w.prototype.setTimeout=function(e,t){this._debug("setTimeout ms=%d unref=%s",e,t);this._clearTimeout();this._timeoutMs=e;this._timeoutUnref=!!t;this._updateTimeout()};w.prototype.destroy=function(){if(this.destroyed)return;this.destroyed=true;this._debug("destroy");this.emit("close");this.end()};w.prototype.end=function(){this._debug("end");this._onUninterested();this._onChoke();l.Duplex.prototype.end.apply(this,arguments)};w.prototype.use=function(e){var t=e.prototype.name;if(!t){throw new Error('Extension class requires a "name" property on the prototype')}this._debug("use extension.name=%s",t);var r=this._nextExt;var i=new e(this);function n(){}if(typeof i.onHandshake!=="function"){i.onHandshake=n}if(typeof i.onExtendedHandshake!=="function"){i.onExtendedHandshake=n}if(typeof i.onMessage!=="function"){i.onMessage=n}this.extendedMapping[r]=t;this._ext[t]=i;this[t]=i;this._nextExt+=1};w.prototype.keepAlive=function(){this._debug("keep-alive");this._push(d)};w.prototype.handshake=function(e,t,i){if(typeof e==="string")e=new r(e,"hex");if(typeof t==="string")t=new r(t,"hex");if(e.length!==20||t.length!==20){throw new Error("infoHash and peerId MUST have length 20")}this._debug("handshake i=%s p=%s exts=%o",e.toString("hex"),t.toString("hex"),i);var n=new r(y);n[5]|=16;if(i&&i.dht)n[7]|=1;this._push(r.concat([p,n,e,t]));this._handshakeSent=true;if(this.peerExtensions.extended){this._sendExtendedHandshake()}};w.prototype._sendExtendedHandshake=function(){var e=s(this.extendedHandshake);e.m={};for(var t in this.extendedMapping){var r=this.extendedMapping[t];e.m[r]=Number(t)}this.extended(0,i.encode(e))};w.prototype.choke=function(){if(this.amChoking)return;this.amChoking=true;this._debug("choke");this.peerRequests.splice(0,this.peerRequests.length);this._push(h)};w.prototype.unchoke=function(){if(!this.amChoking)return;this.amChoking=false;this._debug("unchoke");this._push(m)};w.prototype.interested=function(){if(this.amInterested)return;this.amInterested=true;this._debug("interested");this._push(v)};w.prototype.uninterested=function(){if(!this.amInterested)return;this.amInterested=false;this._debug("uninterested");this._push(g)};w.prototype.have=function(e){this._debug("have %d",e);this._message(4,[e],null)};w.prototype.bitfield=function(e){this._debug("bitfield");if(!r.isBuffer(e))e=e.buffer;this._message(5,[],e)};w.prototype.request=function(e,t,r,i){if(!i)i=function(){};if(this._finished)return i(new Error("wire is closed"));if(this.peerChoking)return i(new Error("peer is choking"));this._debug("request index=%d offset=%d length=%d",e,t,r);this.requests.push(new b(e,t,r,i));this._updateTimeout();this._message(6,[e,t,r],null)};w.prototype.piece=function(e,t,r){this._debug("piece index=%d offset=%d",e,t);this.uploaded+=r.length;this.uploadSpeed(r.length);this.emit("upload",r.length);this._message(7,[e,t],r)};w.prototype.cancel=function(e,t,r){this._debug("cancel index=%d offset=%d length=%d",e,t,r);this._callback(x(this.requests,e,t,r),new Error("request was cancelled"),null);this._message(8,[e,t,r],null)};w.prototype.port=function(e){this._debug("port %d",e);var t=new r(_);t.writeUInt16BE(e,5);this._push(t)};w.prototype.extended=function(e,t){this._debug("extended ext=%s",e);if(typeof e==="string"&&this.peerExtendedMapping[e]){e=this.peerExtendedMapping[e]}if(typeof e==="number"){var n=new r([e]);var a=r.isBuffer(t)?t:i.encode(t);this._message(20,[],r.concat([n,a]))}else{throw new Error("Unrecognized extension: "+e)}};w.prototype._onKeepAlive=function(){this._debug("got keep-alive");this.emit("keep-alive")};w.prototype._onHandshake=function(e,t,r){this._debug("got handshake i=%s p=%s exts=%o",e.toString("hex"),t.toString("hex"),r);this.peerId=t;this.peerExtensions=r;this.emit("handshake",e,t,r);var i;for(i in this._ext){this._ext[i].onHandshake(e,t,r)}if(r.extended&&this._handshakeSent){this._sendExtendedHandshake()}};w.prototype._onChoke=function(){this.peerChoking=true;this._debug("got choke");this.emit("choke");while(this.requests.length){this._callback(this.requests.shift(),new Error("peer is choking"),null)}};w.prototype._onUnchoke=function(){this.peerChoking=false;this._debug("got unchoke");this.emit("unchoke")};w.prototype._onInterested=function(){this.peerInterested=true;this._debug("got interested");this.emit("interested")};w.prototype._onUninterested=function(){this.peerInterested=false;this._debug("got uninterested");this.emit("uninterested")};w.prototype._onHave=function(e){if(this.peerPieces.get(e))return;this._debug("got have %d",e);this.peerPieces.set(e,true);this.emit("have",e)};w.prototype._onBitField=function(e){this.peerPieces=new n(e);this._debug("got bitfield");this.emit("bitfield",this.peerPieces)};w.prototype._onRequest=function(e,t,r){if(this.amChoking)return;this._debug("got request index=%d offset=%d length=%d",e,t,r);var i=function(i,a){if(n!==x(this.peerRequests,e,t,r))return;if(i)return;this.piece(e,t,a)}.bind(this);var n=new b(e,t,r,i);this.peerRequests.push(n);this.emit("request",e,t,r,i)};w.prototype._onPiece=function(e,t,r){this._debug("got piece index=%d offset=%d",e,t);this._callback(x(this.requests,e,t,r.length),null,r);this.downloaded+=r.length;this.downloadSpeed(r.length);this.emit("download",r.length);this.emit("piece",e,t,r)};w.prototype._onCancel=function(e,t,r){this._debug("got cancel index=%d offset=%d length=%d",e,t,r);x(this.peerRequests,e,t,r);this.emit("cancel",e,t,r)};w.prototype._onPort=function(e){this._debug("got port %d",e);this.emit("port",e)};w.prototype._onExtended=function(e,t){if(e===0){var r;try{r=i.decode(t)}catch(n){this._debug("ignoring invalid extended handshake: %s",n.message||n)}if(!r)return;this.peerExtendedHandshake=r;var a;if(typeof r.m==="object"){for(a in r.m){this.peerExtendedMapping[a]=Number(r.m[a].toString())}}for(a in this._ext){if(this.peerExtendedMapping[a]){this._ext[a].onExtendedHandshake(this.peerExtendedHandshake)}}this._debug("got extended handshake");this.emit("extended","handshake",this.peerExtendedHandshake)}else{if(this.extendedMapping[e]){e=this.extendedMapping[e];if(this._ext[e]){this._ext[e].onMessage(t)}}this._debug("got extended message ext=%s",e);this.emit("extended",e,t)}};w.prototype._onTimeout=function(){this._debug("request timed out");this._callback(this.requests.shift(),new Error("request has timed out"),null);this.emit("timeout")};w.prototype._push=function(e){if(this._finished)return;return this.push(e)};w.prototype._write=function(e,t,i){this._bufferSize+=e.length;this._buffer.push(e);while(this._bufferSize>=this._parserSize){var n=this._buffer.length===1?this._buffer[0]:r.concat(this._buffer);this._bufferSize-=this._parserSize;this._buffer=this._bufferSize?[n.slice(this._parserSize)]:[];this._parser(n.slice(0,this._parserSize))}i(null)};w.prototype._read=function(){};w.prototype._callback=function(e,t,r){if(!e)return;this._clearTimeout();if(!this.peerChoking&&!this._finished)this._updateTimeout();e.callback(t,r)};w.prototype._clearTimeout=function(){if(!this._timeout)return;clearTimeout(this._timeout);this._timeout=null};w.prototype._updateTimeout=function(){if(!this._timeoutMs||!this.requests.length||this._timeout)return;this._timeout=setTimeout(this._onTimeout.bind(this),this._timeoutMs);if(this._timeoutUnref&&this._timeout.unref)this._timeout.unref()};w.prototype._parse=function(e,t){this._parserSize=e;this._parser=t};w.prototype._message=function(e,t,i){var n=i?i.length:0;var a=new r(5+4*t.length);a.writeUInt32BE(a.length+n-4,0);a[4]=e;for(var s=0;s0){this._parse(t,this._onmessage)}else{this._onKeepAlive();this._parse(4,this._onmessagelength)}};w.prototype._onmessage=function(e){this._parse(4,this._onmessagelength);switch(e[0]){case 0:return this._onChoke();case 1:return this._onUnchoke();case 2:return this._onInterested();case 3:return this._onUninterested();case 4:return this._onHave(e.readUInt32BE(1));case 5:return this._onBitField(e.slice(1));case 6:return this._onRequest(e.readUInt32BE(1),e.readUInt32BE(5),e.readUInt32BE(9));case 7:return this._onPiece(e.readUInt32BE(1),e.readUInt32BE(5),e.slice(9));case 8:return this._onCancel(e.readUInt32BE(1),e.readUInt32BE(5),e.readUInt32BE(9));case 9:return this._onPort(e.readUInt16BE(1));case 20:return this._onExtended(e.readUInt8(1),e.slice(2));default:this._debug("got unknown message");return this.emit("unknownmessage",e)}};w.prototype._parseHandshake=function(){this._parse(1,function(e){var t=e.readUInt8(0);this._parse(t+48,function(e){var r=e.slice(0,t);if(r.toString()!=="BitTorrent protocol"){this._debug("Error: wire not speaking BitTorrent protocol (%s)",r.toString());this.end();return}e=e.slice(t);this._onHandshake(e.slice(8,28),e.slice(28,48),{dht:!!(e[7]&1),extended:!!(e[5]&16)});this._parse(4,this._onmessagelength)}.bind(this))}.bind(this))};w.prototype._onfinish=function(){this._finished=true;this.push(null);while(this.read()){}clearInterval(this._keepAliveInterval);this._parse(Number.MAX_VALUE,function(){});this.peerRequests=[];while(this.requests.length){this._callback(this.requests.shift(),new Error("wire was closed"),null)}};w.prototype._debug=function(){var e=[].slice.call(arguments);e[0]="["+this._debugId+"] "+e[0];a.apply(null,e)};function x(e,t,r,i){for(var n=0;no){for(var t=0,r=i.length-s;ti._maxBufferedAmount){i._debug("start backpressure: bufferedAmount %d",i._channel.bufferedAmount);i._cb=r}else{r(null)}}else{i._debug("write before connect");i._chunk=e;i._cb=r}};c.prototype._createOffer=function(){var e=this;if(e.destroyed)return;e._pc.createOffer(function(t){if(e.destroyed)return;t.sdp=e.sdpTransform(t.sdp);e._pc.setLocalDescription(t,p,e._onError.bind(e));var r=function(){var r=e._pc.localDescription||t;e._debug("signal");e.emit("signal",{type:r.type,sdp:r.sdp})};if(e.trickle||e._iceComplete)r();else e.once("_iceComplete",r)},e._onError.bind(e),e.offerConstraints)};c.prototype._createAnswer=function(){var e=this;if(e.destroyed)return;e._pc.createAnswer(function(t){if(e.destroyed)return;t.sdp=e.sdpTransform(t.sdp);e._pc.setLocalDescription(t,p,e._onError.bind(e));var r=function(){var r=e._pc.localDescription||t;e._debug("signal");e.emit("signal",{type:r.type,sdp:r.sdp})};if(e.trickle||e._iceComplete)r();else e.once("_iceComplete",r)},e._onError.bind(e),e.answerConstraints)};c.prototype._onIceConnectionStateChange=function(){var e=this;if(e.destroyed)return;var t=e._pc.iceGatheringState;var r=e._pc.iceConnectionState;e._debug("iceConnectionStateChange %s %s",t,r);e.emit("iceConnectionStateChange",t,r);if(r==="connected"||r==="completed"){clearTimeout(e._reconnectTimeout);e._pcReady=true;e._maybeReady()}if(r==="disconnected"){if(e.reconnectTimer){clearTimeout(e._reconnectTimeout);e._reconnectTimeout=setTimeout(function(){e._destroy()},e.reconnectTimer)}else{e._destroy()}}if(r==="closed"){e._destroy()}};c.prototype._maybeReady=function(){var e=this;e._debug("maybeReady pc %s channel %s",e._pcReady,e._channelReady);if(e.connected||e._connecting||!e._pcReady||!e._channelReady)return;e._connecting=true;if(typeof window!=="undefined"&&!!window.mozRTCPeerConnection){e._pc.getStats(null,function(e){var r=[];e.forEach(function(e){r.push(e)});t(r)},e._onError.bind(e))}else{e._pc.getStats(function(e){var r=[];e.result().forEach(function(e){var t={};e.names().forEach(function(r){t[r]=e.stat(r)});t.id=e.id;t.type=e.type;t.timestamp=e.timestamp;r.push(t)});t(r)})}function t(t){t.forEach(function(t){if(t.type==="remotecandidate"){e.remoteAddress=t.ipAddress;e.remotePort=Number(t.portNumber);e.remoteFamily="IPv4";e._debug("connect remote: %s:%s (%s)",e.remoteAddress,e.remotePort,e.remoteFamily)}else if(t.type==="localcandidate"&&t.candidateType==="host"){e.localAddress=t.ipAddress;e.localPort=Number(t.portNumber);e._debug("connect local: %s:%s",e.localAddress,e.localPort)}});e._connecting=false;e.connected=true;if(e._chunk){try{e.send(e._chunk)}catch(r){return e._onError(r)}e._chunk=null;e._debug('sent chunk from "write before connect"');var i=e._cb;e._cb=null;i(null)}e._interval=setInterval(function(){if(!e._cb||!e._channel||e._channel.bufferedAmount>e._maxBufferedAmount)return;e._debug("ending backpressure: bufferedAmount %d",e._channel.bufferedAmount);var t=e._cb;e._cb=null;t(null)},150);if(e._interval.unref)e._interval.unref();e._debug("connect");e.emit("connect")}};c.prototype._onSignalingStateChange=function(){var e=this;if(e.destroyed)return;e._debug("signalingStateChange %s",e._pc.signalingState);e.emit("signalingStateChange",e._pc.signalingState)};c.prototype._onIceCandidate=function(e){var t=this;if(t.destroyed)return;if(e.candidate&&t.trickle){t.emit("signal",{candidate:{candidate:e.candidate.candidate,sdpMLineIndex:e.candidate.sdpMLineIndex,sdpMid:e.candidate.sdpMid}})}else if(!e.candidate){t._iceComplete=true;t.emit("_iceComplete")}};c.prototype._onChannelMessage=function(e){var t=this;if(t.destroyed)return;var r=e.data;t._debug("read: %d bytes",r.byteLength||r.length);if(r instanceof ArrayBuffer){r=l(new Uint8Array(r));t.push(r)}else{try{r=JSON.parse(r)}catch(i){}t.emit("data",r)}};c.prototype._onChannelOpen=function(){var e=this;if(e.connected||e.destroyed)return;e._debug("on channel open");e._channelReady=true;e._maybeReady()};c.prototype._onChannelClose=function(){var e=this;if(e.destroyed)return;e._debug("on channel close");e._destroy()};c.prototype._onAddStream=function(e){var t=this;if(t.destroyed)return;t._debug("on add stream");t.emit("stream",e.stream)};c.prototype._onError=function(e){var t=this;if(t.destroyed)return;t._debug("error %s",e.message||e);t._destroy(e)};c.prototype._debug=function(){var e=this;var t=[].slice.call(arguments);var r=e.channelName&&e.channelName.substring(0,7);t[0]="["+r+"] "+t[0];i.apply(null,t)};function p(){}}).call(this,e("buffer").Buffer)},{buffer:39,debug:120,"get-browser-rtc":31,hat:126,inherits:128,"is-typedarray":32,once:29,stream:66,"typedarray-to-buffer":33}],31:[function(e,t,r){t.exports=function i(){if(typeof window==="undefined")return null;var e={RTCPeerConnection:window.mozRTCPeerConnection||window.RTCPeerConnection||window.webkitRTCPeerConnection,RTCSessionDescription:window.mozRTCSessionDescription||window.RTCSessionDescription||window.webkitRTCSessionDescription,RTCIceCandidate:window.mozRTCIceCandidate||window.RTCIceCandidate||window.webkitRTCIceCandidate};if(!e.RTCPeerConnection)return null;return e}},{}],32:[function(e,t,r){t.exports=a;a.strict=s;a.loose=o;var i=Object.prototype.toString;var n={"[object Int8Array]":true,"[object Int16Array]":true,"[object Int32Array]":true,"[object Uint8Array]":true,"[object Uint8ClampedArray]":true,"[object Uint16Array]":true,"[object Uint32Array]":true,"[object Float32Array]":true,"[object Float64Array]":true};function a(e){return s(e)||o(e)}function s(e){return e instanceof Int8Array||e instanceof Int16Array||e instanceof Int32Array||e instanceof Uint8Array||e instanceof Uint8ClampedArray||e instanceof Uint16Array||e instanceof Uint32Array||e instanceof Float32Array||e instanceof Float64Array}function o(e){return n[i.call(e)]}},{}],33:[function(e,t,r){(function(r){var i=e("is-typedarray").strict;t.exports=function(e){var t=r.TYPED_ARRAY_SUPPORT?r._augment:function(e){return new r(e)};if(e instanceof Uint8Array){return t(e)}else if(e instanceof ArrayBuffer){return t(new Uint8Array(e))}else if(i(e)){return t(new Uint8Array(e.buffer,e.byteOffset,e.byteLength))}else{return new r(e)}}}).call(this,e("buffer").Buffer)},{buffer:39,"is-typedarray":32}],34:[function(e,t,r){(function(r){t.exports=l;var i=e("debug")("simple-websocket");var n=e("inherits");var a=e("is-typedarray");var s=e("stream");var o=e("typedarray-to-buffer");var f=e("ws");var u=typeof window!=="undefined"?window.WebSocket:f;n(l,s.Duplex);function l(e,t){var r=this;if(!(r instanceof l))return new l(e,t);if(!t)t={};i("new websocket: %s %o",e,t);t.allowHalfOpen=false;if(t.highWaterMark==null)t.highWaterMark=1024*1024;s.Duplex.call(r,t);r.url=e;r.connected=false;r.destroyed=false;r._maxBufferedAmount=t.highWaterMark;r._chunk=null;r._cb=null;r._interval=null;r._ws=new u(r.url);r._ws.binaryType="arraybuffer";r._ws.onopen=r._onOpen.bind(r);r._ws.onmessage=r._onMessage.bind(r);r._ws.onclose=r._onClose.bind(r);r._ws.onerror=function(){r._onError(new Error("connection error to "+r.url))};r.on("finish",function(){if(r.connected){setTimeout(function(){r._destroy()},100)}else{r.once("connect",function(){setTimeout(function(){r._destroy()},100)})}})}l.prototype.send=function(e){var t=this;if(!a.strict(e)&&!(e instanceof ArrayBuffer)&&!r.isBuffer(e)&&typeof e!=="string"&&(typeof Blob==="undefined"||!(e instanceof Blob))){e=JSON.stringify(e)}var n=e.length||e.byteLength||e.size;t._ws.send(e);i("write: %d bytes",n)};l.prototype.destroy=function(e){var t=this;t._destroy(null,e)};l.prototype._destroy=function(e,t){var r=this;if(r.destroyed)return;if(t)r.once("close",t);i("destroy (error: %s)",e&&e.message);this.readable=this.writable=false;if(!r._readableState.ended)r.push(null);if(!r._writableState.finished)r.end();r.connected=false;r.destroyed=true;clearInterval(r._interval);r._interval=null;r._chunk=null;r._cb=null;if(r._ws){var n=r._ws;var a=function(){n.onclose=null;r.emit("close")};if(n.readyState===u.CLOSED){a()}else{try{n.onclose=a;n.close()}catch(e){a()}}n.onopen=null;n.onmessage=null;n.onerror=null}r._ws=null;if(e)r.emit("error",e)};l.prototype._read=function(){};l.prototype._write=function(e,t,r){var n=this;if(n.destroyed)return r(new Error("cannot write after socket is destroyed"));if(n.connected){try{n.send(e)}catch(a){return n._onError(a)}if(typeof f!=="function"&&n._ws.bufferedAmount>n._maxBufferedAmount){i("start backpressure: bufferedAmount %d",n._ws.bufferedAmount);n._cb=r}else{r(null)}}else{i("write before connect");n._chunk=e;n._cb=r}};l.prototype._onMessage=function(e){var t=this;if(t.destroyed)return;var n=e.data;i("read: %d bytes",n.byteLength||n.length);if(n instanceof ArrayBuffer){n=o(new Uint8Array(n));t.push(n)}else if(r.isBuffer(n)){t.push(n)}else{try{n=JSON.parse(n)}catch(a){}t.emit("data",n)}};l.prototype._onOpen=function(){var e=this;if(e.connected||e.destroyed)return;e.connected=true;if(e._chunk){try{e.send(e._chunk)}catch(t){return e._onError(t)}e._chunk=null;i('sent chunk from "write before connect"');var r=e._cb;e._cb=null;r(null)}if(typeof f!=="function"){e._interval=setInterval(function(){if(!e._cb||!e._ws||e._ws.bufferedAmount>e._maxBufferedAmount){return}i("ending backpressure: bufferedAmount %d",e._ws.bufferedAmount);var t=e._cb;e._cb=null;t(null)},150);if(e._interval.unref)e._interval.unref()}i("connect");e.emit("connect")};l.prototype._onClose=function(){var e=this;if(e.destroyed)return;i("on close");e._destroy()};l.prototype._onError=function(e){var t=this;if(t.destroyed)return;i("error: %s",e.message||e);t._destroy(e)}}).call(this,e("buffer").Buffer)},{buffer:39,debug:120,inherits:128,"is-typedarray":35,stream:66,"typedarray-to-buffer":36,ws:38}],35:[function(e,t,r){arguments[4][32][0].apply(r,arguments)},{dup:32}],36:[function(e,t,r){arguments[4][33][0].apply(r,arguments)},{buffer:39,dup:33,"is-typedarray":35}],37:[function(e,t,r){},{}],38:[function(e,t,r){arguments[4][37][0].apply(r,arguments)},{dup:37}],39:[function(e,t,r){var i=e("base64-js");var n=e("ieee754");var a=e("is-array");r.Buffer=f;r.SlowBuffer=b;r.INSPECT_MAX_BYTES=50;f.poolSize=8192;var s={};f.TYPED_ARRAY_SUPPORT=function(){function e(){}try{var t=new Uint8Array(1);t.foo=function(){return 42};t.constructor=e;return t.foo()===42&&t.constructor===e&&typeof t.subarray==="function"&&t.subarray(1,1).byteLength===0}catch(r){return false}}();function o(){return f.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function f(e){if(!(this instanceof f)){if(arguments.length>1)return new f(e,arguments[1]);return new f(e)}this.length=0;this.parent=undefined;if(typeof e==="number"){return u(this,e)}if(typeof e==="string"){return l(this,e,arguments.length>1?arguments[1]:"utf8")}return c(this,e)}function u(e,t){e=y(e,t<0?0:_(t)|0);if(!f.TYPED_ARRAY_SUPPORT){for(var r=0;r>>1;if(r)e.parent=s;return e}function _(e){if(e>=o()){throw new RangeError("Attempt to allocate Buffer larger than maximum "+"size: 0x"+o().toString(16)+" bytes")}return e|0}function b(e,t){if(!(this instanceof b))return new b(e,t);var r=new f(e,t);delete r.parent;return r}f.isBuffer=function ee(e){return!!(e!=null&&e._isBuffer)};f.compare=function te(e,t){if(!f.isBuffer(e)||!f.isBuffer(t)){throw new TypeError("Arguments must be Buffers")}if(e===t)return 0;var r=e.length;var i=t.length;var n=0;var a=Math.min(r,i);while(n>>1;case"base64":return J(e).length;default:if(i)return $(e).length;t=(""+t).toLowerCase();i=true}}}f.byteLength=w;f.prototype.length=undefined;f.prototype.parent=undefined;function x(e,t,r){var i=false;t=t|0;r=r===undefined||r===Infinity?this.length:r|0;if(!e)e="utf8";if(t<0)t=0;if(r>this.length)r=this.length;if(r<=t)return"";while(true){switch(e){case"hex":return z(this,t,r);case"utf8":case"utf-8":return L(this,t,r);case"ascii":return R(this,t,r);case"binary":return P(this,t,r);case"base64":return T(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,t,r);default:if(i)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase();i=true}}}f.prototype.toString=function ne(){var e=this.length|0;if(e===0)return"";if(arguments.length===0)return L(this,0,e);return x.apply(this,arguments)};f.prototype.equals=function ae(e){if(!f.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(this===e)return true;return f.compare(this,e)===0};f.prototype.inspect=function se(){var e="";var t=r.INSPECT_MAX_BYTES;if(this.length>0){e=this.toString("hex",0,t).match(/.{2}/g).join(" ");if(this.length>t)e+=" ... "}return""};f.prototype.compare=function oe(e){if(!f.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(this===e)return 0;return f.compare(this,e)};f.prototype.indexOf=function fe(e,t){if(t>2147483647)t=2147483647;else if(t<-2147483648)t=-2147483648;t>>=0;if(this.length===0)return-1;if(t>=this.length)return-1;if(t<0)t=Math.max(this.length+t,0);if(typeof e==="string"){if(e.length===0)return-1;return String.prototype.indexOf.call(this,e,t)}if(f.isBuffer(e)){return r(this,e,t)}if(typeof e==="number"){if(f.TYPED_ARRAY_SUPPORT&&Uint8Array.prototype.indexOf==="function"){return Uint8Array.prototype.indexOf.call(this,e,t)}return r(this,[e],t)}function r(e,t,r){var i=-1;for(var n=0;r+nn){i=n}}var a=t.length;if(a%2!==0)throw new Error("Invalid hex string");if(i>a/2){i=a/2}for(var s=0;sa)r=a;if(e.length>0&&(r<0||t<0)||t>this.length){throw new RangeError("attempt to write outside buffer bounds")}if(!i)i="utf8";var s=false;for(;;){switch(i){case"hex":return k(this,e,t,r);case"utf8":case"utf-8":return S(this,e,t,r);case"ascii":return E(this,e,t,r);case"binary":return A(this,e,t,r);case"base64":return U(this,e,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return I(this,e,t,r);default:if(s)throw new TypeError("Unknown encoding: "+i);i=(""+i).toLowerCase();s=true}}};f.prototype.toJSON=function pe(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function T(e,t,r){if(t===0&&r===e.length){return i.fromByteArray(e)}else{return i.fromByteArray(e.slice(t,r))}}function L(e,t,r){r=Math.min(e.length,r);var i=[];var n=t;while(n239?4:a>223?3:a>191?2:1;if(n+o<=r){var f,u,l,c;switch(o){case 1:if(a<128){s=a}break;case 2:f=e[n+1];if((f&192)===128){c=(a&31)<<6|f&63;if(c>127){s=c}}break;case 3:f=e[n+1];u=e[n+2];if((f&192)===128&&(u&192)===128){c=(a&15)<<12|(f&63)<<6|u&63;if(c>2047&&(c<55296||c>57343)){s=c}}break;case 4:f=e[n+1];u=e[n+2];l=e[n+3];if((f&192)===128&&(u&192)===128&&(l&192)===128){c=(a&15)<<18|(f&63)<<12|(u&63)<<6|l&63;if(c>65535&&c<1114112){s=c}}}}if(s===null){s=65533;o=1}else if(s>65535){s-=65536;i.push(s>>>10&1023|55296);s=56320|s&1023}i.push(s);n+=o}return C(i)}var B=4096;function C(e){var t=e.length;if(t<=B){return String.fromCharCode.apply(String,e)}var r="";var i=0;while(ii)r=i;var n="";for(var a=t;ar){e=r}if(t<0){t+=r;if(t<0)t=0}else if(t>r){t=r}if(tr)throw new RangeError("Trying to access beyond buffer length")}f.prototype.readUIntLE=function he(e,t,r){e=e|0;t=t|0;if(!r)F(e,t,this.length);var i=this[e];var n=1;var a=0;while(++a0&&(n*=256)){i+=this[e+--t]*n}return i};f.prototype.readUInt8=function ve(e,t){if(!t)F(e,1,this.length);return this[e]};f.prototype.readUInt16LE=function ge(e,t){if(!t)F(e,2,this.length);return this[e]|this[e+1]<<8};f.prototype.readUInt16BE=function ye(e,t){if(!t)F(e,2,this.length);return this[e]<<8|this[e+1]};f.prototype.readUInt32LE=function _e(e,t){if(!t)F(e,4,this.length);return(this[e]|this[e+1]<<8|this[e+2]<<16)+this[e+3]*16777216};f.prototype.readUInt32BE=function be(e,t){if(!t)F(e,4,this.length);return this[e]*16777216+(this[e+1]<<16|this[e+2]<<8|this[e+3])};f.prototype.readIntLE=function we(e,t,r){e=e|0;t=t|0;if(!r)F(e,t,this.length);var i=this[e];var n=1;var a=0;while(++a=n)i-=Math.pow(2,8*t);return i};f.prototype.readIntBE=function xe(e,t,r){e=e|0;t=t|0;if(!r)F(e,t,this.length);var i=t;var n=1;var a=this[e+--i];while(i>0&&(n*=256)){a+=this[e+--i]*n}n*=128;if(a>=n)a-=Math.pow(2,8*t);return a};f.prototype.readInt8=function ke(e,t){if(!t)F(e,1,this.length);if(!(this[e]&128))return this[e];return(255-this[e]+1)*-1};f.prototype.readInt16LE=function Se(e,t){if(!t)F(e,2,this.length);var r=this[e]|this[e+1]<<8;return r&32768?r|4294901760:r};f.prototype.readInt16BE=function Ee(e,t){if(!t)F(e,2,this.length);var r=this[e+1]|this[e]<<8;return r&32768?r|4294901760:r};f.prototype.readInt32LE=function Ae(e,t){if(!t)F(e,4,this.length);return this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24};f.prototype.readInt32BE=function Ue(e,t){if(!t)F(e,4,this.length);return this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]};f.prototype.readFloatLE=function Ie(e,t){if(!t)F(e,4,this.length);return n.read(this,e,true,23,4)};f.prototype.readFloatBE=function Te(e,t){if(!t)F(e,4,this.length);return n.read(this,e,false,23,4)};f.prototype.readDoubleLE=function Le(e,t){if(!t)F(e,8,this.length);return n.read(this,e,true,52,8)};f.prototype.readDoubleBE=function Be(e,t){if(!t)F(e,8,this.length);return n.read(this,e,false,52,8)};function M(e,t,r,i,n,a){if(!f.isBuffer(e))throw new TypeError("buffer must be a Buffer instance");if(t>n||te.length)throw new RangeError("index out of range")}f.prototype.writeUIntLE=function Ce(e,t,r,i){e=+e;t=t|0;r=r|0;if(!i)M(this,e,t,r,Math.pow(2,8*r),0);var n=1;var a=0;this[t]=e&255;while(++a=0&&(a*=256)){this[t+n]=e/a&255}return t+r};f.prototype.writeUInt8=function Pe(e,t,r){e=+e;t=t|0;if(!r)M(this,e,t,1,255,0);if(!f.TYPED_ARRAY_SUPPORT)e=Math.floor(e);this[t]=e;return t+1};function j(e,t,r,i){if(t<0)t=65535+t+1;for(var n=0,a=Math.min(e.length-r,2);n>>(i?n:1-n)*8}}f.prototype.writeUInt16LE=function ze(e,t,r){e=+e;t=t|0;if(!r)M(this,e,t,2,65535,0);if(f.TYPED_ARRAY_SUPPORT){this[t]=e;this[t+1]=e>>>8}else{j(this,e,t,true)}return t+2};f.prototype.writeUInt16BE=function Oe(e,t,r){e=+e;t=t|0;if(!r)M(this,e,t,2,65535,0);if(f.TYPED_ARRAY_SUPPORT){this[t]=e>>>8;this[t+1]=e}else{j(this,e,t,false)}return t+2};function D(e,t,r,i){if(t<0)t=4294967295+t+1;for(var n=0,a=Math.min(e.length-r,4);n>>(i?n:3-n)*8&255}}f.prototype.writeUInt32LE=function Fe(e,t,r){e=+e;t=t|0;if(!r)M(this,e,t,4,4294967295,0);if(f.TYPED_ARRAY_SUPPORT){this[t+3]=e>>>24;this[t+2]=e>>>16;this[t+1]=e>>>8;this[t]=e}else{D(this,e,t,true)}return t+4};f.prototype.writeUInt32BE=function Me(e,t,r){e=+e;t=t|0;if(!r)M(this,e,t,4,4294967295,0);if(f.TYPED_ARRAY_SUPPORT){this[t]=e>>>24;this[t+1]=e>>>16;this[t+2]=e>>>8;this[t+3]=e}else{D(this,e,t,false)}return t+4};f.prototype.writeIntLE=function je(e,t,r,i){e=+e;t=t|0;if(!i){var n=Math.pow(2,8*r-1);M(this,e,t,r,n-1,-n)}var a=0;var s=1;var o=e<0?1:0;this[t]=e&255;while(++a>0)-o&255}return t+r};f.prototype.writeIntBE=function De(e,t,r,i){e=+e;t=t|0;if(!i){var n=Math.pow(2,8*r-1);M(this,e,t,r,n-1,-n)}var a=r-1;var s=1;var o=e<0?1:0;this[t+a]=e&255;while(--a>=0&&(s*=256)){this[t+a]=(e/s>>0)-o&255}return t+r};f.prototype.writeInt8=function Ne(e,t,r){ +e=+e;t=t|0;if(!r)M(this,e,t,1,127,-128);if(!f.TYPED_ARRAY_SUPPORT)e=Math.floor(e);if(e<0)e=255+e+1;this[t]=e;return t+1};f.prototype.writeInt16LE=function He(e,t,r){e=+e;t=t|0;if(!r)M(this,e,t,2,32767,-32768);if(f.TYPED_ARRAY_SUPPORT){this[t]=e;this[t+1]=e>>>8}else{j(this,e,t,true)}return t+2};f.prototype.writeInt16BE=function qe(e,t,r){e=+e;t=t|0;if(!r)M(this,e,t,2,32767,-32768);if(f.TYPED_ARRAY_SUPPORT){this[t]=e>>>8;this[t+1]=e}else{j(this,e,t,false)}return t+2};f.prototype.writeInt32LE=function Ge(e,t,r){e=+e;t=t|0;if(!r)M(this,e,t,4,2147483647,-2147483648);if(f.TYPED_ARRAY_SUPPORT){this[t]=e;this[t+1]=e>>>8;this[t+2]=e>>>16;this[t+3]=e>>>24}else{D(this,e,t,true)}return t+4};f.prototype.writeInt32BE=function We(e,t,r){e=+e;t=t|0;if(!r)M(this,e,t,4,2147483647,-2147483648);if(e<0)e=4294967295+e+1;if(f.TYPED_ARRAY_SUPPORT){this[t]=e>>>24;this[t+1]=e>>>16;this[t+2]=e>>>8;this[t+3]=e}else{D(this,e,t,false)}return t+4};function N(e,t,r,i,n,a){if(t>n||te.length)throw new RangeError("index out of range");if(r<0)throw new RangeError("index out of range")}function H(e,t,r,i,a){if(!a){N(e,t,r,4,3.4028234663852886e38,-3.4028234663852886e38)}n.write(e,t,r,i,23,4);return r+4}f.prototype.writeFloatLE=function Ve(e,t,r){return H(this,e,t,true,r)};f.prototype.writeFloatBE=function Ye(e,t,r){return H(this,e,t,false,r)};function q(e,t,r,i,a){if(!a){N(e,t,r,8,1.7976931348623157e308,-1.7976931348623157e308)}n.write(e,t,r,i,52,8);return r+8}f.prototype.writeDoubleLE=function Ke(e,t,r){return q(this,e,t,true,r)};f.prototype.writeDoubleBE=function $e(e,t,r){return q(this,e,t,false,r)};f.prototype.copy=function Ze(e,t,r,i){if(!r)r=0;if(!i&&i!==0)i=this.length;if(t>=e.length)t=e.length;if(!t)t=0;if(i>0&&i=this.length)throw new RangeError("sourceStart out of bounds");if(i<0)throw new RangeError("sourceEnd out of bounds");if(i>this.length)i=this.length;if(e.length-t=0;a--){e[a+t]=this[a+r]}}else if(n<1e3||!f.TYPED_ARRAY_SUPPORT){for(a=0;a=this.length)throw new RangeError("start out of bounds");if(r<0||r>this.length)throw new RangeError("end out of bounds");var i;if(typeof e==="number"){for(i=t;i55295&&r<57344){if(!n){if(r>56319){if((t-=3)>-1)a.push(239,191,189);continue}else if(s+1===i){if((t-=3)>-1)a.push(239,191,189);continue}n=r;continue}if(r<56320){if((t-=3)>-1)a.push(239,191,189);n=r;continue}r=n-55296<<10|r-56320|65536}else if(n){if((t-=3)>-1)a.push(239,191,189)}n=null;if(r<128){if((t-=1)<0)break;a.push(r)}else if(r<2048){if((t-=2)<0)break;a.push(r>>6|192,r&63|128)}else if(r<65536){if((t-=3)<0)break;a.push(r>>12|224,r>>6&63|128,r&63|128)}else if(r<1114112){if((t-=4)<0)break;a.push(r>>18|240,r>>12&63|128,r>>6&63|128,r&63|128)}else{throw new Error("Invalid code point")}}return a}function Z(e){var t=[];for(var r=0;r>8;n=r%256;a.push(n);a.push(i)}return a}function J(e){return i.toByteArray(V(e))}function Q(e,t,r,i){for(var n=0;n=t.length||n>=e.length)break;t[n+r]=e[n]}return n}},{"base64-js":40,ieee754:41,"is-array":42}],40:[function(e,t,r){var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";(function(e){"use strict";var t=typeof Uint8Array!=="undefined"?Uint8Array:Array;var r="+".charCodeAt(0);var n="/".charCodeAt(0);var a="0".charCodeAt(0);var s="a".charCodeAt(0);var o="A".charCodeAt(0);var f="-".charCodeAt(0);var u="_".charCodeAt(0);function l(e){var t=e.charCodeAt(0);if(t===r||t===f)return 62;if(t===n||t===u)return 63;if(t0){throw new Error("Invalid string. Length must be a multiple of 4")}var f=e.length;s="="===e.charAt(f-2)?2:"="===e.charAt(f-1)?1:0;o=new t(e.length*3/4-s);n=s>0?e.length-4:e.length;var u=0;function c(e){o[u++]=e}for(r=0,i=0;r>16);c((a&65280)>>8);c(a&255)}if(s===2){a=l(e.charAt(r))<<2|l(e.charAt(r+1))>>4;c(a&255)}else if(s===1){a=l(e.charAt(r))<<10|l(e.charAt(r+1))<<4|l(e.charAt(r+2))>>2;c(a>>8&255);c(a&255)}return o}function p(e){var t,r=e.length%3,n="",a,s;function o(e){return i.charAt(e)}function f(e){return o(e>>18&63)+o(e>>12&63)+o(e>>6&63)+o(e&63)}for(t=0,s=e.length-r;t>2);n+=o(a<<4&63);n+="==";break;case 2:a=(e[e.length-2]<<8)+e[e.length-1];n+=o(a>>10);n+=o(a>>4&63);n+=o(a<<2&63);n+="=";break}return n}e.toByteArray=c;e.fromByteArray=p})(typeof r==="undefined"?this.base64js={}:r)},{}],41:[function(e,t,r){r.read=function(e,t,r,i,n){var a,s;var o=n*8-i-1;var f=(1<>1;var l=-7;var c=r?n-1:0;var p=r?-1:1;var d=e[t+c];c+=p;a=d&(1<<-l)-1;d>>=-l;l+=o;for(;l>0;a=a*256+e[t+c],c+=p,l-=8){}s=a&(1<<-l)-1;a>>=-l;l+=i;for(;l>0;s=s*256+e[t+c],c+=p,l-=8){}if(a===0){a=1-u}else if(a===f){return s?NaN:(d?-1:1)*Infinity}else{s=s+Math.pow(2,i);a=a-u}return(d?-1:1)*s*Math.pow(2,a-i)};r.write=function(e,t,r,i,n,a){var s,o,f;var u=a*8-n-1;var l=(1<>1;var p=n===23?Math.pow(2,-24)-Math.pow(2,-77):0;var d=i?0:a-1;var h=i?1:-1;var m=t<0||t===0&&1/t<0?1:0;t=Math.abs(t);if(isNaN(t)||t===Infinity){o=isNaN(t)?1:0;s=l}else{s=Math.floor(Math.log(t)/Math.LN2);if(t*(f=Math.pow(2,-s))<1){s--;f*=2}if(s+c>=1){t+=p/f}else{t+=p*Math.pow(2,1-c)}if(t*f>=2){s++;f/=2}if(s+c>=l){o=0;s=l}else if(s+c>=1){o=(t*f-1)*Math.pow(2,n);s=s+c}else{o=t*Math.pow(2,c-1)*Math.pow(2,n);s=0}}for(;n>=8;e[r+d]=o&255,d+=h,o/=256,n-=8){}s=s<0;e[r+d]=s&255,d+=h,s/=256,u-=8){}e[r+d-h]|=m*128}},{}],42:[function(e,t,r){var i=Array.isArray;var n=Object.prototype.toString;t.exports=i||function(e){return!!e&&"[object Array]"==n.call(e)}},{}],43:[function(e,t,r){function i(){this._events=this._events||{};this._maxListeners=this._maxListeners||undefined}t.exports=i;i.EventEmitter=i;i.prototype._events=undefined;i.prototype._maxListeners=undefined;i.defaultMaxListeners=100;i.prototype.setMaxListeners=function(e){if(!a(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");this._maxListeners=e;return this};i.prototype.emit=function(e){var t,r,i,a,f,u;if(!this._events)this._events={};if(e==="error"){if(!this._events.error||s(this._events.error)&&!this._events.error.length){t=arguments[1];if(t instanceof Error){throw t}throw TypeError('Uncaught, unspecified "error" event.')}}r=this._events[e];if(o(r))return false;if(n(r)){switch(arguments.length){case 1:r.call(this);break;case 2:r.call(this,arguments[1]);break;case 3:r.call(this,arguments[1],arguments[2]);break;default:i=arguments.length;a=new Array(i-1);for(f=1;f0&&this._events[e].length>r){this._events[e].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[e].length);if(typeof console.trace==="function"){console.trace()}}}return this};i.prototype.on=i.prototype.addListener;i.prototype.once=function(e,t){if(!n(t))throw TypeError("listener must be a function");var r=false;function i(){this.removeListener(e,i);if(!r){r=true;t.apply(this,arguments)}}i.listener=t;this.on(e,i);return this};i.prototype.removeListener=function(e,t){var r,i,a,o;if(!n(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;r=this._events[e];a=r.length;i=-1;if(r===t||n(r.listener)&&r.listener===t){delete this._events[e];if(this._events.removeListener)this.emit("removeListener",e,t)}else if(s(r)){for(o=a;o-->0;){if(r[o]===t||r[o].listener&&r[o].listener===t){i=o;break}}if(i<0)return this;if(r.length===1){r.length=0;delete this._events[e]}else{r.splice(i,1)}if(this._events.removeListener)this.emit("removeListener",e,t)}return this};i.prototype.removeAllListeners=function(e){var t,r;if(!this._events)return this;if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[e])delete this._events[e];return this}if(arguments.length===0){for(t in this._events){if(t==="removeListener")continue;this.removeAllListeners(t)}this.removeAllListeners("removeListener");this._events={};return this}r=this._events[e];if(n(r)){this.removeListener(e,r)}else{while(r.length)this.removeListener(e,r[r.length-1])}delete this._events[e];return this};i.prototype.listeners=function(e){var t;if(!this._events||!this._events[e])t=[];else if(n(this._events[e]))t=[this._events[e]];else t=this._events[e].slice();return t};i.listenerCount=function(e,t){var r;if(!e._events||!e._events[t])r=0;else if(n(e._events[t]))r=1;else r=e._events[t].length;return r};function n(e){return typeof e==="function"}function a(e){return typeof e==="number"}function s(e){return typeof e==="object"&&e!==null}function o(e){return e===void 0}},{}],44:[function(e,t,r){var i=e("http");var n=t.exports;for(var a in i){if(i.hasOwnProperty(a))n[a]=i[a]}n.request=function(e,t){if(!e)e={};e.scheme="https";return i.request.call(this,e,t)}},{http:67}],45:[function(e,t,r){t.exports=Array.isArray||function(e){return Object.prototype.toString.call(e)=="[object Array]"}},{}],46:[function(e,t,r){r.endianness=function(){return"LE"};r.hostname=function(){if(typeof location!=="undefined"){return location.hostname}else return""};r.loadavg=function(){return[]};r.uptime=function(){return 0};r.freemem=function(){return Number.MAX_VALUE};r.totalmem=function(){return Number.MAX_VALUE};r.cpus=function(){return[]};r.type=function(){return"Browser"};r.release=function(){if(typeof navigator!=="undefined"){return navigator.appVersion}return""};r.networkInterfaces=r.getNetworkInterfaces=function(){return{}};r.arch=function(){return"javascript"};r.platform=function(){return"browser"};r.tmpdir=r.tmpDir=function(){return"/tmp"};r.EOL="\n"},{}],47:[function(e,t,r){(function(e){function t(e,t){var r=0;for(var i=e.length-1;i>=0;i--){var n=e[i];if(n==="."){e.splice(i,1)}else if(n===".."){e.splice(i,1);r++}else if(r){e.splice(i,1);r--}}if(t){for(;r--;r){e.unshift("..")}}return e}var i=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;var n=function(e){return i.exec(e).slice(1)};r.resolve=function(){var r="",i=false;for(var n=arguments.length-1;n>=-1&&!i;n--){var s=n>=0?arguments[n]:e.cwd();if(typeof s!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!s){continue}r=s+"/"+r;i=s.charAt(0)==="/"}r=t(a(r.split("/"),function(e){return!!e}),!i).join("/");return(i?"/":"")+r||"."};r.normalize=function(e){var i=r.isAbsolute(e),n=s(e,-1)==="/";e=t(a(e.split("/"),function(e){return!!e}),!i).join("/");if(!e&&!i){e="."}if(e&&n){e+="/"}return(i?"/":"")+e};r.isAbsolute=function(e){return e.charAt(0)==="/"};r.join=function(){var e=Array.prototype.slice.call(arguments,0);return r.normalize(a(e,function(e,t){if(typeof e!=="string"){throw new TypeError("Arguments to path.join must be strings")}return e}).join("/"))};r.relative=function(e,t){e=r.resolve(e).substr(1);t=r.resolve(t).substr(1);function i(e){var t=0;for(;t=0;r--){if(e[r]!=="")break}if(t>r)return[];return e.slice(t,r-t+1)}var n=i(e.split("/"));var a=i(t.split("/"));var s=Math.min(n.length,a.length);var o=s;for(var f=0;f1){for(var r=1;r= 0x80 (not a basic code point)","invalid-input":"Invalid input"},x=l-c,k=Math.floor,S=String.fromCharCode,E;function A(e){throw RangeError(w[e])}function U(e,t){var r=e.length;var i=[];while(r--){i[r]=t(e[r])}return i}function I(e,t){var r=e.split("@");var i="";if(r.length>1){i=r[0]+"@";e=r[1]}e=e.replace(b,".");var n=e.split(".");var a=U(n,t).join(".");return i+a}function T(e){var t=[],r=0,i=e.length,n,a;while(r=55296&&n<=56319&&r65535){e-=65536;t+=S(e>>>10&1023|55296);e=56320|e&1023}t+=S(e);return t}).join("")}function B(e){if(e-48<10){return e-22}if(e-65<26){return e-65}if(e-97<26){return e-97}return l}function C(e,t){return e+22+75*(e<26)-((t!=0)<<5)}function R(e,t,r){var i=0;e=r?k(e/h):e>>1;e+=k(e/t);for(;e>x*p>>1;i+=l){e=k(e/x)}return k(i+(x+1)*e/(e+d))}function P(e){var t=[],r=e.length,i,n=0,a=v,s=m,o,f,d,h,y,_,b,w,x;o=e.lastIndexOf(g);if(o<0){o=0}for(f=0;f=128){A("not-basic")}t.push(e.charCodeAt(f))}for(d=o>0?o+1:0;d=r){A("invalid-input")}b=B(e.charCodeAt(d++));if(b>=l||b>k((u-n)/y)){A("overflow")}n+=b*y;w=_<=s?c:_>=s+p?p:_-s;if(bk(u/x)){A("overflow")}y*=x}i=t.length+1;s=R(n-h,i,h==0);if(k(n/i)>u-a){A("overflow")}a+=k(n/i);n%=i;t.splice(n++,0,a)}return L(t)}function z(e){var t,r,i,n,a,s,o,f,d,h,y,_=[],b,w,x,E;e=T(e);b=e.length;t=v;r=0;a=m;for(s=0;s=t&&yk((u-r)/w)){A("overflow")}r+=(o-t)*w;t=o;for(s=0;su){A("overflow")}if(y==t){for(f=r,d=l;;d+=l){h=d<=a?c:d>=a+p?p:d-a;if(f0&&u>f){u=f}for(var l=0;l=0){d=c.substr(0,p);h=c.substr(p+1)}else{d=c;h=""}m=decodeURIComponent(d);v=decodeURIComponent(h);if(!i(s,m)){s[m]=v}else if(n(s[m])){s[m].push(v)}else{s[m]=[s[m],v]}}return s};var n=Array.isArray||function(e){return Object.prototype.toString.call(e)==="[object Array]"}},{}],51:[function(e,t,r){"use strict";var i=function(e){switch(typeof e){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return""}};t.exports=function(e,t,r,o){t=t||"&";r=r||"=";if(e===null){e=undefined}if(typeof e==="object"){return a(s(e),function(s){var o=encodeURIComponent(i(s))+r;if(n(e[s])){return a(e[s],function(e){return o+encodeURIComponent(i(e))}).join(t)}else{return o+encodeURIComponent(i(e[s]))}}).join(t)}if(!o)return"";return encodeURIComponent(i(o))+r+encodeURIComponent(i(e))};var n=Array.isArray||function(e){return Object.prototype.toString.call(e)==="[object Array]"};function a(e,t){if(e.map)return e.map(t);var r=[];for(var i=0;i0){if(t.ended&&!n){var s=new Error("stream.push() after EOF");e.emit("error",s)}else if(t.endEmitted&&n){var s=new Error("stream.unshift() after end event");e.emit("error",s)}else{if(t.decoder&&!n&&!i)r=t.decoder.write(r);if(!n)t.reading=false;if(t.flowing&&t.length===0&&!t.sync){e.emit("data",r);e.read(0)}else{t.length+=t.objectMode?1:r.length;if(n)t.buffer.unshift(r);else t.buffer.push(r);if(t.needReadable)b(e)}x(e,t)}}else if(!n){t.reading=false}return h(t)}function h(e){return!e.ended&&(e.needReadable||e.length=m){e=m}else{e--;for(var t=1;t<32;t<<=1)e|=e>>t;e++}return e}function g(e,t){if(t.length===0&&t.ended)return 0;if(t.objectMode)return e===0?0:1;if(e===null||isNaN(e)){if(t.flowing&&t.buffer.length)return t.buffer[0].length;else return t.length}if(e<=0)return 0;if(e>t.highWaterMark)t.highWaterMark=v(e);if(e>t.length){if(!t.ended){t.needReadable=true;return 0}else{return t.length}}return e}p.prototype.read=function(e){u("read",e);var t=this._readableState;var r=e;if(typeof e!=="number"||e>0)t.emittedReadable=false;if(e===0&&t.needReadable&&(t.length>=t.highWaterMark||t.ended)){u("read: emitReadable",t.length,t.ended);if(t.length===0&&t.ended)L(this);else b(this);return null}e=g(e,t);if(e===0&&t.ended){if(t.length===0)L(this);return null}var i=t.needReadable;u("need readable",i);if(t.length===0||t.length-e0)n=T(e,t);else n=null;if(n===null){t.needReadable=true;e=0}t.length-=e;if(t.length===0&&!t.ended)t.needReadable=true;if(r!==e&&t.ended&&t.length===0)L(this);if(n!==null)this.emit("data",n);return n};function y(e,t){var r=null;if(!a.isBuffer(t)&&typeof t!=="string"&&t!==null&&t!==undefined&&!e.objectMode){r=new TypeError("Invalid non-string/buffer chunk")}return r}function _(e,t){if(t.ended)return;if(t.decoder){var r=t.decoder.end();if(r&&r.length){t.buffer.push(r);t.length+=t.objectMode?1:r.length}}t.ended=true;b(e)}function b(e){var t=e._readableState;t.needReadable=false;if(!t.emittedReadable){u("emitReadable",t.flowing);t.emittedReadable=true;if(t.sync)i(w,e);else w(e)}}function w(e){u("emit readable");e.emit("readable");I(e)}function x(e,t){if(!t.readingMore){t.readingMore=true;i(k,e,t)}}function k(e,t){var r=t.length;while(!t.reading&&!t.flowing&&!t.ended&&t.length=i){if(n)o=r.join("");else o=a.concat(r,i);r.length=0}else{if(e0)throw new Error("endReadable called on non-empty stream");if(!t.endEmitted){t.ended=true;i(B,t,e)}}function B(e,t){if(!e.endEmitted&&e.length===0){e.endEmitted=true; +t.readable=false;t.emit("end")}}function C(e,t){for(var r=0,i=e.length;r-1))throw new TypeError("Unknown encoding: "+e);this._writableState.defaultEncoding=e};function d(e,t,r){if(!e.objectMode&&e.decodeStrings!==false&&typeof t==="string"){t=new n(t,r)}return t}function h(e,t,r,i,a){r=d(t,r,i);if(n.isBuffer(r))i="buffer";var s=t.objectMode?1:r.length;t.length+=s;var o=t.lengthe._pos){var a=r.substr(e._pos);if(e._charset==="x-user-defined"){var s=new i(a.length);for(var o=0;oe._pos){e.push(new i(new Uint8Array(u.result.slice(e._pos))));e._pos=u.result.byteLength}};u.onload=function(){e.push(null)};u.readAsArrayBuffer(r);break}if(e._xhr.readyState===f.DONE&&e._mode!=="ms-stream"){e.push(null)}}}).call(this,e("_process"),e("buffer").Buffer)},{"./capability":68,_process:48,buffer:39,foreach:72,inherits:128,stream:66}],71:[function(e,t,r){t.exports={100:"Continue",101:"Switching Protocols",102:"Processing",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi-Status",300:"Multiple Choices",301:"Moved Permanently",302:"Moved Temporarily",303:"See Other",304:"Not Modified",305:"Use Proxy",307:"Temporary Redirect",308:"Permanent Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Time-out",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Request Entity Too Large",414:"Request-URI Too Large",415:"Unsupported Media Type",416:"Requested Range Not Satisfiable",417:"Expectation Failed",418:"I'm a teapot",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",425:"Unordered Collection",426:"Upgrade Required",428:"Precondition Required",429:"Too Many Requests",431:"Request Header Fields Too Large",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Time-out",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",509:"Bandwidth Limit Exceeded",510:"Not Extended",511:"Network Authentication Required"}},{}],72:[function(e,t,r){var i=Object.prototype.hasOwnProperty;var n=Object.prototype.toString;t.exports=function a(e,t,r){if(n.call(t)!=="[object Function]"){throw new TypeError("iterator must be a function")}var a=e.length;if(a===+a){for(var s=0;s0&&!i.call(e,0)){for(var d=0;d0){for(var h=0;h=0&&i.call(e.callee)==="[object Function]"}return r}},{}],76:[function(e,t,r){var i=e("buffer").Buffer;var n=i.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return true;default:return false}};function a(e){if(e&&!n(e)){throw new Error("Unknown encoding: "+e)}}var s=r.StringDecoder=function(e){this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,"");a(e);switch(this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2;this.detectIncompleteChar=f;break;case"base64":this.surrogateSize=3;this.detectIncompleteChar=u;break;default:this.write=o;return}this.charBuffer=new i(6);this.charReceived=0;this.charLength=0};s.prototype.write=function(e){var t="";while(this.charLength){var r=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;e.copy(this.charBuffer,this.charReceived,0,r);this.charReceived+=r;if(this.charReceived=55296&&i<=56319){this.charLength+=this.surrogateSize;t="";continue}this.charReceived=this.charLength=0;if(e.length===0){return t}break}this.detectIncompleteChar(e);var n=e.length;if(this.charLength){e.copy(this.charBuffer,0,e.length-this.charReceived,n);n-=this.charReceived}t+=e.toString(this.encoding,0,n);var n=t.length-1;var i=t.charCodeAt(n);if(i>=55296&&i<=56319){var a=this.surrogateSize;this.charLength+=a;this.charReceived+=a;this.charBuffer.copy(this.charBuffer,a,0,a);e.copy(this.charBuffer,0,0,a);return t.substring(0,n)}return t};s.prototype.detectIncompleteChar=function(e){var t=e.length>=3?3:e.length;for(;t>0;t--){var r=e[e.length-t];if(t==1&&r>>5==6){this.charLength=2;break}if(t<=2&&r>>4==14){this.charLength=3;break}if(t<=3&&r>>3==30){this.charLength=4;break}}this.charReceived=t};s.prototype.end=function(e){var t="";if(e&&e.length)t=this.write(e);if(this.charReceived){var r=this.charReceived;var i=this.charBuffer;var n=this.encoding;t+=i.slice(0,r).toString(n)}return t};function o(e){return e.toString(this.encoding)}function f(e){this.charReceived=e.length%2;this.charLength=this.charReceived?2:0}function u(e){this.charReceived=e.length%3;this.charLength=this.charReceived?3:0}},{buffer:39}],77:[function(e,t,r){var i=e("punycode");r.parse=_;r.resolve=w;r.resolveObject=x;r.format=b;r.Url=n;function n(){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}var a=/^([a-z0-9.+-]+:)/i,s=/:[0-9]*$/,o=["<",">",'"',"`"," ","\r","\n"," "],f=["{","}","|","\\","^","`"].concat(o),u=["'"].concat(f),l=["%","/","?",";","#"].concat(u),c=["/","?","#"],p=255,d=/^[a-z0-9A-Z_-]{0,63}$/,h=/^([a-z0-9A-Z_-]{0,63})(.*)$/,m={javascript:true,"javascript:":true},v={javascript:true,"javascript:":true},g={http:true,https:true,ftp:true,gopher:true,file:true,"http:":true,"https:":true,"ftp:":true,"gopher:":true,"file:":true},y=e("querystring");function _(e,t,r){if(e&&S(e)&&e instanceof n)return e;var i=new n;i.parse(e,t,r);return i}n.prototype.parse=function(e,t,r){if(!k(e)){throw new TypeError("Parameter 'url' must be a string, not "+typeof e)}var n=e;n=n.trim();var s=a.exec(n);if(s){s=s[0];var o=s.toLowerCase();this.protocol=o;n=n.substr(s.length)}if(r||s||n.match(/^\/\/[^@\/]+@[^@\/]+/)){var f=n.substr(0,2)==="//";if(f&&!(s&&v[s])){n=n.substr(2);this.slashes=true}}if(!v[s]&&(f||s&&!g[s])){var _=-1;for(var b=0;b127){T+="x"}else{T+=I[L]}}if(!T.match(d)){var C=A.slice(0,b);var R=A.slice(b+1);var P=I.match(h);if(P){C.push(P[1]);R.unshift(P[2])}if(R.length){n="/"+R.join(".")+n}this.hostname=C.join(".");break}}}}if(this.hostname.length>p){this.hostname=""}else{this.hostname=this.hostname.toLowerCase()}if(!E){var z=this.hostname.split(".");var O=[];for(var b=0;b0?r.host.split("@"):false;if(d){r.auth=d.shift(); +r.host=r.hostname=d.shift()}}r.search=e.search;r.query=e.query;if(!E(r.pathname)||!E(r.search)){r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")}r.href=r.format();return r}if(!c.length){r.pathname=null;if(r.search){r.path="/"+r.search}else{r.path=null}r.href=r.format();return r}var h=c.slice(-1)[0];var m=(r.host||e.host)&&(h==="."||h==="..")||h==="";var y=0;for(var _=c.length;_>=0;_--){h=c[_];if(h=="."){c.splice(_,1)}else if(h===".."){c.splice(_,1);y++}else if(y){c.splice(_,1);y--}}if(!u&&!l){for(;y--;y){c.unshift("..")}}if(u&&c[0]!==""&&(!c[0]||c[0].charAt(0)!=="/")){c.unshift("")}if(m&&c.join("/").substr(-1)!=="/"){c.push("")}var b=c[0]===""||c[0]&&c[0].charAt(0)==="/";if(p){r.hostname=r.host=b?"":c.length?c.shift():"";var d=r.host&&r.host.indexOf("@")>0?r.host.split("@"):false;if(d){r.auth=d.shift();r.host=r.hostname=d.shift()}}u=u||r.host&&c.length;if(u&&!b){c.unshift("")}if(!c.length){r.pathname=null;r.path=null}else{r.pathname=c.join("/")}if(!E(r.pathname)||!E(r.search)){r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")}r.auth=e.auth||r.auth;r.slashes=r.slashes||e.slashes;r.href=r.format();return r};n.prototype.parseHost=function(){var e=this.host;var t=s.exec(e);if(t){t=t[0];if(t!==":"){this.port=t.substr(1)}e=e.substr(0,e.length-t.length)}if(e)this.hostname=e};function k(e){return typeof e==="string"}function S(e){return typeof e==="object"&&e!==null}function E(e){return e===null}function A(e){return e==null}},{punycode:49,querystring:52}],78:[function(e,t,r){(function(r){var i=e("inherits");var n=e("readable-stream").Transform;var a=e("defined");t.exports=s;i(s,n);function s(e,t){if(!(this instanceof s))return new s(e,t);n.call(this);if(!t)t={};if(typeof e==="object"){t=e;e=t.size}this.size=e||512;if(t.nopad)this._zeroPadding=false;else this._zeroPadding=a(t.zeroPadding,true);this._buffered=[];this._bufferedBytes=0}s.prototype._transform=function(e,t,i){this._bufferedBytes+=e.length;this._buffered.push(e);while(this._bufferedBytes>=this.size){var n=r.concat(this._buffered);this._bufferedBytes-=this.size;this.push(n.slice(0,this.size));this._buffered=[n.slice(this.size,n.length)]}i()};s.prototype._flush=function(){if(this._bufferedBytes&&this._zeroPadding){var e=new r(this.size-this._bufferedBytes);e.fill(0);this._buffered.push(e);this.push(r.concat(this._buffered));this._buffered=null}else if(this._bufferedBytes){this.push(r.concat(this._buffered));this._buffered=null}this.push(null)}}).call(this,e("buffer").Buffer)},{buffer:39,defined:79,inherits:128,"readable-stream":88}],79:[function(e,t,r){t.exports=function(){for(var e=0;e0){if(t.ended&&!n){var s=new Error("stream.push() after EOF");e.emit("error",s)}else if(t.endEmitted&&n){var s=new Error("stream.unshift() after end event");e.emit("error",s)}else{if(t.decoder&&!n&&!i)r=t.decoder.write(r);if(!n)t.reading=false;if(t.flowing&&t.length===0&&!t.sync){e.emit("data",r);e.read(0)}else{t.length+=t.objectMode?1:r.length;if(n)t.buffer.unshift(r);else t.buffer.push(r);if(t.needReadable)_(e)}w(e,t)}}else if(!n){t.reading=false}return d(t)}function d(e){return!e.ended&&(e.needReadable||e.length=h){e=h}else{e--;for(var t=1;t<32;t<<=1)e|=e>>t;e++}return e}function v(e,t){if(t.length===0&&t.ended)return 0;if(t.objectMode)return e===0?0:1;if(isNaN(e)||o.isNull(e)){if(t.flowing&&t.buffer.length)return t.buffer[0].length;else return t.length}if(e<=0)return 0;if(e>t.highWaterMark)t.highWaterMark=m(e);if(e>t.length){if(!t.ended){t.needReadable=true;return 0}else return t.length}return e}c.prototype.read=function(e){u("read",e);var t=this._readableState;var r=e;if(!o.isNumber(e)||e>0)t.emittedReadable=false;if(e===0&&t.needReadable&&(t.length>=t.highWaterMark||t.ended)){u("read: emitReadable",t.length,t.ended);if(t.length===0&&t.ended)I(this);else _(this);return null}e=v(e,t);if(e===0&&t.ended){if(t.length===0)I(this);return null}var i=t.needReadable;u("need readable",i);if(t.length===0||t.length-e0)n=U(e,t);else n=null;if(o.isNull(n)){t.needReadable=true;e=0}t.length-=e;if(t.length===0&&!t.ended)t.needReadable=true;if(r!==e&&t.ended&&t.length===0)I(this);if(!o.isNull(n))this.emit("data",n);return n};function g(e,t){var r=null;if(!o.isBuffer(t)&&!o.isString(t)&&!o.isNullOrUndefined(t)&&!e.objectMode){r=new TypeError("Invalid non-string/buffer chunk")}return r}function y(e,t){if(t.decoder&&!t.ended){var r=t.decoder.end();if(r&&r.length){t.buffer.push(r);t.length+=t.objectMode?1:r.length}}t.ended=true;_(e)}function _(e){var t=e._readableState;t.needReadable=false;if(!t.emittedReadable){u("emitReadable",t.flowing);t.emittedReadable=true;if(t.sync)r.nextTick(function(){b(e)});else b(e)}}function b(e){u("emit readable");e.emit("readable");A(e)}function w(e,t){if(!t.readingMore){t.readingMore=true;r.nextTick(function(){x(e,t)})}}function x(e,t){var r=t.length;while(!t.reading&&!t.flowing&&!t.ended&&t.length=i){if(a)o=r.join("");else o=n.concat(r,i);r.length=0}else{if(e0)throw new Error("endReadable called on non-empty stream");if(!t.endEmitted){t.ended=true;r.nextTick(function(){if(!t.endEmitted&&t.length===0){t.endEmitted=true;e.readable=false;e.emit("end")}})}}function T(e,t){for(var r=0,i=e.length;r1){var r=[];for(var i=0;i1||a;w(e,f,r);return}else{throw new Error("invalid input type")}if(!e.name)throw new Error("missing requied `name` property on input");s.path=e.name.split(o.sep);r(null,s)}}),function(e,t){if(e)return r(e);t=l(t);r(null,t,a)})}}function w(e,t,r){k(e,x,function(i,n){if(i)return r(i);if(Array.isArray(n))n=l(n);else n=[n];e=o.normalize(e);if(t){e=e.slice(0,e.lastIndexOf(o.sep)+1)}if(e[e.length-1]!==o.sep)e+=o.sep;n.forEach(function(t){t.getStream=R(t.path);t.path=t.path.replace(e,"").split(o.sep)});r(null,n)})}function x(e,t){t=m(t);c.stat(e,function(r,i){if(r)return t(r);var n={length:i.size,path:e};t(null,n)})}function k(e,t,r){c.readdir(e,function(i,n){if(i&&i.code==="ENOTDIR"){t(e,r)}else if(i){r(i)}else{v(n.filter(S).filter(d.not).map(function(r){return function(i){k(o.join(e,r),t,i)}}),r)}})}function S(e){return e[0]!=="."}function E(e,t,r){r=m(r);var n=[];var s=0;var o=e.map(function(e){return e.getStream});var f=0;var u=0;var l=false;var c=new h(o);var p=new a(t,{zeroPadding:false});c.on("error",y);c.pipe(p).on("data",d).on("end",v).on("error",y);function d(e){s+=e.length;var t=u;g(e,function(e){n[t]=e;f-=1;b()});f+=1;u+=1}function v(){l=true;b()}function y(e){_();r(e)}function _(){c.removeListener("error",y);p.removeListener("data",d);p.removeListener("end",v);p.removeListener("error",y)}function b(){if(l&&f===0){_();r(null,new i(n.join(""),"hex"),s)}}}function A(e,i,a){var o=i.announceList;if(!o){if(typeof i.announce==="string")o=[[i.announce]];else if(Array.isArray(i.announce)){o=i.announce.map(function(e){return[e]})}}if(!o)o=[];if(r.WEBTORRENT_ANNOUNCE){if(typeof r.WEBTORRENT_ANNOUNCE==="string"){o.push([[r.WEBTORRENT_ANNOUNCE]])}else if(Array.isArray(r.WEBTORRENT_ANNOUNCE)){o=o.concat(r.WEBTORRENT_ANNOUNCE.map(function(e){return[e]}))}}if(o.length===0){o=o.concat(t.exports.announceList)}if(typeof i.urlList==="string")i.urlList=[i.urlList];var f={info:{name:i.name},announce:o[0][0],"announce-list":o,"creation date":Number(i.creationDate)||Date.now(),encoding:"UTF-8"};if(i.comment!==undefined)f.comment=i.comment;if(i.createdBy!==undefined)f["created by"]=i.createdBy;if(i.private!==undefined)f.info.private=Number(i.private);if(i.sslCert!==undefined)f.info["ssl-cert"]=i.sslCert;if(i.urlList!==undefined)f["url-list"]=i.urlList;var u=i.pieceLength||s(e.reduce(U,0));f.info["piece length"]=u;E(e,u,function(t,r,s){if(t)return a(t);f.info.pieces=r;e.forEach(function(e){delete e.getStream});if(i.singleFileTorrent){f.info.length=s}else{f.info.files=e}a(null,n.encode(f))})}function U(e,t){return e+t.length}function I(e){return typeof Blob!=="undefined"&&e instanceof Blob}function T(e){return typeof FileList==="function"&&e instanceof FileList}function L(e){return typeof e==="object"&&typeof e.pipe==="function"}function B(e){return function(){return new u(e)}}function C(e){return function(){var t=new y.PassThrough;t.end(e);return t}}function R(e){return function(){return c.createReadStream(e)}}function P(e,t){return function(){var r=new y.Transform;r._transform=function(e,r,i){t.length+=e.length;this.push(e);i()};e.pipe(r);return r}}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{},e("buffer").Buffer)},{bencode:91,"block-stream2":95,buffer:39,dezalgo:106,"filestream/read":112,flatten:113,fs:37,"is-file":114,junk:115,multistream:133,once:117,path:47,"piece-length":118,"run-parallel":154,"simple-sha1":162,stream:66}],91:[function(e,t,r){arguments[4][15][0].apply(r,arguments)},{"./lib/decode":92,"./lib/encode":94,dup:15}],92:[function(e,t,r){arguments[4][16][0].apply(r,arguments)},{"./dict":93,buffer:39,dup:16}],93:[function(e,t,r){arguments[4][17][0].apply(r,arguments)},{dup:17}],94:[function(e,t,r){arguments[4][18][0].apply(r,arguments)},{buffer:39,dup:18}],95:[function(e,t,r){arguments[4][78][0].apply(r,arguments)},{buffer:39,defined:96,dup:78,inherits:128,"readable-stream":105}],96:[function(e,t,r){arguments[4][79][0].apply(r,arguments)},{dup:79}],97:[function(e,t,r){arguments[4][80][0].apply(r,arguments)},{"./_stream_readable":99,"./_stream_writable":101,_process:48,"core-util-is":102,dup:80,inherits:128}],98:[function(e,t,r){arguments[4][81][0].apply(r,arguments)},{"./_stream_transform":100,"core-util-is":102,dup:81,inherits:128}],99:[function(e,t,r){arguments[4][82][0].apply(r,arguments)},{"./_stream_duplex":97,_process:48,buffer:39,"core-util-is":102,dup:82,events:43,inherits:128,isarray:103,stream:66,"string_decoder/":104,util:38}],100:[function(e,t,r){arguments[4][83][0].apply(r,arguments)},{"./_stream_duplex":97,"core-util-is":102,dup:83,inherits:128}],101:[function(e,t,r){arguments[4][84][0].apply(r,arguments)},{"./_stream_duplex":97,_process:48,buffer:39,"core-util-is":102,dup:84,inherits:128,stream:66}],102:[function(e,t,r){arguments[4][59][0].apply(r,arguments)},{buffer:39,dup:59}],103:[function(e,t,r){arguments[4][45][0].apply(r,arguments)},{dup:45}],104:[function(e,t,r){arguments[4][76][0].apply(r,arguments)},{buffer:39,dup:76}],105:[function(e,t,r){arguments[4][88][0].apply(r,arguments)},{"./lib/_stream_duplex.js":97,"./lib/_stream_passthrough.js":98,"./lib/_stream_readable.js":99,"./lib/_stream_transform.js":100,"./lib/_stream_writable.js":101,dup:88,stream:66}],106:[function(e,t,r){arguments[4][19][0].apply(r,arguments)},{asap:107,dup:19,wrappy:109}],107:[function(e,t,r){arguments[4][20][0].apply(r,arguments)},{"./raw":108,dup:20}],108:[function(e,t,r){arguments[4][21][0].apply(r,arguments)},{dup:21}],109:[function(e,t,r){arguments[4][22][0].apply(r,arguments)},{dup:22}],110:[function(e,t,r){arguments[4][33][0].apply(r,arguments)},{buffer:39,dup:33,"is-typedarray":111}],111:[function(e,t,r){arguments[4][32][0].apply(r,arguments)},{dup:32}],112:[function(e,t,r){var i=e("stream").Readable;var n=e("inherits");var a=/^.*\.(\w+)$/;var s=e("typedarray-to-buffer");function o(e,t){var r=this;if(!(this instanceof o)){return new o(e,t)}t=t||{};i.call(this,t);this._offset=0;this._ready=false;this._file=e;this._size=e.size;this._chunkSize=t.chunkSize||Math.max(this._size/1e3,200*1024);this.reader=new FileReader;this._generateHeaderBlocks(e,t,function(e,t){if(e){return r.emit("error",e)}if(Array.isArray(t)){t.forEach(function(e){r.push(e)})}r._ready=true;r.emit("_ready")})}n(o,i);t.exports=o;o.prototype._generateHeaderBlocks=function(e,t,r){r(null,[])};o.prototype._read=function(){if(!this._ready){this.once("_ready",this._read.bind(this));return}var e=this;var t=this.reader;var r=this._offset;var i=this._offset+this._chunkSize;if(i>this._size)i=this._size;if(r===this._size){this.destroy();this.push(null);return}t.onload=function(){e._offset=i;e.push(s(t.result))};t.onerror=function(){e.emit("error",t.error)};t.readAsArrayBuffer(this._file.slice(r,i))};o.prototype.destroy=function(){this._file=null;if(this.reader){this.reader.onload=null;this.reader.onerror=null;try{this.reader.abort()}catch(e){}}this.reader=null}},{inherits:128,stream:66,"typedarray-to-buffer":110}],113:[function(e,t,r){t.exports=function i(e,t){t=typeof t=="number"?t:Infinity;return r(e,1);function r(e,i){return e.reduce(function(e,n){if(Array.isArray(n)&&i=r){break}r=i;n=t[a]}return n}},{}],120:[function(e,t,r){r=t.exports=e("./debug");r.log=a;r.formatArgs=n;r.save=s;r.load=o;r.useColors=i;r.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:f();r.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"];function i(){return"WebkitAppearance"in document.documentElement.style||window.console&&(console.firebug||console.exception&&console.table)||navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31; +}r.formatters.j=function(e){return JSON.stringify(e)};function n(){var e=arguments;var t=this.useColors;e[0]=(t?"%c":"")+this.namespace+(t?" %c":" ")+e[0]+(t?"%c ":" ")+"+"+r.humanize(this.diff);if(!t)return e;var i="color: "+this.color;e=[e[0],i,"color: inherit"].concat(Array.prototype.slice.call(e,1));var n=0;var a=0;e[0].replace(/%[a-z%]/g,function(e){if("%%"===e)return;n++;if("%c"===e){a=n}});e.splice(a,0,i);return e}function a(){return"object"===typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function s(e){try{if(null==e){r.storage.removeItem("debug")}else{r.storage.debug=e}}catch(t){}}function o(){var e;try{e=r.storage.debug}catch(t){}return e}r.enable(o());function f(){try{return window.localStorage}catch(e){}}},{"./debug":121}],121:[function(e,t,r){r=t.exports=s;r.coerce=l;r.disable=f;r.enable=o;r.enabled=u;r.humanize=e("ms");r.names=[];r.skips=[];r.formatters={};var i=0;var n;function a(){return r.colors[i++%r.colors.length]}function s(e){function t(){}t.enabled=false;function i(){var e=i;var t=+new Date;var s=t-(n||t);e.diff=s;e.prev=n;e.curr=t;n=t;if(null==e.useColors)e.useColors=r.useColors();if(null==e.color&&e.useColors)e.color=a();var o=Array.prototype.slice.call(arguments);o[0]=r.coerce(o[0]);if("string"!==typeof o[0]){o=["%o"].concat(o)}var f=0;o[0]=o[0].replace(/%([a-z%])/g,function(t,i){if(t==="%%")return t;f++;var n=r.formatters[i];if("function"===typeof n){var a=o[f];t=n.call(e,a);o.splice(f,1);f--}return t});if("function"===typeof r.formatArgs){o=r.formatArgs.apply(e,o)}var u=i.log||r.log||console.log.bind(console);u.apply(e,o)}i.enabled=true;var s=r.enabled(e)?i:t;s.namespace=e;return s}function o(e){r.save(e);var t=(e||"").split(/[\s,]+/);var i=t.length;for(var n=0;n1e4)return;var t=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(e);if(!t)return;var r=parseFloat(t[1]);var f=(t[2]||"ms").toLowerCase();switch(f){case"years":case"year":case"yrs":case"yr":case"y":return r*o;case"days":case"day":case"d":return r*s;case"hours":case"hour":case"hrs":case"hr":case"h":return r*a;case"minutes":case"minute":case"mins":case"min":case"m":return r*n;case"seconds":case"second":case"secs":case"sec":case"s":return r*i;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return r}}function u(e){if(e>=s)return Math.round(e/s)+"d";if(e>=a)return Math.round(e/a)+"h";if(e>=n)return Math.round(e/n)+"m";if(e>=i)return Math.round(e/i)+"s";return e+"ms"}function l(e){return c(e,s,"day")||c(e,a,"hour")||c(e,n,"minute")||c(e,i,"second")||e+" ms"}function c(e,t,r){if(e=Math.pow(2,e)){return i(e,t)}else return s};i.rack=function(e,t,r){var n=function(n){var s=0;do{if(s++>10){if(r)e+=r;else throw new Error("too many ID collisions, use more bits")}var o=i(e,t)}while(Object.hasOwnProperty.call(a,o));a[o]=n;return o};var a=n.hats={};n.get=function(e){return n.hats[e]};n.set=function(e,t){n.hats[e]=t;return n};n.bits=e||128;n.base=t||16;return n}},{}],127:[function(e,t,r){(function(e){t.exports=r;function r(e){if(!(this instanceof r))return new r(e);this.store=e;if(!this.store||!this.store.get||!this.store.put){throw new Error("First argument must be abstract-chunk-store compliant")}this.mem=[]}r.prototype.put=function(e,t,r){var i=this;i.mem[e]=t;i.store.put(e,t,function(t){i.mem[e]=null;if(r)r(t)})};r.prototype.get=function(e,t,r){if(typeof t==="function")return this.get(e,null,t);var n=t&&t.offset||0;var a=t&&t.length&&n+t.length;var s=this.mem[e];if(s)return i(r,null,t?s.slice(n,a):s);this.store.get(e,t,r)};r.prototype.close=function(e){this.store.close(e)};r.prototype.destroy=function(e){this.store.destroy(e)};function i(t,r,i){e.nextTick(function(){if(t)t(r,i)})}}).call(this,e("_process"))},{_process:48}],128:[function(e,t,r){if(typeof Object.create==="function"){t.exports=function i(e,t){e.super_=t;e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:false,writable:true,configurable:true}})}}else{t.exports=function n(e,t){e.super_=t;var r=function(){};r.prototype=t.prototype;e.prototype=new r;e.prototype.constructor=e}}},{}],129:[function(e,t,r){t.exports=s;var i=e("inherits");var n=e("stream");var a=typeof window!=="undefined"&&window.MediaSource;i(s,n.Writable);function s(e,t){var r=this;if(!(r instanceof s))return new s(e,t);n.Writable.call(r,t);if(!a)throw new Error("web browser lacks MediaSource support");if(!t)t={};r._elem=e;r._mediaSource=new a;r._sourceBuffer=null;r._cb=null;r._type=t.type||o(t.extname);if(!r._type)throw new Error("missing `opts.type` or `opts.extname` options");r._elem.src=window.URL.createObjectURL(r._mediaSource);r._mediaSource.addEventListener("sourceopen",function(){if(a.isTypeSupported(r._type)){r._sourceBuffer=r._mediaSource.addSourceBuffer(r._type);r._sourceBuffer.addEventListener("updateend",r._flow.bind(r));r._flow()}else{r._mediaSource.endOfStream("decode")}});r.on("finish",function(){r._mediaSource.endOfStream()})}s.prototype._write=function(e,t,r){var i=this;if(!i._sourceBuffer){i._cb=function(n){if(n)return r(n);i._write(e,t,r)};return}if(i._sourceBuffer.updating){return r(new Error("Cannot append buffer while source buffer updating"))}i._sourceBuffer.appendBuffer(e);i._cb=r};s.prototype._flow=function(){var e=this;if(e._cb){e._cb(null)}};function o(e){if(!e)return null;if(e[0]!==".")e="."+e;return{".m4a":'audio/mp4; codecs="mp4a.40.5"',".m4v":'video/mp4; codecs="avc1.640029, mp4a.40.5"',".mp3":"audio/mpeg",".mp4":'video/mp4; codecs="avc1.640029, mp4a.40.5"',".webm":'video/webm; codecs="vorbis, vp8"'}[e]}},{inherits:128,stream:66}],130:[function(e,t,r){(function(e){t.exports=r;function r(e,t){if(!(this instanceof r))return new r(e,t);if(!t)t={};this.chunkLength=Number(e);if(!this.chunkLength)throw new Error("First argument must be a chunk length");this.chunks=[];this.closed=false;this.length=Number(t.length)||Infinity;if(this.length!==Infinity){this.lastChunkLength=this.length%this.chunkLength||this.chunkLength;this.lastChunkIndex=Math.ceil(this.length/this.chunkLength)-1}}r.prototype.put=function(e,t,r){if(this.closed)return i(r,new Error("Storage is closed"));var n=e===this.lastChunkIndex;if(n&&t.length!==this.lastChunkLength){return i(r,new Error("Last chunk length must be "+this.lastChunkLength))}if(!n&&t.length!==this.chunkLength){return i(r,new Error("Chunk length must be "+this.chunkLength))}this.chunks[e]=t;i(r,null)};r.prototype.get=function(e,t,r){if(typeof t==="function")return this.get(e,null,t);if(this.closed)return i(r,new Error("Storage is closed"));var n=this.chunks[e];if(!n)return i(r,new Error("Chunk not found"));if(!t)return i(r,null,n);var a=t.offset||0;var s=t.length||n.length-a;i(r,null,n.slice(a,s+a))};r.prototype.close=r.prototype.destroy=function(e){if(this.closed)return i(e,new Error("Storage is closed"));this.closed=true;this.chunks=null;i(e,null)};function i(t,r,i){e.nextTick(function(){if(t)t(r,i)})}}).call(this,e("_process"))},{_process:48}],131:[function(e,t,r){(function(r){var i=e("path");var n=e("fs");function a(){this.types=Object.create(null);this.extensions=Object.create(null)}a.prototype.define=function(e){for(var t in e){var i=e[t];for(var n=0;n=0?n.split("&"):[];s.forEach(function(e){var r=e.split("=");if(r.length!==2)return;var i=r[0];var n=r[1];if(i==="dn")n=decodeURIComponent(n).replace(/\+/g," ");if(i==="tr"||i==="xs"||i==="as"||i==="ws"){n=decodeURIComponent(n)}if(i==="kt")n=decodeURIComponent(n).split("+");if(t[i]){if(Array.isArray(t[i])){t[i].push(n)}else{var a=t[i];t[i]=[a,n]}}else{t[i]=n}});var o;if(t.xt){var f=Array.isArray(t.xt)?t.xt:[t.xt];f.forEach(function(e){if(o=e.match(/^urn:btih:(.{40})/)){t.infoHash=new r(o[1],"hex").toString("hex")}else if(o=e.match(/^urn:btih:(.{32})/)){var n=i.decode(o[1]);t.infoHash=new r(n,"binary").toString("hex")}})}if(t.dn)t.name=t.dn;if(t.kt)t.keywords=t.kt;if(typeof t.tr==="string")t.announce=[t.tr];else if(Array.isArray(t.tr))t.announce=t.tr;else t.announce=[];a(t.announce);t.urlList=[];if(typeof t.as==="string"||Array.isArray(t.as)){t.urlList=t.urlList.concat(t.as)}if(typeof t.ws==="string"||Array.isArray(t.ws)){t.urlList=t.urlList.concat(t.ws)}return t}function o(e){e=n(e);if(e.infoHash)e.xt="urn:btih:"+e.infoHash;if(e.name)e.dn=e.name;if(e.keywords)e.kt=e.keywords;if(e.announce)e.tr=e.announce;if(e.urlList){e.ws=e.urlList;delete e.as}var t="magnet:?";Object.keys(e).filter(function(e){return e.length===2}).forEach(function(r,i){var n=Array.isArray(e[r])?e[r]:[e[r]];n.forEach(function(e,n){if((i>0||n>0)&&(r!=="kt"||n===0))t+="&";if(r==="dn")e=encodeURIComponent(e).replace(/%20/g,"+");if(r==="tr"||r==="xs"||r==="as"||r==="ws"){e=encodeURIComponent(e)}if(r==="kt")e=encodeURIComponent(e);if(r==="kt"&&n>0)t+="+"+e;else t+=r+"="+e})});return t}}).call(this,e("buffer").Buffer)},{buffer:39,"thirty-two":140,uniq:167,xtend:180}],140:[function(e,t,r){var i=e("./thirty-two");r.encode=i.encode;r.decode=i.decode},{"./thirty-two":141}],141:[function(e,t,r){(function(e){var t="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";var i=[255,255,26,27,28,29,30,31,255,255,255,255,255,255,255,255,255,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,255,255,255,255,255,255,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,255,255,255,255,255];function n(e){var t=Math.floor(e.length/5);return e.length%5==0?t:t+1}r.encode=function(r){var i=0;var a=0;var s=0;var o=0;var f=new e(n(r)*8);if(!e.isBuffer(r)){r=new e(r)}while(i3){o=u&255>>s;s=(s+5)%8;o=o<>8-s;i++}else{o=u>>8-(s+5)&31;s=(s+5)%8;if(s==0)i++}f[a]=t.charCodeAt(o);a++}for(i=a;i>>r;o[s]=a;s++;a=255&n<<8-r}}else{throw new Error("Invalid input - it is not base32 encoded string")}}return o.slice(0,s)}}).call(this,e("buffer").Buffer)},{buffer:39}],142:[function(e,t,r){(function(r){t.exports=o;t.exports.decode=o;t.exports.encode=f;var i=e("bencode");var n=e("path");var a=e("simple-sha1");var s=e("uniq");function o(e){if(r.isBuffer(e)){e=i.decode(e)}c(e.info,"info");c(e.info["name.utf-8"]||e.info.name,"info.name");c(e.info["piece length"],"info['piece length']");c(e.info.pieces,"info.pieces");if(e.info.files){e.info.files.forEach(function(e){c(typeof e.length==="number","info.files[0].length");c(e["path.utf-8"]||e.path,"info.files[0].path")})}else{c(typeof e.info.length==="number","info.length")}var t={};t.info=e.info;t.infoBuffer=i.encode(e.info);t.infoHash=a.sync(t.infoBuffer);t.name=(e.info["name.utf-8"]||e.info.name).toString();if(e.info.private!==undefined)t.private=!!e.info.private;if(e["creation date"])t.created=new Date(e["creation date"]*1e3);if(e["created by"])t.createdBy=e["created by"].toString();if(r.isBuffer(e.comment))t.comment=e.comment.toString();t.announce=[];if(e["announce-list"]&&e["announce-list"].length){e["announce-list"].forEach(function(e){e.forEach(function(e){t.announce.push(e.toString())})})}else if(e.announce){t.announce.push(e.announce.toString())}s(t.announce);if(r.isBuffer(e["url-list"])){e["url-list"]=e["url-list"].length>0?[e["url-list"]]:[]}t.urlList=(e["url-list"]||[]).map(function(e){return e.toString()});var o=e.info.files||[e.info];t.files=o.map(function(e,r){var i=[].concat(t.name,e["path.utf-8"]||e.path||[]).map(function(e){return e.toString()});return{path:n.join.apply(null,[n.sep].concat(i)).slice(1),name:i[i.length-1],length:e.length,offset:o.slice(0,r).reduce(u,0)}});t.length=o.reduce(u,0);var f=t.files[t.files.length-1];t.pieceLength=e.info["piece length"];t.lastPieceLength=(f.offset+f.length)%t.pieceLength||t.pieceLength;t.pieces=l(e.info.pieces);return t}function f(e){var t={info:e.info};t["announce-list"]=e.announce.map(function(e){if(!t.announce)t.announce=e;e=new r(e,"utf8");return[e]});if(e.created){t["creation date"]=e.created.getTime()/1e3|0}if(e.urlList){t["url-list"]=e.urlList}return i.encode(t)}function u(e,t){return e+t.length}function l(e){var t=[];for(var r=0;r0;return l(n,s,o,function(e){if(!r)r=e;if(e)i.forEach(c);if(s)return;i.forEach(c);t(r)})});return e.reduce(p)};t.exports=d},{"end-of-stream":123,fs:37,once:150}],149:[function(e,t,r){arguments[4][22][0].apply(r,arguments)},{dup:22}],150:[function(e,t,r){arguments[4][29][0].apply(r,arguments)},{dup:29,wrappy:149}],151:[function(e,t,r){var i=function(e){var t=0;return function(){if(t===e.length)return null;var r=e.length-t;var i=Math.random()*r|0;var n=e[t+i];var a=e[t];e[t]=n;e[t+i]=a;t++;return n}};t.exports=i},{}],152:[function(e,t,r){t.exports=function(e,t){var r=true;var i=t.indexOf("=");if(-1==i)return-2;var n=t.slice(i+1).split(",").map(function(t){var t=t.split("-"),i=parseInt(t[0],10),n=parseInt(t[1],10);if(isNaN(i)){i=e-n;n=e-1}else if(isNaN(n)){n=e-1}if(n>e-1)n=e-1;if(isNaN(i)||isNaN(n)||i>n||i<0)r=false;return{start:i,end:n}});n.type=t.slice(0,i);return r?n:-1}},{}],153:[function(e,t,r){t.exports=n;t.exports.filter=a;var i=e("events").EventEmitter;function n(e,t,r){if(!Array.isArray(r))r=[r];var i=[];r.forEach(function(r){var n=function(){var e=[].slice.call(arguments);e.unshift(r);t.emit.apply(t,e)};i.push(n);e.on(r,n)});return function n(){r.forEach(function(t,r){e.removeListener(t,i[r])})}}function a(e,t){var r=new i;n(e,r,t);return r}},{events:43}],154:[function(e,t,r){var i=e("dezalgo");t.exports=function(e,t){if(t)t=i(t);var r,n,a;if(Array.isArray(e)){r=[];n=e.length}else{a=Object.keys(e);r={};n=a.length}function s(e,i,a){r[e]=a;if(--n===0||i){if(t)t(i,r);t=null}}if(!n){if(t)t(null,r);t=null}else if(a){a.forEach(function(t){e[t](s.bind(undefined,t))})}else{e.forEach(function(e,t){e(s.bind(undefined,t))})}}},{dezalgo:155}],155:[function(e,t,r){arguments[4][19][0].apply(r,arguments)},{asap:156,dup:19,wrappy:158}],156:[function(e,t,r){arguments[4][20][0].apply(r,arguments)},{"./raw":157,dup:20}],157:[function(e,t,r){arguments[4][21][0].apply(r,arguments)},{dup:21}],158:[function(e,t,r){arguments[4][22][0].apply(r,arguments)},{dup:22}],159:[function(e,t,r){(function(r){t.exports=u;var i=e("xtend");var n=e("http");var a=e("https");var s=e("once");var o=e("unzip-response");var f=e("url");function u(e,t){e=typeof e==="string"?{url:e}:i(e);t=s(t);if(e.url)l(e);if(e.headers==null)e.headers={};if(e.maxRedirects==null)e.maxRedirects=10;var r=e.body;e.body=undefined;if(r&&!e.method)e.method="POST";var f=Object.keys(e.headers).some(function(e){return e.toLowerCase()==="accept-encoding"});if(!f)e.headers["accept-encoding"]="gzip, deflate";var c=e.protocol==="https:"?a:n;var p=c.request(e,function(r){if(r.statusCode>=300&&r.statusCode<400&&"location"in r.headers){e.url=r.headers.location;l(e);r.resume();e.maxRedirects-=1;if(e.maxRedirects>0)u(e,t);else t(new Error("too many redirects"));return}t(null,typeof o==="function"?o(r):r)});p.on("error",t);p.end(r);return p}t.exports.concat=function(e,t){return u(e,function(e,i){if(e)return t(e);var n=[];i.on("data",function(e){n.push(e)});i.on("end",function(){t(null,r.concat(n),i)})})};["get","post","put","patch","head","delete"].forEach(function(e){t.exports[e]=function(t,r){if(typeof t==="string")t={url:t};t.method=e.toUpperCase();return u(t,r)}});function l(e){var t=f.parse(e.url);if(t.hostname)e.hostname=t.hostname;if(t.port)e.port=t.port;if(t.protocol)e.protocol=t.protocol;e.path=t.path;delete e.url}}).call(this,e("buffer").Buffer)},{buffer:39,http:67,https:44,once:161,"unzip-response":38,url:77,xtend:180}],160:[function(e,t,r){arguments[4][22][0].apply(r,arguments)},{dup:22}],161:[function(e,t,r){arguments[4][29][0].apply(r,arguments)},{dup:29,wrappy:160}],162:[function(e,t,r){var i=e("rusha");var n=new i;var a=window.crypto||window.msCrypto||{};var s=a.subtle||a.webkitSubtle;var o=n.digest.bind(n);try{s.digest({name:"sha-1"},new Uint8Array).catch(function(){s=false})}catch(f){s=false}function u(e,t){if(!s){setTimeout(t,0,o(e));return}if(typeof e==="string"){e=l(e)}s.digest({name:"sha-1"},e).then(function r(e){t(c(new Uint8Array(e)))},function i(r){t(o(e))})}function l(e){var t=e.length;var r=new Uint8Array(t);for(var i=0;i>>4).toString(16));r.push((n&15).toString(16))}return r.join("")}t.exports=u;t.exports.sync=o},{rusha:163}],163:[function(e,t,r){(function(e){(function(){var r={getDataType:function(t){if(typeof t==="string"){return"string"}if(t instanceof Array){return"array"}if(typeof e!=="undefined"&&e.Buffer&&e.Buffer.isBuffer(t)){return"buffer"}if(t instanceof ArrayBuffer){return"arraybuffer"}if(t.buffer instanceof ArrayBuffer){return"view"}if(t instanceof Blob){return"blob"}throw new Error("Unsupported data type.")}};function i(e){"use strict";var t={fill:0};var a=function(e){for(e+=9;e%64>0;e+=1);return e};var s=function(e,t){for(var r=t>>2;r>2]|=128<<24-(t%4<<3);e[((t>>2)+2&~15)+14]=r>>29;e[((t>>2)+2&~15)+15]=r<<3};var f=function(e,t,r,i,n){var a=this,s,o=n%4,f=i%4,u=i-f;if(u>0){switch(o){case 0:e[n+3|0]=a.charCodeAt(r);case 1:e[n+2|0]=a.charCodeAt(r+1);case 2:e[n+1|0]=a.charCodeAt(r+2);case 3:e[n|0]=a.charCodeAt(r+3)}}for(s=o;s>2]=a.charCodeAt(r+s)<<24|a.charCodeAt(r+s+1)<<16|a.charCodeAt(r+s+2)<<8|a.charCodeAt(r+s+3)}switch(f){case 3:e[n+u+1|0]=a.charCodeAt(r+u+2);case 2:e[n+u+2|0]=a.charCodeAt(r+u+1);case 1:e[n+u+3|0]=a.charCodeAt(r+u)}};var u=function(e,t,r,i,n){var a=this,s,o=n%4,f=i%4,u=i-f;if(u>0){switch(o){case 0:e[n+3|0]=a[r];case 1:e[n+2|0]=a[r+1];case 2:e[n+1|0]=a[r+2];case 3:e[n|0]=a[r+3]}}for(s=4-o;s>2]=a[r+s]<<24|a[r+s+1]<<16|a[r+s+2]<<8|a[r+s+3]}switch(f){case 3:e[n+u+1|0]=a[r+u+2];case 2:e[n+u+2|0]=a[r+u+1];case 1:e[n+u+3|0]=a[r+u]}};var l=function(e,t,r,i,a){var s=this,o,f=a%4,u=i%4,l=i-u;var c=new Uint8Array(n.readAsArrayBuffer(s.slice(r,r+i)));if(l>0){switch(f){case 0:e[a+3|0]=c[0];case 1:e[a+2|0]=c[1];case 2:e[a+1|0]=c[2];case 3:e[a|0]=c[3]}}for(o=4-f;o>2]=c[o]<<24|c[o+1]<<16|c[o+2]<<8|c[o+3]}switch(u){case 3:e[a+l+1|0]=c[l+2];case 2:e[a+l+2|0]=c[l+1];case 1:e[a+l+3|0]=c[l]}};var c=function(e){switch(r.getDataType(e)){case"string":return f.bind(e);case"array":return u.bind(e);case"buffer":return u.bind(e);case"arraybuffer":return u.bind(new Uint8Array(e));case"view":return u.bind(new Uint8Array(e.buffer,e.byteOffset,e.byteLength));case"blob":return l.bind(e)}};var p=function(e,t){switch(r.getDataType(e)){case"string":return e.slice(t);case"array":return e.slice(t);case"buffer":return e.slice(t);case"arraybuffer":return e.slice(t);case"view":return e.buffer.slice(t)}};var d=function(e){var t,r,i="0123456789abcdef",n=[],a=new Uint8Array(e);for(t=0;t>4&15)+i.charAt(r>>0&15)}return n.join("")};var h=function(e){var t;if(e<=65536)return 65536;if(e<16777216){for(t=1;t0){throw new Error("Chunk size must be a multiple of 128 bit")}t.maxChunkLen=e;t.padMaxChunkLen=a(e);t.heap=new ArrayBuffer(h(t.padMaxChunkLen+320+20));t.h32=new Int32Array(t.heap);t.h8=new Int8Array(t.heap);t.core=new i._core({Int32Array:Int32Array,DataView:DataView},{},t.heap);t.buffer=null};m(e||64*1024);var v=function(e,t){var r=new Int32Array(e,t+320,5);r[0]=1732584193;r[1]=-271733879;r[2]=-1732584194;r[3]=271733878;r[4]=-1009589776};var g=function(e,r){var i=a(e);var n=new Int32Array(t.heap,0,i>>2);s(n,e);o(n,e,r);return i};var y=function(e,r,i){c(e)(t.h8,t.h32,r,i,0)};var _=function(e,r,i,n,a){var s=i;if(a){s=g(i,n)}y(e,r,i);t.core.hash(s,t.padMaxChunkLen)};var b=function(e,t){var r=new Int32Array(e,t+320,5);var i=new Int32Array(5);var n=new DataView(i.buffer);n.setInt32(0,r[0],false);n.setInt32(4,r[1],false);n.setInt32(8,r[2],false);n.setInt32(12,r[3],false);n.setInt32(16,r[4],false);return i};var w=this.rawDigest=function(e){var r=e.byteLength||e.length||e.size||0;v(t.heap,t.padMaxChunkLen);var i=0,n=t.maxChunkLen,a;for(i=0;r>i+n;i+=n){_(e,i,n,r,false)}_(e,i,r-i,r,true);return b(t.heap,t.padMaxChunkLen)};this.digest=this.digestFromString=this.digestFromBuffer=this.digestFromArrayBuffer=function(e){return d(w(e).buffer)}}i._core=function s(e,t,r){"use asm";var i=new e.Int32Array(r);function n(e,t){e=e|0;t=t|0;var r=0,n=0,a=0,s=0,o=0,f=0,u=0,l=0,c=0,p=0,d=0,h=0,m=0,v=0;a=i[t+320>>2]|0;o=i[t+324>>2]|0;u=i[t+328>>2]|0;c=i[t+332>>2]|0;d=i[t+336>>2]|0;for(r=0;(r|0)<(e|0);r=r+64|0){s=a;f=o;l=u;p=c;h=d;for(n=0;(n|0)<64;n=n+4|0){v=i[r+n>>2]|0;m=((a<<5|a>>>27)+(o&u|~o&c)|0)+((v+d|0)+1518500249|0)|0;d=c;c=u;u=o<<30|o>>>2;o=a;a=m;i[e+n>>2]=v}for(n=e+64|0;(n|0)<(e+80|0);n=n+4|0){v=(i[n-12>>2]^i[n-32>>2]^i[n-56>>2]^i[n-64>>2])<<1|(i[n-12>>2]^i[n-32>>2]^i[n-56>>2]^i[n-64>>2])>>>31;m=((a<<5|a>>>27)+(o&u|~o&c)|0)+((v+d|0)+1518500249|0)|0;d=c;c=u;u=o<<30|o>>>2;o=a;a=m;i[n>>2]=v}for(n=e+80|0;(n|0)<(e+160|0);n=n+4|0){v=(i[n-12>>2]^i[n-32>>2]^i[n-56>>2]^i[n-64>>2])<<1|(i[n-12>>2]^i[n-32>>2]^i[n-56>>2]^i[n-64>>2])>>>31;m=((a<<5|a>>>27)+(o^u^c)|0)+((v+d|0)+1859775393|0)|0;d=c;c=u;u=o<<30|o>>>2;o=a;a=m;i[n>>2]=v}for(n=e+160|0;(n|0)<(e+240|0);n=n+4|0){v=(i[n-12>>2]^i[n-32>>2]^i[n-56>>2]^i[n-64>>2])<<1|(i[n-12>>2]^i[n-32>>2]^i[n-56>>2]^i[n-64>>2])>>>31;m=((a<<5|a>>>27)+(o&u|o&c|u&c)|0)+((v+d|0)-1894007588|0)|0;d=c;c=u;u=o<<30|o>>>2;o=a;a=m;i[n>>2]=v}for(n=e+240|0;(n|0)<(e+320|0);n=n+4|0){v=(i[n-12>>2]^i[n-32>>2]^i[n-56>>2]^i[n-64>>2])<<1|(i[n-12>>2]^i[n-32>>2]^i[n-56>>2]^i[n-64>>2])>>>31;m=((a<<5|a>>>27)+(o^u^c)|0)+((v+d|0)-899497514|0)|0;d=c;c=u;u=o<<30|o>>>2;o=a;a=m;i[n>>2]=v}a=a+s|0;o=o+f|0;u=u+l|0;c=c+p|0;d=d+h|0}i[t+320>>2]=a;i[t+324>>2]=o;i[t+328>>2]=u;i[t+332>>2]=c;i[t+336>>2]=d}return{hash:n}};if(typeof t!=="undefined"){t.exports=i}else if(typeof window!=="undefined"){window.Rusha=i}if(typeof FileReaderSync!=="undefined"){var n=new FileReaderSync,a=new i(4*1024*1024);self.onmessage=function o(e){var t,r=e.data.data;try{t=a.digest(r);self.postMessage({id:e.data.id,hash:t})}catch(i){self.postMessage({id:e.data.id,error:i.name})}}}})()}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],164:[function(e,t,r){var i=1;var n=65535;var a=4;var s=function(){i=i+1&n};var o=setInterval(s,1e3/a|0);if(o.unref)o.unref();t.exports=function(e){var t=a*(e||5);var r=[0];var s=1;var o=i-1&n;return function(e){var f=i-o&n;if(f>t)f=t;o=i;while(f--){if(s===t)s=0;r[s]=r[s===0?t-1:s-1];s++}if(e)r[s-1]+=e;var u=r[s-1];var l=r.lengthf){return this.emit("warning",new Error("Peer gave maliciously large metadata size"))}this._metadataSize=e.metadata_size;this._numPieces=Math.ceil(this._metadataSize/l);this._remainingRejects=this._numPieces*2;if(this._fetching){this._requestPieces()}};t.prototype.onMessage=function(e){var t,r;try{var n=e.toString();var a=n.indexOf("ee")+2;t=i.decode(n.substring(0,a));r=e.slice(a)}catch(s){return}switch(t.msg_type){case 0:this._onRequest(t.piece);break;case 1:this._onData(t.piece,r,t.total_size);break;case 2:this._onReject(t.piece);break}};t.prototype.fetch=function(){if(this._metadataComplete){return}this._fetching=true;if(this._metadataSize){this._requestPieces()}};t.prototype.cancel=function(){this._fetching=false};t.prototype.setMetadata=function(e){if(this._metadataComplete)return true;try{var t=i.decode(e).info;if(t){e=i.encode(t)}}catch(r){}if(this._infoHashHex&&this._infoHashHex!==o.sync(e)){return false}this.cancel();this.metadata=e;this._metadataComplete=true;this._metadataSize=this.metadata.length;this._wire.extendedHandshake.metadata_size=this._metadataSize;this.emit("metadata",i.encode({info:i.decode(this.metadata)}));return true};t.prototype._send=function(e,t){var n=i.encode(e);if(r.isBuffer(t)){n=r.concat([n,t])}this._wire.extended("ut_metadata",n)};t.prototype._request=function(e){this._send({msg_type:0,piece:e})};t.prototype._data=function(e,t,r){var i={msg_type:1,piece:e};if(typeof r==="number"){i.total_size=r}this._send(i,t)};t.prototype._reject=function(e){this._send({msg_type:2,piece:e})};t.prototype._onRequest=function(e){if(!this._metadataComplete){this._reject(e);return}var t=e*l;var r=t+l;if(r>this._metadataSize){r=this._metadataSize}var i=this.metadata.slice(t,r);this._data(e,i,this._metadataSize)};t.prototype._onData=function(e,t,r){if(t.length>l){return}t.copy(this.metadata,e*l);this._bitfield.set(e);this._checkDone()};t.prototype._onReject=function(e){if(this._remainingRejects>0&&this._fetching){this._request(e);this._remainingRejects-=1}else{this.emit("warning",new Error('Peer sent "reject" too much'))}};t.prototype._requestPieces=function(){this.metadata=new r(this._metadataSize);for(var e=0;e0){this._requestPieces()}else{this.emit("warning",new Error("Peer sent invalid metadata"))}};return t}}).call(this,e("buffer").Buffer)},{bencode:169,bitfield:9,buffer:39,events:43,inherits:128,"simple-sha1":162}],169:[function(e,t,r){arguments[4][15][0].apply(r,arguments)},{"./lib/decode":170,"./lib/encode":172,dup:15}],170:[function(e,t,r){arguments[4][16][0].apply(r,arguments)},{"./dict":171,buffer:39,dup:16}],171:[function(e,t,r){arguments[4][17][0].apply(r,arguments)},{dup:17}],172:[function(e,t,r){arguments[4][18][0].apply(r,arguments)},{buffer:39,dup:18}],173:[function(e,t,r){var i=function(e,t,r){this._byteOffset=t||0;if(e instanceof ArrayBuffer){this.buffer=e}else if(typeof e=="object"){this.dataView=e;if(t){this._byteOffset+=t}}else{this.buffer=new ArrayBuffer(e||0)}this.position=0;this.endianness=r==null?i.LITTLE_ENDIAN:r};t.exports=i;i.prototype={};i.prototype.save=function(e){var t=new Blob([this.buffer]);var r=window.webkitURL||window.URL;if(r&&r.createObjectURL){var i=r.createObjectURL(t);var n=document.createElement("a");n.setAttribute("href",i);n.setAttribute("download",e);n.click();r.revokeObjectURL(i)}else{throw"DataStream.save: Can't create object URL."}};i.BIG_ENDIAN=false;i.LITTLE_ENDIAN=true;i.prototype._dynamicSize=true;Object.defineProperty(i.prototype,"dynamicSize",{get:function(){return this._dynamicSize},set:function(e){if(!e){this._trimAlloc()}this._dynamicSize=e}});i.prototype._byteLength=0;Object.defineProperty(i.prototype,"byteLength",{get:function(){return this._byteLength-this._byteOffset}});Object.defineProperty(i.prototype,"buffer",{get:function(){this._trimAlloc();return this._buffer},set:function(e){this._buffer=e;this._dataView=new DataView(this._buffer,this._byteOffset);this._byteLength=this._buffer.byteLength}});Object.defineProperty(i.prototype,"byteOffset",{get:function(){return this._byteOffset},set:function(e){this._byteOffset=e;this._dataView=new DataView(this._buffer,this._byteOffset);this._byteLength=this._buffer.byteLength}});Object.defineProperty(i.prototype,"dataView",{get:function(){return this._dataView},set:function(e){this._byteOffset=e.byteOffset;this._buffer=e.buffer;this._dataView=new DataView(this._buffer,this._byteOffset);this._byteLength=this._byteOffset+e.byteLength}});i.prototype._realloc=function(e){if(!this._dynamicSize){return}var t=this._byteOffset+this.position+e;var r=this._buffer.byteLength;if(t<=r){if(t>this._byteLength){this._byteLength=t}return}if(r<1){r=1}while(t>r){r*=2}var i=new ArrayBuffer(r);var n=new Uint8Array(this._buffer);var a=new Uint8Array(i,0,n.length);a.set(n);this.buffer=i;this._byteLength=t};i.prototype._trimAlloc=function(){if(this._byteLength==this._buffer.byteLength){return}var e=new ArrayBuffer(this._byteLength);var t=new Uint8Array(e);var r=new Uint8Array(this._buffer,0,t.length);t.set(r);this.buffer=e};i.prototype.shift=function(e){var t=new ArrayBuffer(this._byteLength-e);var r=new Uint8Array(t);var i=new Uint8Array(this._buffer,e,r.length);r.set(i);this.buffer=t;this.position-=e};i.prototype.seek=function(e){var t=Math.max(0,Math.min(this.byteLength,e));this.position=isNaN(t)||!isFinite(t)?0:t};i.prototype.isEof=function(){return this.position>=this._byteLength};i.prototype.mapInt32Array=function(e,t){this._realloc(e*4);var r=new Int32Array(this._buffer,this.byteOffset+this.position,e);i.arrayToNative(r,t==null?this.endianness:t);this.position+=e*4;return r};i.prototype.mapInt16Array=function(e,t){this._realloc(e*2);var r=new Int16Array(this._buffer,this.byteOffset+this.position,e);i.arrayToNative(r,t==null?this.endianness:t);this.position+=e*2;return r};i.prototype.mapInt8Array=function(e){this._realloc(e*1);var t=new Int8Array(this._buffer,this.byteOffset+this.position,e);this.position+=e*1;return t};i.prototype.mapUint32Array=function(e,t){this._realloc(e*4);var r=new Uint32Array(this._buffer,this.byteOffset+this.position,e);i.arrayToNative(r,t==null?this.endianness:t);this.position+=e*4;return r};i.prototype.mapUint16Array=function(e,t){this._realloc(e*2);var r=new Uint16Array(this._buffer,this.byteOffset+this.position,e);i.arrayToNative(r,t==null?this.endianness:t);this.position+=e*2;return r};i.prototype.mapUint8Array=function(e){this._realloc(e*1);var t=new Uint8Array(this._buffer,this.byteOffset+this.position,e);this.position+=e*1;return t};i.prototype.mapFloat64Array=function(e,t){this._realloc(e*8);var r=new Float64Array(this._buffer,this.byteOffset+this.position,e);i.arrayToNative(r,t==null?this.endianness:t);this.position+=e*8;return r};i.prototype.mapFloat32Array=function(e,t){this._realloc(e*4);var r=new Float32Array(this._buffer,this.byteOffset+this.position,e);i.arrayToNative(r,t==null?this.endianness:t);this.position+=e*4;return r};i.prototype.readInt32Array=function(e,t){e=e==null?this.byteLength-this.position/4:e;var r=new Int32Array(e);i.memcpy(r.buffer,0,this.buffer,this.byteOffset+this.position,e*r.BYTES_PER_ELEMENT);i.arrayToNative(r,t==null?this.endianness:t);this.position+=r.byteLength;return r};i.prototype.readInt16Array=function(e,t){e=e==null?this.byteLength-this.position/2:e;var r=new Int16Array(e);i.memcpy(r.buffer,0,this.buffer,this.byteOffset+this.position,e*r.BYTES_PER_ELEMENT);i.arrayToNative(r,t==null?this.endianness:t);this.position+=r.byteLength;return r};i.prototype.readInt8Array=function(e){e=e==null?this.byteLength-this.position:e;var t=new Int8Array(e);i.memcpy(t.buffer,0,this.buffer,this.byteOffset+this.position,e*t.BYTES_PER_ELEMENT);this.position+=t.byteLength;return t};i.prototype.readUint32Array=function(e,t){e=e==null?this.byteLength-this.position/4:e;var r=new Uint32Array(e);i.memcpy(r.buffer,0,this.buffer,this.byteOffset+this.position,e*r.BYTES_PER_ELEMENT);i.arrayToNative(r,t==null?this.endianness:t);this.position+=r.byteLength;return r};i.prototype.readUint16Array=function(e,t){e=e==null?this.byteLength-this.position/2:e;var r=new Uint16Array(e);i.memcpy(r.buffer,0,this.buffer,this.byteOffset+this.position,e*r.BYTES_PER_ELEMENT);i.arrayToNative(r,t==null?this.endianness:t);this.position+=r.byteLength;return r};i.prototype.readUint8Array=function(e){e=e==null?this.byteLength-this.position:e;var t=new Uint8Array(e);i.memcpy(t.buffer,0,this.buffer,this.byteOffset+this.position,e*t.BYTES_PER_ELEMENT);this.position+=t.byteLength;return t};i.prototype.readFloat64Array=function(e,t){e=e==null?this.byteLength-this.position/8:e;var r=new Float64Array(e);i.memcpy(r.buffer,0,this.buffer,this.byteOffset+this.position,e*r.BYTES_PER_ELEMENT);i.arrayToNative(r,t==null?this.endianness:t);this.position+=r.byteLength;return r};i.prototype.readFloat32Array=function(e,t){e=e==null?this.byteLength-this.position/4:e;var r=new Float32Array(e);i.memcpy(r.buffer,0,this.buffer,this.byteOffset+this.position,e*r.BYTES_PER_ELEMENT);i.arrayToNative(r,t==null?this.endianness:t);this.position+=r.byteLength;return r};i.prototype.writeInt32Array=function(e,t){this._realloc(e.length*4);if(e instanceof Int32Array&&this.byteOffset+this.position%e.BYTES_PER_ELEMENT===0){i.memcpy(this._buffer,this.byteOffset+this.position,e.buffer,0,e.byteLength);this.mapInt32Array(e.length,t)}else{for(var r=0;r0;i.memcpy=function(e,t,r,i,n){var a=new Uint8Array(e,t,n);var s=new Uint8Array(r,i,n);a.set(s)};i.arrayToNative=function(e,t){if(t==this.endianness){return e}else{return this.flipArrayEndianness(e)}};i.nativeToEndian=function(e,t){if(this.endianness==t){return e}else{return this.flipArrayEndianness(e)}};i.flipArrayEndianness=function(e){var t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);for(var r=0;rn;i--,n++){var a=t[n];t[n]=t[i];t[i]=a}}return e};i.prototype.failurePosition=0;i.prototype.readStruct=function(e){var t={},r,i,n;var a=this.position;for(var s=0;s>16);this.writeUint8((e&65280)>>8);this.writeUint8(e&255)};i.prototype.adjustUint32=function(e,t){var r=this.position;this.seek(e);this.writeUint32(t);this.seek(r)}},{}],174:[function(e,t,r){var n=e("./DataStream");var a=e("./descriptor");var s=e("./log");var o={ERR_NOT_ENOUGH_DATA:0,OK:1,boxCodes:["mdat","avcC","hvcC","ftyp","payl","vmhd","smhd","hmhd","dref","elst"],fullBoxCodes:["mvhd","tkhd","mdhd","hdlr","smhd","hmhd","nhmd","url ","urn ","ctts","cslg","stco","co64","stsc","stss","stsz","stz2","stts","stsh","mehd","trex","mfhd","tfhd","trun","tfdt","esds","subs","txtC"],containerBoxCodes:[["moov",["trak"]],["trak"],["edts"],["mdia"],["minf"],["dinf"],["stbl"],["mvex",["trex"]],["moof",["traf"]],["traf",["trun"]],["vttc"],["tref"]],sampleEntryCodes:[{prefix:"Visual",types:["mp4v","avc1","avc2","avc3","avc4","avcp","drac","encv","mjp2","mvc1","mvc2","resv","s263","svc1","vc-1","hvc1","hev1"]},{prefix:"Audio",types:["mp4a","ac-3","alac","dra1","dtsc","dtse",,"dtsh","dtsl","ec-3","enca","g719","g726","m4ae","mlpa","raw ","samr","sawb","sawp","sevc","sqcp","ssmv","twos"]},{prefix:"Hint",types:["fdp ","m2ts","pm2t","prtp","rm2t","rrtp","rsrp","rtp ","sm2t","srtp"]},{prefix:"Metadata",types:["metx","mett","urim"]},{prefix:"Subtitle",types:["stpp","wvtt","sbtt","tx3g","stxt"]}],trackReferenceTypes:["scal"],initialize:function(){var e,t;var r;o.FullBox.prototype=new o.Box;o.ContainerBox.prototype=new o.Box;o.stsdBox.prototype=new o.FullBox;o.SampleEntry.prototype=new o.FullBox;o.TrackReferenceTypeBox.prototype=new o.Box;r=o.boxCodes.length;for(e=0;ee.byteLength){e.seek(i);s.w("BoxParser",'Not enough data in stream to parse the entire "'+f+'" box');return{code:o.ERR_NOT_ENOUGH_DATA,type:f,size:a,hdr_size:n}}if(o[f+"Box"]){r=new o[f+"Box"](a-n)}else{if(t){r=new o.SampleEntry(f,a-n)}else{r=new o.Box(f,a-n)}}r.hdr_size=n;r.start=i;r.fileStart=i+e.buffer.fileStart;r.parse(e);e.seek(i+a);return{code:o.OK,box:r,size:a}}};t.exports=o;o.initialize();o.Box.prototype.parse=function(e){if(this.type!="mdat"){this.data=e.readUint8Array(this.size)}else{e.seek(this.start+this.size+this.hdr_size)}};o.FullBox.prototype.parseFullHeader=function(e){this.version=e.readUint8();this.flags=e.readUint24();this.size-=4};o.ContainerBox.prototype.parse=function(e){var t;var r;var i;i=e.position;while(e.position=4){this.compatible_brands[t]=e.readString(4);this.size-=4;t++}};o.mvhdBox.prototype.parse=function(e){this.flags=0;this.parseFullHeader(e);if(this.version==1){this.creation_time=e.readUint64();this.modification_time=e.readUint64();this.timescale=e.readUint32();this.duration=e.readUint64()}else{this.creation_time=e.readUint32();this.modification_time=e.readUint32();this.timescale=e.readUint32();this.duration=e.readUint32()}this.rate=e.readUint32();this.volume=e.readUint16()>>8;e.readUint16();e.readUint32Array(2);this.matrix=e.readUint32Array(9);e.readUint32Array(6);this.next_track_id=e.readUint32()};o.TKHD_FLAG_ENABLED=1;o.TKHD_FLAG_IN_MOVIE=2;o.TKHD_FLAG_IN_PREVIEW=4;o.tkhdBox.prototype.parse=function(e){this.parseFullHeader(e);if(this.version==1){this.creation_time=e.readUint64();this.modification_time=e.readUint64();this.track_id=e.readUint32();e.readUint32();this.duration=e.readUint64()}else{this.creation_time=e.readUint32();this.modification_time=e.readUint32();this.track_id=e.readUint32();e.readUint32();this.duration=e.readUint32()}e.readUint32Array(2);this.layer=e.readInt16();this.alternate_group=e.readInt16();this.volume=e.readInt16()>>8;e.readUint16();this.matrix=e.readInt32Array(9);this.width=e.readUint32();this.height=e.readUint32()};o.mdhdBox.prototype.parse=function(e){this.parseFullHeader(e);if(this.version==1){this.creation_time=e.readUint64();this.modification_time=e.readUint64();this.timescale=e.readUint32();this.duration=e.readUint64()}else{this.creation_time=e.readUint32();this.modification_time=e.readUint32();this.timescale=e.readUint32();this.duration=e.readUint32()}this.language=e.readUint16();var t=[];t[0]=this.language>>10&31;t[1]=this.language>>5&31;t[2]=this.language&31;this.languageString=String.fromCharCode(t[0]+96,t[1]+96,t[2]+96);e.readUint16()};o.hdlrBox.prototype.parse=function(e){this.parseFullHeader(e);if(this.version===0){e.readUint32();this.handler=e.readString(4);e.readUint32Array(3);this.name=e.readCString()}else{this.data=e.readUint8Array(size)}};o.stsdBox.prototype.parse=function(e){var t;var r;this.parseFullHeader(e);r=e.readUint32();for(i=1;i<=r;i++){t=o.parseOneBox(e,true);this.entries.push(t.box)}};o.avcCBox.prototype.parse=function(e){var t;var r;var i;this.configurationVersion=e.readUint8();this.AVCProfileIndication=e.readUint8();this.profile_compatibility=e.readUint8();this.AVCLevelIndication=e.readUint8();this.lengthSizeMinusOne=e.readUint8()&3;r=e.readUint8()&31;this.size-=6;this.SPS=new Array(r);for(t=0;t0){this.ext=e.readUint8Array(this.size)}};o.hvcCBox.prototype.parse=function(e){var t;var r;var i;var n;this.configurationVersion=e.readUint8();n=e.readUint8();this.general_profile_space=n>>6;this.general_tier_flag=(n&32)>>5;this.general_profile_idc=n&31;this.general_profile_compatibility=e.readUint32();this.general_constraint_indicator=e.readUint8Array(6);this.general_level_idc=e.readUint8();this.min_spatial_segmentation_idc=e.readUint16()&4095;this.parallelismType=e.readUint8()&3;this.chromaFormat=e.readUint8()&3;this.bitDepthLumaMinus8=e.readUint8()&7;this.bitDepthChromaMinus8=e.readUint8()&7;this.avgFrameRate=e.readUint16();n=e.readUint8();this.constantFrameRate=n>>6;this.numTemporalLayers=(n&13)>>3;this.temporalIdNested=(n&4)>>2;this.lengthSizeMinusOne=n&3;this.nalu_arrays=[];numOfArrays=e.readUint8();for(t=0;t>7;a.nalu_type=n&63;numNalus=e.readUint16();for(j=0;j>=1}t+=f(i,0);t+=".";if(this.hvcC.general_tier_flag===0){t+="L"}else{t+="H"}t+=this.hvcC.general_level_idc;var n=false;var a="";for(e=5;e>=0;e--){if(this.hvcC.general_constraint_indicator[e]||n){a="."+f(this.hvcC.general_constraint_indicator[e],0)+a;n=true}}t+=a}return t};o.mp4aBox.prototype.getCodec=function(){var e=o.SampleEntry.prototype.getCodec.call(this);if(this.esds&&this.esds.esd){var t=this.esds.esd.getOTI();var r=this.esds.esd.getAudioConfig();return e+"."+f(t)+(r?"."+r:"")}else{return e}};o.esdsBox.prototype.parse=function(e){this.parseFullHeader(e);this.data=e.readUint8Array(this.size);this.size=0;var t=new a;this.esd=t.parseOneDescriptor(new n(this.data.buffer,0,n.BIG_ENDIAN))};o.txtCBox.prototype.parse=function(e){this.parseFullHeader(e);this.config=e.readCString()};o.cttsBox.prototype.parse=function(e){var t;var r;this.parseFullHeader(e);t=e.readUint32();this.sample_counts=[];this.sample_offsets=[];if(this.version===0){for(r=0;rt&&this.flags&o.TFHD_FLAG_BASE_DATA_OFFSET){this.base_data_offset=e.readUint64();t+=8}else{this.base_data_offset=0}if(this.size>t&&this.flags&o.TFHD_FLAG_SAMPLE_DESC){this.default_sample_description_index=e.readUint32();t+=4}else{this.default_sample_description_index=0}if(this.size>t&&this.flags&o.TFHD_FLAG_SAMPLE_DUR){this.default_sample_duration=e.readUint32();t+=4}else{this.default_sample_duration=0}if(this.size>t&&this.flags&o.TFHD_FLAG_SAMPLE_SIZE){this.default_sample_size=e.readUint32();t+=4}else{this.default_sample_size=0}if(this.size>t&&this.flags&o.TFHD_FLAG_SAMPLE_FLAGS){this.default_sample_flags=e.readUint32();t+=4}else{this.default_sample_flags=0}};o.TRUN_FLAGS_DATA_OFFSET=1;o.TRUN_FLAGS_FIRST_FLAG=4;o.TRUN_FLAGS_DURATION=256;o.TRUN_FLAGS_SIZE=512;o.TRUN_FLAGS_FLAGS=1024;o.TRUN_FLAGS_CTS_OFFSET=2048;o.trunBox.prototype.parse=function(e){var t=0;this.parseFullHeader(e);this.sample_count=e.readUint32();t+=4;if(this.size>t&&this.flags&o.TRUN_FLAGS_DATA_OFFSET){this.data_offset=e.readInt32();t+=4}else{this.data_offset=0}if(this.size>t&&this.flags&o.TRUN_FLAGS_FIRST_FLAG){this.first_sample_flags=e.readUint32();t+=4}else{this.first_sample_flags=0}this.sample_duration=[];this.sample_size=[];this.sample_flags=[];this.sample_composition_time_offset=[];if(this.size>t){for(var r=0;r0){for(r=0;rn.MAX_SIZE){this.size+=8}s.d("BoxWriter","Writing box "+this.type+" of size: "+this.size+" at position "+e.position+(t||""));if(this.size>n.MAX_SIZE){e.writeUint32(1)}else{this.sizePosition=e.position;e.writeUint32(this.size)}e.writeString(this.type,null,4);if(this.size>n.MAX_SIZE){e.writeUint64(this.size)}};o.FullBox.prototype.writeHeader=function(e){this.size+=4;o.Box.prototype.writeHeader.call(this,e," v="+this.version+" f="+this.flags);e.writeUint8(this.version);e.writeUint24(this.flags)};o.Box.prototype.write=function(e){if(this.type==="mdat"){if(this.data){this.size=this.data.length;this.writeHeader(e);e.writeUint8Array(this.data)}}else{this.size=this.data.length;this.writeHeader(e);e.writeUint8Array(this.data)}};o.ContainerBox.prototype.write=function(e){this.size=0;this.writeHeader(e);for(var t=0;t>3}else{return null}};o.DecoderConfigDescriptor=function(e){o.Descriptor.call(this,t,e)};o.DecoderConfigDescriptor.prototype=new o.Descriptor;o.DecoderConfigDescriptor.prototype.parse=function(e){this.oti=e.readUint8();this.streamType=e.readUint8();this.bufferSize=e.readUint24();this.maxBitrate=e.readUint32();this.avgBitrate=e.readUint32();this.size-=13;this.parseRemainingDescriptors(e)};o.DecoderSpecificInfo=function(e){o.Descriptor.call(this,r,e)};o.DecoderSpecificInfo.prototype=new o.Descriptor;o.SLConfigDescriptor=function(e){o.Descriptor.call(this,n,e)};o.SLConfigDescriptor.prototype=new o.Descriptor;return this};t.exports=n},{"./log":177}],176:[function(e,t,r){var i=e("./box");var n=e("./DataStream");var a=e("./log");var s=function(e){this.stream=e;this.boxes=[];this.mdats=[];this.moofs=[];this.isProgressive=false;this.lastMoofIndex=0;this.lastBoxStartPosition=0;this.parsingMdat=null;this.moovStartFound=false;this.samplesDataSize=0;this.nextParsePosition=0};t.exports=s;s.prototype.mergeNextBuffer=function(){var e;if(this.stream.bufferIndex+1"+this.stream.buffer.byteLength+")");return true}else{return false}}else{return false}};s.prototype.parse=function(){var e;var t;var r;a.d("ISOFile","Starting parsing with buffer #"+this.stream.bufferIndex+" (fileStart: "+this.stream.buffer.fileStart+" - Length: "+this.stream.buffer.byteLength+") from position "+this.lastBoxStartPosition+" ("+(this.stream.buffer.fileStart+this.lastBoxStartPosition)+" in the file)");this.stream.seek(this.lastBoxStartPosition);while(true){if(this.parsingMdat!==null){r=this.parsingMdat;e=this.reposition(false,r.fileStart+r.hdr_size+r.size);if(e){a.d("ISOFile","Found 'mdat' end in buffer #"+this.stream.bufferIndex);this.parsingMdat=null;continue}else{this.nextParsePosition=this.findEndContiguousBuf(this.stream.bufferIndex);return}}else{this.lastBoxStartPosition=this.stream.position;t=i.parseOneBox(this.stream);if(t.code===i.ERR_NOT_ENOUGH_DATA){if(t.type==="mdat"){r=new i[t.type+"Box"](t.size-t.hdr_size);this.parsingMdat=r;this.mdats.push(r);r.fileStart=this.stream.buffer.fileStart+this.stream.position;r.hdr_size=t.hdr_size;this.stream.buffer.usedBytes+=t.hdr_size;e=this.reposition(false,r.fileStart+r.hdr_size+r.size);if(e){this.parsingMdat=null;continue}else{if(!this.moovStartFound){this.nextParsePosition=r.fileStart+r.size+r.hdr_size}else{this.nextParsePosition=this.findEndContiguousBuf(this.stream.bufferIndex)}return}}else{if(t.type==="moov"){this.moovStartFound=true;if(this.mdats.length===0){this.isProgressive=true}}else if(t.type==="free"){e=this.reposition(false,this.stream.buffer.fileStart+this.stream.position+t.size);if(e){continue}else{this.nextParsePosition=this.stream.buffer.fileStart+this.stream.position+t.size;return}}merged=this.mergeNextBuffer();if(merged){this.nextParsePosition=this.stream.buffer.fileStart+this.stream.buffer.byteLength;continue}else{if(!t.type){this.nextParsePosition=this.stream.buffer.fileStart+this.stream.buffer.byteLength}else{if(this.moovStartFound){this.nextParsePosition=this.stream.buffer.fileStart+this.stream.buffer.byteLength}else{this.nextParsePosition=this.stream.buffer.fileStart+this.stream.position+t.size}}return}}}else{r=t.box;this.boxes.push(r);switch(r.type){case"mdat":this.mdats.push(r);r.fileStart=this.stream.buffer.fileStart+r.start;break;case"moof":this.moofs.push(r);break;case"moov":this.moovStartFound=true;if(this.mdats.length===0){this.isProgressive=true}default:if(this[r.type]!==undefined){a.w("ISOFile","Duplicate Box of type: "+r.type+", overriding previous occurrence")}this[r.type]=r;break}if(r.type==="mdat"){this.stream.buffer.usedBytes+=r.hdr_size}else{this.stream.buffer.usedBytes+=t.size}}}}};s.prototype.reposition=function(e,t){var r;r=this.findPosition(e,t);if(r!==-1){this.stream.buffer=this.stream.nextBuffers[r];this.stream.bufferIndex=r;this.stream.position=t-this.stream.buffer.fileStart;a.d("ISOFile","Repositioning parser at buffer position: "+this.stream.position);return true}else{return false}};s.prototype.findPosition=function(e,t){var r;var i=null;var n=-1;if(e===true){r=0}else{r=this.stream.bufferIndex}while(r=t){a.d("ISOFile","Found position in existing buffer #"+n);return n}else{return-1}}else{return-1}};s.prototype.findEndContiguousBuf=function(e){var t;var r;var i;r=this.stream.nextBuffers[e];if(this.stream.nextBuffers.length>e+1){for(t=e+1;t-1){this.moov.boxes.splice(r,1)}this.moov.mvex=null}this.moov.mvex=new i.mvexBox;this.moov.boxes.push(this.moov.mvex);this.moov.mvex.mehd=new i.mehdBox;this.moov.mvex.boxes.push(this.moov.mvex.mehd);this.moov.mvex.mehd.fragment_duration=this.initial_duration;for(t=0;t0?this.moov.traks[t].samples[0].duration:0;s.default_sample_size=0;s.default_sample_flags=1<<16}this.moov.write(e)};s.prototype.resetTables=function(){var e;var t,r,i,n,a,s,o,f;this.initial_duration=this.moov.mvhd.duration;this.moov.mvhd.duration=0;for(e=0;eg){y++;if(g<0){g=0}g+=o.sample_counts[y]}if(t>0){i.samples[t-1].duration=o.sample_deltas[y];k.dts=i.samples[t-1].dts+i.samples[t-1].duration}else{k.dts=0}if(f){if(t>_){b++;_+=f.sample_counts[b]}k.cts=i.samples[t].dts+f.sample_offsets[b]}else{k.cts=k.dts}if(u){if(t==u.sample_numbers[w]-1){k.is_rap=true;w++}else{k.is_rap=false}}else{k.is_rap=true}if(c){if(c.samples[subs_entry_index].sample_delta+last_subs_sample_index==t){k.subsamples=c.samples[subs_entry_index].subsamples;last_subs_sample_index+=c.samples[subs_entry_index].sample_delta}}}if(t>0)i.samples[t-1].duration=i.mdia.mdhd.duration-i.samples[t-1].dts}};s.prototype.updateSampleLists=function(){var e,t,r;var n,a,s,o;var f;var u,l,c,p,d;var h;while(this.lastMoofIndex0){h.dts=p.samples[p.samples.length-2].dts+p.samples[p.samples.length-2].duration}else{if(c.tfdt){h.dts=c.tfdt.baseMediaDecodeTime}else{h.dts=0}p.first_traf_merged=true}h.cts=h.dts;if(m.flags&i.TRUN_FLAGS_CTS_OFFSET){h.cts=h.dts+m.sample_composition_time_offset[r]}sample_flags=o;if(m.flags&i.TRUN_FLAGS_FLAGS){sample_flags=m.sample_flags[r]}else if(r===0&&m.flags&i.TRUN_FLAGS_FIRST_FLAG){sample_flags=m.first_sample_flags}h.is_rap=sample_flags>>16&1?false:true;var v=c.tfhd.flags&i.TFHD_FLAG_BASE_DATA_OFFSET?true:false;var g=c.tfhd.flags&i.TFHD_FLAG_DEFAULT_BASE_IS_MOOF?true:false;var y=m.flags&i.TRUN_FLAGS_DATA_OFFSET?true:false;var _=0;if(!v){if(!g){if(t===0){_=l.fileStart}else{_=f}}else{_=l.fileStart}}else{_=c.tfhd.base_data_offset}if(t===0&&r===0){if(y){h.offset=_+m.data_offset}else{h.offset=_}}else{h.offset=f}f=h.offset+h.size}}if(c.subs){var b=c.first_sample_index;for(t=0;t0){t+=","}t+=r.mdia.minf.stbl.stsd.entries[0].getCodec()}return t};s.prototype.getTrexById=function(e){var t;if(!this.originalMvex)return null;for(t=0;t=r.fileStart&&s.offset+s.alreadyRead=s){console.debug("["+i.getDurationString(new Date-e,1e3)+"]","["+t+"]",r)}},i:function(t,r){if(n>=s){console.info("["+i.getDurationString(new Date-e,1e3)+"]","["+t+"]",r)}},w:function(t,n){if(r>=s){console.warn("["+i.getDurationString(new Date-e,1e3)+"]","["+t+"]",n)}},e:function(r,n){if(t>=s){console.error("["+i.getDurationString(new Date-e,1e3)+"]","["+r+"]",n)}}};return o}();t.exports=i;i.getDurationString=function(e,t){function r(e,t){var r=""+e;var i=r.split(".");while(i[0].length0){var r="";for(var n=0;n0)r+=",";r+="["+i.getDurationString(e.start(n))+","+i.getDurationString(e.end(n))+"]"}return r}else{return"(empty)"}}},{}],178:[function(e,t,r){var n=e("./box");var a=e("./DataStream");var s=e("./isofile");var o=e("./log");var f=function(){this.inputStream=null;this.nextBuffers=[];this.inputIsoFile=null;this.onMoovStart=null;this.moovStartSent=false;this.onReady=null;this.readySent=false;this.onSegment=null;this.onSamples=null;this.onError=null;this.sampleListBuilt=false;this.fragmentedTracks=[];this.extractedTracks=[];this.isFragmentationStarted=false;this.nextMoofNumber=0};t.exports=f;f.prototype.setSegmentOptions=function(e,t,r){var i=this.inputIsoFile.getTrackById(e);if(i){var n={};this.fragmentedTracks.push(n);n.id=e;n.user=t;n.trak=i;i.nextSample=0;n.segmentStream=null;n.nb_samples=1e3;n.rapAlignement=true;if(r){if(r.nbSamples)n.nb_samples=r.nbSamples;if(r.rapAlignement)n.rapAlignement=r.rapAlignement}}};f.prototype.unsetSegmentOptions=function(e){var t=-1;for(var r=0;r-1){this.fragmentedTracks.splice(t,1)}};f.prototype.setExtractionOptions=function(e,t,r){var i=this.inputIsoFile.getTrackById(e);if(i){var n={};this.extractedTracks.push(n);n.id=e;n.user=t;n.trak=i;i.nextSample=0;n.nb_samples=1e3;n.samples=[];if(r){if(r.nbSamples)n.nb_samples=r.nbSamples}}};f.prototype.unsetExtractionOptions=function(e){var t=-1;for(var r=0;r-1){this.extractedTracks.splice(t,1)}};f.prototype.createSingleSampleMoof=function(e){var t=new n.moofBox;var r=new n.mfhdBox;r.sequence_number=this.nextMoofNumber;this.nextMoofNumber++;t.boxes.push(r);var i=new n.trafBox;t.boxes.push(i);var a=new n.tfhdBox;i.boxes.push(a);a.track_id=e.track_id;a.flags=n.TFHD_FLAG_DEFAULT_BASE_IS_MOOF;var s=new n.tfdtBox;i.boxes.push(s);s.baseMediaDecodeTime=e.dts;var o=new n.trunBox;i.boxes.push(o);t.trun=o;o.flags=n.TRUN_FLAGS_DATA_OFFSET|n.TRUN_FLAGS_DURATION|n.TRUN_FLAGS_SIZE|n.TRUN_FLAGS_FLAGS|n.TRUN_FLAGS_CTS_OFFSET;o.data_offset=0;o.first_sample_flags=0;o.sample_count=1;o.sample_duration=[];o.sample_duration[0]=e.duration;o.sample_size=[];o.sample_size[0]=e.size;o.sample_flags=[];o.sample_flags[0]=0;o.sample_composition_time_offset=[];o.sample_composition_time_offset[0]=e.cts-e.dts;return t};f.prototype.createFragment=function(e,t,r,i){var s=this.inputIsoFile.getTrackById(t);var f=this.inputIsoFile.getSample(s,r);if(f==null){if(this.nextSeekPosition){this.nextSeekPosition=Math.min(s.samples[r].offset,this.nextSeekPosition)}else{this.nextSeekPosition=s.samples[r].offset}return null}var u=i||new a;u.endianness=a.BIG_ENDIAN;var l=this.createSingleSampleMoof(f);l.write(u);l.trun.data_offset=l.size+8;o.d("BoxWriter","Adjusting data_offset with new value "+l.trun.data_offset);u.adjustUint32(l.trun.data_offset_position,l.trun.data_offset);var c=new n.mdatBox;c.data=f.data;c.write(u);return u};ArrayBuffer.concat=function(e,t){o.d("ArrayBuffer","Trying to create a new buffer of size: "+(e.byteLength+t.byteLength));var r=new Uint8Array(e.byteLength+t.byteLength);r.set(new Uint8Array(e),0);r.set(new Uint8Array(t),e.byteLength);return r.buffer};f.prototype.reduceBuffer=function(e,t,r){var i;i=new Uint8Array(r);i.set(new Uint8Array(e,t,r));i.buffer.fileStart=e.fileStart+t;i.buffer.usedBytes=0;return i.buffer};f.prototype.insertBuffer=function(e){var t=true;for(var r=0;ri.byteLength){this.nextBuffers.splice(r,1);r--;continue}else{o.w("MP4Box","Buffer (fileStart: "+e.fileStart+" - Length: "+e.byteLength+") already appended, ignoring")}}else{if(e.fileStart+e.byteLength<=i.fileStart){}else{e=this.reduceBuffer(e,0,i.fileStart-e.fileStart)}o.d("MP4Box","Appending new buffer (fileStart: "+e.fileStart+" - Length: "+e.byteLength+")");this.nextBuffers.splice(r,0,e);if(r===0&&this.inputStream!==null){this.inputStream.buffer=e}}t=false;break}else if(e.fileStart0){e=this.reduceBuffer(e,n,a)}else{t=false;break}}}if(t){o.d("MP4Box","Appending new buffer (fileStart: "+e.fileStart+" - Length: "+e.byteLength+")");this.nextBuffers.push(e);if(r===0&&this.inputStream!==null){this.inputStream.buffer=e}}};f.prototype.processSamples=function(){var e;var t;if(this.isFragmentationStarted&&this.onSegment!==null){for(e=0;e=t.samples.length){o.i("MP4Box","Sending fragmented data on track #"+r.id+" for samples ["+(t.nextSample-r.nb_samples)+","+(t.nextSample-1)+"]");if(this.onSegment){this.onSegment(r.id,r.user,r.segmentStream.buffer,t.nextSample)}r.segmentStream=null;if(r!==this.fragmentedTracks[e]){break}}}}}if(this.onSamples!==null){for(e=0;e=t.samples.length){o.d("MP4Box","Sending samples on track #"+n.id+" for sample "+t.nextSample);if(this.onSamples){this.onSamples(n.id,n.user,n.samples)}n.samples=[];if(n!==this.extractedTracks[e]){break}}}}}};f.prototype.appendBuffer=function(e){var t;var r;if(e===null||e===undefined){throw"Buffer must be defined and non empty"}if(e.fileStart===undefined){throw"Buffer must have a fileStart property"}if(e.byteLength===0){o.w("MP4Box","Ignoring empty buffer (fileStart: "+e.fileStart+")");return}e.usedBytes=0;this.insertBuffer(e);if(!this.inputStream){if(this.nextBuffers.length>0){r=this.nextBuffers[0];if(r.fileStart===0){this.inputStream=new a(r,0,a.BIG_ENDIAN);this.inputStream.nextBuffers=this.nextBuffers;this.inputStream.bufferIndex=0}else{o.w("MP4Box","The first buffer should have a fileStart of 0");return}}else{o.w("MP4Box","No buffer to start parsing from");return}}if(!this.inputIsoFile){this.inputIsoFile=new s(this.inputStream)}this.inputIsoFile.parse();if(this.inputIsoFile.moovStartFound&&!this.moovStartSent){this.moovStartSent=true;if(this.onMoovStart)this.onMoovStart()}if(this.inputIsoFile.moov){if(!this.sampleListBuilt){this.inputIsoFile.buildSampleLists();this.sampleListBuilt=true}this.inputIsoFile.updateSampleLists();if(this.onReady&&!this.readySent){var i=this.getInfo();this.readySent=true;this.onReady(i)}this.processSamples();if(this.nextSeekPosition){t=this.nextSeekPosition;this.nextSeekPosition=undefined}else{t=this.inputIsoFile.nextParsePosition}var n=this.inputIsoFile.findPosition(true,t);if(n!==-1){t=this.inputIsoFile.findEndContiguousBuf(n)}o.i("MP4Box","Next buffer to fetch should have a fileStart position of "+t);return t}else{if(this.inputIsoFile!==null){return this.inputIsoFile.nextParsePosition}else{return 0}}};f.prototype.getInfo=function(){var e={};var t;var r;var n;var a=new Date(4,0,1,0,0,0,0).getTime();e.duration=this.inputIsoFile.moov.mvhd.duration;e.timescale=this.inputIsoFile.moov.mvhd.timescale;e.isFragmented=this.inputIsoFile.moov.mvex!=null;if(e.isFragmented&&this.inputIsoFile.moov.mvex.mehd){e.fragment_duration=this.inputIsoFile.moov.mvex.mehd.fragment_duration}else{e.fragment_duration=0}e.isProgressive=this.inputIsoFile.isProgressive;e.hasIOD=this.inputIsoFile.moov.iods!=null;e.brands=[];e.brands.push(this.inputIsoFile.ftyp.major_brand);e.brands=e.brands.concat(this.inputIsoFile.ftyp.compatible_brands);e.created=new Date(a+this.inputIsoFile.moov.mvhd.creation_time*1e3);e.modified=new Date(a+this.inputIsoFile.moov.mvhd.modification_time*1e3);e.tracks=[];e.audioTracks=[];e.videoTracks=[];e.subtitleTracks=[];e.metadataTracks=[];e.hintTracks=[];e.otherTracks=[];for(i=0;ie*n.timescale){f=r.samples[i-1].offset;l=i-1;break}if(t&&n.is_rap){a=n.offset;s=n.cts;u=i}}if(t){r.nextSample=u;o.i("MP4Box","Seeking to RAP sample #"+r.nextSample+" on track "+r.tkhd.track_id+", time "+o.getDurationString(s,c)+" and offset: "+a);return{offset:a,time:s/c}}else{r.nextSample=l;o.i("MP4Box","Seeking to non-RAP sample #"+r.nextSample+" on track "+r.tkhd.track_id+", time "+o.getDurationString(e)+" and offset: "+a);return{offset:f,time:e}}};f.prototype.seek=function(e,t){var r=this.inputIsoFile.moov;var i;var n;var a;var s={offset:Infinity,time:Infinity};if(!this.inputIsoFile.moov){throw"Cannot seek: moov not received!"}else{for(a=0;an){break}else if(o>=0||n<=l){o=l}}var c=o-n;if(c<0)c=0;i("Buffer length: %f",c);return c<=s}var h=new MediaSource;h.addEventListener("sourceopen",function(){w(0)});t.src=window.URL.createObjectURL(h);var m=new n;m.onError=function(e){i("MP4Box error: %s",e.message);if(b){b()}if(h.readyState==="open"){p("decode")}};var v=false;var g={};m.onReady=function(e){i("MP4 info: %o",e);e.tracks.forEach(function(e){var t;if(e.video){t="video/mp4"}else if(e.audio){t="audio/mp4"}else{return}t+='; codecs="'+e.codec+'"';if(MediaSource.isTypeSupported(t)){var r=h.addSourceBuffer(t);var i={buffer:r,arrayBuffers:[],meta:e,ended:false};r.addEventListener("updateend",A.bind(null,i));m.setSegmentOptions(e.id,null,{nbSamples:e.video?1:100});g[e.id]=i}});if(Object.keys(g).length===0){p("decode");return}var t=m.initializeSegmentation();t.forEach(function(e){S(g[e.id],e.buffer);if(e.id===f){o("init-track-"+f+".mp4",[e.buffer]);u.push(e.buffer)}});v=true};m.onSegment=function(e,t,r,i){var n=g[e];S(n,r,i===n.meta.nb_samples);if(e===f&&u){u.push(r);if(i>1e3){o("track-"+f+".mp4",u);u=null}}};var y;var _=null;var b=null;function w(t){if(t===e.length){m.flush();return}if(_&&t===y){var r=_;setTimeout(function(){if(_===r)_.resume()});return}if(_){_.destroy();b()}y=t;var n={start:y,end:e.length-1};_=e.createReadStream(n);function a(e){_.pause();var t=e.toArrayBuffer();t.fileStart=y;y+=t.byteLength;var r;try{r=m.appendBuffer(t)}catch(n){i("MP4Box threw exception: %s",n.message);if(h.readyState==="open"){p("decode")}_.destroy();b();return}w(r)}_.on("data",a);function s(){b();w(y)}_.on("end",s);function o(e){i("Stream error: %s",e.message);if(h.readyState==="open"){p("network")}}_.on("error",o);b=function(){_.removeListener("data",a);_.removeListener("end",s);_.removeListener("error",o);_=null;b=null}}function x(){if(v){k(t.currentTime)}}function k(e){if(c)l();var t=m.seek(e,true);i("Seeking to time: %d",e);i("Seeked file offset: %d",t.offset);w(t.offset)}function S(e,t,r){e.arrayBuffers.push({buffer:t,ended:r||false});A(e)}function E(){Object.keys(g).forEach(function(e){var t=g[e];if(t.blocked){A(t)}})}function A(e){if(e.buffer.updating)return;e.blocked=!d(e);if(e.blocked)return;if(e.arrayBuffers.length===0)return;var t=e.arrayBuffers.shift();var r=false;try{e.buffer.appendBuffer(t.buffer);e.ended=t.ended;r=true}catch(n){i("SourceBuffer error: %s",n.message);p("decode");return}if(r){U()}}function U(){if(h.readyState!=="open"){return}var e=Object.keys(g).every(function(e){var t=g[e];return t.ended&&!t.buffer.updating});if(e){p()}}};function o(e,t){var r=new Blob(t);var i=URL.createObjectURL(r);var n=document.createElement("a");n.setAttribute("href",i);n.setAttribute("download",e);n.click()}},{debug:120,mp4box:178}],180:[function(e,t,r){t.exports=i;function i(){var e={};for(var t=0;t0)return new Array(e+(/\./.test(t)?2:1)).join(r)+t;return t+""}},{}],183:[function(e,t,r){t.exports={name:"webtorrent",description:"Streaming torrent client",version:"0.62.0",author:{name:"Feross Aboukhadijeh",email:"feross@feross.org",url:"http://feross.org/"},bin:{webtorrent:"./bin/cmd.js"},browser:{"./lib/server":false,"bittorrent-dht/client":false,"fs-chunk-store":"memory-chunk-store","load-ip-set":false,ut_pex:false},bugs:{url:"https://github.com/feross/webtorrent/issues"},dependencies:{"addr-to-ip-port":"^1.0.1",bitfield:"^1.0.2","bittorrent-dht":"^3.0.0","bittorrent-swarm":"^5.0.0","chunk-store-stream":"^2.0.0",clivas:"^0.2.0","create-torrent":"^3.4.0",debug:"^2.1.0","end-of-stream":"^1.0.0",executable:"^1.1.0","fs-chunk-store":"^1.3.4",hat:"0.0.3","immediate-chunk-store":"^1.0.7",inherits:"^2.0.1",inquirer:"^0.9.0","load-ip-set":"^1.0.3",mediasource:"^1.0.0","memory-chunk-store":"^1.2.0",mime:"^1.2.11",minimist:"^1.1.0",moment:"^2.8.3",multistream:"^2.0.2","network-address":"^1.0.0","parse-torrent":"^5.1.0","path-exists":"^1.0.0","pretty-bytes":"^2.0.1",pump:"^1.0.0","random-iterate":"^1.0.1","range-parser":"^1.0.2","re-emitter":"^1.0.0","run-parallel":"^1.0.0","simple-sha1":"^2.0.0",speedometer:"^0.1.2",thunky:"^0.1.0","torrent-discovery":"^3.0.0","torrent-piece":"^1.0.0",uniq:"^1.0.1",ut_metadata:"^2.1.0",ut_pex:"^1.0.1",videostream:"^1.1.4","windows-no-runnable":"0.0.6",xtend:"^4.0.0","zero-fill":"^2.2.0"},devDependencies:{"bittorrent-tracker":"^6.0.0",brfs:"^1.2.0",browserify:"^11.0.0",finalhandler:"^0.4.0","run-auto":"^1.0.0","serve-static":"^1.9.3","simple-get":"^1.0.0",standard:"^5.1.0",tape:"^4.0.0","uglify-js":"^2.4.15",zelda:"^2.0.0",zuul:"^3.0.0"},homepage:"http://webtorrent.io",keywords:["torrent","bittorrent","bittorrent client","streaming","download","webrtc","webrtc data","webtorrent","mad science"],license:"MIT",main:"index.js",optionalDependencies:{"airplay-js":"^0.2.3",chromecasts:"^1.5.3",nodebmc:"0.0.5"},repository:{type:"git",url:"git://github.com/feross/webtorrent.git"},scripts:{build:"browserify -s WebTorrent -e ./ | uglifyjs -m > webtorrent.min.js","build-debug":"browserify -s WebTorrent -e ./ > webtorrent.debug.js",size:"npm run build && cat webtorrent.min.js | gzip | wc -c",test:"standard && node ./bin/test.js","test-browser":"zuul -- test/basic.js","test-browser-local":"zuul --local -- test/basic.js","test-node":"tape test/*.js"}}},{}],184:[function(e,t,r){(function(r,i,n){t.exports=w;var a=e("create-torrent");var s=e("debug")("webtorrent");var o=e("bittorrent-dht/client");var f=e("events").EventEmitter;var u=e("xtend");var l=e("hat");var c=e("inherits");var p=e("load-ip-set");var d=e("run-parallel");var h=e("parse-torrent");var m=e("speedometer");var v=e("zero-fill");var g=e("path");var y=e("./lib/torrent");c(w,f);var _=e("./package.json").version;var b=_.match(/([0-9]+)/g).slice(0,2).map(v(2)).join("");function w(e){var t=this;if(!(t instanceof w))return new w(e);if(!e)e={};f.call(t);if(!s.enabled)t.setMaxListeners(0);t.destroyed=false;t.torrentPort=e.torrentPort||0;t.tracker=e.tracker!==undefined?e.tracker:true;t._rtcConfig=e.rtcConfig;t._wrtc=e.wrtc||i.WRTC;t.torrents=[];t.downloadSpeed=m();t.uploadSpeed=m();t.peerId=e.peerId===undefined?new n("-WW"+b+"-"+l(48),"utf8"):typeof e.peerId==="string"?new n(e.peerId,"hex"):e.peerId;t.peerIdHex=t.peerId.toString("hex");t.nodeId=e.nodeId===undefined?new n(l(160),"hex"):typeof e.nodeId==="string"?new n(e.nodeId,"hex"):e.nodeId;t.nodeIdHex=t.nodeId.toString("hex");if(e.dht!==false&&typeof o==="function"){t.dht=new o(u({nodeId:t.nodeId},e.dht));t.dht.listen(e.dhtPort)}s("new webtorrent (peerId %s, nodeId %s)",t.peerIdHex,t.nodeIdHex);if(typeof p==="function"){p(e.blocklist,{headers:{"user-agent":"WebTorrent/"+_+" (http://webtorrent.io)"}},function(e,r){if(e)return t.error("Failed to load blocklist: "+e.message);t.blocked=r;a()})}else r.nextTick(a);function a(){if(t.destroyed)return;t.ready=true;t.emit("ready")}}Object.defineProperty(w.prototype,"ratio",{get:function(){var e=this;var t=e.torrents.reduce(function(e,t){return e+t.uploaded},0);var r=e.torrents.reduce(function(e,t){return e+t.downloaded},0)||1;return t/r}});w.prototype.get=function(e){var t=this;if(e instanceof y)return e;var r;try{r=h(e)}catch(i){}if(!r)return null;if(!r.infoHash)throw new Error("Invalid torrent identifier");for(var n=0,a=t.torrents.length;n 22 && description.length != 41) { + + var error = "error"; + return error; + + } + + } + +} + + + +function createIssuance(add_from, assetid, quantity, divisible, description, msig_total, transfee, mnemonic, msig_outputs) { + + //var mnemonic = $("#newpassphrase").html(); + + var privkey = getprivkey(add_from, mnemonic); + + var source_html = "https://"+INSIGHT_SERVER+"/api/addr/"+add_from+"/utxo"; + var total_utxo = new Array(); + + $.getJSON( source_html, function( data ) { + + var amountremaining = parseFloat(msig_total) + parseFloat(transfee); + + if (msig_outputs > 1) { + + amountremaining += ((msig_outputs - 1) * msig_total); + + } + + data.sort(function(a, b) { + return b.amount - a.amount; + }); + + $.each(data, function(i, item) { + + var txid = data[i].txid; + var vout = data[i].vout; + var script = data[i].scriptPubKey; + var amount = parseFloat(data[i].amount); + + amountremaining = amountremaining - amount; + amountremaining.toFixed(8); + + var obj = { + "txid": txid, + "address": add_from, + "vout": vout, + "scriptPubKey": script, + "amount": amount + }; + + total_utxo.push(obj); + + //dust limit = 5460 + + if (amountremaining == 0 || amountremaining < -0.00005460) { + return false; + } + + }); + + var utxo_key = total_utxo[0].txid; + + if (amountremaining < 0) { + var satoshi_change = -(amountremaining.toFixed(8) * 100000000).toFixed(0); + } else { + var satoshi_change = 0; + } + + create_asset_unique(assetid, quantity, divisible, description, function(datachunk_unencoded){ + + if (datachunk_unencoded != "error") { + + if ($.isArray(datachunk_unencoded) == false) { + + var datachunk_encoded = xcp_rc4(utxo_key, datachunk_unencoded); + var address_array = addresses_from_datachunk(datachunk_encoded); + + var sender_pubkeyhash = new bitcore.PublicKey(bitcore.PrivateKey.fromWIF(privkey)); + + var scriptstring = "OP_1 33 0x"+address_array[0]+" 33 0x"+address_array[1]+" 33 0x"+sender_pubkeyhash+" OP_3 OP_CHECKMULTISIG"; + console.log(scriptstring); + var data_script = new bitcore.Script(scriptstring); + + var transaction = new bitcore.Transaction(); + + for (i = 0; i < total_utxo.length; i++) { + transaction.from(total_utxo[i]); + } + + var msig_total_satoshis = parseFloat((msig_total * 100000000).toFixed(0)); + + var xcpdata_msig = new bitcore.Transaction.Output({script: data_script, satoshis: msig_total_satoshis}); + + transaction.addOutput(xcpdata_msig); + + if (satoshi_change > 5459) { + transaction.to(add_from, satoshi_change); + } + + transaction.sign(privkey); + + var final_trans = transaction.serialize(); + + } else { + + var sender_pubkeyhash = new bitcore.PublicKey(bitcore.PrivateKey.fromWIF(privkey)); + + var transaction = new bitcore.Transaction(); + + for (i = 0; i < total_utxo.length; i++) { + transaction.from(total_utxo[i]); + } + + var msig_total_satoshis = parseFloat((msig_total * 100000000).toFixed(0)); + + + var first_datachunk_encoded = xcp_rc4(utxo_key, datachunk_unencoded[0]); + var first_address_array = addresses_from_datachunk(first_datachunk_encoded); + + var second_datachunk_encoded = xcp_rc4(utxo_key, datachunk_unencoded[1]); + var second_address_array = addresses_from_datachunk(second_datachunk_encoded); + + var first_scriptstring = "OP_1 33 0x"+first_address_array[0]+" 33 0x"+first_address_array[1]+" 33 0x"+sender_pubkeyhash+" OP_3 OP_CHECKMULTISIG"; + console.log(first_scriptstring); + var first_data_script = new bitcore.Script(first_scriptstring); + + var second_scriptstring = "OP_1 33 0x"+second_address_array[0]+" 33 0x"+second_address_array[1]+" 33 0x"+sender_pubkeyhash+" OP_3 OP_CHECKMULTISIG"; + console.log(second_scriptstring); + var second_data_script = new bitcore.Script(second_scriptstring); + + + + var xcpdata_msig_first = new bitcore.Transaction.Output({script: first_data_script, satoshis: msig_total_satoshis}); + var xcpdata_msig_second = new bitcore.Transaction.Output({script: second_data_script, satoshis: msig_total_satoshis}); + + transaction.addOutput(xcpdata_msig_first); + transaction.addOutput(xcpdata_msig_second); + + if (satoshi_change > 5459) { + transaction.to(add_from, satoshi_change); + } + + transaction.sign(privkey); + + var final_trans = transaction.serialize(); + + } + + } else { + + var final_trans = "error"; + + } + + console.log(final_trans); + + sendBTCissue(final_trans); //uncomment to push raw tx to the bitcoin network + + }); + + }); + +} diff --git a/Chrome Extension/js/xcp-js/transactions.js b/Chrome Extension/js/xcp-js/transactions.js index 823a5a6..0e97835 100644 --- a/Chrome Extension/js/xcp-js/transactions.js +++ b/Chrome Extension/js/xcp-js/transactions.js @@ -71,7 +71,20 @@ function assetid(asset_name) { //asset_name.toUpperCase(); - if(asset_name != "XCP"){ + if (asset_name == "XCP") { + + var asset_id = (1).toString(16); + + } else if (asset_name.substr(0, 1) == "A") { + + var pre_id = asset_name.substr(1); + + var pre_id_bigint = BigIntegerSM(pre_id); + + var asset_id = pre_id_bigint.toString(16); + + + } else { var b26_digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; var name_array = asset_name.split(""); @@ -92,11 +105,7 @@ function assetid(asset_name) { //var asset_id = n; var asset_id = n_bigint.toString(16); - } else { - - var asset_id = (1).toString(16); - - } + } //return asset_id; console.log(asset_id); @@ -214,8 +223,13 @@ function addresses_from_datachunk(datachunk) { function isdatacorrect(data_chunk, asset, asset_total) { var asset_id = padprefix(assetid(asset),16); + + console.log(asset_id); var assethex = data_chunk.substring(42, 26); + + console.log(assethex); + var amount = data_chunk.substring(58, 42); //var asset_dec = parseInt(assethex, 16); var amount_dec = parseInt(amount, 16) / 100000000; @@ -238,7 +252,7 @@ function sendXCP(add_from, add_to, asset, asset_total, btc_total, msig_total, tr var privkey = getprivkey(add_from, mnemonic); - var source_html = "https://insight.bitpay.com/api/addr/"+add_from+"/utxo"; + var source_html = "https://"+INSIGHT_SERVER+"/api/addr/"+add_from+"/utxo"; //var source_html = "https://chain.localbitcoins.com/api/addr/"+add_from+"/utxo"; var total_utxo = new Array(); @@ -361,7 +375,7 @@ function sendXCP_opreturn(add_from, add_to, asset, asset_total, btc_total, trans var privkey = getprivkey(add_from, mnemonic); - var source_html = "https://insight.bitpay.com/api/addr/"+add_from+"/utxo"; + var source_html = "https://"+INSIGHT_SERVER+"/api/addr/"+add_from+"/utxo"; //var source_html = "https://chain.localbitcoins.com/api/addr/"+add_from+"/utxo"; // var source_html = "http://btc.blockr.io/api/v1/address/unspent/"+add_from; @@ -474,7 +488,7 @@ function sendXCP_opreturn(add_from, add_to, asset, asset_total, btc_total, trans if (correct == "yes") { - sendBTCpush(final_trans); //push raw tx to the bitcoin network via Blockchain.info + sendBTCpush(final_trans); //push raw tx to the bitcoin network via chain.so } else { $("#sendtokenbutton").html("Error, refresh to continue..."); } diff --git a/Chrome Extension/loader.gif b/Chrome Extension/loader.gif new file mode 100644 index 0000000..cbe59fb Binary files /dev/null and b/Chrome Extension/loader.gif differ diff --git a/Chrome Extension/main.css b/Chrome Extension/main.css index 3709fe1..380adfd 100644 --- a/Chrome Extension/main.css +++ b/Chrome Extension/main.css @@ -14,14 +14,22 @@ body width: 320px; min-height: 420px; max-height: 700px; + height: 100%; margin: 5px 2px 5px 2px; background-color: #fff; } + + + a { text-decoration: none; } +.swapbotselect { + font-size: 12px; +} + .applink a:link { color: #000; } @@ -79,7 +87,7 @@ a { top: 0px; left: 0px; text-align: center; - padding: 85px 50px 70px 50px; + padding: 100px 50px 70px 50px; /*opacity: 0.99; filter: alpha(opacity=99); */ } @@ -109,14 +117,22 @@ a { #priceBox { +/* position: absolute; right: 2px; - font-size: 16px; + top: 0px; padding: 7px 5px 0 0; - - color: #616161; - text-align: center; +*/ + margin: -8px; + font-size: 16px; + color: #616161; + text-align: center; + } + +#priceBoxBank + { + margin: 0 8px 0 8px; } #priceSrc @@ -160,11 +176,11 @@ a { background-color: #fafafa; border: 2px solid #ccc; color: #000; - padding: 5px 5px 8px 5px; + padding: 5px 5px 5px 5px; display: block; border-radius: 5px; text-align: center; - margin: 10px 5px 10px 5px; + margin: 3px 5px 10px 5px; z-index: 0; } @@ -174,7 +190,7 @@ a { margin: 0 5px 0 5px; background-color: #555; border: 4px solid #ccc; - margin-bottom: 20px; + margin-bottom: 10px; display: none; border-radius: 5px; } @@ -260,7 +276,16 @@ a { } +.issuecenter +{ + text-align: left; +} +#ninjaButton { + + color: #000; + +} .bigbox { @@ -282,7 +307,7 @@ a { .btcasset { background-color: #D49D3F; color: #fff; - padding: 4px 0 4px 0; + padding: 4px 0 5px 0; margin: 4px 0 4px 0; border: 3px solid #EBC481; } @@ -290,7 +315,7 @@ a { .xcpasset { background-color: #AA3939; color: #fff; - padding: 4px 0 4px 0; + padding: 4px 0 5px 0; margin: 4px 0 4px 0; border: 3px solid #FDA8AA; } @@ -298,17 +323,77 @@ a { .singleasset { background-color: #23688F; color: #fff; - padding: 4px 0 4px 0; + padding: 4px 0 5px 0; margin: 4px 0 4px 0; border: 3px solid #67B5E0; } +.enhancedasset { + + background-color: #546E4C; + color: #fff; + padding: 4px 0 5px 0; + margin: 4px 0 4px 0; + border: 3px solid #86AD79; + +} + +.enhancedassetwt { + + background-color: #532061; + color: #fff; + padding: 4px 0 5px 0; + margin: 4px 0 4px 0; + border: 3px solid #9A7AA3; + +} + +.enhancedassetwt-loading { + + background-color: #9A7AA3; + color: #fff; + padding: 10px 0 10px 0; + margin: 4px 0 4px 0; + border: 3px solid #D3BFD9; + +} + +#tutorial_splash { + width: 100%; + height: 100%; + z-index: 10; + top: 0; + left: 0; + position: fixed; +} + +#tutorial_splash_bg { + opacity: 0.4; + background: #000; + width: 100%; + height: 100%; + top: 0; + left: 0; + position: fixed; +} + +#tutorial_splash_img { + width: 100%; + height: 100%; + z-index: 20; + top: 0; + left: 0; + position: fixed; +} + + .singleaddress { padding: 4px 0 4px 0; margin: 4px 0 4px 0; border: 3px solid #67B5E0; } +/* .enhancedasset { background-image: url("/test/enhanced_asset_ltbcoin_top.png"); background-repeat: no-repeat; @@ -319,14 +404,11 @@ a { border: 3px solid #67B5E0; height: 128px; } +*/ .newsArticle { border-radius: 10px 10px 10px 10px; --moz-border-radius: 10px 10px 10px 10px; --webkit-border-radius: 10px 10px 10px 10px; - -webkit-box-shadow: 5px 5px 5px -2px rgba(0,0,0,0.75); --moz-box-shadow: 5px 5px 5px -2px rgba(0,0,0,0.75); -box-shadow: 5px 5px 5px -2px rgba(0,0,0,0.75); + box-shadow: 5px 5px 5px -2px rgba(0,0,0,0.75); border: 2px solid #999; background-color: #3987AD; color: #fff; @@ -357,6 +439,18 @@ box-shadow: 5px 5px 5px -2px rgba(0,0,0,0.75); } +.swapbotselect { + + cursor: pointer; +} + +.sendlabel { + + color: yellow; + padding-left: 15px; +} + + .activetool:hover { background-color: #f8f8f8; cursor: pointer; @@ -364,6 +458,7 @@ box-shadow: 5px 5px 5px -2px rgba(0,0,0,0.75); .comingsoon { opacity: 0.3; + cursor: default; } .assetname { @@ -374,16 +469,47 @@ box-shadow: 5px 5px 5px -2px rgba(0,0,0,0.75); font-weight: bold; display: inline-block; } -.movetowallet { + +.assetname-enhanced { + + padding: 2px 0 2px 8px; + float: left; + font-size: 16px; + font-weight: bold; + display: inline-block; +} + +/* padding: 2px 0 2px 0; margin-right: -15px; float: right; display: inline-block; +*/ + + +.movetowallet { + padding: 2px 0 2px 0; + margin-right: -15px; + float: right; + display: block; font-weight: bold; text-decoration: underline; cursor: pointer; } +.archiveasset { + padding: 2px 0 2px 0; + bottom: 0px; + right: 0px; + position: absolute; + display: block; + font-size: 12px; + text-decoration: underline; + cursor: pointer; + + display: none; +} + .tokenlink { padding: 2px 0 2px 0; display: inline-block; @@ -396,16 +522,56 @@ box-shadow: 5px 5px 5px -2px rgba(0,0,0,0.75); .assetqty { + + display: inline-block; + +} + +.assetqtybox { clear: both; padding: 2px 0 2px 8px; text-align: left; + display: block; + +} + +#currentbalance { + display: inline-block; + padding-right: 10px; + padding-left: 10px; +} + +#currenttoken-pending { + font-size: 14px; + font-style: italic; + + padding-bottom: 6px; + display: inline-block; + vertical-align: middle; + + +} +.assetqty-unconfirmed { + font-style: italic; + display: inline-block; + } + .addressselect { margin-left: 10px; width: 240px; } +.addressselectnoadd { + margin-left: 10px; + width: 240px; +} + +.addressselectnoadd-buysell { + width: 240px; +} + #switchtoxcp { margin-top: 6px; display: none; @@ -429,33 +595,68 @@ box-shadow: 5px 5px 5px -2px rgba(0,0,0,0.75); #footer { width: 100%; - padding: 0 10px 5px 0; + padding: 5px 10px 5px 0; text-align: right; bottom: 0; - height: 25px; + height: 30px; color: #616161; font-weight: bold; + position: fixed; + background-color: #fff; } + +#headerblock +{ + top: 0; + padding: 5px 0 0 0; + height: 60px; + position: fixed; + background-color: #fff; + z-index: 1; +} + #refreshWallet { cursor: pointer; } + .receivedtrans { - background-color: #2D882D; - color: #fff; + color: #2D882D; + background-color: #DBFFE4; padding: 4px 6px 4px 6px; - margin: 4px 0 4px 0; - border: 3px solid #78B494; + margin: 5px 0 5px 0; + border: 2px solid #2D882D; } .senttrans { - background-color: #AA3939; - color: #fff; + color: #AA3939; + background-color: #FFF2ED; padding: 4px 6px 4px 6px; - margin: 4px 0 4px 0; - border: 3px solid #FDA8AA; + margin: 5px 0 5px 0; + border: 2px solid #AA3939; +} + +.btctrans { + color: #CF6B00; + background-color: #FFF8DB; + padding: 4px 6px 4px 6px; + margin: 5px 0 5px 0; + border: 2px solid #CF6B00; +} + + +.receivedtrans a { + color: #2D882D; +} + +.senttrans a { + color: #AA3939; +} + +.btctrans a { + color: #CF6B00; } .assetnametrans { @@ -464,6 +665,12 @@ cursor: pointer; padding-top: 1px; } +.assetnumerictrans { + font-weight: bold; + font-size: 14px; + padding: 1px 0 5px 0; +} + .addresstrans { padding-bottom: 14px; } diff --git a/Chrome Extension/manifest.json b/Chrome Extension/manifest.json index a76011e..70042fc 100644 --- a/Chrome Extension/manifest.json +++ b/Chrome Extension/manifest.json @@ -1,7 +1,7 @@ { "author": "Joe Looney", "background": { - "scripts": [ "js/jquery.min.js", "js/bitcoinjs-min.js" ] + "scripts": [ "js/content.js" ] }, "browser_action": { "default_icon": "pockets-48.png", @@ -16,14 +16,32 @@ "content_scripts": [ { "matches": ["*://*/*"], + "all_frames": true, "js": ["js/jquery.min.js", "js/tipbutton.js"] + }, + { + "matches": ["*://xcp.ninja/*"], + "js": ["js/biginteger.js", "js/issuancebutton.js"] + }, + { + "matches": ["*://chain.so/*"], + "js": ["js/biginteger.js", "js/hex2dec-cs.js", "js/detect.js", "js/bitcoinjs-min.js"] + }, + { + "matches": ["https://www.glidera.io/blank*"], + "js": ["js/content.js"] } ], "web_accessible_resources": [ "*.png", "tipsplash.html", + "issue-tx.html", + "issueticker.js", + "issue-tx-wt.html", + "issueticker-wt.js", "js/jquery.min.js", "js/bootstrap.min.js", + "js/apiserver.js", "js/aes.js", "js/biginteger.js", "js/utxo.js", @@ -40,11 +58,15 @@ "js/qrcode.min.js", "bootstrap.min.css", "tipsplash.js", - "tipticker.js" + "tipticker.js", + "js/glidera.js", + "js/glideraRegister.js", + "js/webtorrent/webtorrent.min.js", + "js/webtorrent/bvam-seed.js" ], "manifest_version": 2, "name": "Tokenly Pockets", - "permissions": [ "storage", "clipboardWrite" ], + "permissions": [ "storage", "clipboardWrite", "downloads", "activeTab", "tabs", "system.cpu" ], "short_name": "Tokenly Pockets", - "version": "0.1.0" + "version": "0.2.1" } diff --git a/Chrome Extension/pc-icon-white.png b/Chrome Extension/pc-icon-white.png new file mode 100644 index 0000000..8fd1d79 Binary files /dev/null and b/Chrome Extension/pc-icon-white.png differ diff --git a/Chrome Extension/pc-icon.png b/Chrome Extension/pc-icon.png new file mode 100644 index 0000000..426153e Binary files /dev/null and b/Chrome Extension/pc-icon.png differ diff --git a/Chrome Extension/popup.html b/Chrome Extension/popup.html index 6a0d5bf..23ee13f 100644 --- a/Chrome Extension/popup.html +++ b/Chrome Extension/popup.html @@ -3,21 +3,23 @@ -LTB Companion Wallet - +Tokenly Pockets + + + - - + + @@ -29,12 +31,22 @@ + + + + + + + + + + @@ -62,8 +74,8 @@

    Source code is available on Github at
    https://github.com/loon3/Tokenly-Pockets

    -
    - +
    +
    @@ -89,8 +101,12 @@

    Enter Passphrase:

    -
    -
    +
    +
    +
    + +
    +
    @@ -161,15 +177,44 @@
    - + + + + + +
    - +
    +
    @@ -179,7 +224,7 @@
    - Loading... +
    -
    Balance will update after one confirmation
    +
    Balance will update after one confirmation
    -
    ($
    )
    +
    ($
    )
    Switch to BTC
    - +
    @@ -234,7 +282,7 @@ --> - + +
    @@ -267,7 +316,7 @@
    -
    Send to:
    +
    Send to:
    Amount:
    @@ -281,20 +330,72 @@
    -
    -
    -
    -
    - +
    + + +
    +
    + + + +
    -
    +
    - + +
    + + + + +
    + + +
    + + + + + +
    + +
    +
    + +
    +
    +

    Buy/Sell Bitcoin (BTC)

    +
    + +
    +
    +
    + +
    +
    +
    +
    Glidera
    +
    Buy/Sell BTC with a U.S. bank account
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    Shapeshift
    +
    Buy BTC with altcoins and tokens
    +
    +
    + + +
    +
    -
    -
    - -
    -
    Shapeshift provides instant conversion of altcoins to Bitcoin (BTC)
    - - - -
    Select wallet address to receive BTC:
    - -
    - -
    -
    -
    After clicking Shapeshift, the LTB Companion Wallet will close and a new window will open where you can select the altcoin you would like to convert.
    - -
    +
    Select Address to Sign Message
    - +
    -
    +
    @@ -439,7 +711,7 @@
    -
    +
    Wallet Settings
    Reveal Passphrase + Addresses and Labels + + - Reset Addresses and Labels + + + + +
    WARNING: Be sure to write down your 12 word passphrase before selecting Reset Passphrase
    Reset Passphrase @@ -488,6 +787,219 @@
    + + + +
    + + +
    +
    + + + + + + +
    + +
    @@ -500,8 +1012,7 @@

    Tokenly Pockets

    Donation Address:
    - - 1LrM4bojLAKfuoFMXkDtVPMGydX1rkaMqH + 1LrM4bojLAKfuoFMXkDtVPMGydX1rkaMqH

    @@ -512,13 +1023,8 @@

    Tokenly Pockets

    -
    - -
    ...
    -
    BTC/USD
    - -
    +
    diff --git a/Chrome Extension/popup.js b/Chrome Extension/popup.js index f32d9d0..f5c12b3 100644 --- a/Chrome Extension/popup.js +++ b/Chrome Extension/popup.js @@ -1,33 +1,96 @@ +function getNetwork() { + return bitcore.Networks.livenet; + //return bitcore.Networks.testnet; +} + +function infoalertstart() { + + chrome.storage.local.get(["infoalert"], function (alertstatus) + { + if (alertstatus.infoalert == "disabled" || alertstatus.infoalert == "never") { + + $( "#infoalert" ).hide(); + + } else { + + $( "#infoalert" ).show(); + + } + + }); + +} + function getExchangeRatesList() { + + chrome.storage.local.get(function(data) { var btcperusd = parseFloat(data.btcperusd); - console.log(data); + //console.log(data); + + $("#ExchangeRate").html(""); - $.each(data.assetrates, function(i, item) { - - var assetname = data.assetrates[i]["assetname"]; + var ratedisplay = ""; + + ratedisplay += ""; + + // + + $.each(data.assetrates, function(i, item) { + + var assetname = data.assetrates[i]["assetname"]; + + var assetprice = parseFloat(data.assetrates[i]["assetprice"]); + + if (assetprice <= 1) { + var assetpricedisplay = assetprice.toFixed(6); + } else { + var assetpricedisplay = assetprice.toFixed(2); + } + + var assetbtcprice = (btcperusd * assetprice).toFixed(8); + + var iconname = assetname.toLowerCase(); - var assetprice = parseFloat(data.assetrates[i]["assetprice"]); - - if (assetprice <= 1) { - var assetpricedisplay = assetprice.toFixed(6); - } else { - var assetpricedisplay = assetprice.toFixed(2); - } - - var assetbtcprice = (btcperusd * assetprice).toFixed(8); + ratedisplay += ""; + + // + + + //var ratedisplay = "
    "+assetname+"
    Market Rate per Token
    $"+assetpricedisplay+"
    "+assetbtcprice+" BTC
    "; + + + + }); + + ratedisplay += "
    SymbolTokenMarket Price per Token
    BTC1 BTC
    $"+parseFloat(1/btcperusd).toFixed(2)+"
    Price USD
    "+assetname+""+assetbtcprice+" BTC
    $"+assetpricedisplay+"
    $"+assetpricedisplay+"
    Market Data provided by Coincap.io
    "; + + chrome.storage.local.get(function(data) { + + if(typeof(data["assetrates_updated"]) !== 'undefined') { + //already set + + var ratesupdated = "Last Updated " + data["assetrates_updated"]; - var iconname = assetname.toLowerCase(); + } else { - var ratedisplay = "
    "+assetname+"
    Market Rate per Token
    $"+assetpricedisplay+"
    "+assetbtcprice+" BTC
    "; - $("#ExchangeRate").append(ratedisplay); + var ratesupdated = "API ERROR"; - }); + } + + ratedisplay += "" + ratesupdated + "
    "; + + $("#ExchangeRate").html(ratedisplay); + + }); + + + }); } @@ -35,7 +98,7 @@ function getExchangeRatesList() { function getNews(){ var source_html = "https://letstalkbitcoin.com/api/v1/blog/posts?limit=5"; - $("#newsStories").html("
    Loading...
    "); + $("#newsStories").html("
    "); $.getJSON( source_html, function( data ) { @@ -66,7 +129,7 @@ function searchLTBuser(username){ var source_html = "https://letstalkbitcoin.com/api/v1/users?search="+username; - $("#ltbDirectorySearchResults").html("
    Loading...
    "); + $("#ltbDirectorySearchResults").html("
    "); $.getJSON( source_html, function( data ) { @@ -93,7 +156,7 @@ function searchLTBuser(username){ $("#ltbDirectorySearchResults").append("
    LTBCOIN Address:
    No Address Listed
    "); } else { var ltbaddress = data.users[i]["profile"]["ltbcoin-address"]["value"]; - $("#ltbDirectorySearchResults").append("
    LTBCOIN Address:
    "+ltbaddress+"
    "); + $("#ltbDirectorySearchResults").append("
    LTBCOIN Address:
    "+ltbaddress+"
    "); } @@ -126,7 +189,7 @@ function setPinBackground() { var bg_link = "url('/pin_bg/"+randomBackground+".jpg')"; $("#pinsplash").css("background-image", bg_link); - $("#pinsplash").css("background-size", "330px 350px"); + $("#pinsplash").css("background-size", "350px 380px"); } @@ -145,6 +208,8 @@ function getStorage() if ( data.encrypted == false) { existingPassphrase(data.passphrase); + + infoalertstart(); } else if ( data.encrypted == true) { @@ -200,21 +265,47 @@ function copyToClipboard(text){ function showBTCtransactions(transactions) { //$("#btcbalance").html("
    You can perform "+transactions.toFixed(0)+" transactions
    Deposit bitcoin for transaction fees
    "); - - if (transactions == 0) { + chrome.storage.local.get(function (data) { - $("#btcbalance").html("
    Deposit bitcoin to send tokens from this address.
    "); - - } else { - $("#btcbalance").html("
    You can perform "+transactions.toFixed(0)+" transactions
    "); - - } + if (transactions == 0) { + + $("#btcbalance").html("
    Deposit bitcoin to send tokens from this address.
    "); + + } else { + + + + //var ratenum = (0.00015470 * (1/data["btcperusd"])); + //var txrate = " at $" + ratenum.toFixed(2) + " / tx"; + + $("#btcbalance").html("
    You can perform "+transactions.toFixed(0)+" transactions"); + + + + + + + } + + + + var infoalertstatus = data.infoalert; - //var titletext = data + " satoshis"; + if (typeof infoalertstatus !== 'undefined') { + if (transactions < 6 && data.infoalert != "never") { + $( "#infoalert" ).show(); - //$("#btcbalbox").prop('title', titletext); - $("#btcbalbox").show(); + } else { + $( "#infoalert" ).hide(); + } + } + //var titletext = data + " satoshis"; + + //$("#btcbalbox").prop('title', titletext); + $("#btcbalbox").show(); + + }); } function qrdepositDropdown() { @@ -313,11 +404,13 @@ if (currenttoken == "XCP") { $("#isdivisible").html("yes"); - $("#xcpbalance").html("" + assetbalance + "
    " + currenttoken + ""); + $("#xcpbalance").html("
    " + assetbalance + "

    " + currenttoken + "
    "); $('#assetbalhide').html(assetbalance); getRate(assetbalance, pubkey, currenttoken); + currenttokenpending(currenttoken); + }); } else { @@ -346,23 +439,53 @@ if (currenttoken == "XCP") { assetbalance = parseFloat(assetbalance).toString(); - + if(assetname.substr(0,1) == "A") { + + var enhancedassetname = $("#xcpbalance").data("enhanced"); + //var assetbalance = parseFloat(data.data[0].balance) + parseFloat(data.data[0].unconfirmed_balance); - $("#xcpbalance").html("" + assetbalance + "
    " + currenttoken + ""); + $("#xcpbalance").html("
    " + assetbalance + "

    "+enhancedassetname+"
    "+currenttoken+"
    "); + + } else { + + $("#xcpbalance").html("
    " + assetbalance + "

    " + currenttoken + "
    "); + + } $('#assetbalhide').html(assetbalance); + + + getRate(assetbalance, pubkey, currenttoken); + + currenttokenpending(currenttoken); } }); - + + + }); } if (typeof assetbalance === 'undefined') { - $("#xcpbalance").html("0
    " + currenttoken + "
    "); + + if(currenttoken.substr(0,1) == "A") { + + var enhancedassetname = $("#xcpbalance").data("enhanced"); + + $("#xcpbalance").html("
    0

    "+enhancedassetname+"
    "+currenttoken+"
    "); + + } else { + + + $("#xcpbalance").html("
    0

    " + currenttoken + "
    "); + + } $('#assetbalhide').html(0); getRate(0, pubkey, currenttoken); + + currenttokenpending(currenttoken); } } @@ -398,7 +521,11 @@ function getPrimaryBalanceBTC(pubkey){ function getPrimaryBalance(pubkey){ - $("#btcsendbox").hide(); + var addressbox = $("#sendtoaddress").val(); + + if (addressbox.length == 0) { + $("#btcsendbox").hide(); + } var currenttoken = $(".currenttoken").html(); @@ -417,43 +544,26 @@ function getPrimaryBalance(pubkey){ function getRate(assetbalance, pubkey, currenttoken){ - if ($("#ltbPrice").html() == "...") { + if ($("#ltbPriceFlipped").html() == "...") { + - - $.getJSON( "http://www.coincap.io/front/xcp", function( data ) { - - var assetrates = new Array(); - - $.each(data, function(i, item) { - var assetname = data[i].short; - var assetprice = data[i].price; - - if (assetname == "LTBC"){ - assetname = "LTBCOIN"; - } - - assetrates[i] = {assetname, assetprice}; - }); - - chrome.storage.local.set( - { - 'assetrates': assetrates, - - }, function () { - - //$.getJSON( "http://joelooney.org/ltbcoin/ltb.php", function( data ) { - $.getJSON( "https://api.bitcoinaverage.com/ticker/USD/", function( data ) { - - // var ltbprice = 1 / parseFloat(data.usd_ltb); - // $("#ltbPrice").html(Number(ltbprice.toFixed(0)).toLocaleString('en')); - - // $("#ltbPrice").data("ltbcoin", { price: ltbprice.toFixed(0) }); - + //$.getJSON( "https://api.bitcoinaverage.com/ticker/USD/", function( data ) { + + $.getJSON( "http://btc.blockr.io/api/v1/exchangerate/current", function( data ) { - var btcprice = 1 / parseFloat(data.last); + + //var btcprice = 1 / parseFloat(data.last); + + var btcprice = parseFloat(data.data[0]["rates"]["BTC"]); $("#ltbPrice").html(Number(btcprice.toFixed(4).toLocaleString('en'))); + + //var btcpriceflipped = data.last; + + var btcpriceflipped = 1 / parseFloat(data.data[0]["rates"]["BTC"]); + + $("#ltbPriceFlipped").html("$"+parseFloat(Math.round(btcpriceflipped * 100) / 100).toFixed(2)); $("#ltbPrice").data("btc", { price: btcprice.toFixed(6) }); @@ -461,7 +571,9 @@ function getRate(assetbalance, pubkey, currenttoken){ if (currenttoken == "BTC") { - var usdValue = parseFloat(data.last) * parseFloat(assetbalance); + //var usdValue = parseFloat(data.last) * parseFloat(assetbalance); + + var usdValue = parseFloat(btcpriceflipped) * parseFloat(assetbalance); $("#xcpfiatValue").html(usdValue.toFixed(2)); $("#switchtoxcp").hide(); @@ -475,12 +587,75 @@ function getRate(assetbalance, pubkey, currenttoken){ { 'btcperusd': btcprice - }); + }, function () { + + + + }); + + + $.getJSON( "http://www.coincap.io/front/", function( data ) { + + var j = 0; + + var assetrates = new Array(); + + $.each(data, function(i, item) { + var assetname = data[i].short; + var assetprice = data[i].price; - }); + if (assetname == "LTBC"){ + assetname = "LTBCOIN"; + + assetrates[j] = {assetname, assetprice}; + j++; + } - }); - }); + if (assetname == "XCP"){ + + assetrates[j] = {assetname, assetprice}; + j++; + } + + + }); + + + + $.getJSON( "http://www.coincap.io/front/xcp", function( data ) { + + + + $.each(data, function(i, item) { + var assetname = data[i].short; + var assetprice = data[i].price; + + if (assetname != "LTBC" && assetname != "XCP"){ + + assetrates[i+j] = {assetname, assetprice}; + + } + + + }); + + var currentdate = new Date(); + var datetime = (currentdate.getMonth()+1) + "/" + currentdate.getDate() + "/" + currentdate.getFullYear() + " at " + currentdate.getHours() + ":" + padprefix(currentdate.getMinutes(), 2); + + + + + chrome.storage.local.set( + { + 'assetrates': assetrates, + 'assetrates_updated': datetime + + }); + + }); + + }); + }); } else { @@ -498,8 +673,7 @@ function getRate(assetbalance, pubkey, currenttoken){ $("#switchtoxcp").show(); } - - + } getBTCBalance(pubkey); @@ -533,22 +707,22 @@ function assetDropdown(m) for (var i = 0; i < totaladdress; i++) { - var derived = HDPrivateKey.derive("m/0'/0/" + i); - var address1 = new bitcore.Address(derived.publicKey, bitcore.Networks.livenet); - - var pubkey = address1.toString(); - - $(".addressselect").append(""); - - if (i == 0) { - $(".addressselect").attr("title",pubkey); - } - //.slice(0,12) + var derived = HDPrivateKey.derive("m/0'/0/" + i); + var address1 = new bitcore.Address(derived.publicKey, bitcore.Networks.livenet); - //$(".addressselect").append(""); - } + var pubkey = address1.toString(); + + $(".addressselect").append(""); + + if (i == 0) { + $(".addressselect").attr("title",pubkey); + } + //.slice(0,12) + + //$(".addressselect").append(""); + } - $(".addressselect").append(""); + $(".addressselect").append(""); }); @@ -594,6 +768,7 @@ function dynamicAddressDropdown(addresslabels, type) if (type == "newaddress") { getBTCBalance(pubkey); var newaddress_position = parseInt(currentsize) - 1; + var newaddress_select = "#walletaddresses option:eq("+newaddress_position+")"; var newaddress_val = $(newaddress_select).val(); $("#xcpaddress").html(newaddress_val); getPrimaryBalance(newaddress_val); @@ -651,9 +826,9 @@ function existingPassphrase(string) { $("#newpassphrase").html(string); - - convertPassphrase(m2); - assetDropdown(m2); + convertPassphrase(m2); + checkImportedLabels(m2, assetDropdown); + $('#allTabs a:first').tab('show') } @@ -704,14 +879,13 @@ function loadAssets(add) { //var source_html = "http://xcp.blockscan.com/api2?module=address&action=balance&btc_address="+add; - var source_html = "https://counterpartychain.io/api/balances/"+add; + var source_html = "https://counterpartychain.io/api/balances/"+add+"?description=1"; var xcp_source_html = "http://counterpartychain.io/api/address/"+add; - var btc_source_html = "https://insight.bitpay.com/api/addr/"+add+"/balance"; - - $( "#alltransactions" ).html(""); + var btc_source_html = "https://"+INSIGHT_SERVER+"/api/addr/"+add+"/balance"; + $( "#allassets" ).html("
    "); $.getJSON( xcp_source_html, function( data ) { //var assetbalance = parseFloat(data.data[0].balance) + parseFloat(data.data[0].unconfirmed_balance); @@ -724,9 +898,9 @@ function loadAssets(add) { $.getJSON( source_html, function( data ) { - $( "#allassets" ).html("
    BTC
    Send
    "); - + $( "#allassets" ).html("
    BTC
    Send
    "); + //EDB047 var isbtcloading = $("#isbtcloading").html(); if (isbtcloading == "true") { @@ -757,102 +931,304 @@ function loadAssets(add) { if (xcpbalance != 0) { - $( "#allassets" ).append("
    XCP
    Send
    "+xcpbalance+"
    "); - + $( "#allassets" ).append("
    XCP
    Send
    "+xcpbalance+"
    "); + //CF5151 } - - $.each(data.data, function(i, item) { - var assetname = data.data[i].asset; - var assetbalance = data.data[i].amount; //.balance for blockscan - if (assetbalance.indexOf(".")==-1) {var divisible = "no";} else {var divisible = "yes";} - - var iconname = assetname.toLowerCase(); - var iconlink = "http://counterpartychain.io/content/images/icons/"+iconname+".png"; + var totalassets = data.data; + var countnumeric = 0; - if (assetname.charAt(0) != "A") { - var assethtml = "
    "+assetname+"
    Send
    "+assetbalance+"
    "; - -// - - -// if(assetname == "LTBCOIN") { -// var assethtml = "
    "+assetname+"
    Send
    Balance: "+assetbalance+"
    "; -// } - - - } - - $( "#allassets" ).append( assethtml ); - - }); + var bvamwtarray = new Array(); + var addressbvam = new Array(); - $( "#allassets" ).append("
    "); - - loadTransactions(add); - - }); - - }); -} + if(data.success != 0) { + + for (var i = 0; i < totalassets.length; i++) { -/*function updateBTC(pubkey){ + var assetdescription = data.data[i].description; + var assetname = data.data[i].asset; + var assetbalance = data.data[i].amount; - var source_html = "https://blockchain.info/q/addressbalance/"+pubkey; - - $.getJSON( source_html, function( data ) { - $("#xcpbalance").html(data); - }); -};*/ + if (assetdescription.substr(0,6) == "TOKNID" && assetname.substring(0, 4) == "A111") { + countnumeric++; + var bvamhash = assetdescription.substr(7); + addressbvam = addressbvam.concat({asset: assetname, amount: assetbalance, hash: bvamhash, data: ""}); + } + if (assetdescription.substr(0,6) == "BVAMWT" && assetname.substring(0, 4) == "A111") { + var bvamhash = assetdescription.substr(7); + var assetname = data.data[i].asset; + var assetbalance = data.data[i].amount; + bvamwtarray = bvamwtarray.concat({hash: bvamhash, asset: assetname, amount: assetbalance, data: ""}) - function makedSignedMessage(msg, addr, sig) - { - var qtHdr = [ - "
    -----BEGIN BITCOIN SIGNED MESSAGE-----",
    -      			"-----BEGIN BITCOIN SIGNATURE-----",
    -      			"-----END BITCOIN SIGNATURE-----
    " - ]; - - return qtHdr[0]+'\n'+msg +'\n'+qtHdr[1]+'\nVersion: Bitcoin-qt (1.0)\nAddress: '+addr+'\n\n'+sig+'\n'+qtHdr[2]; - } - - function getprivkey(inputaddr, inputpassphrase){ - //var inputaddr = $('#inputaddress').val(); - - //var string = inputpassphrase.val().trim().toLowerCase(); - //string = string.replace(/\s{2,}/g, ' '); - var array = inputpassphrase.split(" "); - - m2 = new Mnemonic(array); - - var HDPrivateKey = bitcore.HDPrivateKey.fromSeed(m2.toHex(), bitcore.Networks.livenet); - - - for (var i = 0; i < 50; i++) { - - var derived = HDPrivateKey.derive("m/0'/0/" + i); - var address1 = new bitcore.Address(derived.publicKey, bitcore.Networks.livenet); - - var pubkey = address1.toString(); - - if (inputaddr == pubkey) { - var privkey = derived.privateKey.toWIF(); - break; - - } - } - - return privkey; - } - - - - function signwith(privkey, pubkey, message) { - - - + } + + } + + console.log("Total BVAM: "+countnumeric); + + checkBvam(addressbvam, countnumeric, function(matchingdata, missing){ + + console.log(matchingdata); + + console.log("missing: "+missing); + + + + var allbvamdata = new Array(); + + $.each(data.data, function(i, item) { + var assetname = data.data[i].asset; + var assetbalance = data.data[i].amount; //.balance for blockscan + var assetdescription = data.data[i].description; + if (assetbalance.indexOf(".")==-1) {var divisible = "no";} else {var divisible = "yes";} + + var iconname = assetname.toLowerCase(); + var iconlink = "http://counterpartychain.io/content/images/icons/"+iconname+".png"; + + if (assetname.charAt(0) != "A") { + var assethtml = "
    Archive
    "+assetname+"
    Send
    "+assetbalance+"
    "; + //3082B0 + $( "#allassets" ).append( assethtml ); + + } + + }); + + $.each(matchingdata, function(i, item) { + + var hash = matchingdata[i]["hash"]; + var assetname = matchingdata[i]["asset"]; + var assetbalance = matchingdata[i]["amount"]; + var iconlink = "http://counterpartychain.io/content/images/icons/xcp.png"; + if (assetbalance.indexOf(".")==-1) {var divisible = "no";} else {var divisible = "yes";} + + + if(matchingdata[i]["data"] != "") { + //local bvam + var isvaliddata = validateEnhancedAssetJSON(matchingdata[i]["data"]); + + console.log("Calculated Local JSON Hash: "+isvaliddata); + console.log("Stored Local JSON Hash: "+hash); + + if(isvaliddata != hash) { + + var jsondata = new Array(); + var jsondata = {ownername: matchingdata[i]["data"]["ownername"], ownertwitter: matchingdata[i]["data"]["ownertwitter"], owneraddress: matchingdata[i]["data"]["owneraddress"], asset: matchingdata[i]["data"]["asset"], assetname: matchingdata[i]["data"]["assetname"], assetdescription: matchingdata[i]["data"]["assetdescription"], assetwebsite: matchingdata[i]["data"]["assetwebsite"]}; + + var isvaliddata = validateEnhancedAssetJSON(jsondata); + + console.log("Re-ordered Calculated Local JSON Hash: "+isvaliddata); + console.log("Stored Local JSON Hash: "+hash); + + } + + + if(isvaliddata == hash && matchingdata[i]["data"]["asset"] == assetname) { + + var enhancedname = matchingdata[i]["data"]["assetname"]; + + var assethtml = "
    Archive
    "+enhancedname+"
    Send
    "+assetname+"
    "+assetbalance+"
    "; + + $( "#allassets" ).append( assethtml ); + + } + + } else { + //get bvam + + $.getJSON("http://xcp.ninja/hash/"+hash+".json", function(data) { + + var isvaliddata = validateEnhancedAssetJSON(data); + + console.log("Calculated Remote JSON Hash: "+isvaliddata); + console.log("Stored Remote JSON Hash: "+hash); + + if(isvaliddata == hash && data.asset == assetname) { + + var assethtml = "
    Archive
    "+data.assetname+"
    Send
    "+assetname+"
    "+assetbalance+"
    "; + + var time_date = new Date(); + var time_unix = time_date.getTime(); + + allbvamdata = allbvamdata.concat({hash: hash, type: "TOKNID", data: data, added: time_unix}); + + if(missing == 1) { + addBvam(allbvamdata); + console.log(allbvamdata); + } else { + missing--; + } + + + $( "#allassets" ).append( assethtml ); + + } + }).fail(function(){ + + if(missing == 1) { + + + addBvam(allbvamdata); + console.log(allbvamdata); + } else { + missing--; + } + + }); + + } + + }); + + }); + + + + + getBvamWT(bvamwtarray, function(status) { + + console.log(status); + + }); + + + + var xcp_mempool_html = "https://counterpartychain.io/api/mempool"; + + $.getJSON( xcp_mempool_html, function( data ) { + + if (data.success == 1 && data.total > 0) { + + var currentaddr = $("#xcpaddress").html(); + + $.each(data.data, function(i, item) { + + if (currentaddr == data.data[i].source || currentaddr == data.data[i].destination) { + + if (currentaddr == data.data[i].source) {var debitorcredit = "-";}; + if (currentaddr == data.data[i].destination) {var debitorcredit = "+";}; + + var assetqty = debitorcredit + (data.data[i].quantity * 1); + var assetname = data.data[i].asset; + var assetnameclass = "."+assetname+"-pending"; + + if($(assetnameclass).html() != '') { + + var currentunconf = $(assetnameclass).html(); + + var result = currentunconf.substring(1, currentunconf.length-1); + + console.log(result); + + var combinetxs = parseFloat(result) + parseFloat(assetqty); + + console.log(combinetxs); + + if (combinetxs > 0) { + + var unconftxs = "+" + combinetxs; + + + + } else { + + var unconftxs = combinetxs; + + } + + $(assetnameclass).html("("+unconftxs+")") + + } else { + + $(assetnameclass).html("("+assetqty+")"); + + } + + + var currentunconf = $(assetnameclass).html(); + + var result = parseFloat(currentunconf.substring(1, currentunconf.length-1)); + + if( result > 0 ) { + + $( ".assetqty-unconfirmed" ).css( "color", "#9CFFA7" ); + + } else { + + $( ".assetqty-unconfirmed" ).css( "color", "#FA9B9B" ); + + } + + } + + }); + + } + + }); + + //loadTransactions(add); + + } + + }); + + }); +} + + + + + + function makedSignedMessage(msg, addr, sig) + { + var qtHdr = [ + "
    -----BEGIN BITCOIN SIGNED MESSAGE-----",
    +      			"-----BEGIN BITCOIN SIGNATURE-----",
    +      			"-----END BITCOIN SIGNATURE-----
    " + ]; + + return qtHdr[0]+'\n'+msg +'\n'+qtHdr[1]+'\nVersion: Bitcoin-qt (1.0)\nAddress: '+addr+'\n\n'+sig+'\n'+qtHdr[2]; + } + + function getprivkey(inputaddr, inputpassphrase){ + //var inputaddr = $('#inputaddress').val(); + + //var string = inputpassphrase.val().trim().toLowerCase(); + //string = string.replace(/\s{2,}/g, ' '); + var array = inputpassphrase.split(" "); + + m2 = new Mnemonic(array); + + var HDPrivateKey = bitcore.HDPrivateKey.fromSeed(m2.toHex(), bitcore.Networks.livenet); + + + for (var i = 0; i < 50; i++) { + + var derived = HDPrivateKey.derive("m/0'/0/" + i); + var address1 = new bitcore.Address(derived.publicKey, bitcore.Networks.livenet); + + var pubkey = address1.toString(); + + if (inputaddr == pubkey) { + var privkey = derived.privateKey.toWIF(); + break; + + } + } + + return privkey; + } + + + + function signwith(privkey, pubkey, message) { + + + //var message = "Message, message"; var p = updateAddr(privkey, pubkey); @@ -891,64 +1267,201 @@ function timeConverter(UNIX_timestamp){ } - -function loadTransactions(add) { - - //{"address":"1CWpnJVCQ2hHtehW9jhVjT2Ccj9eo5dc2E","asset":"LTBCOIN","block":348621,"quantity":"-50000.00000000","status":"valid","time":1426978699,"tx_hash":"dc34bbbf3fa02619b2e086a3cde14f096b53dc91f49f43b697aaee3fdec22e86"} - - var source_html = "https://counterpartychain.io/api/transactions/"+add; +function loadTransactionsBTC(add, callback) { + + var source_html = "http://btc.blockr.io/api/v1/address/txs/"+add; $.getJSON( source_html, function( data ) { + var btctxs = new Array(); - $.each(data.data, function(i, item) { +// for (var i = 0; i < 100; i++) { + $.each(data.data.txs, function(i, item) { - var assetname = data.data[i].asset; + var tx = data.data.txs[i]["tx"]; + var time_utc = data.data.txs[i]["time_utc"]; + var confirmations = data.data.txs[i]["confirmations"]; + var amount = data.data.txs[i]["amount"]; - if (assetname.charAt(0) != "A") { + if (amount > 0) { + amount = "+"+amount; + } - var address = data.data[i].address; + var time_date = new Date(time_utc); + var time_unix = time_date.getTime(); - var quantity = data.data[i].quantity; - var time = data.data[i].time; + time_unix = parseFloat(time_unix) / 1000; - var translink = "https://counterpartychain.io/transaction/"+data.data[i].tx_hash; - var addlink = "https://counterpartychain.io/address/"+address; + btctxs.push({assetname: "BTC", address: "", tx: tx, time_utc: time_unix, amount: amount}); - if (parseFloat(quantity) < 0) { - var background = "senttrans"; - var transtype = "Sent to "; - } else { - var background = "receivedtrans"; - var transtype = "Received from "; - } - - - var assethtml = "
    "+assetname+"
    Amount:
    "+quantity+"
    "; - + }); +// } +// console.log(btctxs); + + callback(add, btctxs); + + }); + +} + +function loadTransactions(add, btctxs) { - $( "#alltransactions" ).append( assethtml ); + $( "#alltransactions" ).html("
    "); + + loadBvam(function(bvamdata, hashname, hashhash){ + + loadTransactionsBTC(add, function(add, btctxs) { //{"address":"1CWpnJVCQ2hHtehW9jhVjT2Ccj9eo5dc2E","asset":"LTBCOIN","block":348621,"quantity":"-50000.00000000","status":"valid","time":1426978699,"tx_hash":"dc34bbbf3fa02619b2e086a3cde14f096b53dc91f49f43b697aaee3fdec22e86"} + + var source_html = "https://counterpartychain.io/api/transactions/"+add; + + $.getJSON( source_html, function( data ) { + + var alltxs = new Array(); + + var xcptxs = new Array(); - } + console.log(data); + + if(data.success != 0) { + + $.each(data.data, function(i, item) { + + var assetname = data.data[i].asset; + var address = data.data[i].address; + var quantity = data.data[i].quantity; + var time = data.data[i].time; + var tx = data.data[i].tx_hash; + + xcptxs.push({assetname: assetname, address: address, tx: tx, time_utc: time, amount: quantity}); + + }); + + var alltxs = xcptxs.concat(btctxs); + + } else { + + var alltxs = btctxs; + + } + + console.log(alltxs); + + alltxs.sort(function(a, b) { + return b.time_utc - a.time_utc; + }); + + var j; + + for (var i = 0; i < alltxs.length; i++) { + + // j = i - 1; + + for (var j = 0; j < alltxs.length; j++) { + + if (i != j) { + + if (alltxs[i]["tx"] == alltxs[j]["tx"]) { + + if(alltxs[i].assetname == "BTC") { + alltxs.splice(i, 1); + } else if(alltxs[j].assetname == "BTC") { + alltxs.splice(j, 1); + } + + } + + } + + } + + } + +// console.log(alltxs); + + $( "#alltransactions" ).html( "" ); + + for (var i = 0; i < 100; i++) { + //$.each(alltxs, function(i, item) { + + if (alltxs[i] !== undefined) { + + var assetname = alltxs[i]["assetname"]; + + //if (assetname.charAt(0) != "A") { + + var address = alltxs[i].address; + + var quantity = alltxs[i].amount; + var time = alltxs[i].time_utc; + + var translink = "https://counterpartychain.io/transaction/"+alltxs[i].tx; + var addlink = "https://counterpartychain.io/address/"+address; + + if (parseFloat(quantity) < 0) { + var background = "senttrans"; + var transtype = "Sent to "; + } else { + var background = "receivedtrans"; + var transtype = "Received from "; + } + + if (assetname != "BTC") { + + if (assetname.charAt(0) == "A") { + + if (typeof(hashname[assetname]) !== 'undefined') { + + var assetname_localbvam = hashname[assetname]; + + var assethtml = "
    "+assetname_localbvam+"
    "+assetname+"
    Amount:
    "+quantity+"
    "; + + } else { + + var assethtml = "
    "+assetname+"
    Amount:
    "+quantity+"
    "; + + } + + + } else { + var assethtml = "
    "+assetname+"
    Amount:
    "+quantity+"
    "; + } + + } else { + + translink = "https://chain.so/tx/BTC/"+alltxs[i].tx; + + var assethtml = "
    "+assetname+"
    Amount:
    "+quantity+"
    "; + } + + + $( "#alltransactions" ).append( assethtml ); + + //} + } + //}); + } + + // $( "#alltransactions" ).append("
    "); + + }); }); - $( "#alltransactions" ).append("
    "); - }); - - } function sendtokenaction() { - $("#sendtokenbutton").html("Sending..."); + $("#sendtokenbutton").html("Sending... "); $("#sendtokenbutton").prop('disabled', true); - var assetbalance = $("#xcpbalance").html(); - var array = assetbalance.split(" "); - var currentbalance = parseFloat(array[0]); +// var assetbalance = $("#xcpbalance").html(); +// var array = assetbalance.split(" "); +// var currentbalance = parseFloat(array[0]); + + var assetbalance = $("#assetbalhide").html(); + var currentbalance = parseFloat(assetbalance); var pubkey = $("#xcpaddress").html(); var currenttoken = $(".currenttoken").html(); @@ -966,12 +1479,26 @@ function sendtokenaction() { console.log(sendtoamount); var minersfee = 0.0001; + + if (currenttoken == "BTC") { - var totalsend = parseFloat(sendtoamount) + minersfee; - - if (bitcore.Address.isValid(sendtoaddress)){ + var totalsend = sendtoamount + minersfee; + var btcbalance = $("#btcbalhide").html(); + currentbalance = parseFloat(btcbalance); - if (isNaN(sendtoamount) == true || sendtoamount <= 0 || $.isNumeric( sendtoamount ) == false) { +// console.log("totalsend: "+totalsend); +// console.log("sendtoamount: "+sendtoamount); +// console.log("currentbalance: "+currentbalance); + + } else { + + var totalsend = parseFloat(sendtoamount); + + } + + if (bitcore.Address.isValid(sendtoaddress)){ + + if (isNaN(sendtoamount) == true || sendtoamount <= 0 || $.isNumeric( sendtoamount ) == false) { $("#sendtoamount").val("Invalid Amount"); $("#sendtokenbutton").html("Refresh to continue"); @@ -997,13 +1524,16 @@ function sendtokenaction() { var msig_total = 0.000078; //total btc to multisig output (returned to sender) var mnemonic = $("#newpassphrase").html(); - $("#sendtokenbutton").html("Sending..."); + //$("#sendtokenbutton").html("Sending..."); - //sendXCP(pubkey, sendtoaddress, currenttoken, sendtoamount, btc_total, msig_total, minersfee, mnemonic); sendXCP_opreturn(pubkey, sendtoaddress, currenttoken, sendtoamount, btc_total, minersfee, mnemonic); + + //setUnconfirmed(pubkey, currenttoken, sendtoamount); + //sendXCP(pubkey, sendtoaddress, currenttoken, sendtoamount, btc_total, msig_total, minersfee, mnemonic); + } @@ -1059,6 +1589,7 @@ function resetFive() { var array = string.split(" "); m = new Mnemonic(array); + convertPassphrase(m); assetDropdown(m); $('#allTabs a:first').tab('show'); @@ -1066,8 +1597,123 @@ function resetFive() { } +function setBvamwtOff() { + + chrome.storage.local.get(function(data) { + + if(typeof(data["bvamwt_enabled"]) !== 'undefined') { + //already set + + var enabled = data["bvamwt_enabled"]; + + if (enabled == "no") { + + $('#bvamwttoggle').html("Enable Asset Metadata via Webtorrent"); + + } else { + + $('#bvamwttoggle').html("Disable Asset Metadata via Webtorrent"); + + } + + } else { + + var enabled = "no"; + + chrome.storage.local.set( + { + 'bvamwt_enabled': enabled + }, function () { + + $('#bvamwttoggle').html("Enable Asset Metadata via Webtorrent"); + + }); + + } + + + }) + +} + +function checkBvamwtEnabled(callback) { + + chrome.storage.local.get(function(data) { + + var enabled = data["bvamwt_enabled"]; + + if (enabled == "yes") { + + callback(); + + } + + }) + +} + +function setChainsoOn() { + + chrome.storage.local.get(function(data) { + + if(typeof(data["chainso_detect"]) !== 'undefined') { + //already set + + var detect = data["chainso_detect"]; + + if (detect == "no") { + + var detect = "no"; + + chrome.storage.local.set( + { + 'chainso_detect': detect + }, function () { + + $('#turnoffchainso').html("Enable Chain.so Token Detection"); + + }); + + + } else { + + var detect = "yes"; + + chrome.storage.local.set( + { + 'chainso_detect': detect + }, function () { + + $('#turnoffchainso').html("Disable Chain.so Token Detection"); + + }); + + } + + } else { + + var detect = "yes"; + + chrome.storage.local.set( + { + 'chainso_detect': detect + }, function () { + + $('#turnoffchainso').html("Disable Chain.so Token Detection"); + + }); + + } + + + }) + +} + function setInitialAddressCount() { + setChainsoOn(); + chrome.storage.local.get(function(data) { if(typeof(data["totaladdress"]) !== 'undefined') { @@ -1158,6 +1804,69 @@ function insertAddressLabel(newlabel, callback) { } +function currenttokenpending(token) { + + var xcp_mempool_html = "https://counterpartychain.io/api/mempool"; + + $.getJSON( xcp_mempool_html, function( data ) { + + if (data.success == 1 && data.total > 0) { + + var currentaddr = $("#xcpaddress").html(); + + var totalunconfirmed = 0; + + $.each(data.data, function(i, item) { + + if (currentaddr == data.data[i].source || currentaddr == data.data[i].destination) { + + var assetname = data.data[i].asset; + + if (token == assetname) { + + if (currentaddr == data.data[i].source) { + totalunconfirmed -= parseFloat(data.data[i].quantity); + }; + + if (currentaddr == data.data[i].destination) { + totalunconfirmed += parseFloat(data.data[i].quantity); + }; + + if(totalunconfirmed > 0) { + + $( "#currenttoken-pending" ).css( "color", "#679967" ); + + } else { + + $( "#currenttoken-pending" ).css( "color", "#FA7A7A" ); + + } + + + } + + } + + }); + + var totalqty = totalunconfirmed * 1; + + if (totalunconfirmed > 0) { + + $("#currenttoken-pending").html("(+"+totalqty+")"); + + } else if (totalunconfirmed < 0) { + + $("#currenttoken-pending").html("("+totalqty+")"); + + } + + } + + }); + +} + //function setUnconfirmed(sendaddress, sendasset, sendamount) { // @@ -1186,8 +1895,702 @@ function insertAddressLabel(newlabel, callback) { // //} +function loadAddresslist() { + + var string = $("#newpassphrase").html(); + var array = string.split(" "); + m = new Mnemonic(array); + + var currentsize = $('#walletaddresses option').size(); + + + currentsize = currentsize - 1; + var addressindex = $("#walletaddresses option:selected").index(); + + + $(".addressselectnoadd").html(""); + + var HDPrivateKey = bitcore.HDPrivateKey.fromSeed(m.toHex(), bitcore.Networks.livenet); + + + chrome.storage.local.get(function(data) { + + var addresslabels = data.addressinfo; + + + + + for (var i = 0; i < currentsize; i++) { + + var derived = HDPrivateKey.derive("m/0'/0/" + i); + var address1 = new bitcore.Address(derived.publicKey, bitcore.Networks.livenet); + + var pubkey = address1.toString(); + + //$(".addressselect").append(""); + + $(".addressselectnoadd").append(""); + } + + }); +}; + +//function loadSwapbots() { +// +// +// +// var swapbots_public_html = "http://swapbot.tokenly.com/api/v1/public/bots"; +// +// $.getJSON( swapbots_public_html, function( data ) { +// +// if (data.length > 0) { +// +// var allbots = []; +// +// $.each(data, function(i, item) { +// +// allbots.push(data[i].id); +// +// }); +// +// console.log(allbots); +// } +// }); +// +//} + +function loadFeatureRequests() { + + var issues_public_html = "https://api.github.com/repos/loon3/Tokenly-Pockets/issues"; + + + + $.getJSON( issues_public_html, function( data ) { + + $("#FundDevBody").html(""); + + if (data.length > 0) { + + $("#FundDevBody").append("
    Fund Development
    Below is a list of proposed features for Tokenly Pockets. When a proposed feature reaches its funding goal, it is added to the feature queue and completed in the order in which it's added.
    To fund the features below,
    you need POCKETCHANGE

    Proposed Features:
    "); + + var allfeatures = []; + + $.each(data, function(i, item) { + + var info = data[i].labels[2]; + + if (info != undefined) { + + if (info['name'] == "new feature") { + + var address = data[i].labels[0]['name']; + + var budget = data[i].labels[1]['name']; + + var title = data[i].title; + var body = data[i].body; + var url = data[i].html_url; + var propnum = data[i].number; + + //color: #fff; background-color: #2d3c93; + + $("#FundDevBody").append("
    "+title+"
    "+body+"
    Goal: "+addCommas(budget.substr(1))+"
    Funded: ( 0
    )
    Contribute to Feature:
    "); + + //$("#FundDevBody").append("
    "+title+"
    "+body+"
    Funded: 0
    Contribute to Feature:
    "); + + returnTokenBalance(address, "POCKETCHANGE", function(pcbalance){ + + var issueclass = "."+address; + + var issuepctclass = ".pct-"+address; + + var pcbalnum = parseInt(pcbalance); + var budgetnum = parseInt(budget.substr(1)); + + var fundedpct = (pcbalnum / budgetnum) * 100; + + //if (fundedpct < 1) { + fundedpct = fundedpct.toFixed(1); + //} + + console.log(fundedpct); + + $(issueclass).html(addCommas(pcbalance)); + + $(issuepctclass).html(fundedpct + "%"); + + allfeatures.push({title: title, body: body, url: url, pocketchange: pcbalance}); + + }); + + + + + + } + + } + + }); + + + console.log(allfeatures); + + $("#FundDevBody").append("
    Have an idea for a new feature?
    Create an issue on Github!
    "); + +// return allfeatures; + + } + }); + +} + +function returnTokenBalance(address, currenttoken, callback) { + + var source_html = "https://counterpartychain.io/api/balances/"+address; + + //var source_html = "http://xcp.blockscan.com/api2?module=address&action=balance&btc_address="+pubkey+"&asset="+currenttoken; + + + $.getJSON( source_html, function( data ) { + + if (data.data != undefined) { + + $.each(data.data, function(i, item) { + var assetname = data.data[i].asset; + + if(assetname == currenttoken) { + + var assetbalance = data.data[i].amount; + + assetbalance = parseFloat(assetbalance).toString(); + + callback(assetbalance); + + } + }); + + } else { + + callback(0); + + } + }); + + +} + +function addCommas(nStr) { + nStr += ''; + x = nStr.split('.'); + x1 = x[0]; + x2 = x.length > 1 ? '.' + x[1] : ''; + var rgx = /(\d+)(\d{3})/; + while (rgx.test(x1)) { + x1 = x1.replace(rgx, '$1' + ',' + '$2'); + } + return x1 + x2; +} + + +function loadSwaplist(currenttoken) { + + var swaplist_body = "
    "; + + + var source_html = "http://swapbot.tokenly.com/api/v1/public/availableswaps?inToken="+currenttoken+"&sort=cost"; + + $.getJSON( source_html, function( data ) { + + $.each(data, function(i, item) { + + if(data[i].bot["state"] == "active") { + + var receive_token = data[i].swap["out"]; + + var receive_token_rate = parseFloat(data[i].swap["rate"]).toFixed(8); + + var receive_token_cost = data[i].swap["cost"]; + + var bot_url = data[i].bot["botUrl"]; + + swaplist_body += ""; + + } + + + }); + + + + swaplist_body += "
    TokenPrice per "+currenttoken+"
    "+receive_token+"
    "+receive_token_rate+"
    "; + + $( ".swaplistbody").html(swaplist_body); + + }); +} + +function validateEnhancedAssetJSON(jsondata) { + + var jsonstring = JSON.stringify(jsondata); + + console.log(jsonstring); + + var firstSHA = Crypto.SHA256(jsonstring) + + var hash160 = Crypto.RIPEMD160(Crypto.util.hexToBytes(firstSHA)) + var version = 0x41 // "T" + var hashAndBytes = Crypto.util.hexToBytes(hash160) + hashAndBytes.unshift(version) + + var doubleSHA = Crypto.SHA256(Crypto.util.hexToBytes(Crypto.SHA256(hashAndBytes))) + var addressChecksum = doubleSHA.substr(0,8) + + var unencodedAddress = "41" + hash160 + addressChecksum + + var address = Bitcoin.Base58.encode(Crypto.util.hexToBytes(unencodedAddress)) + + return address + +} + +function getImageHash(fileurl, callback) { + + var xhr = new XMLHttpRequest(); + xhr.open('GET', fileurl, true); + + xhr.responseType = 'arraybuffer'; + + xhr.onload = function(e) { + if (this.status == 200) { + var uInt8Array = new Uint8Array(this.response); + var i = uInt8Array.length; + var biStr = new Array(i); + while (i--) + { biStr[i] = String.fromCharCode(uInt8Array[i]); + } + var data = biStr.join(''); +// var base64 = window.btoa(data); + + var sha256 = Crypto.SHA256(data); + + return sha256; + } + }; + xhr.send(); - \ No newline at end of file +} + +function exportAddresses() +{ + + chrome.storage.local.get(function(data) { + + var addresslabels = data.addressinfo; + var string = $("#newpassphrase").html(); + var array = string.split(" "); + m = new Mnemonic(array); + + var currentsize = $('#walletaddresses option').size(); + var exportfiledata = new Object(); + + currentsize -= 1; + + var HDPrivateKey = bitcore.HDPrivateKey.fromSeed(m.toHex(), bitcore.Networks.livenet); + + for (var i = 0; i < currentsize; i++) { + + var derived = HDPrivateKey.derive("m/0'/0/" + i); + var address1 = new bitcore.Address(derived.publicKey, bitcore.Networks.livenet); + + var pubkey = address1.toString(); + + if (i == 0) { + var firstkey = pubkey; + } + + var currentlabel = addresslabels[i].label; + + addresslabels[i].address = pubkey; + + } + + console.log(JSON.stringify(addresslabels)); + + // Convert object to a string. + var result = JSON.stringify(addresslabels); + + // Save as file + var url = 'data:application/json;base64,' + btoa(result); + var file = firstkey.substr(0,8); + + chrome.downloads.download({ + url: url, + filename: file+'.json' + }); + + }); + +} + +function checkImportedLabels(m, callback) { + + chrome.storage.local.get(function(data) { + + + if(typeof(data["imported_labels"]) !== 'undefined' && data["imported_labels"] != false) { + + var newlabels = data["imported_labels"]; + + var newqty = newlabels.length; + + var HDPrivateKey = bitcore.HDPrivateKey.fromSeed(m.toHex(), bitcore.Networks.livenet); + + var derived = HDPrivateKey.derive("m/0'/0/0"); + var address1 = new bitcore.Address(derived.publicKey, bitcore.Networks.livenet); + + var pubkey = address1.toString(); + +// console.log(newlabels[0].address); +// console.log(pubkey); + + if (newlabels[0].address == pubkey){ + + var newinfo = []; + + $.each(newlabels, function(i, item) { + + newinfo.push({"label": newlabels[i].label}); + + }); + + chrome.storage.local.set( + { + + 'addressinfo': newinfo, + 'totaladdress': newqty, + 'imported_labels': false + + }, function () { + + callback(m); + + }); + + } else { + + callback(m); + + } + + + + } else { + + callback(m); + + } + }); + + + + +} + + +function addBvam(newbvamdata) { + + if (newbvamdata.type == "BVAMWT") { + + chrome.runtime.sendMessage({bvamwt: "seed_new", bvamjson: newbvamdata.data}); + + } + + chrome.storage.local.get(function(data) { + + if(typeof(data["bvam"]) === 'undefined') { + + var allbvam = new Array(); + + } else { + + var allbvam = data["bvam"]; + + } + + allbvam = allbvam.concat(newbvamdata); + + chrome.storage.local.set( + { + + 'bvam': allbvam + + }, function (){}); + + }); + +} + +function loadBvam(callback) { + + chrome.storage.local.get(function(data) { + + if(typeof(data["bvam"]) !== 'undefined') { + + var hashname = new Array(); + var hashhash = new Array(); + + var allbvam = data["bvam"]; + + for (var i = 0; i < allbvam.length; i++) { + + var asset = allbvam[i]["data"]["asset"]; + var name = allbvam[i]["data"]["assetname"]; + var hash = allbvam[i]["hash"]; + + hashname[asset] = name; + hashhash[asset] = hash; + + } + + } else { + + var allbvam = ""; + + } + + console.log(hashname); + console.log(hashhash); + + callback(allbvam, hashname, hashhash); + + }); + +} + + +function checkBvam(assetlist, countnumeric, callback) { + + chrome.storage.local.get(function(data) { + + if(typeof(data["bvam"]) === 'undefined') { + + var allbvam = new Array(); + + } else { + + var allbvam = data["bvam"]; + + } + + console.log(allbvam); + + var storedbvam = new Array(); + + for (var i = 0; i < assetlist.length; i++) { + + for (var j = 0; j < allbvam.length; j++) { + + if (assetlist[i]["hash"] == allbvam[j]["hash"]) { + + assetlist[i]["data"] = allbvam[j]["data"]; + + countnumeric--; + + } + + } + + } + + callback(assetlist, countnumeric); + + + }); + +} + + +function displayBvamWTasset(asset, assetbalance, assetname) { + + if (assetbalance.indexOf(".")==-1) {var divisible = "no";} else {var divisible = "yes";} + var iconlink = "http://counterpartychain.io/content/images/icons/xcp.png"; + + var assethtml = "
    Archive
    "+assetname+"
    Send
    "+asset+"
    "+assetbalance+"
    "; + + $( "."+asset+"-loading" ).hide(); + + $( "#allassets" ).append( assethtml ); + +} + + +function loadingBvamWTasset(asset) { + + var iconlink = "http://counterpartychain.io/content/images/icons/xcp.png"; + + var assethtml = "
    Searching for "+asset+" token metadata...
    "; + + + + $( "#allassets" ).append( assethtml ); + +} + +function writeBvamIssue(hash, jsonstring, callback) { + + //console.log(jsonstring); + + var jsondata = JSON.parse(jsonstring) + //console.log(jsondata); + + var time_date = new Date(); + var time_unix = time_date.getTime(); + + var bvamdataforstorage = {hash: hash, type: "BVAMWT", data: jsondata, added: time_unix}; + //var bvamdataforstorage = {hash: hash, type: "TOKNID", data: jsondata, added: time_unix}; + + addBvamIssue(bvamdataforstorage, callback); + + +} + +function addBvamIssue(newbvamdata, callback) { + + chrome.storage.local.get(function(data) { + + + if(typeof(data["bvamwt_enabled"]) !== 'undefined') { + + var enabled = data["bvamwt_enabled"]; + + if (enabled == "yes") { + + chrome.runtime.sendMessage({bvamwt: "seed_new", bvamjson: newbvamdata.data}); + + } + + } + + + if(typeof(data["bvam"]) === 'undefined') { + + var allbvam = new Array(); + + } else { + + var allbvam = data["bvam"]; + + } + + allbvam = allbvam.concat(newbvamdata); + + chrome.storage.local.set( + { + + 'bvam': allbvam + + }, function(){ + +// if (enabled == "yes") { +// +// chrome.runtime.sendMessage({bvamwt: "restart"}); +// +// } + + callback(); + + }); + + }); + +} + +function clearIssueInputs() { + + $("#assetnameIssue").val(""); + $("#assetdescriptionIssue").val(""); + $("#assetwebsiteIssue").val(""); + + $("#ownernameIssue").val(""); + $("#ownertwitterIssue").val(""); + + $('#amountIssue').val("0"); + +} + + +function ajaxissue(url, data, rawtx) { + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + console.log(xhr.responseText); + + $("#reviewIssueBody").hide(); + + var newTxid = rawtotxid(rawtx); + + console.log(newTxid); + + $("#afterIssueBody").html("
    Token Issued!
    Token will appear in wallet after one confirmation
    Token data is not stored on a server, but shared p2p via Webtorrent. Open the Webtorrent Control Panel to share token data with other Pockets users.
    "); + + $("#afterIssueBody").show(); + + xhr.close; + } + } + xhr.open(data ? "POST" : "GET", url, true); + if (data) xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + xhr.send(data); +} + + +function sendBTCissue(hextx) { +// url = 'http://blockchain.info/pushtx'; +// postdata = 'tx=' + hextx; + + url = 'https://chain.so/api/v2/send_tx/BTC'; + postdata = 'tx_hex=' + hextx; + + if (url != null && url != "") + { + ajaxissue(url, postdata, hextx); + } +} + + +$(document).ready(function () { + +}); + +function timerIncrement() { + + idleTime++; + idleTimeDisplay = idleTime * 10; + + if(idleTime > 1 && idleTime <= 5) { + console.log("Idle for "+idleTimeDisplay+" seconds"); + } + + if (idleTime == 5) { + console.log("refreshing window in 10 seconds..."); + } + + if (idleTime > 5) { // 60 seconds + window.location.reload(); + } +} + + +function displayUnconfirmedBTC(address) { + +//http://btc.blockr.io/api/v1/address/unconfirmed/1C2dWhQHj8Wx319CdJcXi55zbshFkVUFXX + +// {"status":"success","data":{"address":"1C2dWhQHj8Wx319CdJcXi55zbshFkVUFXX","unconfirmed":[{"tx":"6ae4a39063fdc3547b5883b5882a6821c8bbe688a30b710bacb8863db4a75afa","time_utc":"2015-09-21T03:10:01Z","amount":0.21517648,"n":1},{"tx":"6ae4a39063fdc3547b5883b5882a6821c8bbe688a30b710bacb8863db4a75afa","time_utc":"2015-09-21T03:10:01Z","amount":-0.41289248,"n":1}]},"code":200,"message":""} + + +} + diff --git a/Chrome Extension/register.png b/Chrome Extension/register.png new file mode 100644 index 0000000..85e96a3 Binary files /dev/null and b/Chrome Extension/register.png differ diff --git a/Chrome Extension/seedbvam.html b/Chrome Extension/seedbvam.html new file mode 100644 index 0000000..935d592 --- /dev/null +++ b/Chrome Extension/seedbvam.html @@ -0,0 +1,35 @@ + + + + + + Webtorrent Control Panel + + + + + + + + + + + + + + + + + + +
    + +
    +
    Blockchain Validated Asset Metadata
    +
    Webtorrent Control Panel
    +
    Page reloads every minute
    +
    Close window to terminate seeding
    +
    IMPORTANT: Webtorrent peers (that's you!) are connected to each other via WebRTC data channels (webrtc.org).
    This process can use a significant amount of memory depending on the number of torrents seeded.
    +
    + + \ No newline at end of file diff --git a/Chrome Extension/swapbot-icon.png b/Chrome Extension/swapbot-icon.png new file mode 100644 index 0000000..fe3fce9 Binary files /dev/null and b/Chrome Extension/swapbot-icon.png differ diff --git a/Chrome Extension/test/bitpay_example.html b/Chrome Extension/test/bitpay_example.html new file mode 100644 index 0000000..0c3915a --- /dev/null +++ b/Chrome Extension/test/bitpay_example.html @@ -0,0 +1,22 @@ +Pay with Bitcoin + + + + + + + + +
    17niuhxCCVQyazkkcsX7b96V4rWpoY8rKQ
    + + +
    + +
    + +
    +
    + +
    + +
    \ No newline at end of file diff --git a/Chrome Extension/test/paymentbutton_example.js b/Chrome Extension/test/paymentbutton_example.js new file mode 100644 index 0000000..1fd5f15 --- /dev/null +++ b/Chrome Extension/test/paymentbutton_example.js @@ -0,0 +1,12 @@ +var address = "1LrM4bojLAKfuoFMXkDtVPMGydX1rkaMqH"; //send to address +var paymentlabel = "Token Slot Demo"; //payment 'Send to:' label +var tokensaccepted = "tokenly,ltbcoin,btc"; //tokens accepted for payment + +var pocketsurl = $('.pockets-url').text(); +var pocketsimage = $('.pockets-image').text(); + +var label_encoded = encodeURIComponent(paymentlabel).replace(/[!'()*]/g, escape); +var urlattributes = "?address="+address+"&label="+label_encoded+"&tokens="+tokensaccepted; + +$('#payment-button').html(""); //assumes payment button location is + diff --git a/Chrome Extension/test/xcpninja-issue-wt.html b/Chrome Extension/test/xcpninja-issue-wt.html new file mode 100644 index 0000000..8a1be36 --- /dev/null +++ b/Chrome Extension/test/xcpninja-issue-wt.html @@ -0,0 +1,373 @@ + + + + + + +xcp.ninja + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    + +
    +
    +
    Peer to Peer Enhanced Tokens
    +
    Token data via Webtorrent is unique in that you, the issuer of an enhanced token (Counterparty Numeric Asset), are responsible for seeding the Blockchain Validated Asset Metadata (BVAM) file for other token holders to download. BVAM can only be downloaded by wallet software if it is being actively seeded.
    +
    xcp.ninja provides a link at the end of the token issuance process which can be used for seeding your BVAM file. It is recommended that you download the newly created BVAMWT.json (do not change the file name!) so that it can be seeded via any Webtorrent client (ex. instant.io) in the event that xcp.ninja is unavailable.
    +
    For Tokenly Pockets users, once your wallet downloads BVAM for a given token, it is stored within the wallet for future reference and does not need to be downloaded again.
    + +
    + + +
    + + + + + + + + + + \ No newline at end of file diff --git a/Chrome Extension/ticker.js b/Chrome Extension/ticker.js index b20c7b9..cb8ae7a 100644 --- a/Chrome Extension/ticker.js +++ b/Chrome Extension/ticker.js @@ -1,11 +1,56 @@ var bitcore = require('bitcore'); -$( document ).ready(function() { +var client = new WebTorrent(); + +var INSIGHT_SERVER = getInsightServer(); + +var idleTime = 0; +$( document ).ready(function() { + + //Increment the idle time counter every minute. + var idleInterval = setInterval(timerIncrement, 10000); // 5 seconds + + //Zero the idle timer on mouse movement. + $(this).mousemove(function (e) { + idleTime = 0; + }); + $(this).keypress(function (e) { + idleTime = 0; + }); + + window.resizeTo(324,400); + +// getImageHash("pockets-48.png", function(hash){ +// +// console.log("local: "+hash); +// +// }); +// +// getImageHash("http://joelooney.org/ltbcoin/pockets-16.png", function(hash){ +// +// console.log("remote: "+hash); +// +// }); + + setBvamwtOff(); setInitialAddressCount(); setPinBackground(); + + + + $(window).resize(function(){ + if($("body").data("resizebypass") == "glidera"){ + window.resizeTo(382,610); + } else if($("body").data("resizebypass") == "tall"){ + window.resizeTo(324,610); + } else { + window.resizeTo(324,400); + } + }) + $('#alltransactions').hide(); $('#yourtxid').on('click', 'a', function(){ @@ -13,6 +58,7 @@ $( document ).ready(function() { return false; }); + $('#alltransactions').on('click', 'a', function(){ chrome.tabs.create({url: $(this).attr('href')}); return false; @@ -24,13 +70,73 @@ $( document ).ready(function() { return false; }); + $('#FundDevBody').on('click', 'a', function(){ + chrome.tabs.create({url: $(this).attr('href')}); + return false; + }); + $( "#tutorial_splash" ).click(function() { + $("#tutorial_splash").hide(); + }); + + + $('#ninjaButton').click(function(){ + + //chrome.tabs.create({url: "http://xcp.ninja"}); + + $("#errorIssue").html(""); + $("#errorReview").html(""); + + $("#reviewIssueButton").prop('disabled', false); + $("#reviewIssueButton").html('Issue Token'); + + clearIssueInputs(); + + $("#IssueBody").show(); + + $("#reviewIssueBody").hide(); + $("#afterIssueBody").hide(); + + + var newasset = create_new_assetid(); + + $("#assetIssue").val(newasset); + + + }); + +// $("li").click(function(){ +// +// if (this.id != "inventoryTab"){ +// +// client.remove("magnet:?xt=urn:btih:1d1c88903daa90b27107251d4a3462a63b5d2f8e", function(err){ +// +// client.remove("magnet:?xt=urn:btih:5eebd992b799b0577ebc922e40fa765d096f8d6c", function(err){ +// +// console.log("all done!"); +// +// }) +// +// }) +// +// }; +// +// // +// +// }); + $('#shapeshiftStartButton').click(function(){ + + $("#shapeshiftbuttonbox").hide(); + $("#shapeshiftselectadd").show(); + + }); + $('#shapeshiftButton').click(function(){ - var selectedaddress = $("#shapeshiftPubAddress").val(); + var selectedaddress = $("#getbtcAddress").val(); chrome.tabs.create({url: "https://shapeshift.io/shifty.html?destination="+selectedaddress+"&apiKey=da63a102dd3dbbf683d7123c90ce66dad4b7b9c5636bb5c842b6bf207be84195b2a8199dc933aeb7e83ca3a234551673753b0e9c6e53f529e37abc919d108691&amount="}); @@ -45,7 +151,7 @@ $( document ).ready(function() { //on open var manifest = chrome.runtime.getManifest(); - var infobutton = "
    "; + var infobutton = "
    "; $("#nameversion").html("Tokenly Pockets v" + manifest.version + infobutton); @@ -93,10 +199,13 @@ $( document ).ready(function() { if (decrypted_passphrase.length > 0) { $("#pinsplash").hide(); + $(".hideEncrypted").hide(); $("#priceBox").show(); + infoalertstart(); + existingPassphrase(decrypted.toString(CryptoJS.enc.Utf8)); } @@ -141,8 +250,9 @@ $( document ).ready(function() { $("#xcpaddress").html(addr); - getPrimaryBalance(addr); + //getPrimaryBalance(addr); + $('#refreshWallet').trigger('click'); // }); } @@ -178,8 +288,10 @@ $( document ).ready(function() { }, function () { $("#welcomesplash").hide(); + //$("#tutorial_splash").show(); $(".hideEncrypted").hide(); $(".bg").css("min-height", "200px"); + infoalertstart(); }); @@ -227,6 +339,37 @@ $( document ).ready(function() { }); + $('#exportAddresses').click(function(){ + exportAddresses(); + + }); + + $('#importAddresses').click(function(){ + + chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { + chrome.tabs.executeScript(tabs[0].id, {file: "js/import_addresses.js"}, function(){ + + if (chrome.extension.lastError){ + var errorMsg = chrome.extension.lastError.message; + if (errorMsg == "Cannot access a chrome:// URL"){ + $("#hiddenaddlab").show(); + } + } + + }); + }); + + + }); + + + + + $('#AddressesAndLabels').click(function(){ + $('#AddressesAndLabelsOptions').toggle(); + + $('#hiddenaddlab').hide(); + }); $('#setpassphraseatsplash').click(function (){ @@ -249,6 +392,7 @@ $( document ).ready(function() { getStorage(); $("#welcomesplash").hide(); + //$("#tutorial_splash").show(); }); @@ -257,20 +401,47 @@ $( document ).ready(function() { $('#assettransactiontoggle').click(function () { + + var currentaddr = $("#xcpaddress").html(); + if ($('#assettransactiontoggle').html() == "View Tokens") { + $('#assettransactiontoggle').html("View Token Transaction History"); $('#alltransactions').hide(); $('#allassets').show(); + + loadAssets(currentaddr); + } else { + $('#assettransactiontoggle').html("View Tokens"); $('#alltransactions').show(); $('#allassets').hide(); + + loadTransactions(currentaddr); } + }); $('.resetAddress').click(function () { - newPassphrase(); + + + newPassphrase(); + + + + + }); + + $('.addlabbuttons').click(function () + { + + + $('#AddressesAndLabelsOptions').hide(); + + + }); $('.resetFive').click(function () @@ -314,10 +485,33 @@ $( document ).ready(function() { }); $('#sendAssetButton').click( function () { - $("#btcsendbox").toggle(); + + + + $("#btcsendbox").toggle(function(){ + + if($("#btcsendbox").is(":visible")) { + + $("body").data("resizebypass", "tall"); + window.resizeTo(324,610); + + } else { + + $("body").data("resizebypass", "false"); + window.resizeTo(324,400); + + } + + }); + + + if($("#moreBTCinfo").is(":visible")) { $("#moreBTCinfo").hide(); + } + + }); $('#manualAddressButton').click( function () @@ -331,12 +525,27 @@ $( document ).ready(function() { { if($("#btcsendbox").is(":visible")) { $("#btcsendbox").hide(); + } if ($("#moreBTCinfo").length){ - $("#moreBTCinfo").toggle(); + $("#moreBTCinfo").toggle(function(){ + + if($("#moreBTCinfo").is(":visible")) { + + $("body").data("resizebypass", "tall"); + window.resizeTo(324,610); + + } else { + + $("body").data("resizebypass", "false"); + window.resizeTo(324,400); + + } + + }); @@ -352,6 +561,9 @@ $( document ).ready(function() { colorLight : "#ffffff", correctLevel : QRCode.CorrectLevel.H }); + + $("body").data("resizebypass", "tall"); + window.resizeTo(324,610); } }); @@ -377,9 +589,81 @@ $( document ).ready(function() { }); + + $(document).on("click", '#helpButton', function (event) + { + var ontab = $("ul#allTabs li.active a#walletLink").html(); + + if(ontab !== undefined) { + + $( "#infoalertstatus" ).click(); + + $("body").data("resizebypass", "false"); + window.resizeTo(324,400); + + $("#btcsendbox").hide(); + $("#moreBTCinfo").hide(); + $( "#tutorial_splash" ).show(); + + } + }); + + + + $(document).on("click", '.tokenlistingheader', function (event) + { + + $( ".tokenlistingbody" ).remove(); + }); + + $(document).on("click", '.swapbotselect', function (event) + { + console.log($(this).data("url")); + + + chrome.tabs.create({url: $(this).data("url")}); + return false; + }); + +$(document).on("click", '.tokenlisting', function (event) + { + + var currenttoken = $(this).data("token"); + + if ($( "div:contains('"+currenttoken+" Swapbots')" ).length) { + + $( ".tokenlistingbody" ).remove(); + + } else { + + if ($('.tokenlistingbody').length) { + + $( ".tokenlistingbody" ).remove(); + + } + + var row = $(this).closest('tr'); + + $("
    "+currenttoken+" Swapbots
    ").insertAfter(row); + + + loadSwaplist(currenttoken); + + + } + + }); + $(document).on("click", '#refreshWallet', function (event) { + window.resizeTo(324,400); + $("body").data("resizebypass", "false"); + + $("#shapeshiftbuttonbox").show(); + $("#shapeshiftselectadd").hide(); + + $("#currenttoken-pending").html(""); $("#ltbDirectorySearchResults").html(""); $("#ltbUserSearch").val(""); @@ -395,6 +679,7 @@ $( document ).ready(function() { $("#sendtoaddress").val(""); $("#sendtoamount").val(""); + $(".sendlabel").html(""); var assetbalance = $("#xcpbalance").html(); var array = assetbalance.split(" "); @@ -408,10 +693,13 @@ $( document ).ready(function() { getRate(array[0], pubkey, currenttoken); getPrimaryBalance(pubkey); + + currenttokenpending(currenttoken); }); $('#switchtoxcp').click(function () { + $("#currenttoken-pending").html(""); $(".currenttoken").html("BTC"); $("#sendtokenbutton").html("Send BTC"); var pubkey = $("#xcpaddress").html(); @@ -444,13 +732,49 @@ $( document ).ready(function() { $(document).on("click", '.movetowallet', function (event) { - + $("#currenttoken-pending").html(""); + var $assetdiv = $( this ).prev(); - var currentasset = $assetdiv.html(); + + var isnumeric = $assetdiv.data("numeric"); + + if (isnumeric != undefined) { + + var currentasset = isnumeric; + + var enhancedassetfullname = $assetdiv.html(); + +// if (enhancedassetfullname.length > 24) { +// +// var enhancedassetname = enhancedassetfullname.substr(0, 24) + "..."; +// +// } else { + + var enhancedassetname = enhancedassetfullname; + +// } + + $("#xcpbalance").data("enhanced", enhancedassetname); + + $("#sendtokenbutton").html("Send"); + + } else { + + var currentasset = $assetdiv.html(); + + $("#sendtokenbutton").html("Send "+currentasset); + + } + $(".currenttoken").html(currentasset); + + var qtypending = $("."+currentasset+"-pending").html(); + + $("#currenttoken-pending").html(qtypending); + //$(".currenttoken").html("WORKS"); - $("#sendtokenbutton").html("Send "+currentasset); + var pubkey = $("#xcpaddress").html(); @@ -458,34 +782,96 @@ $( document ).ready(function() { getPrimaryBalance(pubkey); + window.resizeTo(324,400); + $("body").data("resizebypass", "false"); + $('#allTabs a:first').tab('show'); }); + + + $(document).on("click", '.movetosend', function (event) { var sendaddress = $( this ).text(); + var username = $( this ).data("user"); + $("#sendtoaddress").val(sendaddress); + $(".sendlabel").html(username); + $("#btcsendbox").show(); $("#moreBTCinfo").hide(); $('#allTabs a:first').tab('show'); }); + + $(document).on("click", '.movetosendFundDev', function (event) + { + + $("#currenttoken-pending").html(""); + + var currentasset = $( this ).data("token"); + var title = $( this ).data("title"); + $(".currenttoken").html(currentasset); + + var qtypending = $("."+currentasset+"-pending").html(); + + $("#currenttoken-pending").html(qtypending); + + //$(".currenttoken").html("WORKS"); + + $("#sendtokenbutton").html("Send "+currentasset); + + var pubkey = $("#xcpaddress").html(); + + //var pubkey = FindAsset(currentasset); + + $(".sendlabel").html(title); + + getPrimaryBalance(pubkey); + + var sendaddress = $( this ).data("address"); + + $("#sendtoaddress").val(sendaddress); + + $("#btcsendbox").show(); + $("#moreBTCinfo").hide(); + + + + $('#allTabs a:first').tab('show'); + + }); + $('#inventoryTab').click(function () { - var address = $("#xcpaddress").html(); + //$('.bg').css({"width":"320px"}); - //$("#alltransactions").hide(); + $('#buysellTab').css({"margin-left":"12px"}); + $("#priceBox").show(); + $("#priceBoxBank").hide(); + $("#buysellTab").data("hovercheck", "on"); - loadAssets(address); - + $('.bg').animate({ + width: "320px" + }, 100 ); + window.resizeTo(324,610); + $("body").data("resizebypass", "tall"); + var address = $("#xcpaddress").html(); + + if ($('#assettransactiontoggle').html() == "View Tokens") { + loadTransactions(address); + } else { + loadAssets(address); + } }); @@ -511,16 +897,145 @@ $( document ).ready(function() { getNews(); }); + + $("#buysellTab").data("hovercheck", "on"); + + $( "#buysellTab" ).hover(function() { + + var hovercheck = $("#buysellTab").data("hovercheck"); + + if (hovercheck == "on") { + + $("#priceBox").toggle(); + $("#priceBoxBank").toggle(); + + + + } + + }); + + + + + + $( "#infoalertstatus" ).click(function () { + + chrome.storage.local.set( + { + + 'infoalert': "disabled" + + }, function () { + + + + }); + + }); + + $( "#nevershow-infoalert" ).click(function () { + + chrome.storage.local.set( + { + + 'infoalert': "never" + + }, function () { + + $("#infoalert").hide(); + + }); + + }); + + + $(document).on('click', '#buysellTab', function () { + + // $('.bg').css({"width":"320px"}); +// $('.bg').animate({ +// width: "320px" +// }, 100 ); + + //$('#buysellTab').css({"margin-left":"12px"}); + + $("#priceBox").hide(); + $("#priceBoxBank").show(); + + $("#buysellTab").data("hovercheck", "off"); + + }); + + $(document).on('click', '#glideraButton', function () { + $('.bg').animate({ + width: "378px" + }, 100 ); + + $('#buysellTab').css({"margin-left":"70px"}); + + //$('.bg').css({"width":"378px"}); + + $("body").data("resizebypass", "glidera"); + + window.resizeTo(382,610); + + }); + $(document).on('click', '#walletTab', function () { + + //$('.bg').css({"width":"320px"}); + $('.bg').animate({ + width: "320px" + }, 100 ); + + + window.resizeTo(324,400); + $("body").data("resizebypass", "false"); + $('#buysellTab').css({"margin-left":"12px"}); + $("#priceBox").show(); + $("#priceBoxBank").hide(); + $("#buysellTab").data("hovercheck", "on"); + + }); + + $(document).on('click', '#settingsTab', function () { + + //$('.bg').css({"width":"320px"}); + $('.bg').animate({ + width: "320px" + }, 100 ); + window.resizeTo(324,610); + $("body").data("resizebypass", "tall"); + $('#buysellTab').css({"margin-left":"12px"}); + $("#priceBox").show(); + $("#priceBoxBank").hide(); + $("#buysellTab").data("hovercheck", "on"); + }); $(document).on('click', '#toolsTab', function () { + + //$('.bg').css({"width":"320px"}); + + $('.bg').animate({ + width: "320px" + }, 100 ); + window.resizeTo(324,610); + $("body").data("resizebypass", "tall"); + $('#buysellTab').css({"margin-left":"12px"}); + $("#priceBox").show(); + $("#priceBoxBank").hide(); + $("#buysellTab").data("hovercheck", "on"); + var $link = $('li.active a[data-toggle="tab"]'); $link.parent().removeClass('active'); var tabLink = $link.attr('href'); $('#allTabs a[href="' + tabLink + '"]').tab('show'); + + loadAddresslist(); }); + $(document).on("click", '#encryptPasswordButton', function (event) { @@ -583,8 +1098,16 @@ $(document).on('click', '#toolsTab', function () { sendtokenaction(); }); + $(document).on("keyup", '#sendtoaddress', function (event) + { + + $(".sendlabel").html(""); + }); + + $(document).on("keyup", '#sendtoamount', function (event) { + var sendamount = parseFloat($("#sendtoamount").val()); var currenttoken = $(".currenttoken").html(); @@ -641,8 +1164,368 @@ $(document).on('click', '#toolsTab', function () { getExchangeRatesList(); }); + + + $('#FundDevApp').click(function(){ + + loadFeatureRequests(); + + + }); + + + $('#hashjsonIssueTOKNID').click(function(){ + + var assetid = $("#assetIssue").val(); + var assetname = $("#assetnameIssue").val(); + var owneraddress = $("#owneraddressIssue").val(); + + if (bitcore.Address.isValid(owneraddress)){ + + is_asset_unique_init(assetid, function(result){ + + var assetname = $("#assetnameIssue").val(); + + if (result == true && assetname.length > 0) { + + var assetid = $("#assetIssue").val(); + var assetname = $("#assetnameIssue").val(); + var assetdesc = $("#assetdescriptionIssue").val(); + var assetweb = $("#assetwebsiteIssue").val(); + + var ownername = $("#ownernameIssue").val(); + var ownertwitter = $("#ownertwitterIssue").val(); + var owneraddress = $("#owneraddressIssue").val(); + + var divisible = $('#divisibleIssue').val(); + var amount = $('#amountIssue').val(); + + var prejsonform = {asset: assetid, assetdescription: assetdesc, assetname: assetname, assetwebsite: assetweb, owneraddress: owneraddress, ownername: ownername, ownertwitter: ownertwitter}; + + var jsonform = JSON.stringify(prejsonform); + + console.log(jsonform); + + var firstSHA = Crypto.SHA256(jsonform); + var hash160 = Crypto.RIPEMD160(Crypto.util.hexToBytes(firstSHA)) + var version = 0x41 // "T" + var hashAndBytes = Crypto.util.hexToBytes(hash160) + hashAndBytes.unshift(version) + + var doubleSHA = Crypto.SHA256(Crypto.util.hexToBytes(Crypto.SHA256(hashAndBytes))) + var addressChecksum = doubleSHA.substr(0,8) + + var unencodedAddress = "41" + hash160 + addressChecksum + + var hash = Bitcoin.Base58.encode(Crypto.util.hexToBytes(unencodedAddress)) + + var description = "TOKNID-"+hash; + + var reviewinfo = "
    Token Name:
    "+assetname+"
    Issuing Address:
    "+owneraddress+"
    Token ID:
    "+assetid+"
    Divisible:
    "+divisible+"
    Amount to be Issued:
    "+amount+"
    Description:
    "+description+"
    "; + + //
    BVAM json:
    "+jsonstring+"
    + $("#reviewIssueBodyInfo").data("bvam_cache", jsonform); + $("#reviewIssueBodyInfo").data("hash_cache", hash); + + $.post( "http://xcp.ninja/logasset.php", { jsonpayload: jsonform, assetid: assetid, hash: hash } ); + + $("#reviewIssueBodyInfo").html(reviewinfo); + + $("#IssueBody").hide(); + $("#reviewIssueBody").show(); + + + } else { + + $("#errorIssue").html( "You must provide a token name!" ); + + } + + }) + } + + }); + + + $('#hashjsonIssue').click(function(){ + + console.log("yo"); + + var assetid = $("#assetIssue").val(); + var assetname = $("#assetnameIssue").val(); + var owneraddress = $("#owneraddressIssue").val(); + + if (bitcore.Address.isValid(owneraddress)){ + + is_asset_unique_init(assetid, function(result){ + + var assetname = $("#assetnameIssue").val(); + + if (result == true && assetname.length > 0) { + + var assetid = $("#assetIssue").val(); + var assetname = $("#assetnameIssue").val(); + var assetdesc = $("#assetdescriptionIssue").val(); + var assetweb = $("#assetwebsiteIssue").val(); + + var ownername = $("#ownernameIssue").val(); + var ownertwitter = $("#ownertwitterIssue").val(); + var owneraddress = $("#owneraddressIssue").val(); + + var divisible = $('#divisibleIssue').val(); + var amount = $('#amountIssue').val(); + + var prejsonform = {ownername: ownername, ownertwitter: ownertwitter, owneraddress: owneraddress, asset: assetid, assetname: assetname, assetdescription: assetdesc, assetwebsite: assetweb}; + + var jsonstring = JSON.stringify(prejsonform); + + console.log(prejsonform); + + var blob = new Blob([jsonstring], {type: "application/json"}); + console.log(blob); + + //chrome.runtime.sendMessage({bvamwt: "end"}); + + var clienthash = new WebTorrent() + + clienthash.seed(blob, {name: "BVAMWT.json"}, function (torrent) { + + console.log("getting token infohash..."); + + var hash = torrent.infoHash; + + console.log(hash); + + var hash_base58 = Bitcoin.Base58.encode(Crypto.util.hexToBytes(hash)) + + var description = "BVAMWT-"+hash_base58; + + var reviewinfo = "
    Token Name:
    "+assetname+"
    Issuing Address:
    "+owneraddress+"
    Token ID:
    "+assetid+"
    Divisible:
    "+divisible+"
    Amount to be Issued:
    "+amount+"
    Description:
    "+description+"
    "; + + //
    BVAM json:
    "+jsonstring+"
    + $("#reviewIssueBodyInfo").data("bvam_cache", jsonstring); + $("#reviewIssueBodyInfo").data("hash_cache", hash_base58); + + $("#reviewIssueBodyInfo").html(reviewinfo); + + $("#IssueBody").hide(); + $("#reviewIssueBody").show(); + + clienthash.destroy() + + }) + + } else { + + $("#errorIssue").html( "You must provide a token name!" ); + + } + + }) + } + + }); + + + $("#reviewIssueButton").click(function(){ + + var add_from = $("#owneraddressIssue").val(); + + var source_html = "http://btc.blockr.io/api/v1/address/info/"+add_from; //blockr + + $.getJSON( source_html, function( apidata ) { //blockr + + var bitcoinparsed = parseFloat(apidata.data.balance); //blockr + + console.log(bitcoinparsed); + + if(bitcoinparsed >= 0.00025600) { + + var bvamjson = $("#reviewIssueBodyInfo").data("bvam_cache"); + var hash = $("#reviewIssueBodyInfo").data("hash_cache"); + + writeBvamIssue(hash, bvamjson, function(){ + + console.log("bvam infohash "+hash+" written to local storage!"); + //console.log("bvam TOKNID hash "+hash+" written to local storage!"); + + $("#reviewIssueButton").prop('disabled', true); + $("#reviewIssueButton").html("Issuing... "); + + var mnemonic = $("#newpassphrase").html(); + + var assetidval = $("#assetIssue").val(); + var add_from = $("#owneraddressIssue").val(); + + var divisible = $('#divisibleIssue').val(); + var quantity = $('#amountIssue').val(); + + var description = "BVAMWT-"+hash; + //var description = "TOKNID-"+hash; + + var btc_total = 0.0000547; //total btc to receiving address + var msig_total = 0.000078; //total btc to multisig output (returned to sender) + + var transfee = 0.0001; //bitcoin tx fee + + var msig_outputs = 2; + + if(description.length <= 41) { + + createIssuance(add_from, assetidval, quantity, divisible, description, msig_total, transfee, mnemonic, msig_outputs); + //console.log(description); + + } + + }); + } else { + + console.log("not enough btc at this address!"); + + $("#errorReview").html("Not enough BTC at this address!"); + + } + + }); + + }); + + + $('#hideshowpass').click(function(){ + + var status = $('#hideshowpass').html(); + + if (status == "Hide Passphrase") { + + $('#hideshowpass').html("Show Passphrase"); + + $('#inputSplashPassphrase').prop('type', 'password'); + + } else { + + $('#hideshowpass').html("Hide Passphrase"); + + $('#inputSplashPassphrase').prop('type', 'text'); + + } + + }); + + $('#hideshowpassSettings').click(function(){ + + var status = $('#hideshowpassSettings').html(); + + if (status == "Hide") { + + $('#hideshowpassSettings').html("Show"); + + $('#manualMnemonic').prop('type', 'password'); + + } else { + + $('#hideshowpassSettings').html("Hide"); + + $('#manualMnemonic').prop('type', 'text'); + + } + + }); + + $('#chainsobutton').click( function () + { + var state = $('#turnoffchainso').html(); + + + + if (state == "Disable Chain.so Token Detection") { + + var detect = "no"; + + chrome.storage.local.set( + { + 'chainso_detect': detect + }, function () { + + $('#turnoffchainso').html("Enable Chain.so Token Detection"); + + }); + + + } else { + + var detect = "yes"; + chrome.storage.local.set( + { + 'chainso_detect': detect + }, function () { + + $('#turnoffchainso').html("Disable Chain.so Token Detection"); + + }); + + } + }); + + $('#bvamwtbutton').click( function () + { + + var state = $('#bvamwttoggle').html(); + + if (state == "Disable Asset Metadata via Webtorrent") { + + //chrome.runtime.sendMessage({bvamwt: "end"}); + + var enabled = "no"; + + chrome.storage.local.set( + { + 'bvamwt_enabled': enabled + }, function () { + + $('#bvamwttoggle').html("Enable Asset Metadata via Webtorrent"); + + }); + + + } else { + + //chrome.runtime.sendMessage({bvamwt: "restart"}); + + var enabled = "yes"; + + chrome.storage.local.set( + { + 'bvamwt_enabled': enabled + }, function () { + + $('#bvamwttoggle').html("Disable Asset Metadata via Webtorrent"); + + }); + + } + }); + + $('#bvamseedbutton').click( function () + { + + chrome.runtime.sendMessage({bvamwt: "create_seed_tab"}); + + }); + + + $('#openinwindowbutton').click( function () + { + chrome.windows.create({ url: 'popup.html', type: 'popup', width: 324, height: 380, left: 500, top: 150 }, function(data){ + + console.log(data); + + }); + }); +//loadSwapbots(); + +//loadFeatureRequests(); }); \ No newline at end of file diff --git a/Chrome Extension/tipsplash.html b/Chrome Extension/tipsplash.html index a12fe3c..f5ad488 100644 --- a/Chrome Extension/tipsplash.html +++ b/Chrome Extension/tipsplash.html @@ -8,6 +8,8 @@ + + @@ -156,14 +158,16 @@
    -
    -
    -
    - - - - -
    +
    +
    +
    Enter Amount
    +
    + +
    +
    + +
    +
    diff --git a/Chrome Extension/tipsplash.js b/Chrome Extension/tipsplash.js index ee04fac..49bb6b0 100644 --- a/Chrome Extension/tipsplash.js +++ b/Chrome Extension/tipsplash.js @@ -296,54 +296,73 @@ function getAssetsandBalances(add) { // $(".assetselect").append("
  • You have no tokens at this address.
  • "); // $("#tokendropdown").hide(); // } + + var assetsataddress = parseFloat(data.total); - $.each(data.data, function(i, item) { - - var assetname = data.data[i].asset; + if (assetsataddress > 0){ + + $.each(data.data, function(i, item) { - if (assetname.charAt(0) != "A") { - - if (tokenarray[0] == "ALL" || jQuery.inArray(assetname, tokenarray) !== -1) { - - var assetbalance = data.data[i].amount; //.balance for blockscan - if (assetbalance.indexOf(".")==-1) {var divisible = "no";} else {var divisible = "yes";} + var assetname = data.data[i].asset; + + if (assetname.charAt(0) != "A") { + + if (tokenarray[0] == "ALL" || jQuery.inArray(assetname, tokenarray) !== -1) { - var iconname = assetname.toLowerCase(); - var iconlink = "http://counterpartychain.io/content/images/icons/"+iconname+".png"; + var assetbalance = data.data[i].amount; //.balance for blockscan + if (assetbalance.indexOf(".")==-1) {var divisible = "no";} else {var divisible = "yes";} - //$("#tokendropdown").show(); + var iconname = assetname.toLowerCase(); + var iconlink = "http://counterpartychain.io/content/images/icons/"+iconname+".png"; - var assethtml = "
    "+assetname+"
    Balance: "+assetbalance+"
    "; + //$("#tokendropdown").show(); + var assethtml = "
    "+assetname+"
    Balance: "+assetbalance+"
    "; - $(".assetselect").append("
  • "+assethtml+"
  • "); - var assetdisplayed = $("#assetdisplayed").html(); + $(".assetselect").append("
  • "+assethtml+"
  • "); - if (assetdisplayed.length == 0) { + var assetdisplayed = $("#assetdisplayed").html(); - $("#assetdisplayed").html(assethtml); + if (assetdisplayed.length == 0) { + + $("#assetdisplayed").html(assethtml); + + } } - - } - } - - $("#fulldropdown").css( "display", "block" ); - //$("#fulldropdown").show(); - $("#dropdown-working").css("display", "none"); - + } + +// $("#fulldropdown").css( "display", "block" ); +// //$("#fulldropdown").show(); +// $("#dropdown-working").css("display", "none"); +// +// +// $( "#walletaddresses" ).removeProp( "disabled" ); + + }); - $( "#walletaddresses" ).removeProp( "disabled" ); + } + + var displayedassetname = $("#assetdisplayed").find(".assetname").text(); + $("#sendtokenbutton").html("Send "+displayedassetname); + + $("#fulldropdown").css( "display", "block" ); + //$("#fulldropdown").show(); + $("#dropdown-working").css("display", "none"); - }); + + $( "#walletaddresses" ).removeProp( "disabled" ); + + + var assetdisplayed = $("#assetdisplayed").html(); if (assetdisplayed.length == 0) { - $("#btcbalance").html("
    You do not have accepted tokens at this address.
    "); + $("#btcbalance").html("
    You do not have accepted tokens in this Pocket.
    "); $("#tokendropdown").hide(); } @@ -514,7 +533,7 @@ function sendtokenaction() { var txsAvailable = $("#txsAvailable").html(); - if (txsAvailable > 1) { + if (txsAvailable >= 1) { if (currenttoken == "BTC") { diff --git a/Chrome Extension/tipticker.js b/Chrome Extension/tipticker.js index fc1ac86..7675946 100644 --- a/Chrome Extension/tipticker.js +++ b/Chrome Extension/tipticker.js @@ -1,4 +1,5 @@ var bitcore = require('bitcore'); +var INSIGHT_SERVER = getInsightServer(); $( document ).ready(function() { @@ -8,6 +9,11 @@ $( document ).ready(function() { var addressfromurl = parseURLParams(thisurl); var sendtoaddress = addressfromurl["address"][0]; var addresslabel = addressfromurl["label"][0]; + + if (addressfromurl["amount"][0] !== "undefined") { + $("#sendtoamount").val(addressfromurl["amount"][0]); + } + //var isxcpurl = addressfromurl["isxcp"][0]; // if (isxcpurl != "true") { @@ -18,7 +24,7 @@ $( document ).ready(function() { $("#tip-label").html(addresslabel); $("#tip-address").html(sendtoaddress); -getExtStorage(); + getExtStorage(); var manifest = chrome.runtime.getManifest(); @@ -86,8 +92,8 @@ getExtStorage(); $("#fulldropdown").css("display", "none"); $("#dropdown-working").css("display", "block"); - $("#sendtokenbutton").html("Send"); - $("#sendtoamount").val(""); + //$("#sendtokenbutton").html("Send"); + //$("#sendtoamount").val(""); $("#sendtokenbutton").prop('disabled', false); var addr = $(this).val(); @@ -108,7 +114,10 @@ getExtStorage(); $(".selectedtoken").html("
    "); - $("#sendtokenbutton").html("Send"); + var displayedassetname = $("#assetdisplayed").find(".assetname").text(); + + + $("#sendtokenbutton").html("Send "+displayedassetname); $("#sendtoamount").val(""); $("#sendtokenbutton").prop('disabled', false); @@ -118,7 +127,9 @@ getExtStorage(); $(document).on("click", '#sendtokenbutton', function (event) { if ($("#sendtokenbutton").html() == "Click to continue") { - $("#sendtokenbutton").html("Send"); + var displayedassetname = $("#assetdisplayed").find(".assetname").text(); + $("#sendtokenbutton").html("Send "+displayedassetname); + $("#sendtoamount").val(""); $("#sendtokenbutton").prop('disabled', false); diff --git a/Chrome Extension/tokenslot-icon.png b/Chrome Extension/tokenslot-icon.png new file mode 100644 index 0000000..85b4cde Binary files /dev/null and b/Chrome Extension/tokenslot-icon.png differ diff --git a/Chrome Extension/verify-icon.png b/Chrome Extension/verify-icon.png new file mode 100644 index 0000000..31ce14a Binary files /dev/null and b/Chrome Extension/verify-icon.png differ diff --git a/Pockets Payment Button.md b/Pockets Payment Button.md new file mode 100644 index 0000000..a38e2ff --- /dev/null +++ b/Pockets Payment Button.md @@ -0,0 +1,58 @@ +Pockets Payment Button +====================== + +The Pockets Payment Button can be added to any web page and provides an interface with Tokenly Pockets that eliminates the need for users to copy and paste token addresses and amounts. + +Developers can define the following parameters: + +- Payment Button Style +- Payment Address +- Payment Label +- Payment Amount +- Tokens Accepted + +Payment Button Style currently has four options: blue (default), green, yellow, or icon (Pockets app icon) + +The `data-tokens` attribute is used to indicate which tokens are accepted. There are three options: a single token `data-tokens="TOKENLY"`, multiple tokens `data-tokens="TOKENLY,LTBCOIN,BTC"` or all tokens `data-tokens="all"` (this includes BTC). + +There are two ways to include the Pockets Payment Button on your web site... + + +Static Method +------------- + +The first method is to use the `.pockets-payment-button` class. This HTML method only works if your parameters are known upon initial page load. See example below. + +`` + + +Dynamic Method +-------------- + +In addition to the Static Method, you can also generate a Pockets Payment Button dynamically using Javascript. + +First, you must include two hidden tags within your page. The hidden tags are assigned the classes `pockets-url` and `pockets-image`. These are necessary to store the user's Tokenly Pockets extension url as well as the Tokenly Pockets icon. Below is an example of how this should look in the page source. + +``` + + +``` + +Available image classes are pockets-image-blue, pockets-image-yellow, pockets-image-green, and pockets-image-icon + +Next, to generate the payment button, you need only reference the information stored in the hidden tags created in the previous step. See the Javascript/jQuery example below which defines the Payment Button parameters and inserts a Pockets Payment Button into a tag with the id `#mydynamicpocketsbutton`. + +``` +var color = "yellow"; //Payment button style +var address = "1EUgmNoALra2YSCGcqdpLCNnGYAFQeLEp9"; //Payment address +var pocketsurl = $('.pockets-url').text(); //Pockets extension url +var pocketsimage = $('.pockets-image-'+color).text(); //Pockets icon +var tokensaccepted = "TOKENLY,LTBCOIN,BTC"; + +var paymentlabel = "Token Slot Demo"; +var label_encoded = encodeURIComponent(paymentlabel).replace(/[!'()*]/g, escape); //URI encode label and remove special characters + +var urlattributes = "?address="+address+"&label="+label_encoded+"&tokens="+tokensaccepted; + +$('#mydynamicpocketsbutton').html(""); +``` diff --git a/README.md b/README.md index e53bde5..289c09e 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,46 @@ +__[Help fund development with POCKETCHANGE](http://swapbot.tokenly.com/public/loon3/f769ae27-43c7-4fc9-93ab-126a1737930a)__ + +--- + # Tokenly Pockets Digital Token Wallet powered by Bitcoin +[![Join the chat at https://gitter.im/loon3/Tokenly-Pockets](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/loon3/Tokenly-Pockets?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + ## Release Notes v0.0.0 - Initial fork from LTB Companion v0.4.6 and re-branding v0.1.0 - Primary token is BTC with BTC price feed, Tokenly branding +v0.1.3 - Fix pin splash asset display bug, Exchange Rates app + +v0.1.4 - New payment button class, Exchange Rates update, Add option to disable Chain.so parsing + +v0.1.5 - Convert to standard BTC/USD exchange rate + +v0.1.6 - Payment page updates + +v0.1.7 - Show unconfirmed tx amounts, show pending new features + +v0.1.8 - Fund Development App + +v0.1.9 - Hide/Show passphrase input fields, added Swapbots to Exchange Rate app + +v0.1.10 - Add XCP and LTBCOIN to Exchange Rates app + +v0.1.11 - Import/Export Address Labels + +v0.1.12 - Blockr.io now used for BTC/USD rate + +v0.1.13 - Fixes mining fee bug when sending tokens + +v0.1.14 - Fixes BTC send Insufficient Funds bug + +v0.1.15 - Help button and overlay, BTC added to transaction history + +v0.2.0 - BVAM via Webtorrent, Glidera integration ## Features @@ -15,6 +48,6 @@ v0.1.0 - Primary token is BTC with BTC price feed, Tokenly branding - Passphrase interoperability with Counterwallet - Client-side passphrase encryption - Message signing -- Bitcoinaverage BTC/USD rate +- BTC/USD rate Please report all issues at https://github.com/Tokenly/Tokenly-Pockets/issues diff --git a/media/bank-icon.png b/media/bank-icon.png new file mode 100644 index 0000000..6686e91 Binary files /dev/null and b/media/bank-icon.png differ diff --git a/media/cashregister.png b/media/cashregister.png new file mode 100644 index 0000000..03ef202 Binary files /dev/null and b/media/cashregister.png differ diff --git a/media/crane.png b/media/crane.png new file mode 100644 index 0000000..ea1ecf7 Binary files /dev/null and b/media/crane.png differ diff --git a/media/expand-icon.png b/media/expand-icon.png new file mode 100644 index 0000000..61bfdc0 Binary files /dev/null and b/media/expand-icon.png differ diff --git a/media/network-icon-lg.png b/media/network-icon-lg.png new file mode 100644 index 0000000..25b4989 Binary files /dev/null and b/media/network-icon-lg.png differ diff --git a/media/ninja-icon.png b/media/ninja-icon.png new file mode 100644 index 0000000..3ee3df0 Binary files /dev/null and b/media/ninja-icon.png differ diff --git a/media/paywithpockets.psd b/media/paywithpockets.psd new file mode 100644 index 0000000..4575902 Binary files /dev/null and b/media/paywithpockets.psd differ diff --git a/media/pockets-128.ai b/media/pockets-128.ai new file mode 100644 index 0000000..0291006 --- /dev/null +++ b/media/pockets-128.ai @@ -0,0 +1,452 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[5 0 R 28 0 R 47 0 R 66 0 R 85 0 R 110 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + xmp.did:ED7F117407206811871FDAFCE368903A + uuid:18089431-cbe5-4643-992b-34f4e83d3d70 + xmp.did:ED7F117407206811871FDAFCE368903A + proof:pdf + + + + + saved + xmp.iid:ED7F117407206811871FDAFCE368903A + 2015-08-29T14:53:24-04:00 + Adobe Illustrator CS5.1 + / + + + + + + + EmbedByReference + + /Users/joelooney/Desktop/scripts/github-loon3/Tokenly-Pockets/Chrome Extension/pockets-128.png + + + + + + + application/pdf + + + Adobe Illustrator CS5.1 + 2015-08-29T14:53:23-04:00 + 2015-08-29T16:39:53-04:00 + 2015-08-29T16:39:53-04:00 + + + + 256 + 172 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgArAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8AhX5hLXz95l/7at9/1Evn V6b+7j/VH3OBP6ilS6RqTKGWzmZW3BEbkEH6Ms4496KKnPp15Agee3kiQniGdGUV60qcIkDyK09Y /wCcYFp+YGoH/tUzf9RNvmu7V/ux/W/QW3BzfT+aBy3Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7 FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq+IvzA/5T3zL/21b7/qJfOr0/8Adx/qj7nAn9Re9/k5 +cfmfzr5nutK1W1sobeGye6R7VJUcuksUYBMksgpSQ9s0+t0UMUAQTzcjHkMjRecfnB+a3mHW7zV /Kd1b2iadp+pTJDLEkonItZXjTkzSMm460UZnaPSRiBMXZH3teTITYRf/OMP/kwNQ/7ZMv8A1E2+ R7U/ux/W/QVwc309mgct2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2 KuxV2KuxV2KviL8wf+U98y/9tW+/6iXzq9P/AHcf6o+5wJ/UXoH/ADjD/wAp9f8A/bKm/wCom3zD 7V/ux/W/QWzB9TAPzC/5T7zL/wBtW9/6iXzM0/8Adx/qj7muf1Fn3/OMP/kwL/8A7ZM3/UTb5h9q f3Y/rfoLZg5vp7NA5bsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVd irsVdirsVeX+aP8AnHvyXrup32qpPeWN9fGSVxFIrwfWJSzGVkkVnNXapUSAdhTNhi7RyQAGxAaZ YQWB3H/OLmtJqESQ63BNppX99ceiy3AY12S3L+my9KkzDau21DljtWNfTv8Aj8cmvwD3o3Q/+cXX aG3bXdXWKdJ2NzFZAypLBReCo8qwmJ68+RKuOnSm8cnav80fNI0/eXp/kX8q/K3ktnl0sTT3biRf rlyyNKI5fSLRViSIMnKBWAYHia0pyNdfqNXPLz5N0MYizDMZm7FXYq7FXYq7FXYq7FXYq7FXYq7F XYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FWLfmN5h1TQtCt7nTHhjubi +tbT1bhQ8aLcScGYgvENq13cD3zI02MTlR7iWEzQeMr/AM5EeYDw5ahbCpQPTTXNAa8yP9K347U8 fbNp/Jse77f2NHjF0f8AzkPr5A56jbqfgqBprmlSef8Ax9j7Pbx9sf5Oj3fb+xfGKraf85AeY7m7 tbWO/t/UuXji/wCOdxCvI3E1L3ijiu29cB7PiATX2/sSMxe1+Qtcvdd8naVrF6EF3ewCWYRgqnIk j4QSfDxzVajGITMRyDfA2LT/AClk7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX Yq7FXYq7FXYq7FXYqwL85w58r2ISvM6tYBaKHNfWFKK1Fb5HMzRfWf6pa8vJ4H+W+m+a/PWuTaSm vzWTW9rLdCVw0oILRwutAyfaEg+7NxqZQwx4uG93GgDI1b0v/lQ3nbn6n+NX5/zeg9fsen/v3+Tb MD+UMf8AMbvCPe831+08zeW/zEt/LdxrMt+frFkJJQvwuJAoVTEzMGokhWhO+Z2Mwni4wK5tRsSq 3tflfzBN5f8AyP0rV4Y0lktraABJK8aSXCxkmhHQPXrmqy4+PUGPn+hviahaTN+dPmpLYXcuh+na EIwuWhmEXF6BW5l+O/IUy38lC64t2PinueqWGrwvoFpqt9JFaxzW0U88jsEiQyIrH4mOwq3c5r5Q 9RAbgdrRNnfWN7EZbO4iuYlYo0kLrIoZeqkqSKjwyJiRzSCr4FdirsVdirsVdirsVdirsVdirsVd irsVdirsVdirsVdirsVdirsVdirsVdirA/zlp/hmw5Up+l9PryBIp646hd/uzM0X1n+qWvLyfH+d K4T37zd/6zVov/Rr/wAnGzTYf8aPxciX92HifloqPMelFqcReW9ahiKeqvUL8R+jfNrl+k+5ojzf S+kaNf61+QWnaZp8Ylu7i1t/TQkKCEuVdjVio2VSeuaKcxHUknlf6HKAuDz5vJ35m3Xl7TfK7w3z S2d3LNcyyG4FtJA6xCKEOwCn0zCaBqKKihzN8bEJGe248mvhlVPd08uw6j5Lg0HVY3jSWxhtruNG AdWWNQwDKWFVYdQSPnmo8ThycQ73I4bFFF6BoFlodlJa2jSOJppbmaWZgzvLM3N2NAqip7AAZHJk MzZSBSZZWl2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KsT/MzQNX1 vy9Fb6Siy3tte214sTyejyFvJzKrJRuLGmxpmTpckYSuXKiGEwSNnzbrH5R+YtOY/WdN1G0UEAyG AXsC1anJprRnYKFIP93m8hrIy5EH7PvcU4yETeebfMGp+TbPyRNcaWmm25iWKSNLtrsshYhWjAd6 gg8v3XhkY4YxyHJ6r+Ffj4pMiRSp5X/KbzTLf2t7b6PqFx9XkjmHrJHpsZ40YUkuWZyOXhF+vYZd XCiCR9/3frWOMvpLyDol7oXk3SdIvuH1uzgEc3pnkvKpOxoK9c0eoyCczIci5UBQpP8AKWTsVdir sVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdiq0QxCQyhFErC jSADkQOxPXDarsCuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Ku xV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kux V2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV 2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV8yfnTbxN581+4Mdq8sLacqm7Yr8L2sh YKKqDUovftm+0R/dxG/X73Fy8ywEx0kZfR0g1NK+r8I9Nd6H1P2q/SczP9M1LVjp/urST6ZBNZft cATT+835V3xv+srLvyxjT/FmiM0VkskepWipJanlJxeG4ZgxBbqQK1PUZj6o+iXPkf0M8fMPq3Od cx2KuxV2KsO8q+eNU1rzJf6Rc6TJZxWSysblg/HklwYY0PJQOToPU/1SOuZOXAIxEgbv9TCMyTTM cxmbsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdir5e/Pon/FfmEb0+saT UVFP947j9nqfnm/7P+iP+d94cTNzKb/lZdfkzqOnaNoOp6Stz5luC0U0jwsVaQuzLVw1PsUyvVjP EmQPpZY+A0Oqa/mYn5KeXLfVdDOjJBr7WMhsnjhcqs0sTei3PlQUemV6Xx5kSv02mfANurzr8mnp 5n01KnfV7I05ADaC7/Z+0evUdPpGZut+g/1T+hqxc311nNuaxD81NWutJ8qSX1tJLG8TMzeg7ROw SCV6c13G6j+hzJ0kBKdFhkNB5jq/mPWdN0rTNTHmFryLVpQljFBqNy7uBL6UjBTDHyEbbN8QzPhi jIkcNV5D9bUZEDm93sWZ7K3djyZo0LE9SSozUS5uQFbArsVdirsVdirsVdirsVdirsVdirsVdirs VdirsVdirsVdirsVdirsVdirsVfLX5+f8pnr3X+90z9kEf7yS/t9R8u/0Z0HZ/8Adx/zvvcTNzLG Pyi/8mX5e/5il/4icyNZ/dS9zDH9QT//AJyM/wDJlTf8wlv/AMROU9m/3XxZZvqS/wDJv/lLNK6/ 8dWz/ZBH9zc/t9R8u/0ZPW/Qf6p/QjFzfXuc05qR+cfK8XmbRJNLlm9BJCSX4lxQoyEEBoz0c/tZ bhy+HK2Mo2Hn/wDyof1rbSrC51KtnoZlOnHjy2nl9Z+aKIm+30/eHM3+UKJIG8ubX4T1mCIQwRxA 1EahAT34ima4m25fgV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Ks E83flHo3mLU7jVfrtxZ3116XrKFhntnNuOMZeCeN1biPfufHMvDrJQFVYa5Ywd3nmqf848a1Cwks ZLDUAjcjIvrabdEVYkJwM9uD8XUp2HuDmw7Riedj7R+tqOEqGlf849eY7mkl+LKy5AAyXU02oXK/ CQSFj+rQUqagGvQe9ZT7RiOVn7P1lRhL0Hyv+S2kaLfWt/PqM93cWky3EUMUcFpa+qqlFYwwpUkK x6tmFl10pAiqv4lsjiAeiZhNrsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirs VdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsV dirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVd irsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdi rsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVSTzB508t+XruwtNXuz bT6mWW0AimkU+m0aMzvGjrGoadAWkKj4hviqD0v8zPI+q3GnW+naot1Nq6l9NWOKYiZUaZXKtwpR Daycqn4aCtOS1VZPirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVd irsVdirsVdirsVeQfn95i8qaDceXrrX/ACs/mN5xe22nSRylGt5pPQJ4LxakjhOSSD4kKfD1xViW mefPKHktBf6Z5MNvaaWk/wBQ9HULi5dTfxXTyj0mhfgrPoHxNyIQNz2+PFX0RbzCa3imAoJEVwPD kK4qqYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY qtf06rzpWvwVp9r2r3xVY/1Wp58K9606fF4/7L8cVVcVdirsVf/Z + + + + + + 1 + True + False + + 256.500488 + 147.397461 + Pixels + + + + + Governor + Governor + Regular + TrueType + Version 1.000 + False + governor.ttf + + + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + + + Document + + + + + + + + + + + + + + + + + + + + + + + + + endstream endobj 3 0 obj <> endobj 7 0 obj <>/Resources<>/Properties<>>>/TrimBox[0.0 0.0 128.0 128.0]/Type/Page>> endobj 8 0 obj <>/Resources<>/Properties<>>>/TrimBox[0.0 0.0 48.0 48.0]/Type/Page>> endobj 9 0 obj <>/Resources<>/Properties<>>>/TrimBox[0.0 0.0 16.0 16.0]/Type/Page>> endobj 10 0 obj <>/Resources<>/Properties<>>>/TrimBox[0.0 0.0 256.5 147.397]/Type/Page>> endobj 87 0 obj <>/Resources<>/Font<>/ProcSet[/PDF/Text]/Properties<>>>/TrimBox[0.0 0.0 160.0 48.0]/Type/Page>> endobj 122 0 obj <>stream +HwVu6PprqVr +2Pt.}`b.C4.#C2350T0370VH j53Rq, p 0̈́N endstream endobj 123 0 obj <> endobj 110 0 obj <> endobj 125 0 obj [/View/Design] endobj 126 0 obj <>>> endobj 124 0 obj <> endobj 127 0 obj <> endobj 128 0 obj <>stream +HWYlTUϹtZR0nPE,tA +-d. +eڙ.0P IJDP eGT@PC +A"Ԁ;Z {rg=QId_NH[mG-Hf;|2`qkhkl1(oNyΆw&䱇@ i3kj񭶧 ]W=UD7`6=З[-3F>y},v41uO#ctC>%ʧ[@.) +iS ɴF҇GC +UC%M}GdxP0yRzqI7L#bb%&% ;Ggq/Ov0.5DPZ#50͢ +l䀬Da~ZjeFHJsI<ٕA21A A*L$.$-e φ`-W̊v"e\_΀.SŘp9@fk@b ]8jǯ + + ܁>RHm@W9PR-`$ n),jT?,'zOaq&))8HɪRn^5ђ,VX`͟ ʳ-9fNQX1I16}WJ[FXRMOKo/Gzz@H8tX<1TFRdalUۖ;{zj6TղwX+UbsҡDZ)K>IR=  +L3Ƈv3CheeA.y?R:*qF`#Mg#s1Z"oQ","aVu`[۶üąnˡl:bGĠ#s-lܼdafV> endobj 114 0 obj <> endobj 129 0 obj <> endobj 130 0 obj <>stream +%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 15.0 %%AI8_CreatorVersion: 15.1.0 %%For: (Joe Looney) () %%Title: (pockets-128.ai) %%CreationDate: 8/29/15 4:39 PM %%Canvassize: 16383 %%BoundingBox: -387 -190 714 537 %%HiResBoundingBox: -386.4668 -189.2783 713.5 536.9688 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 11.0 %AI12_BuildNumber: 39 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: -231.5269 220.0005 24.9736 367.3979 %AI3_TemplateBox: 199.5 60.5 199.5 60.5 %AI3_TileBox: -481.2764 5.69922 252.7236 581.6992 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -347.5 376.5 2 930 612 18 1 0 39 165 0 0 0 1 1 0 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:0 0 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 131 0 obj <>stream +%%BoundingBox: -387 -190 714 537 %%HiResBoundingBox: -386.4668 -189.2783 713.5 536.9688 %AI7_Thumbnail: 128 88 8 %%BeginData: 3770 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45840629292F2929292F2929292F067EFD71FF7D2928290629282906 %29282906297EFD71FF7E062F29290629292906292929067EFD71FF7E0706 %292953295329532829280759FD71FF7E062F29FD06FFA9292F0684FD71FF %7E29062F7EA8A8FFA8A8532929297DFD71FF7E06292929017EFF7E012929 %2F067EFD71FF5929282906297EFF5929282906297DFD71FF84072F292F07 %7EFF84072F292F067EFD71FF7D29292906297EFF7D29292906297EFD71FF %7E062F2929067EFF7E062F2929067EFD71FF7D07062928077DFF7E070629 %280659FD71FF7E0129292F29545353062F29292984FD71FFA85A2F2F0629 %0107062F06532F7EA8FD74FFA9A95A537E547EA9A9FDFCFFFDFCFFFDFCFF %FD92FFA9A9A8A9A8A9A8A9A8A9A8A9A8A9A8FD71FFA9295A5354535A535A %537E53542F7EFD71FF7E53292F292F292F292F2953285353FD71FFA9537E %5354535A5354535A5354537EFD71FF7E535353292F2953292F29532F5353 %FD71FFA9532F0653535A535A535429292F7EFFFFFD057EA9FD69FF7E5329 %077EFD06FF53015353FFA8532F5329537EFD69FFA95353067EA8A9FFFF84 %A92929537EFFFF537EA8A92FA9FFFF7E7EA8FD64FF7E54292906072FFF84 %290629065353FFFF5329A8532F84FFFF7E53A8FD64FFA953532929065AFF %A9282F29292F7EFFFF2F297E5306A9FD69FF7E532829282953FFA8290629 %065353FFFF7E5353537EA8FD69FFA95353292F065AFFA9292F29292F7EFD %04FFA9FD6CFF7E532929062953FFA8290629065353FD71FFA92F542F5329 %2F5354292F2F53535AFD71FFA87E535329532F2F29532F53535A7EFD74FF %A9A97E7E535A5AA8A8FD7CFFA9FDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFC %FFFD3AFF542F532F5353532F532F532F5A2FA8FD71FF2F542F5329542F53 %2F532F53535484FD11FFA9FD5FFF532F292929282F2929282F292F2FA8FD %10FF7D537EFD5EFF537E53542F5453542F545354535AA8FD10FF842FA9FD %5EFF532F29292F2953292F292F062F2FA9FD06FFA8A9A8A9A8AFFD65FF53 %540653FD06FF7E29295484FD06FFA9597E537E59FD64FFA8532F2929FFA9 %FD04FF7E012F2FA8FD06FFA85459845953A8FD64FF5354292F2F53A8FF5A %2F292F2954A8FD07FF2F7EFF7E2FFD64FFAF542F29062906A8FF54062906 %2F2FA8FD06FFA85306A90653A8FD64FF5354FD0429A8FF53FD042954A8FD %07FF53537E5353FD65FF532929282906A9FF53062906292FA8FD06FFA8A9 %847E84A9FD65FF53542929292FA9FF53FD042954A8FD71FF535353292906 %7E7E2F062F29532FA8FD71FF7EFD045354292F2F542F545354A8FD72FFA9 %A87E7E2F532F53537E7EFD7AFFA8A9FDFCFFFDFCFFFDFCFFFDFCFFFDFCFF %FDFCFFFDFCFFFDFCFFFD49FFA8A8FD7EFF2752277D27FD7AFFA87D7D277D %7DFD7BFFA8FFA8A8A8FD7BFF52277D525227FD7AFF2727527D5227A8FDFC %FFFD0EFFFF %%EndData endstream endobj 132 0 obj <>stream +%AI12_CompressedDataxܽz8(Os$fIh0PLlyw$wF&7`y-iiuiInW.!E0.4aجl,[nŸ|]OD0ШH4͘U>*|dhgaV?g ќpaHG_D `4HGLO8Xٹϩ_<œt Vbl]buc3g0g +;hPuiN*'i4t Ed$Lk$3.զ2#̂aZ9oorЋ󷳴Fs+UfMk_4bXœ[FbP-h@%q|N Jb|]i@XMXʖePOHF8Gt2`f ͵,gC/fl9"hQ"s4 ]Rot'oxPyLUOĒ߁Gͨ^yvD7n jr<:{~iDsՐElTe5b:Օ[T1*=tgtϚvI\_'E-_j`G!\pЍt_x2d|3dcX"]x;` n.әݒ<Ln*J zIGIz L +7 9/zCf1F7쀹qv ؂G5ٮ ~bp:$(1 ?ȟzنo ++v$=Δ:ke` +/@dOYP+ +]ܞkסdo6Z/s& l 6SIY덠O:K얛: IЅѯG[$4b hm<7C/Sn#gg6C\?ۇʛqKtJ-f-͠Aj}?[f74VQ˞0RdžV=Aụ'۱u!|i?৿qsaˮ#3 "2RK9K*!:AͶc90̥D +T?҉"X& K N$H3gʁ ]J'"DOAΥc!VO ?%,1Y2Ѵ)sR FFjsB3x ? (=~滈i/5?+UHw`C<nU-$N‘SK,0%3 pg +x xPBYq7 Ǚ?"q3@+#w !0$8}~Ӊe`D2.g +K " 4?f? @EMF8A*G0UHw` H3@Sgt V"݅K8eq- K[ Wz I"gԩCw|; +hw>)&$+?3"ZCF֊{a.6@n% &ڛ-A#6AR'sv(#I>>`AQX9Z;!   ]%1:Ԃ36F? og蔤n6Q:x ?GB_Ť1Im(HG59|Ӿe4B[r +E-B38U7S`"XJKzCAǏ~X5\5Љz7یŘ@˶@gv;<X$創=$u;yV`62gXgw1Nzr1\ĊVZ}Rbp|l=2qlbI.C&c&, 0h =fˎh_9&u6= =*_б + $ڥ7?6P eJEhkK&ц׈x31t׍JYoffR6hS7Mf6k< vyt2[}-eVNV̍ LmXjŭ)}dmm󻃃l5!]'c2"ovC& _W+6 R@NDGjw^ bǝj +lS-M;;C퓉DLxE+ nXx+&̠G՘OurW a`j?5n^ 2rσo5CXTPhEȩad*"[B-8ZFSp=2o8k ,oQdу@ZoHE~呆T'ԛPMbܬac5ZlǴx6(y n3#J|CN;鰑ԺO> ʌ B +yHJ+'0{p8_jva12=#Dg(=\o-^B{Oκ4Gua=nz '[1x+ſe&ߏF<譄.7Y1JwxմF7Ȳ aihr|3. |{_`,`hjP |A%r ]o%z +&ApQaz95ϔn9pF ;ǻ2c@ +zMpJMpp6d@k/63 i2gcmsيZ +xkPs$S*_ \gNR| _]5x 'B5`S -\>>|ȕ:!8}(DݦtwuYS0 S{Ix9AMlLIb^IoۦV516ju sZ˝+F"CaC/}T*!"&XjlmS jvTns/Ȩ#ehu 57}p{D;/EVkmC|Pqɴb*x*,O79C]`$x^#Hy" roxp#bUw[r*- +4ݔW\E/9ۿ˼̕??K6 W)(+xpg~|QeAyWP>T6pɖFpoݣ{;_\=:OjW^&_@ =%u;(5z ,-|F_.wU*բα歀| +3.a-|\?5_25*(ÿK Eْ^l??px`*hO?$DhH݃p%Fs>&]CP@ ~"씿Q!,m-.k/xh,oy%hފJR"ςH{ xzzoE(Ezv߉LpDb +߮E:8bXL I( ^R n-?6;qn㌆& xV'T4 +^2C`8Rs$ HAuOP~N2(޵e="EVn\ARt z\/:QLj7PV\ +mGJ:ag/Sl==_ ds9,@15W y9j% +t@TJ'~I}e&7K[7IT0y{ӣO`#: ts,;^.0YÛHqU?Uȵ^j볩K,jcW,Qxpex ]D߮|[. @b"񐯜QGNٛ~!'WU[RTMjs@֯{"f/Hw.do3b|ǧR=s11~m1]dFnG0j`>в,Ml\k^w"yG6F{[|}=A$;Kr0}?3;{U}ϯڑA-\sO:70M={/sIu(-RA#{Û䥯3}YzAӮ۪>W19^fB2f0> e\;N/x +R9,PGJIjj"j6j$9bɢ@;o(IA$ EERliyCXN ;@k)?bDQOJTJ<sOn,LbG6 +Hw2RsURxP# {q)v_-, +vzϕ ٧Y)"rDb[JU= eu)*梃$g]H2ϥ{7tëP_rb CuYzI&9h :Wŏo'<B *0~Mn ÑJJ(o;(hz*Oɭ~yttrtUD霃?YxlTWy:ŀGˤLjaq{9{B+193$4_ Z.eU~]P_o>儎 +[Qe_Rð9͛gKao5$>T"Hbo'ߵ -U| ?I^Adºr:s4լL[-?>M% R|^md!+J he-+BZ+czEIex,DzsP& f%3qIk2DRl/̋#UF+]]ӠKr*KdhiAҗg+nF/S\B%uboT^ˆ+"zM^g^c + `I1V~`hJ]l'$Zi__oiN zO6S@z=~jԧϻi=P q0X$`ѫ;s{\|p 7CC" Ee +Б[׳](B !6ShХ/͔ʢ)l|U(cAU +1M4\"yEdlUֵe˞ x`T-R6EoHX񨟽n_8 EY#nl䦵 + Ϝ$He?=j+_ŀSŸdVq~@O.k |<{ 0/ NuJg}噴,+kCpaP U2g7j 4QYt ހTz]Ojtһj3@5:gaJb?B cD*VI`ފOwcwSPd&wޏJ8V Uɇ3N70 {4'?U"b +{(T`AWZySrt֓SnLwl\kA%,^M=~sXOxite_U3490{ߦkPɇ8 +!΢&AHU=%p>[*9Dm]Buz֚=2o^kF%!_%5W\֌jbB2o0Kt.\.C[rX]Ӭ=`F3'|bc\ M[x)YEcMb{r)Wl&M7f3G zsfD @\ fo]R~Z"Fk 5-kϰ;;:duҦL +-aeEv7u-3 _,YU)Ш~@|ΖT'ݝb"aM7L"ĖtiIشKh)Ϥ>G &o3ӊ}Z3x>[|d^1 +Kvj/H$MޭԟlA4m >¢KT+VPfLTb=w!MDn!ԾhCyyjj^kJq'z31_v9\Q ;OY`Ԛ?vfV% m"H}EzʼnJ=2?}qR,Liɉg$=WN?{Z9֠8),!Aglp5?ֹ^GPྩ ++ +[熁 Fsj)"L]n;5`vVmA~99 9sp73qK0Z?z9Z/5\W*Fh&O71_gc҃{z9ENk)&._" +aW8}r?ϑX; +^\8Gkޤ4[V7'+>%(gSesqW2?t_zzƂ});VuGzV]gw)Ιf;~4=# w{s'6^4/qfgVҎ׫x?U[ 5q XAaE"ME'=>KAc>vH)~ &~oiB,¬` v.;=Xj4ynH5Baף>VҾԋ.y7硼%CHmGZyWUH_/v*Cu%5֎ +L<|\4BJb7>oveDh{9oi0oa7#miwm7Z_HQs?T WH3C)oc >?>t~H^㪌{a}?]&E:hWHs.<`ٲ4}>s>4 5c~0/*TBJx}uHW [HC;f>@zjpJ@5cuC瑖^ZXFvuR#,Vjs$4UZoER#`YjH1 R]iFߦK?ْ4{ѐyARݥɊޅ{|h^SxI橬-xeNif(byZt5={6|p:4~?R^çE:(\ ÷ûIhXFoDh5쵍z@i W7CiȟFO.Ÿ5XU⨳i內ȥi(jKLy}{ȿO㡮Yh^ȡ6RhAbsl^v +2 )5dϞޫNXwpF\Ǡ7|B34Eo+/$(&jngUZ4xI| M?oH/l)0B?!R:"sA +E@;V5޻P Mߖz +c\FʝO鮄4!MjCW!R9h"N +cO/#=rqc0rP0v#tE̐Gbz$}լ=$L:^j Qv<4ghzrcͼmD30Lv)R74Khg2qMuufW*owjot+f$NVJgxAoXX\5Xxb:S1CAuc ( f?Yu rbj7֪-)v'p\+!M%Wx}BA]M. =pr?;T/ \qy9F동R皓̲e\r UcQC!#XtE -o -mDՑ鈂bzaD}andvwr+C$>aD+{qˮe!h2ҹUo۱ظm#]a(y +#Syfz5pI񉲟' brӘ߾qCWS%>"%$.2ZěZ ҬKgeHr MmJVRN)Y?|F34a^4jl'!.>%N0W*,panȾX4 _i +U4]VJ>pWuuhdpmA!?y[cOX14_4vOR< O;qhɆNҖeu4΀ėU^ 8*fpؐ2ڬ Gsφg(lȷB`·NBs"Ma p mV ±[Z1XF{,صEP,ʀ'v<}xJ`U+4]\Dg׉nd!]z'<]C'|2ؑ5ttG!+33SpQ5tA +:EQ5tHQQ5ttjcjtItj5ttJ\Cg^ASmH6xVaү32p)ۼc"V:Dfz-d۾jk;uvHm&vl\@Ű:[M>[Ex?Kk|fagV3b]9gw|.u)j%E-[detbhfKhZյvD ȻMWWAڜucYfk+mQf3cl:Wk?2Uӌjeݫ%av5'ۭв WH!kɎzzA:Cb7lă3]Rg76g5`#qYDך4 `mvrܯj>u|['V/窤qiq^F]*hYߣP`ռۮKV51!l +QLHAYUE12}(h{RS;Sz~ j}Lg;9_!Y؍lj u1bn|/S\,uuﺍ`OI4Z0 ˰vvϴqYEb-f7 ӗ0Xf-Və7,0 $è+?2lxIJGWX2'[:$\6|/]Tc{IOîTƞʱ&<lddvو}22.9%XWFƤKq +;t'#%32݌̲FFǚgd|0MوFFac#_;)L22vSs~DFFHśۣ32-G3, c1.o ,s;<0~\вC,A:&qk'Q 02JG sಾ̷9lqhm] OۯhӬƻ;lҊA$(U)SƜlP\ݶ]GYgkMqz8Xp'<̤n;N]g!Vĝ{GNx~>BV_k-~\R/!Ec^(d +%vlKכqY>QFWYܗ.ƨ٬mC*ގ VUXZm Z8Jm5V6IHniVCMؙϤŽ~;[HQ]7}7.ͤxiVaH=mz:66FZ}b {ߙU zIvKW{^;o'vR#vD]h3-fc-lpF0ceCU51Wc7ܜsu֒Nzퟅ{#mo4CڸqD`\eV.}O9k:(lp| (jTRdtz />?vj:)O9,䣋Ug_T&c:9W6W,ZTi--v7ޫuj֨cUr+v4Tng!Y `=6Ab_^m=<2a{j۝ʢbPP;IwL"(ۄce6ؗ@ìsH-AvvmamowtB`}vv钒AY!C@XNs6\$"&q}_`Y6ws^6 +u[1e}v|Rʆl#| MJ5`/b2*<9ϯs\"*:E|'nrS޾5CΰW񼼜hœԸ9)/j^Wsz6=k\5]]lV*dDS{y`[Or)|"f{++j:&g$oxPjW;>nbFQ ;|(SU{زz8?B-"ŪXi";f1!RockXTU~ҴN¸<4qt;(?ںjQ=i"iK`麪RkVzTm_塪 4$}J0v20F-@h]0l*c~ktLg$| ɍjo5WG_B bve^ڴ!1X-_}F7t+6Nʏs3x*#mcݳyԛFKNf S=aLUOuUBsaWXFGHک;i۞O9sFjKB2m$~DQFY 94"Ɲ2U2ެoX +h0 }Vwcb`vo6>4 T*Q̲gY\5HF;bA C*@]iZaQhu ʐ\h> +n xkbF3dp[hʘj VE{ y`Qپ7٘:)إ|Bd_ʧS~K4+Х|:YR>M?t)qWڽj}v*i;X ;{tyN e^?;gC~)YglNp6~WBy)'qa9{:nExNٽ^?[yˣ\?{ءzĽ~ڹog/܁K/;^?K$mQoS/ë̶Nyk)xHVۧ>c[Mw)3={#5^k{Ϭu{ERs~9أUv[t|K;u;&h~gz}|vsSgUWA[ǽ~F"~٩n;V 5U {^z{lyG'#o8>G>OoݩTc{ql'V?>z=^?s7Ǡ~{tVcWky Nqy=W:S ɍ|ps{[}ߎ;^?N9gk{t%-'$wK0>m~{Xvoө=^?X+l^?X;^?5Ŵ534|+ܞ3ogTol:>ګq{6;9Qf5x˱,\TO9u}V(pePT$02YTdnUhcYYioXyz*u#VmfzK[߷m `qSUHo7;yK%"QiEXW]w|\<qmͳgVԯ-ۼᾈjIooq΢Eޣ+,e[V NFMtY+cS;L#W|̜eo?Q{gess}"G SݯlKW@$_;P,TX`.\#(/9|__hCĿ狱k +Ibikp[cfj]j.1è3kuʊ9yi_14Q:.o*,Ժ\6 QnfS! ȶ-ߋk<@}Kaw:`1g!vhT%抭A\p;, auE``kh"?>9F9 + +_pk*+Ƃb5Z7iɐ{[ <n pKGHzV>L҃-=j/6|K"~C~QIj >&bx=߅_y7bF*UG+6ª%>7 ^Cjam12KO+CĒ "(vF6jz2CJeuVzyB}%+%6 }Ŭ:`pT̿PQQ|D')Uˆy_)=O&5`৘)΃IU8b'\9pcLkL/r~Q3Xt +HcĢ箄2~ 2U#~W~RRB:<;H?'B;y~U_/e2WǴґLyY~JKl/ZM@wq/op0 ӗEღ+bl +<]sVa\z( GAI$E Dn +Be *TuCCaBVd-4Hؑzճ4a%ЖfAo^HPY +,z@^" +bqE2Ta^o"mKL|.2EiqTRz~!5U}A#ĢB r{V C~@/ڎba j[LБɶ [jCOp:&࣊Xs{߅:-+KƤIFokUXWTѝTsV:Yp?-!a,yN-L<%z'< ؍Gj C/JEh A8/hɋBA_|;3[rU^,N +M@*!EzUi ; +5Mֻ +Ey#@Mf>( +\' xAF"O/p<`^o=.MjD3xG8(:P\]+cyԦgw/cv-I 0sמ1Z;R]͋}27 A $?!mxU!zbxmꯤǑ~ϿξTy H '\"ؽ"TfyYۋv$ށo779  cwG0ý+.R +v0TF//ÛKrK@ ^ʷʓ*DG +UEN7 DQn=E#TEr :~Y˥wNFR^}~nѺ1`F[_(@E3'h2 F֠;Rې5XnÆ1ي?ذbG9-n$>e4SLӓ#yl[s+/dDl.Ո,g :uX =}̏tuswUwS=? +Ջ݉CA{H-OVC> Dq"Gʾ=m{ҡ6ڣx08+d`FC"9`O?cvׯ']Z +|2bvh_8Шt"qbQ +JP/ʭ09%WeBq4YZ;kv?+]nf^)rτ˱+We^XF /M+_/Z6dl:\a/Hd; K{rYCzH0 \q։:ʅR }@*0{ׁ׌RcGUmCýx8p/wD<R#*Obh*&G-L\cm Jϧ^ɿcR^}lCb)fH\\Q~qdy|,v<@#Prwce$pMxEjJ9XMϏ."0vvU\Z9ǽ +|mAwϧ-݆>U.ʓ1+2p{bu0_c+JB`sGi7M n3כ*C"34r..xF /''^XI'M&MOUc&MXMk|GL=Q]L-D /|)t}iI1S~s `$\F!TчJ*1 4T "z00<; B[ @aB!vg#( e/ "6f#VTNQ T!ZmP"DsYZB .V\GoIiDF=@hx,"{yTA`$n[⣇2cQak<%hZr^'T[~ZG/f B!ȇlv=%(qUm.J+ُ;W[2]M^y/_S"Tm)DhR"Sb59ꄤ0!2\Q `*,u⌈k F0T+wէi.UR?xЛK +;/(ו1JTϴ_+T=Aıf"x)m}5VWdK[5{&^"-e)T2oI0"{pMX)~# O:>??%XU+|s7A?uܣu 8>J.+7Vx|11mkphĊ.y.oI +Vl2副׽H^< LѹՄ[^_m^ X 4O'~W".+ɘ'D+ybTa ++ULjʱ"gih IlBH~ 3,o˂*lCNjpD_:u<'OUi(%j@H QJRIT4۳1cl6mp{:{^twt;s-BU{eܹs8Y;˛g`ϼ~eϼ~ݠ s_Uwo vo S3vƤ{)ƳB(B6 Υzp Tu{H5],+v`W5` .:1o 9wɡGu[WH"* XCeg譫\62V71v&5lū,muɁ]e{߯M,&0Sty@,tzx|lF7t%?,TviG_@bi\ϱg?v08ڷ-~r M^7|;׍MooYmyۼm/̞!#[6Oopxꯗ?Т;Vؕm^ku>9O,xwo{7\ѻs\u9.;}yQ 1[>z1774!v8xrɻg֜1jw.r؟ՠY.5\Sպz;%E%hhڝPm @ + \ЅPm ݇w@@oQ%]WYiSw,Fם7ڼqՒVdֆ}j|󖩫%Em;c|Tѫ]ǵi3 WU]wfVGñƯ}9OP9G u%Ŭ@UfoYxh/ƺλ֙3[˖wՋN,} E7aSP,4q9=-5_g ޢis 8ccڙFc΋_-T]TX _v5>RsPcPgT=qVŶrۃӣ6g=kZZ.ZT֌uG!(uwU{r# vyzFGoSnt˦RQǙUHvwQ?G>D!(o{Y" vZ/Yv9:e7:ڢM&8&OLTl!gϱߊ V ;aLt}_C e3uGI֜m+\ys + ΣtzVUޓ +{.?|3+t_<jb84xLId듆]ftEQsxJi |Y?m1_ExbI*3KP_v-O, +?- +vFc_[dH*4JJ͕ B١rnb">{UFEv mU[%:ݺ#gڢOټz%J~bXj7j]wEHZm svk Y3j:+Ǘru3QD]tFu6.#@:эwP SaWpGtl٩;!Uisc+O4ٍ.wٱGy +s=s[_ r{2YUyeV`qv`e ]+:wx++^;I)OF/ڑcF Tqǖ-}kOw-r̝(طj͉{&o^4X6b!E߷XmDK} MϬ9z`4 ڵsÚpCڑb&܇z5VurzwlKOңu +5v +?m "/e (a"8 +3YA_ FvM4P{l͍=D/EF1&15}S|1b/PߝT"*HA""4H0E,IV@H`eqӲ}(˃,Yq$BQjlէXB$Raas,-% +8/aNc(4,6RէX0?I¨ XZ)XpNaF4+`EpI,scF˄ژ SQ,hR$Q!MSUUlQmfRp2~&tCGKCC).yĩ*EJ|4DikG.M}y4AV#RhJka*YC>LʒV zp2qZ5⩧)b_Wd<+ /~ E9 h5'JZ!' ΓF \Z| }R)Jh~ c#R'`S%@N4gbjtE#Eʃ:L%K n*v@A ǕvnN] l쬡"*w}RAcZT1Qʓ(MQ`<(`h!LCmZtU`$V&j< *SisTh(͕\C*묄2r*gK&RUaiRe(hauٰ$e, -H0$dVBmZ +IJay^DfrQ[qzfroӓӧn?9y <}l䩡9=t̑;o'M8~ඓM◫Ll{f'O _ >(&_صooL` oӄVHBȥҪ__Hh,W)AETLL 7no׆GKɯK #w|_=u$gzϻ0r;߰%腁ᇗ$gCypم,=!BҳH dpa(%xX?{`TiW%|SUWʡVr]>V>m>Q%:2J<cF* #\巿_7|Uv|y [}rbdx7%Yidd?~y~l5FgG X=$/o:# =3ddw|`5ހA bd33g(dl\5Z;@-PCCa!nV)`o`4n*JN쏺[7?u]+ozzXA_˺Fn&/2+GL|+cZUq 0ʓgu$Xc _'#F~WnO"@ B-И&Y~Ͻ/|ަ܏P(c"#Z?7>MV>q5i:jBKug稣_GYYԯыSm/VsVe{vZ9 Ug*VzXU*tNHiW9raiK>ab 0) ۉY-x9ҩFMt1z#EÇ׽JƄIaN$>_=WڞL| Q"+y`e_9QgG }OgqƽkY̿n}qItFcRix&#n?vAF̽)Ue)QͿ:Qn vU%yaPxq_v-n7%G?l|jcv=#v^y=?[edW]H6ef@Lz#`UZ٬?yE?lzZ+? ~D f7:#/"XY'AbWckaFub.l5[]{^r7 ۞uM}źGRku^[5׵?s^%m}l>۪6~^/&G^{OjZ yFrqxw·̓ggյmJ}08_B.<0# v$1qo ̨tDaݰhudwa̿ƄIa؎ߑ CW?[3rJGCk+}Ɏ1UTk-.<0# ҩΟY{O6>w/y]Yڋ:}w kͽoG럊7|w+cF{Ϛ_cߛ2*ejƟ ˿?dU@0iӴw>_,I_zfzA n:K>wgkMg^7;\\ڟq||`π2l5]^ v~m~aF&?~8N?~>_rkt|}|sj nڟ.Gk?MgޞW_/\ÌμvzR/g|t`hݓSkStn^ӝgd?4/9_-߿tv}olif1a?]?kݰmϝ?rٞCIS[3µO_OGaxKguO7C{ W{]y~>S?{:B0ߗ>vd?XџvA9_tzoߋ1S_V<}Vw['gw2}^}< =;|wWW]y {/Ӌi>mtȃA~}>m>.h۟ۿC/ͧO^Ϳ3˜0,_Zva^-,s~OWï_I\gw2 I:|O\#t|4ZiF0?~eh鶯 ̗cIA^hhc\MNثwۥtFta2+q.jh? #/pKP}bKx'X~#L]H bUQ|A`gTY 0Pa* #Խ> 7~-_d!_-_`lw=/Ado =>Jy_Ns(mZ8 +7ط=/p2NCR+0:yk0r;'?ө~w~UNB< `gّzN@}.N~nx[\FE( ean00{&k?:{>_ȷ7|MKض*'F&ZPmO=_zCGLҡF'_BPBP@6*)UGr0 5}0ڧl~q{DrݓG-Uh>"|o _´"%{`^=|C& _Bmd~ݯ {a ²7 ? S;2| u>_|mth+pnQ/z}MF(N< W{|| m㿣w zgC֥(,<1 +#/oϱ>>60 V>&ov,b`%O_yQzۓlG1dO-gڷh(]||#ܹzKS(4s>uq#aKq~h1Ç"5(* 08`c-+曟C?ٟ"(ٯ˟3}'~|[J/zۏ _70y,E(rn!G$@'P *| M3YBB>\]<ߡ;9Mnk d̕e;[s!ōyWKٟ2"YπzʩU)|@f~|O~O|#{p&N< $(G=Sn˛O+Q"=!\@ + :Ͻ)'֯|> !|Fv<#ҟ4m7Dϋ{={={={={={=;s|)շxor/{C-?z׻_=?o6?].Xu.޹몋337.y+޾? rw.o;rsֳqnҚ;ɇ?VuȇQ꧱o_6j/_l~yzߛZ7p_ԏ凟ZW%9,Z53}m}-} MϬ9z`4-P}4n>zpcUc9%]@6_'R(("Y4dQ5h4"~$Fш@8/:eA.i*\)CEYDI4"Ȳ"Y(pA, d浐ljDiA'I-AZyzrD%#RY$% 9m2 ,#Ry4>6\fT 9.E R,䴉r'2ǁk>|7MJ_@C>D/m!dG$21m\/@VXC"bhK#L@(m1"="C|%7J 1 *M#*"-$n(aN9'Hg8e" $JHP٥٪\tiph\Ґ +μ +Lq9)RY1T6%I[ővy!B.&) 1BE@*Tygzm(sPB-*T"hRJ"FUE}0PA$m#X9A +<AY"Jj +Pȅx'АO 򸤭,!|yt5銰d"u?d:OjiӐOݶQKBz*ٝ^@טdȰ҂V]֝@V-'AFs)O[D  +W4/iIUDa' Qjz @V&p ;DQBOrS悦%D +D +%dtBAf2)ȩ{B$*3Qj<4! +V0PKA&ꁓϕeR@en܏"6_Z +R]Y#Q +W`5,MUY4c RdWyqUu6Lo1/UTƒ12xDK1MJ(LrpzU \ 8>NV+A"UM& /8JTpٽA.,)*TȴBB"@Y6P +H(,2pU8BvJAR0/~LcSPOH3w#)iFˍ@Qo+XYJB@ח !5Y"2PӃFdV,XYCTCpRӷ̴H骁f+#Gq9ݔyR-Z9JuR7A EYif.. -wa}5Z1Jӄgq-ij¸\$Of!YMAFZXȳ8`Lk!GPpiV y{:#j 7'ӌqsܤrdU]<S#> iClW]L7 .(JNk`&Ӡ%gIn@Z#R7Bk>۝q#5'-~[HJn-x=Ue278l@sⵠ/Q˗yT2`vCӢd0HYtփV>>QlN`FuVւ;WjvK3`M)>_Raj'Y[T*rŜp5#``+ZkA+^I+5er@UJ8"1 8P[IrJڀZYűVűF}*ɄGLfnΕ`U/ +# !yӔOjZu>ʂQ4mkA+~ȇӌH#BAɇ-"5W@A1Tè"7:݌F$^ajEOd0IKp"UDN%@ ?aPb,R"CR +LLބ:9> q[Pͱ(CD *ȑ Vc:L3/ +R3>/2IC()BGLK${ΖVcɢ'l00,sr?t[9MAta"' +(^N 4C.7,n/\sjR+lS ꀿ fy +J*5:IYab4e̸WAo@$Q  iBI5(2%5#$0NܫGo#"Ŕola%^$AȜ)ߝ$Ɠd%fօ-!Vͅ.cO M%k +s]g**0uOUOw܇^՗8b=vԶZ/[<Mۭem2+횒/@A#7ꃙy*h (5:\@`jPJۏSvOUթk_gTruv=vq'ϲ2z9m@Gժ.`L* zZe +e@ӮЈVb_Q@k_GSէאh iĬHhzB-Tz>D:'XAA;a̠ENkIYafe=L~yWcXhN~Y@v^6W=E'[%Uyh<:+~z-JhĢ!4`Nj-O/@ ,-h!nOq洞GN +cjXVu>f!؆S0u AAa1߃@I~#U[L $Ujv6 + |$,K3ޗjǎ2抣߇@XF~/tP Y +0I_Ъ G`Z&mətČ0wBې7"cڠfԡ +j2>L*/GhUH$DMGΎF T;u- yEc> u6ìl<++|aVcQoK-vs'[YY,4VZKRY < >NJ,ʔ4aVVmlfq#TCvP+E;,6NX鴆%v?ra s4Nba-|y +mXcį{u=\ؔ}15)AQb|FiAOFjz֧Ʒ+tYCTx Ƀ_06Yߝ#R9ԞJt왖tU `ZQ=N)L]C)%ߴ0HS<< ǩv3 +Ԣ5ҹWY{@|$u O5 /|d|B:8εcԞ f| +nOf?r=d!,mGWV0 ˝c/4/1y|B `yHbFMނ%|C 3}̮OZ3QaB7Ps2"{kd4aV$]2wF|E +F,\@aV`ƱMY8iR9gfd}uXl.Rh71O0uciڻC>8JVEtK 僙k0rU)p(ڦ:^ê%ǧ%etlyU}-&mqs-A-x,*!cci,&*IniLٓcKU_kp =>Üv‰Fz1p_bƂOc^U1 +X̫u R<&zYMTի/M̷$]&U%D苬+5lė48Lp('.y EeK@3@ S1 #t¾a߃.Zj -IeJ7ijZՄyv^ӷRQJ"h$UV>1ҒFK&4~uqJ>[g+Qܥϕ_T|"ޤпu-3@:’mJB T6W?МgrzpoѢm'wLO=>9wL6&N0y +i<=srzqɻIhڭ?ɠh endstream endobj 120 0 obj <>stream +HWA ﯘsEJk(9$8#vj'.5EqǸǏ-OO>us-mnCV-/L^4Nyv'ǂ\v=;&Ǡv +ɖBmq}n)s 9^($Зʅ\C7 +\rӬ!ֲ6%-D"TxꞂ%vUC7 )_9 aMH_wAWN& lC^l!%Pq4)Y\kPd|"CbΥp}+Ql?ڦت v)hbm![f65v+/]f["Quf5HIm#$oKVOooeM#]սebf&Ϭ 9ŀ~/C܆rEl5rK*jVw@a3Όr U +W_j*Ak%+@|dltY|%ÉbopahQw8l^4bzEli˳ R>n׵/Ϯ>0&Cfңu>A ̚,Ika#A6L}:ս[qE=F՞vB?lgS)T"EYIPM}yhYD0"f<61CS6.˅@N@"&SrRK2tХLyEX"Fi%YH5-[JT K_C)X& r%^V +V{(}E8S(}*X{Z@Zf
    H%R凄BKRƒX0U>%$;KyZK$mR-m%Hl$2#3o Nā0^'xmI 찚=Hߚ@Z +FI%?^iǖ]&O݃O-.^5?w$;~x|Rī8:&ؠ`jbR ?v7 &6޷#㮬vyEgmKۮeD_UYдFcm"oRd]+&r+X4ZcN-ΓtQi1v_B_:[}.,N6n%Þ`J ݒ:_?h +l0gYN$`Fp c٪ TuC`պӦ((eVˬ6=-rnF8x-odwmZj]BoEYP}pm*D'sxehCifY#DU{aWRv|jQtٝ7-ZKJfy֗b\)VgVpR,ȗ֯1ur@jVePXa[%NL g 3EקV^8J(姵*K%#wQ?GA31j#e &mq;Ul:}MUϭI5ʚ0?}3Sٜ׾H/":r,.!rvtd /7wKg)oo mN8Q>eXzo꣒G}hɽu s6P̣N7Wm14't=\rݺ>gr:`kT`̾ss{DETiZ݁Zl_sߙ;y ^&{a.ٴ-]&YCS}pp, +"2TvbM ҄ S@o׷ft:G +})r@BUx>0`~W#рq]g+u5:FPͮUg i}1wÎ SVdթ8潺@'< ЍSy.*j$!ڠ ooO?n`䷚W endstream endobj 121 0 obj <> endobj 118 0 obj <>stream +HlOA +1 vWxZD|zЃpH$0!~٘. <宦`5=ݤY W63J!nR"g9i+fP2n7Dʬԥ!wH:`;ۗ1 endstream endobj 119 0 obj <> endobj 116 0 obj <>stream +HVɎ6+x655 ' "n-Z|*˧5_~} [$.9DMOXg _ "~8 VV_oo&1MZ-xQ(Yl1_D,m_? T5TXlBL%O) +̍).w~vݢhjP9>¾X#J q>o?Iˌ8 $%)|}q*uU*TY(Ϲ]IQR(ʕ jo]pb*Нߑg**r.k0΋!v"Y> |Q|1%:aTg}8),P GYTth#U +Hϕ?+3`5ᶤ:J-wR43!qV#tYQR\NF.(Ijr0䄹6#%h%0^6  JܳÓ^5] jyQ*ZKABA9Xz֧2-1?g}Ma;@|Ûw̸I򣞗n`y$;!ڙkP.0 |N=b~\ۄ`k+? ro;,2F f .̳ͩ Gvгq[L^1vmLIqN)H8XZ׼f)5aJ3FHZcN2/(&UB5_Ҳq5zrKw3e#!yJm##ӂrWx t?!Q:> endobj 112 0 obj <>stream +HW͎6 )|0ZQ"EMSP}Iɡ(3VmhRHzu}ן޿K e!e寕ֈ?Z)堲YǯM*eQۂ(ey\>-.P~B L bҚB˧wKP^|uO!R`=O+6㧐^󋄒_X5-rͷbk|ֵrȰX (`S d",QȜgfJT$ +`L,@gJ +:Sgžh!ՐTp؃ K'#A*o6"wEi~lz;,E U EUԵ'}-c M XNi- V5PA^0hd3kAnQqp*2,lDP(D+~jA#$#Aю( 1t$|wޠg0&ԷX +U8/]^P轔46^qrdFH;gg '%ِPHA-tOK6Et\.Uv,hڥ"}bV{w2ѭH_n~Odi_COuW:hvbJ(yOU:Q ^zGxcW>QfF" $ǃ0Sf);)ɛgg#!unMiBq ҍFεGN "I}bs:FNFz=ږ\K懠ҊBDK B]ѵQ촘PE(MPLZh5x"Xw}@ksH"ڜK} Þ^pl_ 3,ȇ_Ub`6%SUz?f3|L6/x M/H5Ηlȓk_LyCN̔C,N%'[z?4͇a7 endstream endobj 113 0 obj <> endobj 5 0 obj <> endobj 28 0 obj <> endobj 47 0 obj <> endobj 66 0 obj <> endobj 85 0 obj <> endobj 101 0 obj [/View/Design] endobj 102 0 obj <>>> endobj 78 0 obj [/View/Design] endobj 79 0 obj <>>> endobj 59 0 obj [/View/Design] endobj 60 0 obj <>>> endobj 40 0 obj [/View/Design] endobj 41 0 obj <>>> endobj 21 0 obj [/View/Design] endobj 22 0 obj <>>> endobj 111 0 obj [110 0 R] endobj 133 0 obj <> endobj xref 0 134 0000000004 65535 f +0000000016 00000 n +0000000218 00000 n +0000013919 00000 n +0000000006 00000 f +0000068731 00000 n +0000000011 00000 f +0000013996 00000 n +0000014328 00000 n +0000014662 00000 n +0000014984 00000 n +0000000012 00000 f +0000000013 00000 f +0000000014 00000 f +0000000015 00000 f +0000000016 00000 f +0000000017 00000 f +0000000018 00000 f +0000000019 00000 f +0000000020 00000 f +0000000023 00000 f +0000069553 00000 n +0000069584 00000 n +0000000024 00000 f +0000000025 00000 f +0000000026 00000 f +0000000027 00000 f +0000000029 00000 f +0000068801 00000 n +0000000030 00000 f +0000000031 00000 f +0000000032 00000 f +0000000033 00000 f +0000000034 00000 f +0000000035 00000 f +0000000036 00000 f +0000000037 00000 f +0000000038 00000 f +0000000039 00000 f +0000000042 00000 f +0000069437 00000 n +0000069468 00000 n +0000000043 00000 f +0000000044 00000 f +0000000045 00000 f +0000000046 00000 f +0000000048 00000 f +0000068872 00000 n +0000000049 00000 f +0000000050 00000 f +0000000051 00000 f +0000000052 00000 f +0000000053 00000 f +0000000054 00000 f +0000000055 00000 f +0000000056 00000 f +0000000057 00000 f +0000000058 00000 f +0000000061 00000 f +0000069321 00000 n +0000069352 00000 n +0000000062 00000 f +0000000063 00000 f +0000000064 00000 f +0000000065 00000 f +0000000067 00000 f +0000068943 00000 n +0000000068 00000 f +0000000069 00000 f +0000000070 00000 f +0000000071 00000 f +0000000072 00000 f +0000000073 00000 f +0000000074 00000 f +0000000075 00000 f +0000000076 00000 f +0000000077 00000 f +0000000080 00000 f +0000069205 00000 n +0000069236 00000 n +0000000081 00000 f +0000000082 00000 f +0000000083 00000 f +0000000084 00000 f +0000000000 00000 f +0000069014 00000 n +0000000000 00000 f +0000015331 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000069087 00000 n +0000069119 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000015942 00000 n +0000069669 00000 n +0000067458 00000 n +0000068665 00000 n +0000018576 00000 n +0000018462 00000 n +0000066414 00000 n +0000067392 00000 n +0000066131 00000 n +0000066348 00000 n +0000063960 00000 n +0000066065 00000 n +0000015700 00000 n +0000015876 00000 n +0000016134 00000 n +0000016016 00000 n +0000016048 00000 n +0000016388 00000 n +0000016636 00000 n +0000018652 00000 n +0000018830 00000 n +0000019869 00000 n +0000023842 00000 n +0000069696 00000 n +trailer <<0B696F7015E54117A71FD5D8C27A632F>]>> startxref 69822 %%EOF \ No newline at end of file diff --git a/media/pockets-48.png b/media/pockets-48.png new file mode 100644 index 0000000..92ff49c Binary files /dev/null and b/media/pockets-48.png differ diff --git a/media/tokenly-pockets-v2.ai b/media/tokenly-pockets-v2.ai new file mode 100644 index 0000000..8c1b1be --- /dev/null +++ b/media/tokenly-pockets-v2.ai @@ -0,0 +1,243 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[5 0 R 6 0 R 24 0 R 25 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + Adobe Illustrator CS5.1 + 2015-08-29T09:33:32-04:00 + 2015-08-29T10:30:49-04:00 + 2015-08-29T10:30:49-04:00 + + + + 124 + 256 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAB8AwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A5ZnYuudirsVdirsVdirs VdirsVdirsVdirsVdir6m/5xq/8AJdyf9tCf/iEec/2n/e/By8H0vVs1zc+Cr9Qt9cKoAUSuAB0A 5HOwjydcVDCrsVdirsVdirsVdirsVdirsVdirsVdir6s/wCccY0X8to2UUL3lwz+5+Ff1AZz3aX9 78HMw/S9QzXtrwnSP+cZ47nULm98w6kYoZppJI7GxAqEZyVDTSAgbdQE+nNvPtShUR83HGDvegaT +S/5aaYqiPRIbhx1kuy1wSfdZCyfcuYc9bll/E2DFEdE9TyX5ORQiaDpyqOii0gAH0BMp8ef84/N lwjuU7jyH5IuV4z+X9OkArStpBUV8DxqMI1GQfxH5rwDuY/qX5F/lhfA/wC4gWsh/wB2W0ssdNqf Z5FP+Fy6OvyjqxOKLC9a/wCcXNHk5Nousz2zdViu40nX5ck9Ej7jmVDtWX8QazgHQvOfMf5CfmLo 3KSKzXVbdf8Adtg3qNTt+6YJLX/VU5nYu0MUute9rlhkHn1xb3FtM8FxE8M8Z4yRSKVdT4FTQjMw EHk1KeFXYq7FXYqm+heUvM2vzCLRtMuL0k8S8SExqTt8choij3YjK8maEPqNJESeT2Pyd/zjJM/p 3Xmy+9Ndm/R1mQW+UkxFB7hAf9bNXm7U6QHxLfHB3vcdA8vaN5f0yPTNHtltLGIkpEpZt23JLMWZ ifEnNTkySmbkbLkAAckxyCXYqgdU17Q9JQPqmoW1gh3DXMyRV+XMiuThjlLkCUEgc2N3H5xfllA3 F/MFsTuP3YkkG3uisMvGiyn+EsfEj3q9n+a35cXZAi8xWS1/39KIf+TvDInSZR/CVGSPeyOy1HT7 6P1bG6iuoh/uyF1kX71JGUyiRzDIFEZFLsVS3V/LXl7WVC6tplrf0FFNxCkhH+qWBI+jLIZZR+kk IMQebEb78hvyuuyzDSDbu1atBPOnXwUuUH3Zkx7QzDqwOKKVy/8AONv5cu1VN9GP5VnUj/hkY5Md p5fJj4EUVa/848/ljCwMllcXIAoVluZQD7/uzGcie0cp6/YnwYsm0v8ALbyDpZBstBskcbiR4llc fJ5ObD78onqckucizEAOjI1RUUKgCquwUCgAyhk3irsVdir5m/ND88fOb65qug6XIuk2djdTWhmt yTcSehI0Zb1T9jlxr8ABHic32l0GPhEjuSLcXJlN0HkE9xPcTPNcSNNNIavLIxZmPiWO5zZAAcmh Twq7FVW2urm2lE1tK8Ey/ZkjYow+RWhwEA81fTn/ADjvdebtR8v3uqa3qdxe2ckog06O5cyEekP3 jh2q5BLBRv2OaHtIQjICIo9XLw2Ru9bzWtyA1PzBoWlSQR6pqNtYPc8vq4uZUh9ThTlx5la05DJw xylyBKCQERa31jdrytbiK4XryidXH/Ck5ExI5ptXwK08iRoXkYIg6sxoB9JxVItR8++SdNr9d12x hYdYzcRl/wDgFJb8Mujp8kuUSxMwOrD9Y/5yJ/LiwUi1nuNTkGwW2hZRX3af0hT5VzJh2blPPZgc 0XnPmf8A5ya8x3sbwaBYRaUjVAuZT9Ym+aghY1PzVszsXZcR9RtqlnPR67+SuoX2oflppF7fXEl1 dzm6aaeVi7sfrkwqWO+a3XREcpA5bfcG7EbizfMRsfFH5lRCL8wfMig1B1K6ffxeVmP686rSn91H 3BwJ/UWNZexdirsVVLeCa4njt4UMk0zLHEg6szGigfM4CaFq+4fKPl+Dy95Z03RYaFbGBI3YdGk6 yP8A7JyWzk82TjmZd7nxFCk3ytk+Rvz181nX/P8AdxxPystJ/wBBtwDtyjJ9ZvpkqK+AGdJoMPBj Hed3CyyuTz0Eggg0I6HM1rV/0hf/APLTL/wbf1yPCO5bU5bieahlkaQjpzYtT78IACqeFXYq7FX2 F+R0Qi/KvQVBrVJ3/wCDuZW/jnM68/vpfjo5uL6QzrMRsfF/5rxel+Y/mJa1reyPX/XPL+OdTpD+ 6j7nByfUWJ5kMHYq7FWf/kZoI1j8yNNDryg0/lfyilf7gfuz/wAjWTMPX5OHEfPZsxC5Pr3Oac1J fOmvr5f8qarrJIDWdu7w16GUjjEv+ykKjLcGPjmI97GRoW+H5HeR2kdizuSzMdySdyTnWOAtxV2K uxV2KuxV2Kvsb8llZfyv0AMKH0XND4GZyPwzmNd/fSc3F9IZtmK2Pjb844jF+ZvmBSa1uA//AAca t/HOn0R/dRcHL9RYZmUwdirsVe9f84saYDca/qjLuiQWsTU7OXeQV/2CZp+1p7RDkaccy+gs0zkv JP8AnJfVmtfIttYI1G1G8RZB4xwq0h/4cJmy7LheS+4NOc7Pl7N+4jsVdirsVdirsVdir7N/KL/y Wnl7/mFX/iRzl9Z/ey97nY/pDL8xmb49/PCJovzT15WoSXgbbwe2iYfgc6bQH9zH8dXCy/UWC5lt bsVdir6V/wCcXUUeU9WenxG/oT3oIUp+vNF2r9Y9zlYOT2fNW3vA/wDnKt3CeWEB+BjfMR7r9XA/ 4kc3HZP8Xw/S4+o6Pn/Ny4zsVdirsVdirsVdir7T/KyNI/y58uqgoDYwsfmy8j+JzltX/ey97nY/ pDKcx2b5F/PyN0/NbWWYbSC1Zfl9UiX9a50nZ5/cj4/e4Wb6i89zNa3Yq7FXvf8Azi1rMYm1zRXY CR1ivIF7kITHL93JM0/asPpl8HIwHmH0Dmmcl5f/AM5B+ULrXvJi3tlGZbzR5Dc+mu7NAy8ZgB4i it8gc2HZ2YQyUeUmrNGw+U86Fw3YqjdJ0bVdYvUsdLtJby7k+zDCpdqeJp0A7k7ZGcxEWTQSATyW appl/pWoXGnahA1te2rmOeF6VVh8qg+xGxxhMSFjkpFIXJIdirsVfbH5aRNH+XvltW6nTbVtvB4l Yfgc5XVH97L3lzofSGSZQzfJn/OQiOv5oX5YUDw2zKfEeio/WM6Ps7+5HxcPN9TzbM5qdirsVZL+ Xfmx/KnnDT9Z3NvE/p3iL1aCQcZBTuQDyHuBlGpw+JAxZQlRt9p2tzb3VtFdW0izW86LJDKhqrI4 qrA+BBzliCDRc9UIrsemBXmPmr/nHzyNrl5Je23raTcyktILQr6LMep9JwQv+wIGZ+LtHJAUd2qW EFLdM/5xk8lW8ivfX17egf7q5RxIfnxUv9zDLJdqZDyADEYA9N0Dyx5f8vWn1TRbCGxgNOQiX4nI 6F3NXc+7E5gZMspm5G24RA5POvz0/KseZNNOvaTFXXrBP3sSDe6gXfjQdZE6p4/Z8KZug1fAeGX0 n7GrLjvcc3y50zoHEaxV2Kvt38vf+UB8tf8AbKsv+oZM5TUf3kv6x+9z4fSE/wApZPlP/nI1WH5l SkggNaW5UnuKEbfSM6Hs3+6+Lh5vqeX5sGp2KuxV2KvavyR/OaHRI08teY5SullqaffNuLcsSTHJ /wAVk9D+z/q/Z1eu0XH648+rfiy1sX0hFLFNEksTrJFIAySIQysp3BBGxGaIinKXYq7FUNqWqabp lo95qN1FZ2sf2553WNB9LEDJRgZGgLKCaeO+eP8AnJPSLISWnlSD9I3Q+H6/OGS2U+KJ8Lyf8KPn mzwdmSO89mmecdHzvqOoXOo39xf3RU3N1I00xRFjUu5qxCIFUbnsM3UYiIoOKTaGySuxV9yeTRTy hoYHT9H2v/Jlc5PN9cveXPjyCcZUyfL/APzkta3I8+Q3JicW7WMKLMVPAsHkJUN0qK5v+zCPDrzc TPzeR5sml2KuxV2KuxVlXlD8zvOnlMCPSb9vqdamxnHqwGu5ojfYr3KEHMfNpceT6huzjkI5M8T/ AJyh83hKPpWnl9qsBMBXvt6h/XmH/JUO8tnjlKdW/wCcjPzHvkKW0lrpoP7VtByanznM33gZZDs3 EOdlic0nn2sa9retXP1nVr6e+n7PcSNIQPBeR+EewzNhjjEVEU1kk80Bk0OxV2Kr4YZp5VihRpZX PFI0BZmJ7ADc4CaV90eWrdrby5pVswIaGzt42DCjApEo3HY7ZyWU3InzdhHkmOQSsnt4LiF4biNZ oZBR4pFDKw8CpqDhBI5KwPzF+Rf5ca1zcad+jbhv93WDejT/AJ5UaH/hMy8evyx6372uWKJeYeYv +cYNcg5y6BqkN9GNxb3SmCX5Bl5ox+fHNhj7VifqFNMsB6PMfMPkHzl5eLfpjSLi2iXrccfUh/5H R84/+GzPx6jHP6S1GBHNj+XMXYq7FXYq7FXYqitO0vUtSuBbadaTXly3SG3jaVz/ALFATkZTERZN KBb0Ty9/zjz+YOq8JLyKHSLdt+V09ZKe0UfNq+zccwsnaOKPLdtjhkXp3l7/AJxo8n2XGTWbu41a UUrGD9WhP+xQmT/kpmBk7UmfpFNscA6vTND8q+W9Ci9PR9Nt7FT9poY1V2/1n+030nMDJllP6jbc Igck0ytLsVdirsVdiriAQQRUHYg4qxDzF+Uv5f6/ze90iGK5fc3VqPq8tf5iY+IY/wCsDmTj1mSH IsJY4l5h5i/5xd+3L5d1j/Utb9f+Z0Q/5l5sMfav84fJplg7nmPmL8pfzA0Dm97pE0tsm5urUfWI qfzEx8io/wBYDM/HrMc+RapY5BJdE8qeZdcl9LSNMub1gaMYo2KqR/M9OK/SctnmhD6iAxESeT0r y9/zjR5wvuMms3dvpMRpWMH6zMP9ihEf/JTMDJ2pAfSLbY4D1eneXv8AnHn8vtK4SXkU2r3C78rp 6R19oo+C09m5ZgZO0csuWzdHDEPRdO0vTNNtxbadaQ2VsvSG3jWJB/sUAGYUpmRsm2wCkTkUuxV2 KuxV2KuxV2KuxV2KuxV2KuxVwAHQU7/firsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsV dirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVd irsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdi rsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdir sVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirs VdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsV dirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVd irsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdi rsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdir sVdirsVdir//2Q== + + + + + + 1 + False + False + + 89.999512 + 90.000000 + Pixels + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + + + Document + + + application/pdf + + + proof:pdf + uuid:d53c994a-c4c2-fa40-af53-5ed9c49f8caf + uuid:15aba0f1-eae5-b344-901a-28bbedf4208f + + + + + + + + + + + + + + + + + + + + + + + + + endstream endobj 3 0 obj <> endobj 8 0 obj <>/Resources<>/Properties<>>>/Thumb 30 0 R/TrimBox[0.0 0.0 89.9995 90.0]/Type/Page>> endobj 27 0 obj <>stream +HTTKNA )woCPPB r)n S.]nozzy8._x츸 MTiOGx:N4T9yI +C䝛'Kx_/ o&>߉Ǐ DG Sډ4 ꔒA9 8FN# kIDa0O1fG16ԍЌ{!Y(`YwkmU>"e7~&Nh kԮ NTˀ9xsP/muaMZ(E 2Lu3 -Ռ8IxnuE+nJDY.20>eP\)PQ r +2q3߷Rd28v uwСHUW Iղ@ݫDJGa(9eb:jjoE 4#Ѷ,,Y 434mC_>綠4rUAߙꂷt{6X_P ++壨`[.uUtF"lfFi|R`\8)9sR>P'o#fM|M<:yՌ_H։#x\\%{r#'Z5 endstream endobj 30 0 obj <>stream +8;T+Q224C,?!U_Q^2=?)TGT;!N)0lp\IK8V.S!F:Mkh!=h!8p#Y6+nE!)MVkXT~> endstream endobj 31 0 obj [/Indexed/DeviceRGB 255 32 0 R] endobj 32 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 24 0 obj <> endobj 25 0 obj <> endobj 35 0 obj [/View/Design] endobj 36 0 obj <>>> endobj 33 0 obj [/View/Design] endobj 34 0 obj <>>> endobj 29 0 obj <> endobj 28 0 obj <> endobj 37 0 obj <> endobj 38 0 obj <>stream +%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 15.0 %%AI8_CreatorVersion: 15.1.0 %%For: (Joe Looney) () %%Title: (tokenly-pockets-v2.ai) %%CreationDate: 8/29/15 10:30 AM %%Canvassize: 16383 %%BoundingBox: 357 258 447 445 %%HiResBoundingBox: 357.833 258.5732 446.6592 444.166 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 11.0 %AI12_BuildNumber: 39 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 354.4165 355.6504 444.416 445.6504 %AI3_TemplateBox: 399.5 400.5 399.5 400.5 %AI3_TileBox: 111.416 44.6504 687.416 778.6504 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 2 %AI9_OpenToView: 284.5 454.75 4 930 632 18 1 0 6 154 0 0 0 1 1 0 1 1 0 1 %AI5_OpenViewLayers: 77 %%PageOrigin:0 0 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 39 0 obj <>stream +%%BoundingBox: 357 258 447 445 %%HiResBoundingBox: 357.833 258.5732 446.6592 444.166 %AI7_Thumbnail: 64 128 8 %%BeginData: 7644 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C452F292F292F292F292F292F292F292F292F292F292F292F292F292F %292F292F292F292F292F292F292F292F292F292F292F292F292F292F292F %2929A8FD04FF062929290629292906292929062929290629292906292929 %062929290629292906292929062929290629292906292929062929290629 %2929062928A9FD04FF29292F2929292F2929292F2929292F2929292F2929 %292F2929292F2929292F2929292F2929292F2929292F2929292F2929292F %2929292F2929292FA8FD04FF062906292829062928290629282906292829 %062928290629282906292829062928290629282906292829062928290629 %2829062928290629282906A9FD04FF53292F292F292F292F292F292F292F %292F292F292F292F292F292F292F292F292F292F292F292F292F292F292F %292F292F292F292F292F292F292FA8FD04FF292906292929062929290629 %292906292929062929290629292906292929062929290629292906292929 %0629292906292929062929290629292928FD05FF532929292F2929292F29 %29292F2929292F2929292F2929292F2929292F2929292F2929292F292929 %2F2929292F2929292F2929292F2929292F292FA8FD04FF29292829062906 %290129062906290607012906290629282906292829062928290629282906 %29282906292829062928290629282906292829062928A9FD04FF54292906 %2F295A5A847EA97EA984A87E7E535329290729292F292F292F292F292F29 %2F292F292F292F292F292F292F292F292F292F292F29292954FD05FF2F29 %2F7EA8FD0EFFA97E7E532F06290629062929290629292906292929062929 %2906292929062929290629062953A9FD06FF7EA8FD16FFA97E542929062F %2929292F2929292F2929292F2929292FFD04290729297EA9FD24FF7E5306 %2906290629062906292829062906290629062928547EFD2AFF7E7E535329 %2F292F2929292F292F295A7EA8A8FD30FFA9FFA8A87EA87EA884A9A8FD59 %FF7E7E53542F532953537E7EA9A8FD30FF847E292906FD07290629292F2F %7E7EFD23FFA984FD05FFA9A82F2906292829062929290629292906292829 %062953FD20FFA9532929FD05FF7E01FD04292F2929292F2929292F292929 %2F292906A9FD1CFFA884535329290654FD05FF7D07062928290629282906 %292829062928290629062FA8FD07FFA87E7EA8A8FFAFFFA9FFFFFFA9FFA8 %A97E7E5353282906290629282929FD05FF7E062F292F292F292F292F292F %292F292F292F29297EFD08FFA90629292F29532F542F532F54292F292907 %29292F292F292F292F0654FD05FF7E290629292906292929062929290629 %2929062929A9FD08FF2F2929290629062906290629062928290629292906 %292929062929292FFD05FFA92929292F2929292F2929292F2929292F2929 %065AFD08FFA829292F2929292F2929292F2929292F2929292F2929292F29 %29292F295AFD05FF7E290629062928290629282906292829062928297EFD %08FF7E062906292829062928290629282906292829062928290629282906 %2953FD05FFA9292F292F292F292F292F292F292F292F292929FD09FF2929 %292F292F292F292F292F292F292F292F292F292F292F292F292F297EFD05 %FF7E29282906292929062929290629292906290653FD08FF7E2928290629 %29290629292906292929062929290629292906292929062953FD05FFA929 %2F2929292F2929292F2929292FFD04297EFD08FF7E062F2929292F292929 %2F2929292F2929292F2929292F2929292F2929067EFD05FF842906292829 %06292829062928290629282906A9FD08FF29290629282906292829062928 %290629282906292829062928290629282953FD05FFA9292F292F292F292F %292F292F292F292F2954FD08FFA829292F292F292F292F292F292F292F29 %2F292F292F292F292F292F292F067EFD05FFA82906292929062929290629 %29290629292953FD08FF7E06290629292906292929062929290629292906 %292929062929290629292953FD06FF2929292F2929292F2929292F292929 %2F077EFD08FF53FD04292F2929292F2929292F2929292F2929292F292929 %2F2929292F297EFD05FFA829062906292829062928290629282906297EFD %07FFA9530629282906292829062928290629282906292829062928290629 %2829062959FD06FF2929292F292F292F292F292F292F292F29A9FD08FF29 %2F292F292F292F292F292F292F292F292F292F292F292F292F292F292F29 %7EFD05FFA82F06290629292906292929062929290629A8FD07FFA8290629 %292906292929062929290629292906292929062929290629292906297EFD %06FFFD05292F2929292F2929292F292929FD09FF2929292F2929292F2929 %292F2929292F2929292F2929292F2929292F292906A8FD05FFA92F062928 %29062928290629282906290629A8FD07FFA8292829062928290629282906 %292829062928290629282906292829062928297EFD06FF292F292F292F29 %2F292F292F292F292929A9FD08FF2929292F292F292F292F292F292F292F %292F292F292F292F292F292F292F06A9FD06FF2F06292929062929290629 %2929062928297EFD08FF5A06290629292906292929062928290629292906 %29292906292929062929297EFD06FF2929292F2929292F2929292F292929 %2F077EFD08FF84FD04292F2929292F292906FD04292F2929292F2929292F %2929292F07A8FD05FFA8530629062928290629282906292829062929FD09 %FF53290629062928290629062F7EA9292906292829062928290629282906 %297EFD06FF5329292F292F292F292F292F292F292F29297EFD09FF5A2906 %29292906292F84FFFFFFA9292F292F292F292F292F292F292F29A9FD06FF %53062906292929062929290629292906290653FD0AFFA87E5354537E84FD %06FF7E062929290629292906292929062984FD06FF2FFD04292F2929292F %2929292F2929292F29A9FD17FF7E062F2929292F2929292F292906A9FD06 %FF5301292829062928290629282906292829062929FD18FF530629282906 %292829062928297EFD06FF5329292F292F292F292F292F292F292F292F29 %2953FD17FFA92F292F292F292F292F292929AFFD06FF5406292929062929 %290629292906292929062928297EFD15FF84530629292906292929062928 %29A8FD06FF5329292F2929292F2929292F2929292F2929292F29297EFD12 %FFA953FD04292F2929292F2929292F29A9FD06FF7E062906292829062928 %2906292829062928290629062953FD0FFF7E530629062928290629282906 %2928290629A8FD06FF7E29292F292F292F292F292F292F292F292F292F29 %2F29292984FD0AFFA87E2929292F292F292F292F292F292F292F292F29A9 %FD06FF7E0629062929290629292906292929062929290629292906290629 %53847EA87E84595328290629062929290629292906292929062929290629 %A8FD06FF53FD04292F2929292F2929292F2929292F2929292F2929292F29 %290629292906FD04292F2929292F2929292F2929292F2929292F292929FD %07FF84292901290629282906292829062928290629282906292829062928 %2906292829062928290629282906292829062928290629062901292854A8 %FD08FFA87E532F2929292F292F292F292F292F292F292F292F292F292F29 %2F292F292F292F292F292F292F292F292F292F29290729297E84FD0EFFA8 %84532F062906290629292906292929062929290629292906292929062929 %29062929290629292906290629297EA8FD15FFA953532929062F2929292F %2929292F2929292F2929292F2929292F2929292F29292829072F5384A9FD %1AFFA8A95953062906290629282906292829062928290629282906292829 %0629062F53A8A8FD22FF7E5A29290729292F292F292F292F292F292F292F %292929547EA9FD29FF7E7E292901292829062929290629062928547EA9FD %2FFFA87E2F2F072928290729297E84FD36FFA87E5329297EA8FDFCFFFDFC %FFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFC %FFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFD62FFFF %%EndData endstream endobj 40 0 obj <>stream +%AI12_CompressedDataxܽg8(|:^C$J +bJ1?dFsv,H4i4SΌ7CFŒ~CǍWryin7B4$|fMmvss_R~?f;_~`n0Pz1/daT`n7D11Bqi^v6h yB4 {¡aV~3:FoFn,7.n<r1@P/)0`o!Jd}~0__!_}m@39\_~: Ab֋YGNMhbž,Xz] 3 !!G/0&.b1H/m Z@ p4G"Q @C9C o0̓aIo 1l'D!O4h)3Y90 +NAPR榅"0`_A8}_4p#050Uz>l""= 4O/tz,!s*J`,ǹ +~`5fTkD<*қq=lhh҃hfrS0S`uoh</Sי_ 뿨fj-mD[MP[@0 +j"A{`?ZwC <;| 6ђj4H|=j cc6R~F `$0.cnuc@vz5bl@ }(ḿJ&j 03v: Gbh} ~?7/iNX>3cEN݀ ^F<& F/? 0MbK(Pwou GSmdenpN2(QsfG0`?gHplrcoƀ|T/B_l1VcOCMo{\ng җ`y`ČGSxg>fhz ׃A/5C'}ߤBBh3l b Jvԅ KybuIcv7mw]*w1OzKcpa3 "sH0&4zVql\I.8AN"Ǿ翦w 13tf.f_S&{?_F2;V~%RmIϿq̣rO:__߄j蟹ĝ?ܞw>Vz6D`R wĂ1PGoQeSI(])L/po_z |f}>#P˃0Rf 7ap(`_ُ>l"0SszW\n64<@p4=7a/ҥ"Mq +EcQJ,RJ}|1!'RZZ|71@ط 9#1=in¨CLH$B't$G-GG jYϠ,gdGO'#7cX=췇>eκnFPol[6r 4+ >sv#yX.erOٞ#𰥤8/5Flv0CqTU +/ +ٕ POt(TL;/.5[å#mU$&</mn%,rꂧ*hX%'92x`(QR/EP[aah6ձ0P;Pn´xS bdۘ[ηnPO&;ME%9P!b]{Ps @cDY).؈u9{pkF̮#~Kv@ێbaaS$G9< p(5:hc +qvZ.,֠+ρe:UGT3Oz<).Fjȼ2ؖ7K|CpGe؈o#q9d}=GJ-a6#oCʇ9뾆* +vI2c|/R8v{>yx5W (f/(6yj."[zQ$'abg*|[!Ynx)('e3D6 F`-+iFHM{otk!2ls(.M=-0,ar`$KPةd忠Py`aϑa 0tgNE +焬`<]s`06Oًsiyu5V0% `B(,-JUb l"=a/ X&0" I2ŘY=(bn7C +qWH_9wQo^x9AMtLI^Io۪5Q6ju uZ kH\@F +%8dMQ'H6mK?RjDS`t; +vVǾ[̷C0 }dZ ?j6r!uuZ7j^5L&Î2- mp~Fhg!f$ ~ixmjLikO/: (6ڭՆ0Mv=\데dqԈ T(4` pTq-Xr-Df%/% EQ4Y2ӯ>v6 T$lUQjILݚ}Y PRT8KeL޳; TM-=Fb3A*e % +K&BwsZhlu]R +yZGs:ZVkyIZa;˴h +5hM-46ɶCShaJfp_ Rixv F jRq;h#RCS?h".[_:۩P 6'Un4Z vɝGɋY`Iq}l7#=զh‘S8ɖU!lCJ64j4VhI{xc/#SoffR-c(gl1OZni:slPn}<-`&h 664괆  ee#hBk"cUo+#&Mq}0Z=ɘ9>"SA\~6nʨa35Nd.%v[KpP(4!=`w yzu= 97Z|3/ n늷$=zcDzF-xV\0`<m1 +t| >T>51踞wUw6MWtmz"M.57xvR!lߊJ!^Va! J .6ykK^%(h>;- Sc*_$OZ> ]զ<63g*l>m; x&g󴔑_Jw3H[q<1X~|#ezىO}ny}ʿ䃵]z|?MYw6pL:`؜(j͂D2c 9/og:g}#sj=gh¤"!O [JEb0ʽHmŌ[sIsv`^?T$9G?4! (v|5S*,kee佃irK>!(B o3E&Ovis`npR?0gK$a X@߁/>}6跐)#RC0eg~}- lxY:oj.[OW|jdf!{x^lv?7 {eJ& `;7hwd>~fh}02Jt4I(сm@5ʩK}lyL $dpnb=\)O,7 wnEhBH6쮶J-B~oٟx][Lsֹ Yk_wٰ7"e!Z/lg4[*삄3)B |~*5 M1~we8͝ņhJ" qU3Rsd5RM`Oˆe@WNw'Mb5G9mK~nߦy.w*̉оfm`LڣSq"o0[V[,7;ϿY|@>tGL|b,N;_e?&7ҧpB[f.}4O9 +%!&>UuÍB6$7<; oC8':\h)]pMXP72|BPK]bͲ`SPoyȑg9a5ȾZ& p_}*?Dـg ǒ?.EZr3S}{V'ÜBG +p/bv~ `R|qazM |rۛa,L_` +NJHbL;_ߨPL1Sm:(@EP/̹٧):s]TMCǠ]Mىx$4=|pL>=<rV[Erz?Q)ZKkɼ4Z,7wDdqֈֳ,-̮J kc6Xx$4={ + A<$w#&#͖Cv&|2ij z\iD: Wm߸k$ٷfptr[ۯλ٘A|IFɝ sbZWL3wH8 AGՋu^ +n&nQ +9 D^>47zby}Q Xnmy4?U1D>W23Ƚ1MPL셑mW Q`]q5ȆZOQfM' ֋.|c7Ur?~ب&@:'r6nd|O+dېqï}dIL- 1AJ+8 \m^u`L/jzܢGVQL x"$>VIʐn!74Q`I|m>>Q*iz_yye!;'aȼ2c p{ɵ$^Ц`6$1Exy[ḿp-%rH0IMI{܆cuq#Cp^ U7m22x9nq˛YҖݱLkľwj'g쇶6u3Y(&f\B_?΃N=ԯ /$G,7MLb؎u*jwt&|"& m-7k;5}V1M^zuV׮fM>,ne鎗m"= +@쌅l  `AxX;|42- +YB* |b1QD5;Q}fGnƂ*o)Q+c*;TKptڅtz7?{~,d!z8L[㇕0eS6i'6QVydꄞ4 +~v}/i6ٟ\L3s7*8zy׌1@笔@^s؝\O_?ͤ9R{wma^2̡* EߡP5!y +Xs?T#m_~>O !t%z8yP$k"Vc1<;@q󗮣EXY8c`9]` 5wQ@mocoش |dг{zl}?)4[՗ӓ6$R/<$Y˓}WϿ±HzlES5GEF"Y7*jp6 +^>:ʵ1'W+/ ԣj +]ēU~֩)쁎TRLl\f)9wOAP6 9Ϛ.C 7\|b1bRZ~CawR.Q5F@eB ,Q~5eEʿ{ +9o%$buD!EDKL˧PS]5|`oSCx=՜V`!?1(72RNpvM,K.HY3#,羟QF6㮣όZw5'ר08kH+=Z=.gs0nH1Fp| o@[~A(]00.-s tw`yL$a;m&xX/`f=[MfѲ~ў& DK6a&yћp½\ߝ۬('q q>i%gA9]@ Q`T>ΊD̬k,&t)5XɌp/P +4oW迊|F @ +rսa<*s-"xtی&3>e*6D7wBކƓtX +/jTͬ5+rxߐ{vr&2?xB>Ċ~?;I)y_L@ZəZ$M5Gy7LJ'or?)g +\~|~h ~1 +>3Xh:u?̸/O.-%rlw"Nv}~sd"kK +48\ޣuGMΑGL8dK}á]ulyS[{r FBup\zBSc{a%M-ֽ%w>4Ȫ0%nу3U4,<h1N'kq w4ؽ_Z- vfeR0/_lI@+AxMJHtl#}oe!5X$hw^8z[H31V,Jd94l]{AN^)1XoߔEZ,)`aA@ +Kbצ?2Dk?U[7FJ_e#oj V-BjHB}kn* M']CjY rckgQuy9{vUCL,)JKXf="4 dM Y/W RVf@RJH)j~K,-2lZX]M42 !-|.HQ~ R`aZZFهRPHBoGTU81ZвH@Di|JB, ڏ |lr#"EHԋɎh)y嘵e3<"m[w %JHĻ'16Y_Eq2AyU֤h1wcSDz9H&MD|[LVA* +6 i>5xx+#Z~m#8"p+'IJ^.89V[Y&q=:SKD!9vqo7r9]Z(כ}S'#+Ti֣~Q~ъT +Y*P9w9VǷ/S̈4w<Q}[U~<-OCN巿Ӟ-Qy:QŎJ) ɛ +|X0K*Q~Z'T(nMw\{ڧOo+t(|&?_ ;zLyŷD?ݪfw59gkVo\ΛFhFݦT{k|c n5l%kMhHn7~}:;n i"Gqv⹏. +;R >EI8*rH5ܝH%"R`oH7'c CϔCZ\H&;4ظ[ 1;3BZ;kN`Ӏihf=|,_HoȁGy,4l÷n_) mXn,(!#<'KRF +1+§.5^+ oG<`Z"SM0d9^VDTtx?+vr~t\؟ۑ]}6J~ 5dwf7SY"7\!`LhI=[I#ـ#B' c9hi$.g3*oX/xĆY#HtϠ|ra|LF# &<(њ?d0yp}qHf|;'.7CN!,([b+J9+ѱrS|c<K"z +)Xacglt]|9XCG7-F[DI}~ƠD-q~ҶR9}L,v)FIW0&]ίYe!̟Agm +/f9}x/%V}5fhy gL Wr20]okR,pX9r\%bln؟팥CѠUcn[~UNKbOU=QY +<-gR͝;:5tc+d<޺PRG4EtEb[fw]!WEUBkuV1H|C$ȍA|i?rXovӽ^liXϣsZ"B ԯ󇕻$'N, Q.3>%jV.!:GFr-6OsK:BbbPQXQYO:3N!Wd(%K,ml{vҔKBd$^gqۭ\o39OR]>d%Il7[ŎHղRx`Qp>8]ʳ H,3>OhcX 3O<k8HؔJLi>iM +tiX/ڴ>+ICժ#Ė◯X*9f]H,ڲVc@RSpi2 hg +h]Y:m>):%Ne*W7U{|9Bt:*).j;*ӳ^t[!28}B©;JO%w +]h@9(= w*J&T%}8IMG}*NZ*Ž 0buCKJIXKH4/*Zc~K41$v ^E^U/9DDj-ۙM]AA("cpNh'.r&GƷ^^}y[@,k]\ (%bG8 R#I.?DT6UC)iC Ǽz|9 F: O6T?M.m8|La8{fĺL-('i1< +Ѕgtǵdt!sBU6lkCu]PL 2ڰ8.XJ}ZEtu%N"3ܰR"e-Jamcu`3 RvmEldNr.;&sw2ポR1YMMZ$`.4[}5k w*A@vx{Ӷɻ7z=!tœL Sp."P01d;}eK_.qˋY첀Q{lc1XdݻCǹOX^r:jCs3ȡC*dб69tt([ +9trH :8ڤl/7L㯶ˇ&sdO(I \a`ͼ:ЬnN8%AJ!<i:dQ+ӑ羾᰽$,#3uO^543Re ^ '#-]eqr>=$ẆCrw|8UurG/vޙH9&]Lr/^ݠaB1<ݜ8:C\|E̹8O\y9"QĻHQrn:sw{~)}PE+£BD2lIYXާG8⮋!",³WDH;8^uhaܶ\ Sʦ4/U2R}7H`~I3#upCHQ7WHm_)#}U2RGX  \-: >d$!Y2@\7uR-%ÝwG#ܻOKJuR8OS+ +Uj*[4NgKsO7Ciyj^;6]ePWXD^I 5&XUUz)%YgP kɲ3' +d&wg=)VsS446dr9y'0S;/'P +1d͝bq!u&Wa3,T.]%nwCeM^HaQrX-+J`i4 Pʰ ڻHy32F!WRޙj.naxi%;SQCZ!e3[ʤ@ٔr7EJ8;x%H~Iaք6 +f vO/L:HLQ.Jc;Ґ<(WIKMl}O:ޤZǪf%>U+Ա$4mS(vr6ŮM'Kj6ܺ\)N4u4rFM'%^/Ϧ˥;K8Nn5˳䈁_'N.N"v)KJn;'^ݤ%k G1psuqZ:9GӺ8^j=>zuzd>:iRP_Sht ;URKpB,.$ եrSE#K="T_/ vv;bN6ɥeQ"2wjղBwc2wOYN|2*twir(2wr&)\PՕRzY78⯲TY":_1p(kt?>yhv +'$:y~9u5J2Iɀ}xhdJ{;vx!2i*l'ױZm(:xN?^[]4vPPiƱf{q\ٍ\Z:7ruz8AytIKci^V@L;Ġƒ=%pN_W̑TMdW13282q= -3Sz֩10]eU0-Z$dz:߮\Gx9*uYUd[&E^̹GΩ\*NȯlsJq3Qͭz>I%Eo9YZWso5Ouchɱukܷ%ֶj=y?4}ZE:Z>6<@QvX.Oy#Tљާ!M5eПdP,$6t$1i鼜_ +Su 8}$&YWlO+WGoAo.:WLCuKs\G3N5 Jy+ؕ쌜,͚pZ9S^MsՋaUuIz{HwiG޳F`ÓiJ&s‡`Z_ꏛ&G3jlns?Dx;x7 s\t eNNٔEk^̝v9نST+32J"k+t$J=ESHiHwȕ4 >|*E_xA74c?pQ>N:(߱gOS](N㬾(zZEsFYOz?SOqJ*3ͻ.u7u]n(պ~' uf]?~SϨ'7k %.Sͯ{6յ,HdɱiFřXƳp^yf% +/A +i>P'ʑQxC4?dhY3U-~扯{:Dѽ&u!N4һWmC|3oO=M-*oY?bXLݮi/y_ߍx4r;d͚zMRa'_/4ς;RS$aڛDϿRG̲dzKe\_E% a5ɠJd%"]ԙC m(75zmQ&)7^7Fy$ +?^zIY%IoPcLrLQE`mS>UiwL6>? XRfr{zl)XkҌY0ن(jSe3H[Ooxk-06)^VJV^&J6Xo AN_]לzx^g)|Zln>o*hEm=;GB/])|ziA ][d!{|-v^( qVJ9 {-`>>'iǟ: We~b5ɇN0!k\l~aFI*#r7wC!Uw_Ս hS־ki>\O3^^V3S +FslX-?[vNH6J,d%x7;f gW-~c7anA. 8/L#yix<A+<0KZ*lC}.b-gF:\9˖2p!^"4|~`jµM>E{0xDj`닛A_U/OU}/2+̊u7Aco.>lǠD&|1Xɗ8Թ@Z&|ހ62Lr\o+dČ;e*)%ާ "~[z7LL`",؄"5H +Hss:M}WɜNL3O^wudL_<1}NG U_󓻭9`ࣾBNiA"~+s{]Ce Wa.Vk/2 +}af#ǤF?cbts{4.&IDdhS^}c qaxBKd)HSFKz:^مZ(oƛ?;2e9>? 2+}=K4zto}pM{ W;左n3kYj *F/Mo^. VO}|3CtdežG[-$~?zvM@{ao";i۟xm Ͽ|Ӣ׆AHF֓rx*VɪzR6};z|;Y +؊QGvJz,:>\g"ϊ!kO;'2wi >o׊joL| ,)[zK͇`$d9W[t:έa׻ąs+"_NOG^qɊ4~z:$d}p1",z"eb 3JDXcstŝzNgON8x6Nw؅Xձ3_ؚu`Goq|q#0/[`*Q-O&Xy$b G "51 >ue0 @aI9"Pm(Lr$C!œQIHs B jD%É0VW<#bJ 0nTe=@1f^@ 3$*UA":fHA _)f)t~L?S!<+1҆婫q._+al8_ Ά cB +BKx/`]/a*cQ! +)T.-R1KЭ-d3%mTFeyT2+59BV#;R[p9~(/wb& ydv L\i +9lnLDoH^^`c?P(-aZ[r_67f(YjzIJ%|TĎedb#H;0sL̹L,-r2o e(Fށeds.V|@vvr:9#eZZg3j$ʒHeٓ*ЅB. +ثJFU/ KYo>&1}z(M@~sҌ2$nY ˷E%O*Y~xn_ kS(OXHT38fˌt|6B߾  Ұʤ[˲CG;c=*>p>l';Ʉa.-wApz>,K^؃)gRL+~,UW4uG(6c#|E_> |ܧ5:b?ބ-aO%"-MXbF3wɁ2Vrِ-懤B] #{cA} уd`VnzX"B<gcy"UOaoL +8A3%G\o-#Ovy&}%7 c8/@aKe?)C$![?,)JϧeHGm=ސ4E5谢{c4rPmƔň/J\l/Y_P2Ċ~?On:@Q"ɤ f<19LʛDŏN,(^'&cTaƵ}yJ?vh)`@w$3#4Ƿc:nec^2,Ծ]Brٽ :ne҄ϽAǭ ˥2踕A&}/[׸EAV{t8{tݽ eq+o/[pgˠV{t(v :ne`n^20ˠVXX{tF/Aǭ 'cwu]dav-B6ګG'*wnQ(|xwxKV4}R}u)A;rУlR[{.51 ⎳@\֙Mf7nzAIh)8e%N&G|ntAEX8^DSI :{/YȄR8@Wo}qb)ˁtkWvOXl &fäX ĤMӠEN[$2*ut\EpY,4`FޣNJU(;K ';qD%s}E + V†?qjK&B…QHF.LF@n)($Vw&Ŀ{k ;moe-/Ca[&‚?;{ a 4 nusygNJ+*`: EVP va >P5jBap;|tݘ 92[8jكq/,ci7:9wZ4aZC> +._LLdk7\0w"E- 8w>Fq7Y$RH sZ;"lar`v'eH,p'_X]@~iP6t.Pgd%o$fF(}vcymzz@1OJ1o}6a}<íǾn6KAzod77\ݮ5͇KJo ⬮5"΍|emB4 ^bDgv($}vf9'K= 7XYZ|[/JujW|DU܋~jmX/Ķ.bĀ5/]dUi Uz}zS:_doA D1]6ui/;\>>6O4N'[p{sXhFvQ;'Q/4H ~#j&<FA"襹22b%ĩxxQB+u;Z! 4m#IOZ_/yeg\I)ō}0tS4 mlҩGi-=Om?<mO~'ՠy j4䦎ƑGm"6H(L=&Kma^!>!HQDEG/ +]"27ՒXUdQ+@\@q!,%ŢԊQNg1Ka3mFzQFdz F?-hҋ:"C@lLFN]xJ`TӈJ/JLǥUf!M) WQAI.L@ȳl̂TgR@` ȑ HQ"0,KbzPQӠҫу|;ѣxލƔ?z9P +uʑr̩v~0s{%߽F|w?./op^^_^w?_?$8^|/ endstream endobj 5 0 obj <> endobj 6 0 obj <> endobj 17 0 obj [/View/Design] endobj 18 0 obj <>>> endobj 15 0 obj [/View/Design] endobj 16 0 obj <>>> endobj 26 0 obj [25 0 R 24 0 R] endobj 41 0 obj <> endobj xref 0 42 0000000004 65535 f +0000000016 00000 n +0000000185 00000 n +0000012181 00000 n +0000000000 00000 f +0000049121 00000 n +0000049191 00000 n +0000000000 00000 f +0000012232 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000049377 00000 n +0000049408 00000 n +0000049261 00000 n +0000049292 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000014083 00000 n +0000014154 00000 n +0000049493 00000 n +0000012582 00000 n +0000014570 00000 n +0000014457 00000 n +0000013318 00000 n +0000013522 00000 n +0000013570 00000 n +0000014341 00000 n +0000014372 00000 n +0000014225 00000 n +0000014256 00000 n +0000014644 00000 n +0000014818 00000 n +0000015859 00000 n +0000023702 00000 n +0000049525 00000 n +trailer <]>> startxref 49650 %%EOF \ No newline at end of file diff --git a/media/tutorial_splash.psd b/media/tutorial_splash.psd new file mode 100644 index 0000000..caa7eae Binary files /dev/null and b/media/tutorial_splash.psd differ diff --git a/media/vendingmachine.png b/media/vendingmachine.png new file mode 100644 index 0000000..b2d725d Binary files /dev/null and b/media/vendingmachine.png differ diff --git a/versions/0.1.10.zip b/versions/0.1.10.zip new file mode 100644 index 0000000..9a421da Binary files /dev/null and b/versions/0.1.10.zip differ diff --git a/versions/0.1.11.zip b/versions/0.1.11.zip new file mode 100644 index 0000000..af56d40 Binary files /dev/null and b/versions/0.1.11.zip differ diff --git a/versions/0.1.12.zip b/versions/0.1.12.zip new file mode 100644 index 0000000..f0dd97d Binary files /dev/null and b/versions/0.1.12.zip differ diff --git a/versions/0.1.13.zip b/versions/0.1.13.zip new file mode 100644 index 0000000..25ecdae Binary files /dev/null and b/versions/0.1.13.zip differ diff --git a/versions/0.1.14.zip b/versions/0.1.14.zip new file mode 100644 index 0000000..8dabcff Binary files /dev/null and b/versions/0.1.14.zip differ diff --git a/versions/0.1.15.zip b/versions/0.1.15.zip new file mode 100644 index 0000000..22b6811 Binary files /dev/null and b/versions/0.1.15.zip differ diff --git a/versions/0.1.3.zip b/versions/0.1.3.zip new file mode 100644 index 0000000..53c0382 Binary files /dev/null and b/versions/0.1.3.zip differ diff --git a/versions/0.1.4.zip b/versions/0.1.4.zip new file mode 100644 index 0000000..d678aaf Binary files /dev/null and b/versions/0.1.4.zip differ diff --git a/versions/0.1.5.zip b/versions/0.1.5.zip new file mode 100644 index 0000000..656da81 Binary files /dev/null and b/versions/0.1.5.zip differ diff --git a/versions/0.1.6.zip b/versions/0.1.6.zip new file mode 100644 index 0000000..9a1e1f3 Binary files /dev/null and b/versions/0.1.6.zip differ diff --git a/versions/0.1.7.zip b/versions/0.1.7.zip new file mode 100644 index 0000000..62f24a6 Binary files /dev/null and b/versions/0.1.7.zip differ diff --git a/versions/0.1.8.zip b/versions/0.1.8.zip new file mode 100644 index 0000000..c99f577 Binary files /dev/null and b/versions/0.1.8.zip differ diff --git a/versions/0.1.9.zip b/versions/0.1.9.zip new file mode 100644 index 0000000..58a516c Binary files /dev/null and b/versions/0.1.9.zip differ diff --git a/versions/v0.2.0.zip b/versions/v0.2.0.zip new file mode 100644 index 0000000..3c0dd1c Binary files /dev/null and b/versions/v0.2.0.zip differ