From 11b2ab7249ace2142bb3375bc9614e27f0ea8bc3 Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Wed, 27 Nov 2024 19:31:35 +0100 Subject: [PATCH] fix: suggestions from code review --- docs/src/content/docs/ref/core-advanced.mdx | 36 ++-- src/imports/stdlib.ts | 195 ++++++++++---------- stdlib/std/contract.tact | 8 +- 3 files changed, 122 insertions(+), 117 deletions(-) diff --git a/docs/src/content/docs/ref/core-advanced.mdx b/docs/src/content/docs/ref/core-advanced.mdx index c31a3b207..25dba26cd 100644 --- a/docs/src/content/docs/ref/core-advanced.mdx +++ b/docs/src/content/docs/ref/core-advanced.mdx @@ -21,7 +21,7 @@ Various niche, dangerous or unstable features which can produce unexpected resul fun gasConsumed(): Int; ``` -Returns the [nanoToncoin](/book/integers#nanotoncoin) [`Int{:tact}`][int] amount of [gas][gas] consumed by [TVM][tvm] in the current transaction so far. The resulting value includes the cost of calling this function. +Returns the [nanoToncoin][nanotoncoin] [`Int{:tact}`][int] amount of [gas][gas] consumed by [TVM][tvm] in the current transaction so far. The resulting value includes the cost of calling this function. Usage example: @@ -43,7 +43,7 @@ let gas: Int = gasConsumed(); fun myStorageDue(): Int; ``` -Returns the [nanoToncoin](/book/integers#nanotoncoin) [`Int{:tact}`][int] amount of the accumulated [storage fee][storage-fee] debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated. +Returns the [nanoToncoin][nanotoncoin] [`Int{:tact}`][int] amount of the accumulated [storage fee][storage-fee] debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated. Usage example: @@ -66,9 +66,9 @@ let debt: Int = myStorageDue(); fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int; ``` -Calculates and returns the [storage fee][storage-fee] in [nanoToncoins](/book/integers#nanotoncoin) [`Int{:tact}`][int] for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the [masterchain][masterchain] if `isMasterchain` is `true{:tact}`, otherwise the prices of the [basechain][basechain]. The current prices are obtained from the [config param 18 of TON Blockchain](https://docs.ton.org/develop/howto/blockchain-configs#param-18). +Calculates and returns the [storage fee][storage-fee] in [nanoToncoins][nanotoncoin] [`Int{:tact}`][int] for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the [masterchain][masterchain] if `isMasterchain` is `true{:tact}`, otherwise the prices of the [basechain][basechain]. The current prices are obtained from the [config param 18 of TON Blockchain](https://docs.ton.org/develop/howto/blockchain-configs#param-18). -Note, that the values of `cells` and `bits` are taken modulo their maximum values plus $1$. That is, specifying values higher than those listed in [account state limits (`max_acc_state_cells` and `max_acc_state_bits`)](/book/exit-codes#50) will have the same result as with specifying the exact limits. In addition, make sure you take [deduplication of cells with the same hash][deduplication] into account. +Note, that the values of `cells` and `bits` are taken modulo their maximum values plus $1$. That is, specifying values higher than those listed in [account state limits (`max_acc_state_cells` and `max_acc_state_bits`)](/book/exit-codes#50) will have the same result as with specifying the exact limits. In addition, make sure you take into account the [deduplication of cells with the same hash][deduplication]. Attempts to specify negative number of `cells`, `bits` or `seconds` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. @@ -101,7 +101,7 @@ let fee: Int = getStorageFee(1_000, 1_000, 1_000, false); fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int; ``` -Calculates and returns the [compute fee][compute-fee] in [nanoToncoins](/book/integers#nanotoncoin) [`Int{:tact}`][int] for a transaction that consumed `gasUsed` amount of [gas][gas]. Uses the prices of the [masterchain][masterchain] if `isMasterchain` is `true{:tact}`, otherwise the prices of the [basechain][basechain]. The current prices are obtained from the [config param 20 for the masterchain and config param 21 for the basechain][param-20-21] of TON Blockchain. +Calculates and returns the [compute fee][compute-fee] in [nanoToncoins][nanotoncoin] [`Int{:tact}`][int] for a transaction that consumed `gasUsed` amount of [gas][gas]. Uses the prices of the [masterchain][masterchain] if `isMasterchain` is `true{:tact}`, otherwise the prices of the [basechain][basechain]. The current prices are obtained from the [config param 20 for the masterchain and config param 21 for the basechain][param-20-21] of TON Blockchain. When the `gasUsed` is less than a certain threshold called [`flat_gas_limit`][param-20-21], there's a minimum price to pay based on the value of [`flat_gas_price`][param-20-21]. The less gas is used below this threshold, the higher the minimum price will be. See the example for [`getSimpleComputeFee(){:tact}`](#getsimplecomputefee) to derive that threshold. @@ -163,7 +163,7 @@ extends fun readForwardFee(self: Context): Int; Extension function for the [`Context{:tact}`](/ref/core-common#context). -Reads [forward fee](https://docs.ton.org/develop/smart-contracts/guidelines/processing) and returns it as [`Int{:tact}`][int] amount of [nanoToncoins](/book/integers#nanotoncoin). +Reads [forward fee](https://docs.ton.org/develop/smart-contracts/guidelines/processing) and returns it as [`Int{:tact}`][int] amount of [nanoToncoins][nanotoncoin]. Usage example: @@ -185,13 +185,13 @@ let fwdFee: Int = context().readForwardFee(); fun getForwardFee(cells: Int, bits: Int, isMasterchain: Bool): Int; ``` -Calculates and returns the [forward fee][forward-fee] in [nanoToncoins](/book/integers#nanotoncoin) [`Int{:tact}`][int] for an outgoing message consisting of a given number of `cells` and `bits`. Uses the prices of the [masterchain][masterchain] if `isMasterchain` is `true{:tact}`, otherwise the prices of the [basechain][basechain]. The current prices are obtained from the [config param 24 for the masterchain and config param 25 for the basechain][param-24-25] of TON Blockchain. +Calculates and returns the [forward fee][forward-fee] in [nanoToncoins][nanotoncoin] [`Int{:tact}`][int] for an outgoing message consisting of a given number of `cells` and `bits`. Uses the prices of the [masterchain][masterchain] if `isMasterchain` is `true{:tact}`, otherwise the prices of the [basechain][basechain]. The current prices are obtained from the [config param 24 for the masterchain and config param 25 for the basechain][param-24-25] of TON Blockchain. If both the source and the destination addresses are in the [basechain][basechain], then specify `isMasterchain` as `false{:tact}`. Otherwise, specify `true{:tact}`. -Note, that the values of `cells` and `bits` are taken modulo their maximum values plus $1$. That is, specifying values higher than those listed in [account state limits (`max_msg_cells` and `max_msg_bits`)](/book/exit-codes#50) will have the same result as with specifying the exact limits. In addition, make sure you take [deduplication of cells with the same hash][deduplication] into account. +Note, that the values of `cells` and `bits` are taken modulo their maximum values plus $1$. That is, specifying values higher than those listed in [account state limits (`max_msg_cells` and `max_msg_bits`)](/book/exit-codes#50) will have the same result as with specifying the exact limits. -However, regardless of the values of `cells` and `bits`, this function always adds the minimum price based on the value of [`lump_price`][param-24-25]. See the example for [`getSimpleForwardFee(){:tact}`](#getsimpleforwardfee) to derive it. +However, regardless of the values of `cells` and `bits`, this function always adds the minimum price based on the value of [`lump_price`][param-24-25]. See the example for [`getSimpleForwardFee(){:tact}`](#getsimpleforwardfee) to derive it. In addition, make sure you take into account the [deduplication of cells with the same hash][deduplication], since for example the root cell and its data bits don't count towards the forward fee and are covered by the [`lump_price`][param-24-25]. Attempts to specify negative number of `cells` or `bits` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. @@ -212,6 +212,7 @@ let fee: Int = getForwardFee(1_000, 1_000, false); [Forward fee in TON Docs][forward-fee]\ [Forward fee calculation in TON Docs][forward-fee-calc]\ + [`CDATASIZEQ` instruction for computing the number of distinct cells, data bits and refs in a `Cell{:tact}`](https://docs.ton.org/v3/documentation/tvm/instructions#F940)\ [`getSimpleForwardFee(){:tact}`](#getsimpleforwardfee)\ [`getOriginalFwdFee(){:tact}`](#getoriginalfwdfee) @@ -253,9 +254,9 @@ let lumpPrice = fee - feeNoLump; fun getOriginalFwdFee(fwdFee: Int, isMasterchain: Bool): Int; ``` -Calculates and returns the so-called _original_ [forward fee][forward-fee] in [nanoToncoins](/book/integers#nanotoncoin) [`Int{:tact}`][int] for an outgoing message based on the `fwdFee` obtained from the incoming message. If both the source and the destination addresses are in the [basechain][basechain], then specify `isMasterchain` as `false{:tact}`. Otherwise, specify `true{:tact}`. +Calculates and returns the so-called _original_ [forward fee][forward-fee] in [nanoToncoins][nanotoncoin] [`Int{:tact}`][int] for an outgoing message based on the `fwdFee` obtained from the incoming message. If both the source and the destination addresses are in the [basechain][basechain], then specify `isMasterchain` as `false{:tact}`. Otherwise, specify `true{:tact}`. -This function is useful when the outgoing message depends heavily on the structure of the incoming message, so much so that you cannot fully predict the fee using [`getForwardFee(){:tact}`](#getforwardfee) alone. +This function is useful when the outgoing message depends heavily on the structure of the incoming message, so much so that you cannot fully predict the fee using [`getForwardFee(){:tact}`](#getforwardfee) alone. Even if you could, calculating the exact fee with [nanoToncoin][nanotoncoin]-level precision can be very expensive, so the approximation given by this function is often good enough. Attempts to specify a negative value of `fwdFee` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. @@ -445,7 +446,7 @@ fun nativeSendMessage(cell: Cell, mode: Int); fun nativeReserve(amount: Int, mode: Int); ``` -Calls native `raw_reserve` function with specified amount and mode. The `raw_reserve` is a function that creates an output action to reserve a specific amount of [nanoToncoins](/book/integers#nanotoncoin) from the remaining balance of the account. +Calls native `raw_reserve` function with specified amount and mode. The `raw_reserve` is a function that creates an output action to reserve a specific amount of [nanoToncoins][nanotoncoin] from the remaining balance of the account. It has the following signature in FunC: @@ -454,10 +455,10 @@ raw_reserve(int amount, int mode) impure asm "RAWRESERVE"; ``` The function takes two arguments: -* `amount`: The number of [nanoToncoins](/book/integers#nanotoncoin) to reserve. +* `amount`: The number of [nanoToncoins][nanotoncoin] to reserve. * `mode`: Determines the reservation behavior. -Function `raw_reserve` is roughly equivalent to creating an outbound message carrying the specified `amount` of [nanoToncoins](/book/integers#nanotoncoin) (or `b` $-$ `amount` [nanoToncoins](/book/integers#nanotoncoin), where `b` is the remaining balance) to oneself. This ensures that subsequent output actions cannot spend more money than the remainder. +Function `raw_reserve` is roughly equivalent to creating an outbound message carrying the specified `amount` of [nanoToncoins][nanotoncoin] (or `b` $-$ `amount` [nanoToncoins][nanotoncoin], where `b` is the remaining balance) to oneself. This ensures that subsequent output actions cannot spend more money than the remainder. It's possible to use raw [`Int{:tact}`][int] values and manually provide them for the `mode`, but for your convenience there's a set of constants which you may use to construct the compound `mode` with ease. Take a look at the following tables for more information on base modes and optional flags. @@ -473,9 +474,9 @@ The resulting `mode` value can have the following base modes: Mode value | Constant name | Description ---------: | :---------------------------- | ----------- -$0$ | `ReserveExact{:tact}` | Reserves exactly the specified `amount` of [nanoToncoins](/book/integers#nanotoncoin). -$1$ | `ReserveAllExcept{:tact}` | Reserves all, but the specified `amount` of [nanoToncoins](/book/integers#nanotoncoin). -$2$ | `ReserveAtMost{:tact}` | Reserves at most the specified `amount` of [nanoToncoins](/book/integers#nanotoncoin). +$0$ | `ReserveExact{:tact}` | Reserves exactly the specified `amount` of [nanoToncoins][nanotoncoin]. +$1$ | `ReserveAllExcept{:tact}` | Reserves all, but the specified `amount` of [nanoToncoins][nanotoncoin]. +$2$ | `ReserveAtMost{:tact}` | Reserves at most the specified `amount` of [nanoToncoins][nanotoncoin]. ### Optional flags {#nativereserve-optional-flags} @@ -582,6 +583,7 @@ parsedVarAddr.address.loadUint(123); // 345 [s]: /book/structs-and-messages#structs [masterchain]: /book/masterchain [cell-hash]: /ref/core-cell#cellhash +[nanotoncoin]: /book/integers#nanotoncoin [tvm]: https://docs.ton.org/learn/tvm-instructions/tvm-overview [basechain]: https://docs.ton.org/v3/concepts/ton-blockchain/smart-contract-addresses#address-components diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index 8ac68429e..f38b5ce7c 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -222,102 +222,105 @@ files['std/contract.tact'] = 'ZnJvbSB0aGUgY29uZmlnIHBhcmFtIDE4IG9mIFRPTiBCbG9ja2NoYWluLgovLy8KLy8vIE5vdGUsIHRoYXQgdGhlIHZhbHVlcyBvZiBgY2VsbHNgIGFuZCBgYml0c2Ag' + 'YXJlIHRha2VuIG1vZHVsbyB0aGVpciBtYXhpbXVtIHZhbHVlcyBwbHVzIDEuIFRoYXQgaXMsIHNwZWNpZnlpbmcgdmFsdWVzIGhpZ2hlciB0aGFuIHRob3NlIGxpc3Rl' + 'ZCBpbiBhY2NvdW50IHN0YXRlIGxpbWl0cyAoYG1heF9hY2Nfc3RhdGVfY2VsbHNgIGFuZCBgbWF4X2FjY19zdGF0ZV9iaXRzYCkgd2lsbCBoYXZlIHRoZSBzYW1lIHJl' + - 'c3VsdCBhcyB3aXRoIHNwZWNpZnlpbmcgdGhlIGV4YWN0IGxpbWl0cy4gSW4gYWRkaXRpb24sIG1ha2Ugc3VyZSB5b3UgdGFrZSBkZWR1cGxpY2F0aW9uIG9mIGNlbGxz' + - 'IHdpdGggdGhlIHNhbWUgaGFzaCBpbnRvIGFjY291bnQuCi8vLwovLy8gQXR0ZW1wdHMgdG8gc3BlY2lmeSBuZWdhdGl2ZSBudW1iZXIgb2YgYGNlbGxzYCwgYGJpdHNg' + - 'IG9yIGBzZWNvbmRzYCB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBleGl0IGNvZGUgNTogYEludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlYC4KLy8vCi8vLyBgYGB0' + - 'YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgZmVlOiBJbnQgPSBnZXRTdG9yYWdlRmVlKDFfMDAwLCAxXzAwMCwgMV8wMDAsIGZhbHNlKTsKLy8vIH0K' + - 'Ly8vIGBgYAovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0c3RvcmFnZWZlZQovLy8gKiBodHRw' + - 'czovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNnZXRzaW1wbGVzdG9yYWdlZmVlCi8vLwphc20gZnVuIGdldFN0b3JhZ2VGZWUoY2VsbHM6IElu' + - 'dCwgYml0czogSW50LCBzZWNvbmRzOiBJbnQsIGlzTWFzdGVyY2hhaW46IEJvb2wpOiBJbnQgeyBHRVRTVE9SQUdFRkVFIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2' + - 'YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8vIENhbGN1bGF0ZXMgYW5kIHJldHVybnMgdGhlIGNvbXB1dGUgZmVlIGluIG5hbm9Ub25jb2lucyBgSW50YCBm' + - 'b3IgYSB0cmFuc2FjdGlvbiB0aGF0IGNvbnN1bWVkIGBnYXNVc2VkYCBhbW91bnQgb2YgZ2FzLiBVc2VzIHRoZSBwcmljZXMgb2YgdGhlIG1hc3RlcmNoYWluIGlmIGBp' + - 'c01hc3RlcmNoYWluYCBpcyBgdHJ1ZWAsIG90aGVyd2lzZSB0aGUgcHJpY2VzIG9mIHRoZSBiYXNlY2hhaW4uIFRoZSBjdXJyZW50IHByaWNlcyBhcmUgb2J0YWluZWQg' + - 'ZnJvbSB0aGUgY29uZmlnIHBhcmFtIDIwIGZvciB0aGUgbWFzdGVyY2hhaW4gYW5kIGNvbmZpZyBwYXJhbSAyMSBmb3IgdGhlIGJhc2VjaGFpbiBvZiBUT04gQmxvY2tj' + - 'aGFpbi4KLy8vCi8vLyBXaGVuIHRoZSBgZ2FzVXNlZGAgaXMgbGVzcyB0aGFuIGEgY2VydGFpbiB0aHJlc2hvbGQgY2FsbGVkIGBmbGF0X2dhc19saW1pdGAsIHRoZXJl' + - 'J3MgYSBtaW5pbXVtIHByaWNlIHRvIHBheSBiYXNlZCBvbiB0aGUgdmFsdWUgb2YgYGZsYXRfZ2FzX3ByaWNlYC4gVGhlIGxlc3MgZ2FzIGlzIHVzZWQgYmVsb3cgdGhp' + - 'cyB0aHJlc2hvbGQsIHRoZSBoaWdoZXIgdGhlIG1pbmltdW0gcHJpY2Ugd2lsbCBiZS4gU2VlIHRoZSBleGFtcGxlIGZvciBgZ2V0U2ltcGxlQ29tcHV0ZUZlZSgpYCB0' + - 'byBkZXJpdmUgdGhhdCB0aHJlc2hvbGQuCi8vLwovLy8gQXR0ZW1wdHMgdG8gc3BlY2lmeSBuZWdhdGl2ZSB2YWx1ZSBvZiBgZ2FzVXNlZGAgdGhyb3cgYW4gZXhjZXB0' + - 'aW9uIHdpdGggZXhpdCBjb2RlIDU6IGBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAg' + - 'ICAgbGV0IGZlZTogSW50ID0gZ2V0Q29tcHV0ZUZlZSgxXzAwMCwgZmFsc2UpOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5n' + - 'Lm9yZy9yZWYvY29yZS1hZHZhbmNlZCNnZXRjb21wdXRlZmVlCi8vLwphc20gZnVuIGdldENvbXB1dGVGZWUoZ2FzVXNlZDogSW50LCBpc01hc3RlcmNoYWluOiBCb29s' + - 'KTogSW50IHsgR0VUR0FTRkVFIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8vIFNpbWlsYXIgdG8gYGdldENv' + - 'bXB1dGVGZWUoKWAsIGJ1dCB3aXRob3V0IHRoZSBgZmxhdF9nYXNfcHJpY2VgLCBpLmUuIHdpdGhvdXQgYSBtaW5pbXVtIHByaWNlIHRvIHBheSBpZiB0aGUgYGdhc1Vz' + - 'ZWRgIGlzIGxlc3MgdGhhbiBhIGNlcnRhaW4gdGhyZXNob2xkIGNhbGxlZCBgZmxhdF9nYXNfbGltaXRgLiBDYWxjdWxhdGVzIGFuZCByZXR1cm5zIG9ubHkgdGhlIGBn' + - 'YXNVc2VkYCB0aW1lcyB0aGUgY3VycmVudCBnYXMgcHJpY2UuCi8vLwovLy8gQXR0ZW1wdHMgdG8gc3BlY2lmeSBuZWdhdGl2ZSBudW1iZXIgb2YgYGNlbGxzYCwgYGJp' + - 'dHNgIG9yIGBzZWNvbmRzYCB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBleGl0IGNvZGUgNTogYEludGVnZXIgb3V0IG9mIGV4cGVjdGVkIHJhbmdlYC4KLy8vCi8vLyBg' + - 'YGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgZmVlID0gZ2V0Q29tcHV0ZUZlZSgwLCBmYWxzZSk7Ci8vLyAgICAgbGV0IGZlZU5vRmxhdCA9IGdl' + - 'dFNpbXBsZUNvbXB1dGVGZWUoMCwgZmFsc2UpOwovLy8gICAgIGxldCBtYXhGbGF0UHJpY2UgPSBmZWUgLSBmZWVOb0ZsYXQ7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBT' + - 'ZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldHNpbXBsZXN0b3JhZ2VmZWUKLy8vICogaHR0cHM6Ly9kb2NzLnRh' + - 'Y3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0c3RvcmFnZWZlZQovLy8KYXNtIGZ1biBnZXRTaW1wbGVDb21wdXRlRmVlKGdhc1VzZWQ6IEludCwgaXNNYXN0' + - 'ZXJjaGFpbjogQm9vbCk6IEludCB7IEdFVEdBU0ZFRVNJTVBMRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8v' + - 'LyBDYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBmb3J3YXJkIGZlZSBpbiBuYW5vVG9uY29pbnMgYEludGAgZm9yIGFuIG91dGdvaW5nIG1lc3NhZ2UgY29uc2lzdGlu' + - 'ZyBvZiBhIGdpdmVuIG51bWJlciBvZiBgY2VsbHNgIGFuZCBgYml0c2AuIFVzZXMgdGhlIHByaWNlcyBvZiB0aGUgbWFzdGVyY2hhaW4gaWYgYGlzTWFzdGVyY2hhaW5g' + - 'IGlzIGB0cnVlezp0YWN0fWAsIG90aGVyd2lzZSB0aGUgcHJpY2VzIG9mIHRoZSBiYXNlY2hhaW4uIFRoZSBjdXJyZW50IHByaWNlcyBhcmUgb2J0YWluZWQgZnJvbSB0' + - 'aGUgY29uZmlnIHBhcmFtIDI0IGZvciB0aGUgbWFzdGVyY2hhaW4gYW5kIGNvbmZpZyBwYXJhbSAyNSBmb3IgdGhlIGJhc2VjaGFpbiBvZiBUT04gQmxvY2tjaGFpbi4K' + - 'Ly8vCi8vLyBJZiBib3RoIHRoZSBzb3VyY2UgYW5kIHRoZSBkZXN0aW5hdGlvbiBhZGRyZXNzZXMgYXJlIGluIHRoZSBiYXNlY2hhaW4sIHRoZW4gc3BlY2lmeSBgaXNN' + - 'YXN0ZXJjaGFpbmAgYXMgYGZhbHNlYC4gT3RoZXJ3aXNlLCBzcGVjaWZ5IGB0cnVlYC4KLy8vCi8vLyBOb3RlLCB0aGF0IHRoZSB2YWx1ZXMgb2YgYGNlbGxzYCBhbmQg' + - 'YGJpdHNgIGFyZSB0YWtlbiBtb2R1bG8gdGhlaXIgbWF4aW11bSB2YWx1ZXMgcGx1cyAxLiBUaGF0IGlzLCBzcGVjaWZ5aW5nIHZhbHVlcyBoaWdoZXIgdGhhbiB0aG9z' + - 'ZSBsaXN0ZWQgaW4gYWNjb3VudCBzdGF0ZSBsaW1pdHMgKGBtYXhfbXNnX2NlbGxzYCBhbmQgYG1heF9tc2dfYml0c2ApIHdpbGwgaGF2ZSB0aGUgc2FtZSByZXN1bHQg' + - 'YXMgd2l0aCBzcGVjaWZ5aW5nIHRoZSBleGFjdCBsaW1pdHMuIEluIGFkZGl0aW9uLCBtYWtlIHN1cmUgeW91IHRha2UgZGVkdXBsaWNhdGlvbiBvZiBjZWxscyB3aXRo' + - 'IHRoZSBzYW1lIGhhc2ggaW50byBhY2NvdW50LgovLy8KLy8vIEhvd2V2ZXIsIHJlZ2FyZGxlc3Mgb2YgdGhlIHZhbHVlcyBvZiBgY2VsbHNgIGFuZCBgYml0c2AsIHRo' + - 'aXMgZnVuY3Rpb24gYWx3YXlzIGFkZHMgdGhlIG1pbmltdW0gcHJpY2UgYmFzZWQgb24gdGhlIHZhbHVlIG9mIGBsdW1wX3ByaWNlYC4gU2VlIHRoZSBleGFtcGxlIGZv' + - 'ciBbYGdldFNpbXBsZUZvcndhcmRGZWUoKXs6dGFjdH1gXSgjZ2V0c2ltcGxlZm9yd2FyZGZlZSkgdG8gZGVyaXZlIGl0LgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNp' + - 'ZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2Agb3IgYGJpdHNgIHRocm93IGFuIGV4Y2VwdGlvbiB3aXRoIGV4aXQgY29kZSA1OiBgSW50ZWdlciBvdXQgb2YgZXhw' + - 'ZWN0ZWQgcmFuZ2VgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBmZWU6IEludCA9IGdldEZvcndhcmRGZWUoMV8wMDAsIDFf' + - 'MDAwLCBmYWxzZSk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldGZv' + - 'cndhcmRmZWUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0c2ltcGxlZm9yd2FyZGZlZQovLy8gKiBodHRwczovL2Rv' + - 'Y3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNnZXRvcmlnaW5hbGZ3ZGZlZQovLy8KYXNtIGZ1biBnZXRGb3J3YXJkRmVlKGNlbGxzOiBJbnQsIGJpdHM6' + - 'IEludCwgaXNNYXN0ZXJjaGFpbjogQm9vbCk6IEludCB7IEdFVEZPUldBUkRGRUUgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41' + - 'LjAuCi8vLwovLy8gU2ltaWxhciB0byBgZ2V0Rm9yd2FyZEZlZSgpYCwgYnV0IHdpdGhvdXQgdGhlIGBsdW1wX3ByaWNlYCwgaS5lLiB3aXRob3V0IHRoZSBtaW5pbXVt' + - 'IHByaWNlIHRvIHBheSByZWdhcmRsZXNzIG9mIHRoZSBhbW91bnQgb2YgYGNlbGxzYCBvciBgYml0c2AuIENhbGN1bGF0ZXMgYW5kIHJldHVybnMgb25seSB0aGUgYGNl' + - 'bGxzYCB0aW1lcyB0aGUgY3VycmVudCBjZWxsIHByaWNlIHBsdXMgYGJpdHNgIHRpbWVzIHRoZSBjdXJyZW50IGJpdCBwcmljZS4KLy8vCi8vLyBBdHRlbXB0cyB0byBz' + - 'cGVjaWZ5IG5lZ2F0aXZlIG51bWJlciBvZiBgY2VsbHNgIG9yIGBiaXRzYCB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBleGl0IGNvZGUgNTogYEludGVnZXIgb3V0IG9m' + - 'IGV4cGVjdGVkIHJhbmdlYC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgZmVlID0gZ2V0Rm9yd2FyZEZlZSgxXzAwMCwgMV8w' + - 'MDAsIGZhbHNlKTsKLy8vICAgICBsZXQgZmVlTm9MdW1wID0gZ2V0U2ltcGxlRm9yd2FyZEZlZSgxXzAwMCwgMV8wMDAsIGZhbHNlKTsKLy8vICAgICBsZXQgbHVtcFBy' + - 'aWNlID0gZmVlIC0gZmVlTm9MdW1wOwovLy8gfQovLy8gYGBgCi8vLwovLy8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZh' + - 'bmNlZCNnZXRzaW1wbGVmb3J3YXJkZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldGZvcndhcmRmZWUKLy8vCmFz' + - 'bSBmdW4gZ2V0U2ltcGxlRm9yd2FyZEZlZShjZWxsczogSW50LCBiaXRzOiBJbnQsIGlzTWFzdGVyY2hhaW46IEJvb2wpOiBJbnQgeyBHRVRGT1JXQVJERkVFU0lNUExF' + - 'IH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8vIENhbGN1bGF0ZXMgYW5kIHJldHVybnMgdGhlIHNvLWNhbGxl' + - 'ZCBfb3JpZ2luYWxfIGZvcndhcmQgZmVlIGluIG5hbm9Ub25jb2lucyBgSW50YCBmb3IgYW4gb3V0Z29pbmcgbWVzc2FnZSBiYXNlZCBvbiB0aGUgYGZ3ZEZlZWAgb2J0' + - 'YWluZWQgZnJvbSB0aGUgaW5jb21pbmcgbWVzc2FnZS4gSWYgYm90aCB0aGUgc291cmNlIGFuZCB0aGUgZGVzdGluYXRpb24gYWRkcmVzc2VzIGFyZSBpbiB0aGUgYmFz' + - 'ZWNoYWluLCB0aGVuIHNwZWNpZnkgYGlzTWFzdGVyY2hhaW5gIGFzIGBmYWxzZWAuIE90aGVyd2lzZSwgc3BlY2lmeSBgdHJ1ZWAuCi8vLwovLy8gVGhpcyBmdW5jdGlv' + - 'biBpcyB1c2VmdWwgd2hlbiB0aGUgb3V0Z29pbmcgbWVzc2FnZSBkZXBlbmRzIGhlYXZpbHkgb24gdGhlIHN0cnVjdHVyZSBvZiB0aGUgaW5jb21pbmcgbWVzc2FnZSwg' + - 'c28gbXVjaCBzbyB0aGF0IHlvdSBjYW5ub3QgZnVsbHkgcHJlZGljdCB0aGUgZmVlIHVzaW5nIGBnZXRGb3J3YXJkRmVlKClgIGFsb25lLgovLy8KLy8vIEF0dGVtcHRz' + - 'IHRvIHNwZWNpZnkgYSBuZWdhdGl2ZSB2YWx1ZSBvZiBgZndkRmVlYCB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBleGl0IGNvZGUgNTogYEludGVnZXIgb3V0IG9mIGV4' + - 'cGVjdGVkIHJhbmdlYC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgZndkRmVlOiBJbnQgPSBjb250ZXh0KCkucmVhZEZvcndh' + - 'cmRGZWUoKTsKLy8vICAgICBsZXQgb3JpZ0ZlZTogSW50ID0gZ2V0T3JpZ2luYWxGd2RGZWUoZmVlLCBmYWxzZSk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8v' + - 'LyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldG9yaWdpbmFsZndkZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcu' + - 'b3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldGZvcndhcmRmZWUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjY29udGV4dHJl' + - 'YWRmb3J3YXJkZmVlCi8vLwphc20gZnVuIGdldE9yaWdpbmFsRndkRmVlKGZ3ZEZlZTogSW50LCBpc01hc3RlcmNoYWluOiBCb29sKTogSW50IHsgR0VUT1JJR0lOQUxG' + - 'V0RGRUUgfQoKLy8vIFN0cnVjdCByZXByZXNlbnRpbmcgdGhlIHN0YW5kYXJkIGFkZHJlc3Mgb24gVE9OIEJsb2NrY2hhaW4gd2l0aCBzaWduZWQgOC1iaXQgYHdvcmtj' + - 'aGFpbmAgSUQgYW5kIGFuIHVuc2lnbmVkIDI1Ni1iaXQgYGFkZHJlc3NgIGluIHRoZSBzcGVjaWZpZWQgYHdvcmtjaGFpbmAuIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEu' + - 'NS4wLgovLy8KLy8vIEF0IHRoZSBtb21lbnQsIG9ubHkgYHdvcmtjaGFpbmAgSURzIHVzZWQgb24gVE9OIGFyZSAwIG9mIHRoZSBiYXNlY2hhaW4gYW5kIC0xIG9mIHRo' + - 'ZSBtYXN0ZXJjaGFpbi4KLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI3BhcnNlc3RkYWRkcmVzcwov' + - 'Ly8gKiBodHRwczovL2dpdGh1Yi5jb20vdG9uLWJsb2NrY2hhaW4vdG9uL2Jsb2IvbWFzdGVyL2NyeXB0by9ibG9jay9ibG9jay50bGIjTDEwNS1MMTA2Ci8vLwpzdHJ1' + - 'Y3QgU3RkQWRkcmVzcyB7CiAgICB3b3JrY2hhaW46IEludCBhcyBpbnQ4OwogICAgYWRkcmVzczogSW50IGFzIHVpbnQyNTY7Cn0KCi8vLyBTdHJ1Y3QgcmVwcmVzZW50' + - 'aW5nIHRoZSBhZGRyZXNzIG9mIHZhcmlhYmxlIGxlbmd0aCB3aXRoIHNpZ25lZCAzMi1iaXQgYHdvcmtjaGFpbmAgSUQgYW5kIGEgYFNsaWNlYCBjb250YWluaW5nIHVu' + - 'c2lnbmVkIGBhZGRyZXNzYCBpbiB0aGUgc3BlY2lmaWVkIGB3b3JrY2hhaW5gLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBWYXJpYWJsZS1sZW5n' + - 'dGggYWRkcmVzc2VzIGFyZSBpbnRlbmRlZCBmb3IgZnV0dXJlIGV4dGVuc2lvbnMsIGFuZCB3aGlsZSB2YWxpZGF0b3JzIG11c3QgYmUgcmVhZHkgdG8gYWNjZXB0IHRo' + - 'ZW0gaW4gaW5ib3VuZCBtZXNzYWdlcywgdGhlIHN0YW5kYXJkIChub24tdmFyaWFibGUpIGFkZHJlc3NlcyBhcmUgdXNlZCB3aGVuZXZlciBwb3NzaWJsZS4KLy8vCi8v' + - 'LyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI3BhcnNldmFyYWRkcmVzcwovLy8gKiBodHRwczovL2dpdGh1Yi5j' + - 'b20vdG9uLWJsb2NrY2hhaW4vdG9uL2Jsb2IvbWFzdGVyL2NyeXB0by9ibG9jay9ibG9jay50bGIjTDEwNy1MMTA4Ci8vLwpzdHJ1Y3QgVmFyQWRkcmVzcyB7CiAgICB3' + - 'b3JrY2hhaW46IEludCBhcyBpbnQzMjsKICAgIGFkZHJlc3M6IFNsaWNlOwp9CgovLy8gQXNzZW1ibHkgZnVuY3Rpb24uIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4w' + - 'LgovLy8KLy8vIENvbnZlcnRzIGEgYFNsaWNlYCBjb250YWluaW5nIGFuIGFkZHJlc3MgaW50byB0aGUgYFN0ZEFkZHJlc3NgIFN0cnVjdCBhbmQgcmV0dXJucyBpdC4K' + - 'Ly8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgYWRkciA9IGFkZHJlc3MoIkVRRHRGcEV3Y0ZBRWNSZTVtTFZoMk42QzB4LV9oSkVN' + - 'N1c2MV9KTG5TRjc0cDRxMiIpOwovLy8gICAgIGxldCBwYXJzZWRBZGRyID0gcGFyc2VTdGRBZGRyZXNzKGFkZHIuYXNTbGljZSgpKTsKLy8vCi8vLyAgICAgcGFyc2Vk' + - 'QWRkci53b3JrY2hhaW47IC8vIDAKLy8vICAgICBwYXJzZWRBZGRyLmFkZHJlc3M7ICAgLy8gMTA3Li4uMjg3Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBz' + - 'Oi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI3BhcnNlc3RkYWRkcmVzcwovLy8KYXNtIGZ1biBwYXJzZVN0ZEFkZHJlc3Moc2xpY2U6IFNsaWNl' + - 'KTogU3RkQWRkcmVzcyB7IFJFV1JJVEVTVERBRERSIH0KCi8vLyBBc3NlbWJseSBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gQ29u' + - 'dmVydHMgYSBgU2xpY2VgIGNvbnRhaW5pbmcgYW4gYWRkcmVzcyBvZiB2YXJpYWJsZSBsZW5ndGggaW50byB0aGUgYFZhckFkZHJlc3NgIFN0cnVjdCBhbmQgcmV0dXJu' + - 'cyBpdC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgdmFyQWRkclNsaWNlID0gYmVnaW5DZWxsKCkKLy8vICAgICAgICAgLnN0' + - 'b3JlVWludCg2LCAzKSAgICAgLy8gdG8gcmVjb2duaXplIHRoZSBmb2xsb3dpbmcgYXMgYSBWYXJBZGRyZXNzCi8vLyAgICAgICAgIC5zdG9yZVVpbnQoMTIzLCA5KSAg' + - 'IC8vIG1ha2UgYWRkcmVzcyBvY2N1cHkgMTIzIGJpdHMKLy8vICAgICAgICAgLnN0b3JlVWludCgyMzQsIDMyKSAgLy8gc3BlY2lmeSB3b3JrY2hhaW4gSUQgb2YgMjM0' + - 'Ci8vLyAgICAgICAgIC5zdG9yZVVpbnQoMzQ1LCAxMjMpIC8vIHNwZWNpZnkgYWRkcmVzcyBvZiAzNDUKLy8vICAgICAgICAgLmFzU2xpY2UoKTsKLy8vICAgICBsZXQg' + - 'cGFyc2VkVmFyQWRkciA9IHBhcnNlVmFyQWRkcmVzcyh2YXJBZGRyU2xpY2UpOwovLy8KLy8vICAgICBwYXJzZWRWYXJBZGRyLndvcmtjaGFpbjsgICAgICAgICAgICAg' + - 'Ly8gMjM0Ci8vLyAgICAgcGFyc2VkVmFyQWRkci5hZGRyZXNzOyAgICAgICAgICAgICAgIC8vIENTe0NlbGx7MDAyLi4uMmIzfSBiaXRzOiA0NC4uMTY3OyByZWZzOiAw' + - 'Li4wfQovLy8gICAgIHBhcnNlZFZhckFkZHIuYWRkcmVzcy5sb2FkVWludCgxMjMpOyAvLyAzNDUKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2Nz' + - 'LnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFyc2V2YXJhZGRyZXNzCi8vLwphc20gZnVuIHBhcnNlVmFyQWRkcmVzcyhzbGljZTogU2xpY2UpOiBWYXJB' + - 'ZGRyZXNzIHsgUkVXUklURVZBUkFERFIgfQo='; + 'c3VsdCBhcyB3aXRoIHNwZWNpZnlpbmcgdGhlIGV4YWN0IGxpbWl0cy4gSW4gYWRkaXRpb24sIG1ha2Ugc3VyZSB5b3UgdGFrZSBpbnRvIGFjY291bnQgdGhlIGRlZHVw' + + 'bGljYXRpb24gb2YgY2VsbHMgd2l0aCB0aGUgc2FtZSBoYXNoLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2AsIGBi' + + 'aXRzYCBvciBgc2Vjb25kc2AgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBjb2RlIDU6IGBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZWAuCi8vLwovLy8g' + + 'YGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZlZTogSW50ID0gZ2V0U3RvcmFnZUZlZSgxXzAwMCwgMV8wMDAsIDFfMDAwLCBmYWxzZSk7Ci8v' + + 'LyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldHN0b3JhZ2VmZWUKLy8vICog' + + 'aHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0c2ltcGxlc3RvcmFnZWZlZQovLy8KYXNtIGZ1biBnZXRTdG9yYWdlRmVlKGNlbGxz' + + 'OiBJbnQsIGJpdHM6IEludCwgc2Vjb25kczogSW50LCBpc01hc3RlcmNoYWluOiBCb29sKTogSW50IHsgR0VUU1RPUkFHRUZFRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9u' + + 'LiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBDYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBjb21wdXRlIGZlZSBpbiBuYW5vVG9uY29pbnMgYElu' + + 'dGAgZm9yIGEgdHJhbnNhY3Rpb24gdGhhdCBjb25zdW1lZCBgZ2FzVXNlZGAgYW1vdW50IG9mIGdhcy4gVXNlcyB0aGUgcHJpY2VzIG9mIHRoZSBtYXN0ZXJjaGFpbiBp' + + 'ZiBgaXNNYXN0ZXJjaGFpbmAgaXMgYHRydWVgLCBvdGhlcndpc2UgdGhlIHByaWNlcyBvZiB0aGUgYmFzZWNoYWluLiBUaGUgY3VycmVudCBwcmljZXMgYXJlIG9idGFp' + + 'bmVkIGZyb20gdGhlIGNvbmZpZyBwYXJhbSAyMCBmb3IgdGhlIG1hc3RlcmNoYWluIGFuZCBjb25maWcgcGFyYW0gMjEgZm9yIHRoZSBiYXNlY2hhaW4gb2YgVE9OIEJs' + + 'b2NrY2hhaW4uCi8vLwovLy8gV2hlbiB0aGUgYGdhc1VzZWRgIGlzIGxlc3MgdGhhbiBhIGNlcnRhaW4gdGhyZXNob2xkIGNhbGxlZCBgZmxhdF9nYXNfbGltaXRgLCB0' + + 'aGVyZSdzIGEgbWluaW11bSBwcmljZSB0byBwYXkgYmFzZWQgb24gdGhlIHZhbHVlIG9mIGBmbGF0X2dhc19wcmljZWAuIFRoZSBsZXNzIGdhcyBpcyB1c2VkIGJlbG93' + + 'IHRoaXMgdGhyZXNob2xkLCB0aGUgaGlnaGVyIHRoZSBtaW5pbXVtIHByaWNlIHdpbGwgYmUuIFNlZSB0aGUgZXhhbXBsZSBmb3IgYGdldFNpbXBsZUNvbXB1dGVGZWUo' + + 'KWAgdG8gZGVyaXZlIHRoYXQgdGhyZXNob2xkLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgdmFsdWUgb2YgYGdhc1VzZWRgIHRocm93IGFuIGV4' + + 'Y2VwdGlvbiB3aXRoIGV4aXQgY29kZSA1OiBgSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewov' + + 'Ly8gICAgIGxldCBmZWU6IEludCA9IGdldENvbXB1dGVGZWUoMV8wMDAsIGZhbHNlKTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3Qt' + + 'bGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0Y29tcHV0ZWZlZQovLy8KYXNtIGZ1biBnZXRDb21wdXRlRmVlKGdhc1VzZWQ6IEludCwgaXNNYXN0ZXJjaGFpbjog' + + 'Qm9vbCk6IEludCB7IEdFVEdBU0ZFRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBTaW1pbGFyIHRvIGBn' + + 'ZXRDb21wdXRlRmVlKClgLCBidXQgd2l0aG91dCB0aGUgYGZsYXRfZ2FzX3ByaWNlYCwgaS5lLiB3aXRob3V0IGEgbWluaW11bSBwcmljZSB0byBwYXkgaWYgdGhlIGBn' + + 'YXNVc2VkYCBpcyBsZXNzIHRoYW4gYSBjZXJ0YWluIHRocmVzaG9sZCBjYWxsZWQgYGZsYXRfZ2FzX2xpbWl0YC4gQ2FsY3VsYXRlcyBhbmQgcmV0dXJucyBvbmx5IHRo' + + 'ZSBgZ2FzVXNlZGAgdGltZXMgdGhlIGN1cnJlbnQgZ2FzIHByaWNlLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2As' + + 'IGBiaXRzYCBvciBgc2Vjb25kc2AgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBjb2RlIDU6IGBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZWAuCi8vLwov' + + 'Ly8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZlZSA9IGdldENvbXB1dGVGZWUoMCwgZmFsc2UpOwovLy8gICAgIGxldCBmZWVOb0ZsYXQg' + + 'PSBnZXRTaW1wbGVDb21wdXRlRmVlKDAsIGZhbHNlKTsKLy8vICAgICBsZXQgbWF4RmxhdFByaWNlID0gZmVlIC0gZmVlTm9GbGF0OwovLy8gfQovLy8gYGBgCi8vLwov' + + 'Ly8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNnZXRzaW1wbGVzdG9yYWdlZmVlCi8vLyAqIGh0dHBzOi8vZG9j' + + 'cy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldHN0b3JhZ2VmZWUKLy8vCmFzbSBmdW4gZ2V0U2ltcGxlQ29tcHV0ZUZlZShnYXNVc2VkOiBJbnQsIGlz' + + 'TWFzdGVyY2hhaW46IEJvb2wpOiBJbnQgeyBHRVRHQVNGRUVTSU1QTEUgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8v' + + 'LwovLy8gQ2FsY3VsYXRlcyBhbmQgcmV0dXJucyB0aGUgZm9yd2FyZCBmZWUgaW4gbmFub1RvbmNvaW5zIGBJbnRgIGZvciBhbiBvdXRnb2luZyBtZXNzYWdlIGNvbnNp' + + 'c3Rpbmcgb2YgYSBnaXZlbiBudW1iZXIgb2YgYGNlbGxzYCBhbmQgYGJpdHNgLiBVc2VzIHRoZSBwcmljZXMgb2YgdGhlIG1hc3RlcmNoYWluIGlmIGBpc01hc3RlcmNo' + + 'YWluYCBpcyBgdHJ1ZXs6dGFjdH1gLCBvdGhlcndpc2UgdGhlIHByaWNlcyBvZiB0aGUgYmFzZWNoYWluLiBUaGUgY3VycmVudCBwcmljZXMgYXJlIG9idGFpbmVkIGZy' + + 'b20gdGhlIGNvbmZpZyBwYXJhbSAyNCBmb3IgdGhlIG1hc3RlcmNoYWluIGFuZCBjb25maWcgcGFyYW0gMjUgZm9yIHRoZSBiYXNlY2hhaW4gb2YgVE9OIEJsb2NrY2hh' + + 'aW4uCi8vLwovLy8gSWYgYm90aCB0aGUgc291cmNlIGFuZCB0aGUgZGVzdGluYXRpb24gYWRkcmVzc2VzIGFyZSBpbiB0aGUgYmFzZWNoYWluLCB0aGVuIHNwZWNpZnkg' + + 'YGlzTWFzdGVyY2hhaW5gIGFzIGBmYWxzZWAuIE90aGVyd2lzZSwgc3BlY2lmeSBgdHJ1ZWAuCi8vLwovLy8gTm90ZSwgdGhhdCB0aGUgdmFsdWVzIG9mIGBjZWxsc2Ag' + + 'YW5kIGBiaXRzYCBhcmUgdGFrZW4gbW9kdWxvIHRoZWlyIG1heGltdW0gdmFsdWVzIHBsdXMgMS4gVGhhdCBpcywgc3BlY2lmeWluZyB2YWx1ZXMgaGlnaGVyIHRoYW4g' + + 'dGhvc2UgbGlzdGVkIGluIGFjY291bnQgc3RhdGUgbGltaXRzIChgbWF4X21zZ19jZWxsc2AgYW5kIGBtYXhfbXNnX2JpdHNgKSB3aWxsIGhhdmUgdGhlIHNhbWUgcmVz' + + 'dWx0IGFzIHdpdGggc3BlY2lmeWluZyB0aGUgZXhhY3QgbGltaXRzLgovLy8KLy8vIEhvd2V2ZXIsIHJlZ2FyZGxlc3Mgb2YgdGhlIHZhbHVlcyBvZiBgY2VsbHNgIGFu' + + 'ZCBgYml0c2AsIHRoaXMgZnVuY3Rpb24gYWx3YXlzIGFkZHMgdGhlIG1pbmltdW0gcHJpY2UgYmFzZWQgb24gdGhlIHZhbHVlIG9mIGBsdW1wX3ByaWNlYC4gU2VlIHRo' + + 'ZSBleGFtcGxlIGZvciBbYGdldFNpbXBsZUZvcndhcmRGZWUoKXs6dGFjdH1gXSgjZ2V0c2ltcGxlZm9yd2FyZGZlZSkgdG8gZGVyaXZlIGl0LiBJbiBhZGRpdGlvbiwg' + + 'bWFrZSBzdXJlIHlvdSB0YWtlIGludG8gYWNjb3VudCB0aGUgZGVkdXBsaWNhdGlvbiBvZiBjZWxscyB3aXRoIHRoZSBzYW1lIGhhc2gsIHNpbmNlIGZvciBleGFtcGxl' + + 'IHRoZSByb290IGNlbGwgYW5kIGl0cyBkYXRhIGJpdHMgZG9uJ3QgY291bnQgdG93YXJkcyB0aGUgZm9yd2FyZCBmZWUgYW5kIGFyZSBjb3ZlcmVkIGJ5IHRoZSBgbHVt' + + 'cF9wcmljZWAuCi8vLwovLy8gQXR0ZW1wdHMgdG8gc3BlY2lmeSBuZWdhdGl2ZSBudW1iZXIgb2YgYGNlbGxzYCBvciBgYml0c2AgdGhyb3cgYW4gZXhjZXB0aW9uIHdp' + + 'dGggZXhpdCBjb2RlIDU6IGBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0' + + 'IGZlZTogSW50ID0gZ2V0Rm9yd2FyZEZlZSgxXzAwMCwgMV8wMDAsIGZhbHNlKTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRh' + + 'Y3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0Zm9yd2FyZGZlZQovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNn' + + 'ZXRzaW1wbGVmb3J3YXJkZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldG9yaWdpbmFsZndkZmVlCi8vLwphc20g' + + 'ZnVuIGdldEZvcndhcmRGZWUoY2VsbHM6IEludCwgYml0czogSW50LCBpc01hc3RlcmNoYWluOiBCb29sKTogSW50IHsgR0VURk9SV0FSREZFRSB9CgovLy8gR2xvYmFs' + + 'IGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBTaW1pbGFyIHRvIGBnZXRGb3J3YXJkRmVlKClgLCBidXQgd2l0aG91dCB0aGUgYGx1' + + 'bXBfcHJpY2VgLCBpLmUuIHdpdGhvdXQgdGhlIG1pbmltdW0gcHJpY2UgdG8gcGF5IHJlZ2FyZGxlc3Mgb2YgdGhlIGFtb3VudCBvZiBgY2VsbHNgIG9yIGBiaXRzYC4g' + + 'Q2FsY3VsYXRlcyBhbmQgcmV0dXJucyBvbmx5IHRoZSBgY2VsbHNgIHRpbWVzIHRoZSBjdXJyZW50IGNlbGwgcHJpY2UgcGx1cyBgYml0c2AgdGltZXMgdGhlIGN1cnJl' + + 'bnQgYml0IHByaWNlLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2Agb3IgYGJpdHNgIHRocm93IGFuIGV4Y2VwdGlv' + + 'biB3aXRoIGV4aXQgY29kZSA1OiBgSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAg' + + 'IGxldCBmZWUgPSBnZXRGb3J3YXJkRmVlKDFfMDAwLCAxXzAwMCwgZmFsc2UpOwovLy8gICAgIGxldCBmZWVOb0x1bXAgPSBnZXRTaW1wbGVGb3J3YXJkRmVlKDFfMDAw' + + 'LCAxXzAwMCwgZmFsc2UpOwovLy8gICAgIGxldCBsdW1wUHJpY2UgPSBmZWUgLSBmZWVOb0x1bXA7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBz' + + 'Oi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldHNpbXBsZWZvcndhcmRmZWUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVm' + + 'L2NvcmUtYWR2YW5jZWQjZ2V0Zm9yd2FyZGZlZQovLy8KYXNtIGZ1biBnZXRTaW1wbGVGb3J3YXJkRmVlKGNlbGxzOiBJbnQsIGJpdHM6IEludCwgaXNNYXN0ZXJjaGFp' + + 'bjogQm9vbCk6IEludCB7IEdFVEZPUldBUkRGRUVTSU1QTEUgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8g' + + 'Q2FsY3VsYXRlcyBhbmQgcmV0dXJucyB0aGUgc28tY2FsbGVkIF9vcmlnaW5hbF8gZm9yd2FyZCBmZWUgaW4gbmFub1RvbmNvaW5zIGBJbnRgIGZvciBhbiBvdXRnb2lu' + + 'ZyBtZXNzYWdlIGJhc2VkIG9uIHRoZSBgZndkRmVlYCBvYnRhaW5lZCBmcm9tIHRoZSBpbmNvbWluZyBtZXNzYWdlLiBJZiBib3RoIHRoZSBzb3VyY2UgYW5kIHRoZSBk' + + 'ZXN0aW5hdGlvbiBhZGRyZXNzZXMgYXJlIGluIHRoZSBiYXNlY2hhaW4sIHRoZW4gc3BlY2lmeSBgaXNNYXN0ZXJjaGFpbmAgYXMgYGZhbHNlYC4gT3RoZXJ3aXNlLCBz' + + 'cGVjaWZ5IGB0cnVlYC4KLy8vCi8vLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWZ1bCB3aGVuIHRoZSBvdXRnb2luZyBtZXNzYWdlIGRlcGVuZHMgaGVhdmlseSBvbiB0aGUg' + + 'c3RydWN0dXJlIG9mIHRoZSBpbmNvbWluZyBtZXNzYWdlLCBzbyBtdWNoIHNvIHRoYXQgeW91IGNhbm5vdCBmdWxseSBwcmVkaWN0IHRoZSBmZWUgdXNpbmcgYGdldEZv' + + 'cndhcmRGZWUoKWAgYWxvbmUuIEV2ZW4gaWYgeW91IGNvdWxkLCBjYWxjdWxhdGluZyB0aGUgZXhhY3QgZmVlIHdpdGggbmFub1RvbmNvaW4tbGV2ZWwgcHJlY2lzaW9u' + + 'IGNhbiBiZSB2ZXJ5IGV4cGVuc2l2ZSwgc28gdGhlIGFwcHJveGltYXRlIHZhbHVlIGdpdmVuIGJ5IHRoaXMgZnVuY3Rpb24gaXMgb2Z0ZW4gZ29vZCBlbm91Z2guCi8v' + + 'LwovLy8gQXR0ZW1wdHMgdG8gc3BlY2lmeSBhIG5lZ2F0aXZlIHZhbHVlIG9mIGBmd2RGZWVgIHRocm93IGFuIGV4Y2VwdGlvbiB3aXRoIGV4aXQgY29kZSA1OiBgSW50' + + 'ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBmd2RGZWU6IEludCA9IGNvbnRl' + + 'eHQoKS5yZWFkRm9yd2FyZEZlZSgpOwovLy8gICAgIGxldCBvcmlnRmVlOiBJbnQgPSBnZXRPcmlnaW5hbEZ3ZEZlZShmZWUsIGZhbHNlKTsKLy8vIH0KLy8vIGBgYAov' + + 'Ly8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0b3JpZ2luYWxmd2RmZWUKLy8vICogaHR0cHM6Ly9k' + + 'b2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0Zm9yd2FyZGZlZQovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZh' + + 'bmNlZCNjb250ZXh0cmVhZGZvcndhcmRmZWUKLy8vCmFzbSBmdW4gZ2V0T3JpZ2luYWxGd2RGZWUoZndkRmVlOiBJbnQsIGlzTWFzdGVyY2hhaW46IEJvb2wpOiBJbnQg' + + 'eyBHRVRPUklHSU5BTEZXREZFRSB9CgovLy8gU3RydWN0IHJlcHJlc2VudGluZyB0aGUgc3RhbmRhcmQgYWRkcmVzcyBvbiBUT04gQmxvY2tjaGFpbiB3aXRoIHNpZ25l' + + 'ZCA4LWJpdCBgd29ya2NoYWluYCBJRCBhbmQgYW4gdW5zaWduZWQgMjU2LWJpdCBgYWRkcmVzc2AgaW4gdGhlIHNwZWNpZmllZCBgd29ya2NoYWluYC4gQXZhaWxhYmxl' + + 'IHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gQXQgdGhlIG1vbWVudCwgb25seSBgd29ya2NoYWluYCBJRHMgdXNlZCBvbiBUT04gYXJlIDAgb2YgdGhlIGJhc2VjaGFp' + + 'biBhbmQgLTEgb2YgdGhlIG1hc3RlcmNoYWluLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFy' + + 'c2VzdGRhZGRyZXNzCi8vLyAqIGh0dHBzOi8vZ2l0aHViLmNvbS90b24tYmxvY2tjaGFpbi90b24vYmxvYi9tYXN0ZXIvY3J5cHRvL2Jsb2NrL2Jsb2NrLnRsYiNMMTA1' + + 'LUwxMDYKLy8vCnN0cnVjdCBTdGRBZGRyZXNzIHsKICAgIHdvcmtjaGFpbjogSW50IGFzIGludDg7CiAgICBhZGRyZXNzOiBJbnQgYXMgdWludDI1NjsKfQoKLy8vIFN0' + + 'cnVjdCByZXByZXNlbnRpbmcgdGhlIGFkZHJlc3Mgb2YgdmFyaWFibGUgbGVuZ3RoIHdpdGggc2lnbmVkIDMyLWJpdCBgd29ya2NoYWluYCBJRCBhbmQgYSBgU2xpY2Vg' + + 'IGNvbnRhaW5pbmcgdW5zaWduZWQgYGFkZHJlc3NgIGluIHRoZSBzcGVjaWZpZWQgYHdvcmtjaGFpbmAuIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8v' + + 'IFZhcmlhYmxlLWxlbmd0aCBhZGRyZXNzZXMgYXJlIGludGVuZGVkIGZvciBmdXR1cmUgZXh0ZW5zaW9ucywgYW5kIHdoaWxlIHZhbGlkYXRvcnMgbXVzdCBiZSByZWFk' + + 'eSB0byBhY2NlcHQgdGhlbSBpbiBpbmJvdW5kIG1lc3NhZ2VzLCB0aGUgc3RhbmRhcmQgKG5vbi12YXJpYWJsZSkgYWRkcmVzc2VzIGFyZSB1c2VkIHdoZW5ldmVyIHBv' + + 'c3NpYmxlLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFyc2V2YXJhZGRyZXNzCi8vLyAqIGh0' + + 'dHBzOi8vZ2l0aHViLmNvbS90b24tYmxvY2tjaGFpbi90b24vYmxvYi9tYXN0ZXIvY3J5cHRvL2Jsb2NrL2Jsb2NrLnRsYiNMMTA3LUwxMDgKLy8vCnN0cnVjdCBWYXJB' + + 'ZGRyZXNzIHsKICAgIHdvcmtjaGFpbjogSW50IGFzIGludDMyOwogICAgYWRkcmVzczogU2xpY2U7Cn0KCi8vLyBBc3NlbWJseSBmdW5jdGlvbi4gQXZhaWxhYmxlIHNp' + + 'bmNlIFRhY3QgMS41LjAuCi8vLwovLy8gQ29udmVydHMgYSBgU2xpY2VgIGNvbnRhaW5pbmcgYW4gYWRkcmVzcyBpbnRvIHRoZSBgU3RkQWRkcmVzc2AgU3RydWN0IGFu' + + 'ZCByZXR1cm5zIGl0LgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBhZGRyID0gYWRkcmVzcygiRVFEdEZwRXdjRkFFY1JlNW1M' + + 'VmgyTjZDMHgtX2hKRU03VzYxX0pMblNGNzRwNHEyIik7Ci8vLyAgICAgbGV0IHBhcnNlZEFkZHIgPSBwYXJzZVN0ZEFkZHJlc3MoYWRkci5hc1NsaWNlKCkpOwovLy8K' + + 'Ly8vICAgICBwYXJzZWRBZGRyLndvcmtjaGFpbjsgLy8gMAovLy8gICAgIHBhcnNlZEFkZHIuYWRkcmVzczsgICAvLyAxMDcuLi4yODcKLy8vIH0KLy8vIGBgYAovLy8K' + + 'Ly8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFyc2VzdGRhZGRyZXNzCi8vLwphc20gZnVuIHBhcnNlU3RkQWRkcmVz' + + 'cyhzbGljZTogU2xpY2UpOiBTdGRBZGRyZXNzIHsgUkVXUklURVNUREFERFIgfQoKLy8vIEFzc2VtYmx5IGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUu' + + 'MC4KLy8vCi8vLyBDb252ZXJ0cyBhIGBTbGljZWAgY29udGFpbmluZyBhbiBhZGRyZXNzIG9mIHZhcmlhYmxlIGxlbmd0aCBpbnRvIHRoZSBgVmFyQWRkcmVzc2AgU3Ry' + + 'dWN0IGFuZCByZXR1cm5zIGl0LgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCB2YXJBZGRyU2xpY2UgPSBiZWdpbkNlbGwoKQov' + + 'Ly8gICAgICAgICAuc3RvcmVVaW50KDYsIDMpICAgICAvLyB0byByZWNvZ25pemUgdGhlIGZvbGxvd2luZyBhcyBhIFZhckFkZHJlc3MKLy8vICAgICAgICAgLnN0b3Jl' + + 'VWludCgxMjMsIDkpICAgLy8gbWFrZSBhZGRyZXNzIG9jY3VweSAxMjMgYml0cwovLy8gICAgICAgICAuc3RvcmVVaW50KDIzNCwgMzIpICAvLyBzcGVjaWZ5IHdvcmtj' + + 'aGFpbiBJRCBvZiAyMzQKLy8vICAgICAgICAgLnN0b3JlVWludCgzNDUsIDEyMykgLy8gc3BlY2lmeSBhZGRyZXNzIG9mIDM0NQovLy8gICAgICAgICAuYXNTbGljZSgp' + + 'OwovLy8gICAgIGxldCBwYXJzZWRWYXJBZGRyID0gcGFyc2VWYXJBZGRyZXNzKHZhckFkZHJTbGljZSk7Ci8vLwovLy8gICAgIHBhcnNlZFZhckFkZHIud29ya2NoYWlu' + + 'OyAgICAgICAgICAgICAvLyAyMzQKLy8vICAgICBwYXJzZWRWYXJBZGRyLmFkZHJlc3M7ICAgICAgICAgICAgICAgLy8gQ1N7Q2VsbHswMDIuLi4yYjN9IGJpdHM6IDQ0' + + 'Li4xNjc7IHJlZnM6IDAuLjB9Ci8vLyAgICAgcGFyc2VkVmFyQWRkci5hZGRyZXNzLmxvYWRVaW50KDEyMyk7IC8vIDM0NQovLy8gfQovLy8gYGBgCi8vLwovLy8gU2Vl' + + 'OiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNwYXJzZXZhcmFkZHJlc3MKLy8vCmFzbSBmdW4gcGFyc2VWYXJBZGRyZXNzKHNsaWNl' + + 'OiBTbGljZSk6IFZhckFkZHJlc3MgeyBSRVdSSVRFVkFSQUREUiB9Cg=='; files['std/crypto.tact'] = 'YXNtIGV4dGVuZHMgZnVuIGhhc2goc2VsZjogQ2VsbCk6IEludCB7IEhBU0hDVSB9Cgphc20gZXh0ZW5kcyBmdW4gaGFzaChzZWxmOiBTbGljZSk6IEludCB7IEhBU0hT' + 'VSB9Cgphc20gZnVuIGNoZWNrU2lnbmF0dXJlKGhhc2g6IEludCwgc2lnbmF0dXJlOiBTbGljZSwgcHVibGljX2tleTogSW50KTogQm9vbCB7IENIS1NJR05VIH0KCmFz' + diff --git a/stdlib/std/contract.tact b/stdlib/std/contract.tact index a88d23c2c..1420e3be2 100644 --- a/stdlib/std/contract.tact +++ b/stdlib/std/contract.tact @@ -52,7 +52,7 @@ asm fun myStorageDue(): Int { DUEPAYMENT } /// /// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain. /// -/// Note, that the values of `cells` and `bits` are taken modulo their maximum values plus 1. That is, specifying values higher than those listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take deduplication of cells with the same hash into account. +/// Note, that the values of `cells` and `bits` are taken modulo their maximum values plus 1. That is, specifying values higher than those listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash. /// /// Attempts to specify negative number of `cells`, `bits` or `seconds` throw an exception with exit code 5: `Integer out of expected range`. /// @@ -112,9 +112,9 @@ asm fun getSimpleComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEES /// /// If both the source and the destination addresses are in the basechain, then specify `isMasterchain` as `false`. Otherwise, specify `true`. /// -/// Note, that the values of `cells` and `bits` are taken modulo their maximum values plus 1. That is, specifying values higher than those listed in account state limits (`max_msg_cells` and `max_msg_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take deduplication of cells with the same hash into account. +/// Note, that the values of `cells` and `bits` are taken modulo their maximum values plus 1. That is, specifying values higher than those listed in account state limits (`max_msg_cells` and `max_msg_bits`) will have the same result as with specifying the exact limits. /// -/// However, regardless of the values of `cells` and `bits`, this function always adds the minimum price based on the value of `lump_price`. See the example for [`getSimpleForwardFee(){:tact}`](#getsimpleforwardfee) to derive it. +/// However, regardless of the values of `cells` and `bits`, this function always adds the minimum price based on the value of `lump_price`. See the example for [`getSimpleForwardFee(){:tact}`](#getsimpleforwardfee) to derive it. In addition, make sure you take into account the deduplication of cells with the same hash, since for example the root cell and its data bits don't count towards the forward fee and are covered by the `lump_price`. /// /// Attempts to specify negative number of `cells` or `bits` throw an exception with exit code 5: `Integer out of expected range`. /// @@ -155,7 +155,7 @@ asm fun getSimpleForwardFee(cells: Int, bits: Int, isMasterchain: Bool): Int { G /// /// Calculates and returns the so-called _original_ forward fee in nanoToncoins `Int` for an outgoing message based on the `fwdFee` obtained from the incoming message. If both the source and the destination addresses are in the basechain, then specify `isMasterchain` as `false`. Otherwise, specify `true`. /// -/// This function is useful when the outgoing message depends heavily on the structure of the incoming message, so much so that you cannot fully predict the fee using `getForwardFee()` alone. +/// This function is useful when the outgoing message depends heavily on the structure of the incoming message, so much so that you cannot fully predict the fee using `getForwardFee()` alone. Even if you could, calculating the exact fee with nanoToncoin-level precision can be very expensive, so the approximate value given by this function is often good enough. /// /// Attempts to specify a negative value of `fwdFee` throw an exception with exit code 5: `Integer out of expected range`. ///