From cbe6d51eb950928dd2cc425b133ba814748f69c3 Mon Sep 17 00:00:00 2001 From: Peter Harpending Date: Mon, 23 Jan 2023 00:40:22 -0700 Subject: [PATCH] have transitioned jr to typescript --- jrx/dist/content.d.ts | 72 ++++ jrx/{ => dist}/content.js | 59 +-- jrx/dist/content.js.map | 1 + jrx/dist/popup.d.ts | 193 ++++++++++ jrx/dist/popup.js | 539 +++++++++++++++++++++++++++ jrx/dist/popup.js.map | 1 + jrx/jex.eterms | 5 + jrx/manifest.json | 2 +- jrx/popup.html | 2 +- jrx/popup.js | 205 ----------- jrx/src/content.ts | 170 +++++++++ jrx/src/popup.ts | 751 ++++++++++++++++++++++++++++++++++++++ jrx/tsconfig.json | 16 + 13 files changed, 1770 insertions(+), 246 deletions(-) create mode 100644 jrx/dist/content.d.ts rename jrx/{ => dist}/content.js (85%) create mode 100644 jrx/dist/content.js.map create mode 100644 jrx/dist/popup.d.ts create mode 100644 jrx/dist/popup.js create mode 100644 jrx/dist/popup.js.map create mode 100644 jrx/jex.eterms delete mode 100644 jrx/popup.js create mode 100644 jrx/src/content.ts create mode 100644 jrx/src/popup.ts create mode 100644 jrx/tsconfig.json diff --git a/jrx/dist/content.d.ts b/jrx/dist/content.d.ts new file mode 100644 index 0000000..4b3b3e3 --- /dev/null +++ b/jrx/dist/content.d.ts @@ -0,0 +1,72 @@ +declare let detect_msg: { + id: string; + name: string; + networkId: string; + origin: string; + type: string; +}; +declare let detect_awcp_msg: { + type: string; + data: { + jsonrpc: string; + method: string; + params: { + id: string; + name: string; + networkId: string; + origin: string; + type: string; + }; + }; +}; +declare function post_detect_msg(): void; +declare function mk_detectable(): Promise; +declare function sleep(ms: number): Promise; +/** + * This handles messages from *other parts of the extension* + */ +declare function handler(msg: any): void; +/** + * This handles messages from page scripts + */ +declare function window_message_handler(msg: { + data: any; +}): void; +/** + * window_message_handler handles all messages sent into the event bus, + * including messages that we sent (yay js). window_message_handler branches on + * whether the message is for us or not (is the science good or bad?). If the + * message is for us (the science is good), then this function is triggered. + * + * The bottom line is this is the function that *actually* handles messages + * from the window + */ +declare function the_science_is_good(awcp_rcp_data: { + id: string | number; + method: string; + params: object; +}): void; +/** + * Called in response to "connection.open" requests from page scripts + * + * FIXME: this should query the user to see if he wants to connect + */ +declare function post_connect_msg(msg_ident: string | number): void; +/** + * Called in response to "address.subscribe" requests from page scripts + * + * this is to get the wallet's address + */ +declare function bg_address_subscribe(msg_ident: string | number): void; +/** + * Called in response to "transaction.sign" requests from page scripts + * + * user wants us to sign a transaction + */ +declare function bg_tx_sign(msg_ident: string | number, params: object): void; +/** + * Called in response to "message.sign" requests from page scripts + * + * user wants us to sign a message + */ +declare function bg_msg_sign(msg_ident: string | number, params: object): void; diff --git a/jrx/content.js b/jrx/dist/content.js similarity index 85% rename from jrx/content.js rename to jrx/dist/content.js index 0b0bb9e..385211b 100644 --- a/jrx/content.js +++ b/jrx/dist/content.js @@ -1,44 +1,34 @@ -let detect_msg = - {id : "urmom", - name : "JR", - networkId : "ae_uat", - origin : "ur dads balls", - type : "extension"}; - -let detect_awcp_msg = - {type: "to_aepp", - data: {jsonrpc: "2.0", - method: "connection.announcePresence", - params: detect_msg}}; - - - +"use strict"; +let detect_msg = { id: "urmom", + name: "JR", + networkId: "ae_uat", + origin: "ur dads balls", + type: "extension" }; +let detect_awcp_msg = { type: "to_aepp", + data: { jsonrpc: "2.0", + method: "connection.announcePresence", + params: detect_msg } }; function post_detect_msg() { window.postMessage(detect_awcp_msg, '*'); } - - async function mk_detectable() { //while (true) { // 3 seconds times 40 is 2 minutes - for (let i=1; i<=40; i++) { + for (let i = 1; i <= 40; i++) { console.error('pee'); post_detect_msg(); await sleep(3000); } } - function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } - - /** * This handles messages from *other parts of the extension* */ function handler(msg) { console.error('message: ', msg); - switch(msg) { + switch (msg) { case 'mk-detectable': mk_detectable(); return; @@ -46,7 +36,6 @@ function handler(msg) { console.error('your mom is dead'); } } - /** * This handles messages from page scripts */ @@ -76,7 +65,6 @@ function window_message_handler(msg) { console.error('the science is bad'); } } - /** * window_message_handler handles all messages sent into the event bus, * including messages that we sent (yay js). window_message_handler branches on @@ -96,7 +84,7 @@ function the_science_is_good(awcp_rcp_data) { // params : {name : "sidekick examples", // version : 1}}} // can assume it is a call - let msg_ident = awcp_rcp_data.id; + let msg_ident = awcp_rcp_data.id; let msg_method = awcp_rcp_data.method; // branch here on the "method" field switch (msg_method) { @@ -117,7 +105,6 @@ function the_science_is_good(awcp_rcp_data) { console.error("we're going to have to put the science to sleep"); } } - /** * Called in response to "connection.open" requests from page scripts * @@ -126,16 +113,13 @@ function the_science_is_good(awcp_rcp_data) { function post_connect_msg(msg_ident) { // : EventData_W2A_connection_open // http://localhost:6969/local-awcp-0.2.1/types/EventData_W2A_connection_open.html - let connect_response = - {type: "to_aepp", - data: {jsonrpc: "2.0", - id: msg_ident, - method: "connection.open", - result: detect_msg}}; + let connect_response = { type: "to_aepp", + data: { jsonrpc: "2.0", + id: msg_ident, + method: "connection.open", + result: detect_msg } }; window.postMessage(connect_response, '*'); } - - /** * Called in response to "address.subscribe" requests from page scripts * @@ -143,8 +127,6 @@ function post_connect_msg(msg_ident) { */ function bg_address_subscribe(msg_ident) { } - - /** * Called in response to "transaction.sign" requests from page scripts * @@ -152,7 +134,6 @@ function bg_address_subscribe(msg_ident) { */ function bg_tx_sign(msg_ident, params) { } - /** * Called in response to "message.sign" requests from page scripts * @@ -160,10 +141,10 @@ function bg_tx_sign(msg_ident, params) { */ function bg_msg_sign(msg_ident, params) { } - +// @ts-ignore browser browser.runtime.onMessage.addListener(handler); window.addEventListener('message', window_message_handler); //window.addEventListener('message', function(evt) { console.error('BYYYYYYYYYYYYYYY', evt) }); //window.addEventListener('click', function() { console.error('HERRRO'); }); - console.error('poop'); +//# sourceMappingURL=content.js.map \ No newline at end of file diff --git a/jrx/dist/content.js.map b/jrx/dist/content.js.map new file mode 100644 index 0000000..b55cc2b --- /dev/null +++ b/jrx/dist/content.js.map @@ -0,0 +1 @@ +{"version":3,"file":"content.js","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/jrx/dist/popup.d.ts b/jrx/dist/popup.d.ts new file mode 100644 index 0000000..63d0f4e --- /dev/null +++ b/jrx/dist/popup.d.ts @@ -0,0 +1,193 @@ +/** + * This is the script for the popup window + */ +/** + * runs whenever the popup opens + */ +declare function main(): Promise; +/** + * Tells the content script to spam the event bus with detection messages + */ +declare function detuctable(): Promise; +/** + * gets the id of the current tab + */ +declare function active_tab_id(): Promise; +/** + * clear the list of keypairs and relist + * + * clearing is so this can be a re-entry call + */ +declare function relist_keypairs(): Promise; +/** + * kill all child nodes in the dom + */ +declare function pfizer(elt: HTMLElement): void; +/** + * This function is called in the init phase (after the user clicks the popup) + * + * If we have keypairs, put them in the keypairs element in the popup window + * + * Example call objects: + * + * Case of no keypairs: + * + * ```js + * obj = {} + * ``` + * + * Case of a named keypair + * + * ```js + * obj = { + * keypairs: [ + * { + * name: string, + * publicKey: uint8array + * secretKey: uint8array + * }, + * { + * name: string, + * publicKey: uint8array + * secretKey: uint8array + * } + * ] + * } + * ``` + */ +declare function handle_keypairs(obj: { + keypairs?: Array; +}): Promise; +/** + * function called if there are no keypairs + */ +declare function no_keypairs(): void; +declare type keypair = { + publicKey: Uint8Array; + secretKey: Uint8Array; +}; +declare type named_keypair = keypair & { + name: string; +}; +/** + * This function is called when the user clicks the button to generate a keypair + */ +declare function generate_keypair(): Promise; +/** + * This function is called in the case where there is at least one keypair, and + * it renders the list of keypairs + */ +declare function ls_keypairs(keypairs: Array): Promise; +/** + * This renders a single keypair item in the list of keypairs + */ +declare function render_keypair(parent_ul: HTMLElement, nk: named_keypair): Promise; +/** + * take the publicKey bytes and output a string of the form ak_... + */ +declare function publicKey_bytes_to_str(publicKey_bytes: Uint8Array): Promise; +/** + * take the first 4 bytes from sha256(sha256(inputBytes)) and concatenate it onto input, return that + * + * From https://github.com/aeternity/protocol/blob/c007deeac4a01e401238412801ac7084ac72d60e/node/api/api_encoding.md + * + * ```erlang + * add_check_bytes(Bin) when is_binary(Bin) -> + * <> = sha256(sha256(Bin)), + * <>. + * ``` + */ +declare function shasha4_concat(input_bytes: Uint8Array): Promise; +/** + * the first 4 bytes of the sha256 of the sha256 of the input + * + * returns a Uint8Array + */ +declare function shasha4(input_bytes: Uint8Array): Promise; +/** + * Console.log the message and put it in the log thing + */ +declare function logln(message: string): void; +/** + * Base58 encoding/decoding + */ +/** + * Encode a Uint8Array into base58 + */ +declare function encode(binary: Uint8Array): string; +/** + * count the number of leading zeros in a uint8array + * + * @internal + */ +declare function nlz(bytes: Uint8Array): number; +/** + * Generate a bunch of '1's for however many leading zeros there are + * + * @internal + */ +declare function encode_zeros(how_many: number): string; +/** + * Encode a Uint8Array that has no leading zeros + * + * @internal + */ +declare function encode_rest(bytes: Uint8Array): string; +/** + * Convert a bytestring to a bignum + * + * @internal + */ +declare function bytes_to_bigint(bytes: Uint8Array): bigint; +/** + * Convert a BigInt to Base58 + * + * @internal + */ +declare function bignum_to_base58(q: bigint): string; +/** + * Decode a Base58 string into a Uint8Array + */ +declare function decode(base58: string): Uint8Array; +/** + * count the number of leading 1 characters in a uint8array + * + * @internal + */ +declare function nlo(base58: string): number; +/** + * Generate a bunch of '0's for however many leading ones there are + * + * @internal + */ +declare function decode_ones(how_many: number): Array; +/** + * Decode a string that has no leading 1s + * + * @internal + */ +declare function decode_rest(base58: string): Array; +/** + * Convert a base58 string to a bignum + * + * @internal + */ +declare function base58_to_bigint(base58: string): bigint; +/** + * convert a bignum into a byte array + * + * @end + */ +declare function bigint_to_base256(q: bigint): Array; +/** + * Base58 integer -> character conversion table + * + * @internal + */ +declare function bigint_to_char(n: bigint): string; +/** + * Base58 character -> integer conversion table + * + * @internal + */ +declare function char_to_bigint(s: string): bigint; diff --git a/jrx/dist/popup.js b/jrx/dist/popup.js new file mode 100644 index 0000000..475dd7e --- /dev/null +++ b/jrx/dist/popup.js @@ -0,0 +1,539 @@ +"use strict"; +/** + * This is the script for the popup window + */ +//import {default as nacl} from './nacl.js'; +main(); +/** + * runs whenever the popup opens + */ +async function main() { + // detect button action + document.getElementById('mk-detectable').onclick = detuctable; + document.getElementById('generate').onclick = generate_keypair; + // delete keypairs + // browser.storage.local.clear(); + await relist_keypairs(); +} +/** + * Tells the content script to spam the event bus with detection messages + */ +async function detuctable() { + let ati = await active_tab_id(); + // @ts-ignore browser api unknown + browser.tabs.sendMessage(ati, // active tab + 'mk-detectable'); // message + // @ts-ignore disabled exists on this + document.getElementById('mk-detectable').disabled = true; + // FIXME: update button with detect info +} +/** + * gets the id of the current tab + */ +async function active_tab_id() { + // @ts-ignore browser api unkown + let active_tabs = await browser.tabs.query({ active: true, currentWindow: true }); + return active_tabs[0].id; +} +/** + * clear the list of keypairs and relist + * + * clearing is so this can be a re-entry call + */ +async function relist_keypairs() { + // delete all list items + pfizer(document.getElementById('keypairs')); + // look for keypairs then relist + // @ts-ignore browser api + let obj = await browser.storage.local.get('keypairs'); + await handle_keypairs(obj); +} +/** + * kill all child nodes in the dom + */ +function pfizer(elt) { + while (elt.firstChild) { + elt.removeChild(elt.firstChild); + } +} +/** + * This function is called in the init phase (after the user clicks the popup) + * + * If we have keypairs, put them in the keypairs element in the popup window + * + * Example call objects: + * + * Case of no keypairs: + * + * ```js + * obj = {} + * ``` + * + * Case of a named keypair + * + * ```js + * obj = { + * keypairs: [ + * { + * name: string, + * publicKey: uint8array + * secretKey: uint8array + * }, + * { + * name: string, + * publicKey: uint8array + * secretKey: uint8array + * } + * ] + * } + * ``` + */ +async function handle_keypairs(obj) { + logln('handle_keypairs'); + // branch on if there are no keypairs + // no 'keypairs' key + if (!!!obj.keypairs) { + no_keypairs(); + } + // 'keypairs' key but points to empty array + else if (0 === obj.keypairs.length) { + no_keypairs(); + } + else { + await ls_keypairs(obj.keypairs); + } +} +/** + * function called if there are no keypairs + */ +function no_keypairs() { + logln('no keypairs!'); + document.getElementById('no-keypairs').hidden = false; +} +// publicKey : Uint8Array, +// secretKey : Uint8Array}; +/** + * This function is called when the user clicks the button to generate a keypair + */ +async function generate_keypair() { + logln('generating a keypair'); + // @ts-ignore namespace nacl + let keypair = nacl.sign.keyPair(); + // @ts-ignore changing type + keypair.name = "Untitled Keypair 1"; + // fixme: ADD keypair (factor out into separate function) + // @ts-ignore cannot find namespace browser + browser.storage.local.set({ 'keypairs': [keypair] }); + await relist_keypairs(); +} +/** + * This function is called in the case where there is at least one keypair, and + * it renders the list of keypairs + */ +async function ls_keypairs(keypairs) { + logln('keypairs!'); + console.log('keypairs: ', keypairs); + // make keypair list visible + let keypairs_ul = document.getElementById('keypairs'); + keypairs_ul.hidden = false; + // render each keypair + for (let kp of keypairs) { + console.log(kp); + await render_keypair(keypairs_ul, kp); + } + //let keypairs_json = JSON.stringify(keypairs, undefined, 4); + //document.getElementById('keypairs').innerHTML = keypairs_json; +} +/** + * This renders a single keypair item in the list of keypairs + */ +async function render_keypair(parent_ul, nk) { + let name = nk.name; + let publicKey = nk.publicKey; + // create the element + //
  • + let li = document.createElement('li'); + //
  • ->
  • {name}
  • + li.innerHTML += name; + //
  • {name}
  • ->
  • {name}
  • + li.appendChild(document.createElement('br')); + // + let code = document.createElement('code'); + let pubkey_str = await publicKey_bytes_to_str(publicKey); + // -> ak_... + code.innerHTML += pubkey_str; + //
  • ...
  • ->
  • ......
  • + li.appendChild(code); + //
      ->
      • ...
      + parent_ul.appendChild(li); +} +/** + * take the publicKey bytes and output a string of the form ak_... + */ +async function publicKey_bytes_to_str(publicKey_bytes) { + // From https://github.com/aeternity/protocol/blob/c007deeac4a01e401238412801ac7084ac72d60e/node/api/api_encoding.md + // + // ```erlang + // add_check_bytes(Bin) when is_binary(Bin) -> + // <> = sha256(sha256(Bin)), + // <>. + // ``` + let bytes_to_encode = await shasha4_concat(publicKey_bytes); + let b58_str = encode(bytes_to_encode); + return 'ak_' + b58_str; +} +/** + * take the first 4 bytes from sha256(sha256(inputBytes)) and concatenate it onto input, return that + * + * From https://github.com/aeternity/protocol/blob/c007deeac4a01e401238412801ac7084ac72d60e/node/api/api_encoding.md + * + * ```erlang + * add_check_bytes(Bin) when is_binary(Bin) -> + * <> = sha256(sha256(Bin)), + * <>. + * ``` + */ +async function shasha4_concat(input_bytes) { + let shasha4_bytes = await shasha4(input_bytes); + let input_bytes_length = input_bytes.byteLength; + // this is so dumb + // make blank array + let return_bytes = new Uint8Array(input_bytes_length + 4); + // copy input bytes into it + for (let input_bytes_idx0 = 0; input_bytes_idx0 < input_bytes_length; input_bytes_idx0++) { + return_bytes[input_bytes_idx0] = input_bytes[input_bytes_idx0]; + } + // copy sha bytes + for (let shasha4_bytes_idx0 = 0; shasha4_bytes_idx0 < 4; shasha4_bytes_idx0++) { + // if shasha4_bytes_idx0 = 0, then we want to start at input_bytes_length + let return_bytes_idx0 = input_bytes_length + shasha4_bytes_idx0; + return_bytes[return_bytes_idx0] = shasha4_bytes[shasha4_bytes_idx0]; + } + return return_bytes; +} +/** + * the first 4 bytes of the sha256 of the sha256 of the input + * + * returns a Uint8Array + */ +async function shasha4(input_bytes) { + let x = await crypto.subtle.digest('SHA-256', input_bytes); + let y = await crypto.subtle.digest('SHA-256', x); + let z = y.slice(0, 4); + return new Uint8Array(z); +} +/** + * Console.log the message and put it in the log thing + */ +function logln(message) { + console.log(message); + document.getElementById('log').innerHTML += message; + document.getElementById('log').innerHTML += '\n'; +} +/** + * Base58 encoding/decoding + */ +//============================================================================= +// ENCODING +//============================================================================= +/** + * Encode a Uint8Array into base58 + */ +function encode(binary) { + let num_leading_zeros = nlz(binary); + let rest = binary.slice(num_leading_zeros); + let ones = encode_zeros(num_leading_zeros); + let rest_b58 = encode_rest(rest); + let result = ones + rest_b58; + return result; +} +/** + * count the number of leading zeros in a uint8array + * + * @internal + */ +function nlz(bytes) { + let n = 0; + for (let this_byte of bytes) { + if (0 === this_byte) { + n++; + } + else { + break; + } + } + return n; +} +/** + * Generate a bunch of '1's for however many leading zeros there are + * + * @internal + */ +function encode_zeros(how_many) { + let ones = ''; + for (let i = 1; i <= how_many; i++) { + ones += '1'; + } + return ones; +} +/** + * Encode a Uint8Array that has no leading zeros + * + * @internal + */ +function encode_rest(bytes) { + let bytes_bignum = bytes_to_bigint(bytes); + let result = bignum_to_base58(bytes_bignum); + return result; +} +/** + * Convert a bytestring to a bignum + * + * @internal + */ +function bytes_to_bigint(bytes) { + let acc_bigint = 0n; + for (let this_byte of bytes) { + acc_bigint <<= 8n; + acc_bigint += BigInt(this_byte); + } + return acc_bigint; +} +/** + * Convert a BigInt to Base58 + * + * @internal + */ +function bignum_to_base58(q) { + let s = ''; + while (q !== 0n) { + let this_n = q % 58n; + q /= 58n; + let this_b58_char = bigint_to_char(this_n); + s = this_b58_char + s; + } + return s; +} +//============================================================================= +// DECODING +//============================================================================= +/** + * Decode a Base58 string into a Uint8Array + */ +function decode(base58) { + let num_leading_ones = nlo(base58); + let rest = base58.slice(num_leading_ones); + let zeros = decode_ones(num_leading_ones); + let rest_arr = decode_rest(rest); + let pre_result = zeros.concat(rest_arr); + return new Uint8Array(pre_result); +} +/** + * count the number of leading 1 characters in a uint8array + * + * @internal + */ +function nlo(base58) { + let n = 0; + for (let this_char of base58) { + if ('1' === this_char) { + n++; + } + else { + break; + } + } + return n; +} +/** + * Generate a bunch of '0's for however many leading ones there are + * + * @internal + */ +function decode_ones(how_many) { + let zeros = []; + for (let i = 1; i <= how_many; i++) { + zeros.push(0); + } + return zeros; +} +/** + * Decode a string that has no leading 1s + * + * @internal + */ +function decode_rest(base58) { + let result_bignum = base58_to_bigint(base58); + let result = bigint_to_base256(result_bignum); + return result; +} +/** + * Convert a base58 string to a bignum + * + * @internal + */ +function base58_to_bigint(base58) { + let acc_bigint = 0n; + for (let this_char of base58) { + acc_bigint *= 58n; + acc_bigint += char_to_bigint(this_char); + } + return acc_bigint; +} +/** + * convert a bignum into a byte array + * + * @end + */ +function bigint_to_base256(q) { + let arr_reverse = []; + while (q !== 0n) { + let r = Number(q % 256n); + q /= 256n; + arr_reverse.push(r); + } + arr_reverse.reverse(); + return arr_reverse; +} +//============================================================================= +// TRANSLATION TABLES +//============================================================================= +/** + * Base58 integer -> character conversion table + * + * @internal + */ +function bigint_to_char(n) { + switch (n) { + case 0n: return '1'; + case 1n: return '2'; + case 2n: return '3'; + case 3n: return '4'; + case 4n: return '5'; + case 5n: return '6'; + case 6n: return '7'; + case 7n: return '8'; + case 8n: return '9'; + case 9n: return 'A'; + case 10n: return 'B'; + case 11n: return 'C'; + case 12n: return 'D'; + case 13n: return 'E'; + case 14n: return 'F'; + case 15n: return 'G'; + case 16n: return 'H'; + case 17n: return 'J'; + case 18n: return 'K'; + case 19n: return 'L'; + case 20n: return 'M'; + case 21n: return 'N'; + case 22n: return 'P'; + case 23n: return 'Q'; + case 24n: return 'R'; + case 25n: return 'S'; + case 26n: return 'T'; + case 27n: return 'U'; + case 28n: return 'V'; + case 29n: return 'W'; + case 30n: return 'X'; + case 31n: return 'Y'; + case 32n: return 'Z'; + case 33n: return 'a'; + case 34n: return 'b'; + case 35n: return 'c'; + case 36n: return 'd'; + case 37n: return 'e'; + case 38n: return 'f'; + case 39n: return 'g'; + case 40n: return 'h'; + case 41n: return 'i'; + case 42n: return 'j'; + case 43n: return 'k'; + case 44n: return 'm'; + case 45n: return 'n'; + case 46n: return 'o'; + case 47n: return 'p'; + case 48n: return 'q'; + case 49n: return 'r'; + case 50n: return 's'; + case 51n: return 't'; + case 52n: return 'u'; + case 53n: return 'v'; + case 54n: return 'w'; + case 55n: return 'x'; + case 56n: return 'y'; + case 57n: return 'z'; + default: + throw new Error('invalid base58 bigint: ' + n); + } +} +/** + * Base58 character -> integer conversion table + * + * @internal + */ +function char_to_bigint(s) { + switch (s) { + case '1': return 0n; + case '2': return 1n; + case '3': return 2n; + case '4': return 3n; + case '5': return 4n; + case '6': return 5n; + case '7': return 6n; + case '8': return 7n; + case '9': return 8n; + case 'A': return 9n; + case 'B': return 10n; + case 'C': return 11n; + case 'D': return 12n; + case 'E': return 13n; + case 'F': return 14n; + case 'G': return 15n; + case 'H': return 16n; + case 'J': return 17n; + case 'K': return 18n; + case 'L': return 19n; + case 'M': return 20n; + case 'N': return 21n; + case 'P': return 22n; + case 'Q': return 23n; + case 'R': return 24n; + case 'S': return 25n; + case 'T': return 26n; + case 'U': return 27n; + case 'V': return 28n; + case 'W': return 29n; + case 'X': return 30n; + case 'Y': return 31n; + case 'Z': return 32n; + case 'a': return 33n; + case 'b': return 34n; + case 'c': return 35n; + case 'd': return 36n; + case 'e': return 37n; + case 'f': return 38n; + case 'g': return 39n; + case 'h': return 40n; + case 'i': return 41n; + case 'j': return 42n; + case 'k': return 43n; + case 'm': return 44n; + case 'n': return 45n; + case 'o': return 46n; + case 'p': return 47n; + case 'q': return 48n; + case 'r': return 49n; + case 's': return 50n; + case 't': return 51n; + case 'u': return 52n; + case 'v': return 53n; + case 'w': return 54n; + case 'x': return 55n; + case 'y': return 56n; + case 'z': return 57n; + default: + throw new Error('invalid base58 char: ' + s); + } +} +//# sourceMappingURL=popup.js.map \ No newline at end of file diff --git a/jrx/dist/popup.js.map b/jrx/dist/popup.js.map new file mode 100644 index 0000000..71a2985 --- /dev/null +++ b/jrx/dist/popup.js.map @@ -0,0 +1 @@ +{"version":3,"file":"popup.js","sourceRoot":"","sources":["../src/popup.ts"],"names":[],"mappings":";AAAA;;GAEG;AAEH,4CAA4C;AAE5C,IAAI,EAAE,CAAC;AAEP;;GAEG;AACH,KAAK,UACL,IAAI;IAIA,uBAAuB;IACvB,QAAQ,CAAC,cAAc,CAAC,eAAe,CAAE,CAAC,OAAO,GAAG,UAAU,CAAC;IAC/D,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAE,CAAC,OAAO,GAAG,gBAAgB,CAAC;IAEhE,kBAAkB;IAClB,iCAAiC;IACjC,MAAM,eAAe,EAAE,CAAC;AAC5B,CAAC;AAID;;GAEG;AACH,KAAK,UACL,UAAU;IAIN,IAAI,GAAG,GAAG,MAAM,aAAa,EAAE,CAAC;IAChC,iCAAiC;IACjC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,EAAgB,aAAa;IAChC,eAAe,CAAC,CAAC,CAAE,UAAU;IACtD,qCAAqC;IACrC,QAAQ,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC;IACzD,wCAAwC;AAC5C,CAAC;AAGD;;GAEG;AACH,KAAK,UACL,aAAa;IAIT,gCAAgC;IAChC,IAAI,WAAW,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAC,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAC,CAAC,CAAC;IAChF,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7B,CAAC;AAGD;;;;GAIG;AACH,KAAK,UACL,eAAe;IAIX,wBAAwB;IACxB,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAE,CAAC,CAAC;IAC7C,gCAAgC;IAChC,yBAAyB;IACzB,IAAI,GAAG,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACtD,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;AAC/B,CAAC;AAGD;;GAEG;AACH,SACA,MAAM,CACD,GAAiB;IAGlB,OAAO,GAAG,CAAC,UAAU,EAAE;QACnB,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;KACnC;AACL,CAAC;AAGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,KAAK,UACL,eAAe,CACV,GAAwC;IAGzC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACzB,qCAAqC;IACrC,oBAAoB;IACpB,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE;QACjB,WAAW,EAAE,CAAC;KACjB;IACD,2CAA2C;SACtC,IAAI,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE;QAChC,WAAW,EAAE,CAAC;KACjB;SACI;QACD,MAAM,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;KACnC;AACL,CAAC;AAGD;;GAEG;AACH,SACA,WAAW;IAIP,KAAK,CAAC,cAAc,CAAC,CAAC;IACtB,QAAQ,CAAC,cAAc,CAAC,aAAa,CAAE,CAAC,MAAM,GAAG,KAAK,CAAC;AAC3D,CAAC;AAQD,gCAAgC;AAChC,iCAAiC;AAGjC;;GAEG;AACH,KAAK,UACL,gBAAgB;IAIZ,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC9B,4BAA4B;IAC5B,IAAI,OAAO,GAAyB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IACxD,2BAA2B;IAC3B,OAAO,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACpC,yDAAyD;IACzD,2CAA2C;IAC3C,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAC,UAAU,EAAE,CAAC,OAAO,CAAC,EAAC,CAAC,CAAC;IACnD,MAAM,eAAe,EAAE,CAAC;AAC5B,CAAC;AAID;;;GAGG;AACH,KAAK,UACL,WAAW,CACN,QAA+B;IAGhC,KAAK,CAAC,WAAW,CAAC,CAAC;IACnB,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;IACnC,4BAA4B;IAC5B,IAAI,WAAW,GAAG,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAE,CAAC;IACvD,WAAW,CAAC,MAAM,GAAG,KAAK,CAAC;IAC3B,sBAAsB;IACtB,KAAK,IAAI,EAAE,IAAI,QAAQ,EAAE;QACrB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,MAAM,cAAc,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;KACzC;IACD,6DAA6D;IAC7D,gEAAgE;AACpE,CAAC;AAED;;GAEG;AACH,KAAK,UACL,cAAc,CACT,SAAuB,EACvB,EAAyB;IAK1B,IAAI,IAAI,GAAqB,EAAE,CAAC,IAAI,CAAC;IACrC,IAAI,SAAS,GAAgB,EAAE,CAAC,SAAS,CAAC;IAC1C,qBAAqB;IACrB,YAAY;IACZ,IAAI,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IACtC,+BAA+B;IAC/B,EAAE,CAAC,SAAS,IAAI,IAAI,CAAC;IACrB,yCAAyC;IACzC,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;IAE7C,gBAAgB;IAChB,IAAI,IAAI,GAAuB,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9D,IAAI,UAAU,GAAiB,MAAM,sBAAsB,CAAC,SAAS,CAAC,CAAC;IACvE,uCAAuC;IACvC,IAAI,CAAC,SAAS,IAAI,UAAU,CAAC;IAC7B,+CAA+C;IAC/C,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAErB,qCAAqC;IACrC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AAC9B,CAAC;AAGD;;GAEG;AACH,KAAK,UACL,sBAAsB,CACjB,eAA4B;IAG7B,oHAAoH;IACpH,EAAE;IACF,YAAY;IACZ,8CAA8C;IAC9C,0DAA0D;IAC1D,oCAAoC;IACpC,MAAM;IACN,IAAI,eAAe,GAAG,MAAM,cAAc,CAAC,eAAe,CAAC,CAAC;IAC5D,IAAI,OAAO,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;IACtC,OAAO,KAAK,GAAG,OAAO,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;GAUG;AACH,KAAK,UACL,cAAc,CACT,WAAuB;IAGxB,IAAI,aAAa,GAAQ,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;IACpD,IAAI,kBAAkB,GAAG,WAAW,CAAC,UAAU,CAAC;IAChD,kBAAkB;IAClB,mBAAmB;IACnB,IAAI,YAAY,GAAS,IAAI,UAAU,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC;IAChE,2BAA2B;IAC3B,KAAK,IAAI,gBAAgB,GAAG,CAAC,EACpB,gBAAgB,GAAG,kBAAkB,EACrC,gBAAgB,EAAE,EAC3B;QACI,YAAY,CAAC,gBAAgB,CAAC,GAAG,WAAW,CAAC,gBAAgB,CAAC,CAAC;KAClE;IACD,iBAAiB;IACjB,KAAK,IAAI,kBAAkB,GAAG,CAAC,EACtB,kBAAkB,GAAG,CAAC,EACtB,kBAAkB,EAAE,EAC7B;QACI,yEAAyE;QACzE,IAAI,iBAAiB,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;QAChE,YAAY,CAAC,iBAAiB,CAAC,GAAG,aAAa,CAAC,kBAAkB,CAAC,CAAC;KACvE;IACD,OAAO,YAAY,CAAC;AACxB,CAAC;AAED;;;;GAIG;AACH,KAAK,UACL,OAAO,CACF,WAAwB;IAGzB,IAAI,CAAC,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC3D,IAAI,CAAC,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtB,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC;AAKD;;GAEG;AACH,SACA,KAAK,CACA,OAAgB;IAGjB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAE,CAAC,SAAS,IAAI,OAAO,CAAC;IACrD,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAE,CAAC,SAAS,IAAI,IAAI,CAAC;AACtD,CAAC;AAID;;GAEG;AAGH,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E;;GAEG;AACH,SACA,MAAM,CACD,MAAmB;IAGpB,IAAI,iBAAiB,GAAgB,GAAG,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,IAAI,GAA6B,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrE,IAAI,IAAI,GAA6B,YAAY,CAAC,iBAAiB,CAAC,CAAC;IACrE,IAAI,QAAQ,GAAyB,WAAW,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,MAAM,GAA2B,IAAI,GAAG,QAAQ,CAAC;IACrD,OAAO,MAAM,CAAC;AAClB,CAAC;AAID;;;;GAIG;AACH,SACA,GAAG,CACE,KAAiB;IAGlB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,SAAS,IAAI,KAAK,EAC3B;QACI,IAAI,CAAC,KAAK,SAAS,EAAE;YAAE,CAAC,EAAE,CAAC;SAAI;aACV;YAAE,MAAM;SAAE;KAClC;IACD,OAAO,CAAC,CAAC;AACb,CAAC;AAID;;;;GAIG;AACH,SACA,YAAY,CACP,QAAiB;IAGlB,IAAI,IAAI,GAAY,EAAE,CAAC;IACvB,KAAK,IAAI,CAAC,GAAI,CAAC,EACN,CAAC,IAAI,QAAQ,EACb,CAAC,EAAE,EACZ;QACI,IAAI,IAAI,GAAG,CAAC;KACf;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AAID;;;;GAIG;AACH,SACA,WAAW,CACN,KAAkB;IAGnB,IAAI,YAAY,GAAY,eAAe,CAAC,KAAK,CAAC,CAAC;IACnD,IAAI,MAAM,GAAkB,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC3D,OAAO,MAAM,CAAC;AAClB,CAAC;AAID;;;;GAIG;AACH,SACA,eAAe,CACV,KAAiB;IAGlB,IAAI,UAAU,GAAY,EAAE,CAAC;IAC7B,KAAI,IAAI,SAAS,IAAI,KAAK,EAC1B;QACI,UAAU,KAAK,EAAE,CAAC;QAClB,UAAU,IAAK,MAAM,CAAC,SAAS,CAAC,CAAC;KACpC;IACD,OAAO,UAAU,CAAC;AACtB,CAAC;AAID;;;;GAIG;AACH,SACA,gBAAgB,CACX,CAAS;IAGV,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,OAAO,CAAC,KAAK,EAAE,EACf;QACI,IAAI,MAAM,GAAmB,CAAC,GAAG,GAAG,CAAC;QACrC,CAAC,IAAI,GAAG,CAAC;QAET,IAAI,aAAa,GAAY,cAAc,CAAC,MAAM,CAAC,CAAC;QACpD,CAAC,GAAG,aAAa,GAAG,CAAC,CAAC;KACzB;IACD,OAAO,CAAC,CAAC;AACb,CAAC;AAID,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E;;GAEG;AACH,SACA,MAAM,CACD,MAAc;IAGf,IAAI,gBAAgB,GAAmB,GAAG,CAAC,MAAM,CAAC,CAAC;IACnD,IAAI,IAAI,GAA+B,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACtE,IAAI,KAAK,GAA8B,WAAW,CAAC,gBAAgB,CAAC,CAAC;IACrE,IAAI,QAAQ,GAA2B,WAAW,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,UAAU,GAAyB,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9D,OAAO,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;AACtC,CAAC;AAID;;;;GAIG;AACH,SACA,GAAG,CACE,MAAc;IAGf,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,SAAS,IAAI,MAAM,EAC5B;QACI,IAAI,GAAG,KAAK,SAAS,EAAE;YAAE,CAAC,EAAE,CAAC;SAAI;aACV;YAAE,MAAM;SAAE;KACpC;IACD,OAAO,CAAC,CAAC;AACb,CAAC;AAID;;;;GAIG;AACH,SACA,WAAW,CACN,QAAiB;IAGlB,IAAI,KAAK,GAAmB,EAAE,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAI,CAAC,EACN,CAAC,IAAI,QAAQ,EACb,CAAC,EAAE,EACZ;QACI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AAID;;;;GAIG;AACH,SACA,WAAW,CACN,MAAc;IAGf,IAAI,aAAa,GAAmB,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC7D,IAAI,MAAM,GAA0B,iBAAiB,CAAC,aAAa,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC;AAClB,CAAC;AAID;;;;GAIG;AACH,SACA,gBAAgB,CACX,MAAc;IAGf,IAAI,UAAU,GAAY,EAAE,CAAC;IAC7B,KAAI,IAAI,SAAS,IAAI,MAAM,EAC3B;QACI,UAAU,IAAI,GAAG,CAAC;QAClB,UAAU,IAAI,cAAc,CAAC,SAAS,CAAC,CAAC;KAC3C;IACD,OAAO,UAAU,CAAC;AACtB,CAAC;AAGD;;;;GAIG;AACH,SACA,iBAAiB,CACZ,CAAS;IAGV,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,OAAM,CAAC,KAAK,EAAE,EACd;QACI,IAAI,CAAC,GAAW,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACjC,CAAC,IAAI,IAAI,CAAC;QACV,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACvB;IACD,WAAW,CAAC,OAAO,EAAE,CAAC;IACtB,OAAO,WAAW,CAAC;AACvB,CAAC;AAGD,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAG/E;;;;GAIG;AACH,SACA,cAAc,CACT,CAAS;IAGV,QAAO,CAAC,EAAE;QACN,KAAM,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAM,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAM,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAM,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAM,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAM,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAM,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAM,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAM,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAM,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC;QACrB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"} \ No newline at end of file diff --git a/jrx/jex.eterms b/jrx/jex.eterms new file mode 100644 index 0000000..7a006fd --- /dev/null +++ b/jrx/jex.eterms @@ -0,0 +1,5 @@ +{type, extension}. +{realm, local}. +{name, jrx}. +{version, "0.1.0"}. +{deps, []}. diff --git a/jrx/manifest.json b/jrx/manifest.json index 2645045..47d12ca 100644 --- a/jrx/manifest.json +++ b/jrx/manifest.json @@ -5,7 +5,7 @@ "icons" : {"48" : "icons/jrx-icon-48.png", "96" : "icons/jrx-icon-96.png"}, "content_scripts" : [{"matches" : ["*://*/*"], - "js" : ["content.js"]}], + "js" : ["dist/content.js"]}], "browser_action" : {"default_icon" : "icons/jrx-icon-32.png", "default_title" : "Jaeck Russell", "default_popup" : "popup.html"}, diff --git a/jrx/popup.html b/jrx/popup.html index ee822d4..767fcc3 100644 --- a/jrx/popup.html +++ b/jrx/popup.html @@ -25,6 +25,6 @@ - + diff --git a/jrx/popup.js b/jrx/popup.js deleted file mode 100644 index f2efe4a..0000000 --- a/jrx/popup.js +++ /dev/null @@ -1,205 +0,0 @@ -/** - * This is the script for the popup window - */ - -//import {default as nacl} from './nacl.js'; - -/** - * runs whenever the popup opens - */ -async function -main() -{ - // detect button action - document.getElementById('mk-detectable').onclick = mk_detectable; - document.getElementById('generate').onclick = generate_keypair; - - // delete keypairs - // browser.storage.local.clear(); - relist_keypairs(); -} - - - -/** - * Tells the content script to spam the event bus with detection messages - */ -async function -mk_detectable() -{ - let ati = await active_tab_id(); - browser.tabs.sendMessage(ati, // active tab - 'mk-detectable'); // message - document.getElementById('mk-detectable').disabled = true; - // FIXME: update button with detect info -} - - -/** - * gets the id of the current tab - */ -async function -active_tab_id() -{ - let active_tabs = await browser.tabs.query({active: true, currentWindow: true}); - return active_tabs[0].id; -} - - -/** - * clear the list of keypairs and relist - * - * clearing is so this can be a re-entry call - */ -function -relist_keypairs() -{ - // delete all list items - pfizer(document.getElementById('keypairs')); - // look for keypairs then relist - browser.storage.local.get('keypairs').then(handle_keypairs, (err) => { console.error(err); } ); -} - -/** - * kill all child nodes in the dom - */ -function -pfizer(elt) -{ - while (elt.firstChild) { - elt.removeChild(elt.firstChild); - } -} - - -/** - * This function is called in the init phase (after the user clicks the popup) - * - * If we have keypairs, put them in the keypairs element in the popup window - * - * Example call objects: - * - * Case of no keypairs: - * - * ```js - * obj = {} - * ``` - * - * Case of a named keypair - * - * ```js - * obj = { - * keypairs: [ - * { - * name: string, - * publicKey: uint8array - * secretKey: uint8array - * }, - * { - * name: string, - * publicKey: uint8array - * secretKey: uint8array - * } - * ] - * } - * ``` - */ -function -handle_keypairs(obj) -{ - logln('handle_keypairs'); - // branch on if there are no keypairs - // no 'keypairs' key - if (!!!obj.keypairs) { - no_keypairs(); - } - // 'keypairs' key but points to empty array - else if (0 === obj.keypairs.length) { - no_keypairs(); - } - else { - ls_keypairs(obj.keypairs); - } -} - - -/** - * function called if there are no keypairs - */ -function -no_keypairs() -{ - logln('no keypairs!'); - document.getElementById('no-keypairs').hidden = false; -} - - -/** - * This function is called when the user clicks the button to generate a keypair - */ -function -generate_keypair() -{ - logln('generating a keypair'); - let keypair = nacl.sign.keyPair(); - keypair.name = "Untitled Keypair 1"; - // fixme: ADD keypair (factor out into separate function) - browser.storage.local.set({'keypairs': [keypair]}); - relist_keypairs(); -} - - - -/** - * This function is called in the case where there is at least one keypair, and - * it renders the list of keypairs - */ -function -ls_keypairs(keypairs) -{ - logln('keypairs!'); - console.log('keypairs: ', keypairs) - // make keypair list visible - let keypairs_ul = document.getElementById('keypairs'); - keypairs_ul.hidden = false; - // render each keypair - for (let kp of keypairs) { - console.log(kp); - render_keypair(keypairs_ul, kp); - } - //let keypairs_json = JSON.stringify(keypairs, undefined, 4); - //document.getElementById('keypairs').innerHTML = keypairs_json; -} - - -/** - * This renders a single keypair item in the list of keypairs - */ -function -render_keypair(parent_ul, {name, publicKey}) -{ - // create the element - let li = document.createElement('li'); - li.innerHTML += name; - parent_ul.appendChild(li); -} - - - -/** - * Console.log the message and put it in the log thing - */ -function -logln(message) -{ - console.log(message); - document.getElementById('log').innerHTML += message; - document.getElementById('log').innerHTML += '\n'; -} - -/** - * send the given message to the tab - */ - - -main(); diff --git a/jrx/src/content.ts b/jrx/src/content.ts new file mode 100644 index 0000000..199318c --- /dev/null +++ b/jrx/src/content.ts @@ -0,0 +1,170 @@ +let detect_msg = + {id : "urmom", + name : "JR", + networkId : "ae_uat", + origin : "ur dads balls", + type : "extension"}; + +let detect_awcp_msg = + {type: "to_aepp", + data: {jsonrpc: "2.0", + method: "connection.announcePresence", + params: detect_msg}}; + + + +function post_detect_msg() { + window.postMessage(detect_awcp_msg, '*'); +} + + +async function mk_detectable() { + //while (true) { + // 3 seconds times 40 is 2 minutes + for (let i=1; i<=40; i++) { + console.error('pee'); + post_detect_msg(); + await sleep(3000); + } +} + +function sleep(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + + +/** + * This handles messages from *other parts of the extension* + */ +function handler(msg: any) { + console.error('message: ', msg); + switch(msg) { + case 'mk-detectable': + mk_detectable(); + return; + default: + console.error('your mom is dead'); + } +} + +/** + * This handles messages from page scripts + */ +function window_message_handler(msg: {data: any}) { + console.error('the science is coming', msg); + // example science: + // { + // "type": "to_waellet", + // "data": { + // "jsonrpc": "2.0", + // "id": "ske-connect-1", + // "method": "connection.open", + // "params": { + // "name": "sidekick examples", + // "version": 1 + // } + // } + // } + let the_science = msg.data; + console.error('THE SCIENCE: ', the_science); + console.error('is the science good or bad?'); + if (the_science.type === 'to_waellet') { + console.error('the science is good'); + the_science_is_good(the_science.data); + } + else { + console.error('the science is bad'); + } +} + +/** + * window_message_handler handles all messages sent into the event bus, + * including messages that we sent (yay js). window_message_handler branches on + * whether the message is for us or not (is the science good or bad?). If the + * message is for us (the science is good), then this function is triggered. + * + * The bottom line is this is the function that *actually* handles messages + * from the window + */ +function the_science_is_good(awcp_rcp_data: {id: string|number, method: string, params: object}) { + // example science data: + // // layer 3: json rpc + // {jsonrpc : "2.0", + // id : "ske-connect-1", + // method : "connection.open", + // // layer 4: AWCP-specific semantics + // params : {name : "sidekick examples", + // version : 1}}} + // can assume it is a call + let msg_ident = awcp_rcp_data.id; + let msg_method = awcp_rcp_data.method; + // branch here on the "method" field + switch (msg_method) { + case "connection.open": + post_connect_msg(msg_ident); + break; + case "address.subscribe": + bg_address_subscribe(msg_ident); + break; + case "transaction.sign": + bg_tx_sign(msg_ident, awcp_rcp_data.params); + break; + case "message.sign": + bg_msg_sign(msg_ident, awcp_rcp_data.params); + break; + default: + console.error('the science is worse than i initially thought'); + console.error("we're going to have to put the science to sleep"); + } +} + +/** + * Called in response to "connection.open" requests from page scripts + * + * FIXME: this should query the user to see if he wants to connect + */ +function post_connect_msg(msg_ident: string|number) { + // : EventData_W2A_connection_open + // http://localhost:6969/local-awcp-0.2.1/types/EventData_W2A_connection_open.html + let connect_response = + {type: "to_aepp", + data: {jsonrpc: "2.0", + id: msg_ident, + method: "connection.open", + result: detect_msg}}; + window.postMessage(connect_response, '*'); +} + + +/** + * Called in response to "address.subscribe" requests from page scripts + * + * this is to get the wallet's address + */ +function bg_address_subscribe(msg_ident: string|number) { +} + + +/** + * Called in response to "transaction.sign" requests from page scripts + * + * user wants us to sign a transaction + */ +function bg_tx_sign(msg_ident: string|number, params: object) { +} + +/** + * Called in response to "message.sign" requests from page scripts + * + * user wants us to sign a message + */ +function bg_msg_sign(msg_ident: string|number, params: object) { +} + +// @ts-ignore browser +browser.runtime.onMessage.addListener(handler); +window.addEventListener('message', window_message_handler); +//window.addEventListener('message', function(evt) { console.error('BYYYYYYYYYYYYYYY', evt) }); +//window.addEventListener('click', function() { console.error('HERRRO'); }); + +console.error('poop'); diff --git a/jrx/src/popup.ts b/jrx/src/popup.ts new file mode 100644 index 0000000..89a305d --- /dev/null +++ b/jrx/src/popup.ts @@ -0,0 +1,751 @@ +/** + * This is the script for the popup window + */ + +//import {default as nacl} from './nacl.js'; + +main(); + +/** + * runs whenever the popup opens + */ +async function +main + () + : Promise +{ + // detect button action + document.getElementById('mk-detectable')!.onclick = detuctable; + document.getElementById('generate')!.onclick = generate_keypair; + + // delete keypairs + // browser.storage.local.clear(); + await relist_keypairs(); +} + + + +/** + * Tells the content script to spam the event bus with detection messages + */ +async function +detuctable + () + : Promise +{ + let ati = await active_tab_id(); + // @ts-ignore browser api unknown + browser.tabs.sendMessage(ati, // active tab + 'mk-detectable'); // message + // @ts-ignore disabled exists on this + document.getElementById('mk-detectable').disabled = true; + // FIXME: update button with detect info +} + + +/** + * gets the id of the current tab + */ +async function +active_tab_id + () + : Promise +{ + // @ts-ignore browser api unkown + let active_tabs = await browser.tabs.query({active: true, currentWindow: true}); + return active_tabs[0].id; +} + + +/** + * clear the list of keypairs and relist + * + * clearing is so this can be a re-entry call + */ +async function +relist_keypairs + () + : Promise +{ + // delete all list items + pfizer(document.getElementById('keypairs')!); + // look for keypairs then relist + // @ts-ignore browser api + let obj = await browser.storage.local.get('keypairs'); + await handle_keypairs(obj); +} + + +/** + * kill all child nodes in the dom + */ +function +pfizer + (elt : HTMLElement) + : void +{ + while (elt.firstChild) { + elt.removeChild(elt.firstChild); + } +} + + +/** + * This function is called in the init phase (after the user clicks the popup) + * + * If we have keypairs, put them in the keypairs element in the popup window + * + * Example call objects: + * + * Case of no keypairs: + * + * ```js + * obj = {} + * ``` + * + * Case of a named keypair + * + * ```js + * obj = { + * keypairs: [ + * { + * name: string, + * publicKey: uint8array + * secretKey: uint8array + * }, + * { + * name: string, + * publicKey: uint8array + * secretKey: uint8array + * } + * ] + * } + * ``` + */ +async function +handle_keypairs + (obj : {keypairs? : Array}) + : Promise +{ + logln('handle_keypairs'); + // branch on if there are no keypairs + // no 'keypairs' key + if (!!!obj.keypairs) { + no_keypairs(); + } + // 'keypairs' key but points to empty array + else if (0 === obj.keypairs.length) { + no_keypairs(); + } + else { + await ls_keypairs(obj.keypairs); + } +} + + +/** + * function called if there are no keypairs + */ +function +no_keypairs + () + : void +{ + logln('no keypairs!'); + document.getElementById('no-keypairs')!.hidden = false; +} + +type keypair + = {publicKey : Uint8Array, + secretKey : Uint8Array}; + +type named_keypair + = keypair & {name : string}; +// publicKey : Uint8Array, +// secretKey : Uint8Array}; + + +/** + * This function is called when the user clicks the button to generate a keypair + */ +async function +generate_keypair + () + : Promise +{ + logln('generating a keypair'); + // @ts-ignore namespace nacl + let keypair : keypair = nacl.sign.keyPair(); + // @ts-ignore changing type + keypair.name = "Untitled Keypair 1"; + // fixme: ADD keypair (factor out into separate function) + // @ts-ignore cannot find namespace browser + browser.storage.local.set({'keypairs': [keypair]}); + await relist_keypairs(); +} + + + +/** + * This function is called in the case where there is at least one keypair, and + * it renders the list of keypairs + */ +async function +ls_keypairs + (keypairs : Array) + : Promise +{ + logln('keypairs!'); + console.log('keypairs: ', keypairs) + // make keypair list visible + let keypairs_ul = document.getElementById('keypairs')!; + keypairs_ul.hidden = false; + // render each keypair + for (let kp of keypairs) { + console.log(kp); + await render_keypair(keypairs_ul, kp); + } + //let keypairs_json = JSON.stringify(keypairs, undefined, 4); + //document.getElementById('keypairs').innerHTML = keypairs_json; +} + +/** + * This renders a single keypair item in the list of keypairs + */ +async function +render_keypair + (parent_ul : HTMLElement, + nk : named_keypair) +// {name : string, +// publicKey : Uint8Array} : named_keypair) + : Promise +{ + let name : string = nk.name; + let publicKey : Uint8Array = nk.publicKey; + // create the element + //
    • + let li = document.createElement('li'); + //
    • ->
    • {name}
    • + li.innerHTML += name; + //
    • {name}
    • ->
    • {name}
    • + li.appendChild(document.createElement('br')); + + // + let code : HTMLElement = document.createElement('code'); + let pubkey_str : string = await publicKey_bytes_to_str(publicKey); + // -> ak_... + code.innerHTML += pubkey_str; + //
    • ...
    • ->
    • ......
    • + li.appendChild(code); + + //
        ->
        • ...
        + parent_ul.appendChild(li); +} + + +/** + * take the publicKey bytes and output a string of the form ak_... + */ +async function +publicKey_bytes_to_str + (publicKey_bytes : Uint8Array) + : Promise +{ + // From https://github.com/aeternity/protocol/blob/c007deeac4a01e401238412801ac7084ac72d60e/node/api/api_encoding.md + // + // ```erlang + // add_check_bytes(Bin) when is_binary(Bin) -> + // <> = sha256(sha256(Bin)), + // <>. + // ``` + let bytes_to_encode = await shasha4_concat(publicKey_bytes); + let b58_str = encode(bytes_to_encode); + return 'ak_' + b58_str; +} + +/** + * take the first 4 bytes from sha256(sha256(inputBytes)) and concatenate it onto input, return that + * + * From https://github.com/aeternity/protocol/blob/c007deeac4a01e401238412801ac7084ac72d60e/node/api/api_encoding.md + * + * ```erlang + * add_check_bytes(Bin) when is_binary(Bin) -> + * <> = sha256(sha256(Bin)), + * <>. + * ``` + */ +async function +shasha4_concat + (input_bytes: Uint8Array) + : Promise +{ + let shasha4_bytes = await shasha4(input_bytes); + let input_bytes_length = input_bytes.byteLength; + // this is so dumb + // make blank array + let return_bytes = new Uint8Array(input_bytes_length + 4); + // copy input bytes into it + for (let input_bytes_idx0 = 0; + input_bytes_idx0 < input_bytes_length; + input_bytes_idx0++) + { + return_bytes[input_bytes_idx0] = input_bytes[input_bytes_idx0]; + } + // copy sha bytes + for (let shasha4_bytes_idx0 = 0; + shasha4_bytes_idx0 < 4; + shasha4_bytes_idx0++) + { + // if shasha4_bytes_idx0 = 0, then we want to start at input_bytes_length + let return_bytes_idx0 = input_bytes_length + shasha4_bytes_idx0; + return_bytes[return_bytes_idx0] = shasha4_bytes[shasha4_bytes_idx0]; + } + return return_bytes; +} + +/** + * the first 4 bytes of the sha256 of the sha256 of the input + * + * returns a Uint8Array + */ +async function +shasha4 + (input_bytes : Uint8Array) + : Promise +{ + let x = await crypto.subtle.digest('SHA-256', input_bytes); + let y = await crypto.subtle.digest('SHA-256', x); + let z = y.slice(0, 4); + return new Uint8Array(z); +} + + + + +/** + * Console.log the message and put it in the log thing + */ +function +logln + (message : string) + : void +{ + console.log(message); + document.getElementById('log')!.innerHTML += message; + document.getElementById('log')!.innerHTML += '\n'; +} + + + +/** + * Base58 encoding/decoding + */ + + +//============================================================================= +// ENCODING +//============================================================================= + +/** + * Encode a Uint8Array into base58 + */ +function +encode + (binary : Uint8Array) + : string +{ + let num_leading_zeros : number = nlz(binary); + let rest : Uint8Array = binary.slice(num_leading_zeros); + let ones : string = encode_zeros(num_leading_zeros); + let rest_b58 : string = encode_rest(rest); + let result : string = ones + rest_b58; + return result; +} + + + +/** + * count the number of leading zeros in a uint8array + * + * @internal + */ +function +nlz + (bytes: Uint8Array) + : number +{ + let n = 0; + for (let this_byte of bytes) + { + if (0 === this_byte) { n++; } + else { break; } + } + return n; +} + + + +/** + * Generate a bunch of '1's for however many leading zeros there are + * + * @internal + */ +function +encode_zeros + (how_many : number) + : string +{ + let ones : string = ''; + for (let i = 1; + i <= how_many; + i++) + { + ones += '1'; + } + + return ones; +} + + + +/** + * Encode a Uint8Array that has no leading zeros + * + * @internal + */ +function +encode_rest + (bytes : Uint8Array) + : string +{ + let bytes_bignum : bigint = bytes_to_bigint(bytes); + let result : string = bignum_to_base58(bytes_bignum); + return result; +} + + + +/** + * Convert a bytestring to a bignum + * + * @internal + */ +function +bytes_to_bigint + (bytes: Uint8Array) + : bigint +{ + let acc_bigint : bigint = 0n; + for(let this_byte of bytes) + { + acc_bigint <<= 8n; + acc_bigint += BigInt(this_byte); + } + return acc_bigint; +} + + + +/** + * Convert a BigInt to Base58 + * + * @internal + */ +function +bignum_to_base58 + (q: bigint) + : string +{ + let s = ''; + while (q !== 0n) + { + let this_n : bigint = q % 58n; + q /= 58n; + + let this_b58_char : string = bigint_to_char(this_n); + s = this_b58_char + s; + } + return s; +} + + + +//============================================================================= +// DECODING +//============================================================================= + +/** + * Decode a Base58 string into a Uint8Array + */ +function +decode + (base58: string) + : Uint8Array +{ + let num_leading_ones : number = nlo(base58); + let rest : string = base58.slice(num_leading_ones); + let zeros : Array = decode_ones(num_leading_ones); + let rest_arr : Array = decode_rest(rest); + let pre_result : Array = zeros.concat(rest_arr); + return new Uint8Array(pre_result); +} + + + +/** + * count the number of leading 1 characters in a uint8array + * + * @internal + */ +function +nlo + (base58: string) + : number +{ + let n = 0; + for (let this_char of base58) + { + if ('1' === this_char) { n++; } + else { break; } + } + return n; +} + + + +/** + * Generate a bunch of '0's for however many leading ones there are + * + * @internal + */ +function +decode_ones + (how_many : number) + : Array +{ + let zeros : Array = []; + for (let i = 1; + i <= how_many; + i++) + { + zeros.push(0); + } + + return zeros; +} + + + +/** + * Decode a string that has no leading 1s + * + * @internal + */ +function +decode_rest + (base58: string) + : Array +{ + let result_bignum : bigint = base58_to_bigint(base58); + let result : Array = bigint_to_base256(result_bignum); + return result; +} + + + +/** + * Convert a base58 string to a bignum + * + * @internal + */ +function +base58_to_bigint + (base58: string) + : bigint +{ + let acc_bigint : bigint = 0n; + for(let this_char of base58) + { + acc_bigint *= 58n; + acc_bigint += char_to_bigint(this_char); + } + return acc_bigint; +} + + +/** + * convert a bignum into a byte array + * + * @end + */ +function +bigint_to_base256 + (q: bigint) + : Array +{ + let arr_reverse = []; + while(q !== 0n) + { + let r: number = Number(q % 256n); + q /= 256n; + arr_reverse.push(r); + } + arr_reverse.reverse(); + return arr_reverse; +} + + +//============================================================================= +// TRANSLATION TABLES +//============================================================================= + + +/** + * Base58 integer -> character conversion table + * + * @internal + */ +function +bigint_to_char + (n: bigint) + : string +{ + switch(n) { + case 0n: return '1'; + case 1n: return '2'; + case 2n: return '3'; + case 3n: return '4'; + case 4n: return '5'; + case 5n: return '6'; + case 6n: return '7'; + case 7n: return '8'; + case 8n: return '9'; + case 9n: return 'A'; + case 10n: return 'B'; + case 11n: return 'C'; + case 12n: return 'D'; + case 13n: return 'E'; + case 14n: return 'F'; + case 15n: return 'G'; + case 16n: return 'H'; + case 17n: return 'J'; + case 18n: return 'K'; + case 19n: return 'L'; + case 20n: return 'M'; + case 21n: return 'N'; + case 22n: return 'P'; + case 23n: return 'Q'; + case 24n: return 'R'; + case 25n: return 'S'; + case 26n: return 'T'; + case 27n: return 'U'; + case 28n: return 'V'; + case 29n: return 'W'; + case 30n: return 'X'; + case 31n: return 'Y'; + case 32n: return 'Z'; + case 33n: return 'a'; + case 34n: return 'b'; + case 35n: return 'c'; + case 36n: return 'd'; + case 37n: return 'e'; + case 38n: return 'f'; + case 39n: return 'g'; + case 40n: return 'h'; + case 41n: return 'i'; + case 42n: return 'j'; + case 43n: return 'k'; + case 44n: return 'm'; + case 45n: return 'n'; + case 46n: return 'o'; + case 47n: return 'p'; + case 48n: return 'q'; + case 49n: return 'r'; + case 50n: return 's'; + case 51n: return 't'; + case 52n: return 'u'; + case 53n: return 'v'; + case 54n: return 'w'; + case 55n: return 'x'; + case 56n: return 'y'; + case 57n: return 'z'; + default: + throw new Error('invalid base58 bigint: ' + n); + } +} + + + +/** + * Base58 character -> integer conversion table + * + * @internal + */ +function +char_to_bigint + (s: string) + : bigint +{ + switch(s) { + case '1': return 0n; + case '2': return 1n; + case '3': return 2n; + case '4': return 3n; + case '5': return 4n; + case '6': return 5n; + case '7': return 6n; + case '8': return 7n; + case '9': return 8n; + case 'A': return 9n; + case 'B': return 10n; + case 'C': return 11n; + case 'D': return 12n; + case 'E': return 13n; + case 'F': return 14n; + case 'G': return 15n; + case 'H': return 16n; + case 'J': return 17n; + case 'K': return 18n; + case 'L': return 19n; + case 'M': return 20n; + case 'N': return 21n; + case 'P': return 22n; + case 'Q': return 23n; + case 'R': return 24n; + case 'S': return 25n; + case 'T': return 26n; + case 'U': return 27n; + case 'V': return 28n; + case 'W': return 29n; + case 'X': return 30n; + case 'Y': return 31n; + case 'Z': return 32n; + case 'a': return 33n; + case 'b': return 34n; + case 'c': return 35n; + case 'd': return 36n; + case 'e': return 37n; + case 'f': return 38n; + case 'g': return 39n; + case 'h': return 40n; + case 'i': return 41n; + case 'j': return 42n; + case 'k': return 43n; + case 'm': return 44n; + case 'n': return 45n; + case 'o': return 46n; + case 'p': return 47n; + case 'q': return 48n; + case 'r': return 49n; + case 's': return 50n; + case 't': return 51n; + case 'u': return 52n; + case 'v': return 53n; + case 'w': return 54n; + case 'x': return 55n; + case 'y': return 56n; + case 'z': return 57n; + default: + throw new Error('invalid base58 char: ' + s); + } +} diff --git a/jrx/tsconfig.json b/jrx/tsconfig.json new file mode 100644 index 0000000..f240cdc --- /dev/null +++ b/jrx/tsconfig.json @@ -0,0 +1,16 @@ +{"compilerOptions" : {"target" : "es2022", + "strict" : true, + "esModuleInterop" : true, + "skipLibCheck" : true, + "forceConsistentCasingInFileNames" : true, + "noImplicitAny" : true, + "strictNullChecks" : true, + "strictPropertyInitialization" : true, + "sourceMap" : true, + "outDir" : "dist", + "declaration" : true}, + "$schema" : "https://json.schemastore.org/tsconfig", + "display" : "Recommended", + "include" : ["src/**/*"], + "exclude" : ["src/jex_include"], + "composite" : true}