diff --git a/Telegram-iOS/en.lproj/Localizable.strings b/Telegram-iOS/en.lproj/Localizable.strings index 0656169f6c..d411d4c1c9 100644 --- a/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram-iOS/en.lproj/Localizable.strings @@ -4780,6 +4780,7 @@ Any member of this group will be able to see messages in the channel."; "Wallet.Info.Send" = "Send"; "Wallet.Info.RefreshErrorTitle" = "An Error Occurred"; "Wallet.Info.RefreshErrorText" = "The wallet state can not be retrieved at this time. Please try again later."; +"Wallet.Info.RefreshErrorNetworkText" = "The wallet state can not be retrieved at this time. Please try again later."; "Wallet.Info.UnknownTransaction" = "Empty Transaction"; "Wallet.Info.TransactionTo" = "to"; "Wallet.Info.TransactionFrom" = "from"; @@ -4881,8 +4882,12 @@ Any member of this group will be able to see messages in the channel."; "Wallet.Words.NotDoneOk" = "OK, Sorry"; "Wallet.Words.NotDoneResponse" = "Apologies Accepted"; +"Wallet.Send.NetworkError" = "Network Error"; +"Wallet.Send.ErrorNotEnoughFunds" = "Not Enough Funds"; "Wallet.Send.ErrorInvalidAddress" = "Invalid wallet address. Please correct and try again."; "Wallet.Send.ErrorDecryptionFailed" = "Please make sure that your device has a passcode set in iOS Settings and try again."; +"Wallet.Send.UninitializedTitle" = "Warning"; +"Wallet.Send.UninitializedText" = "This address belongs to an empty wallet. Are you sure you want to transfer grams to it?"; "Wallet.Send.SendAnyway" = "Send Anyway"; "Wallet.Receive.CreateInvoice" = "Create Invoice"; diff --git a/submodules/CloudData/Sources/CloudData.swift b/submodules/CloudData/Sources/CloudData.swift index cc4d4338f5..28a79576ff 100644 --- a/submodules/CloudData/Sources/CloudData.swift +++ b/submodules/CloudData/Sources/CloudData.swift @@ -47,32 +47,47 @@ private func fetchRawData(prefix: String) -> Signal { } @available(iOS 10.0, *) -public func cloudDataAdditionalAddressSource(phoneNumber: Signal) -> Signal { - return phoneNumber - |> take(1) - |> mapToSignal { phoneNumber -> Signal in - var prefix = "" - if let phoneNumber = phoneNumber, phoneNumber.count >= 1 { - prefix = String(phoneNumber[phoneNumber.startIndex ..< phoneNumber.index(after: phoneNumber.startIndex)]) - } - return fetchRawData(prefix: prefix) - |> map { data -> MTBackupDatacenterData? in - if let datacenterData = MTIPDataDecode(data, phoneNumber ?? "") { - return datacenterData - } else { - return nil +private final class CloudDataPrefixContext { + private let prefix: String + private let value = Promise() + + private var lastRequestTimestamp: Double? + + init(prefix: String) { + self.prefix = prefix + } + + private func fetch() { + let fetchSignal = ( + fetchRawData(prefix: self.prefix) + |> map(Optional.init) + |> `catch` { error -> Signal in + switch error { + case .networkUnavailable: + return .complete() + default: + return .single(nil) + } } + |> restart + ) + |> take(1) + self.value.set(fetchSignal) + } + + func get() -> Signal { + var shouldFetch = false + let timestamp = CFAbsoluteTimeGetCurrent() + if let lastRequestTimestamp = self.lastRequestTimestamp { + shouldFetch = timestamp >= lastRequestTimestamp + 1.0 * 60.0 + } else { + shouldFetch = true } - |> `catch` { error -> Signal in - return .complete() - } - |> mapToSignal { data -> Signal in - if let data = data { - return .single(data) - } else { - return .complete() - } + if shouldFetch { + self.lastRequestTimestamp = timestamp + self.fetch() } + return self.value.get() } } @@ -80,32 +95,25 @@ public func cloudDataAdditionalAddressSource(phoneNumber: Signal Signal { + let context: CloudDataPrefixContext + if let current = self.prefixContexts[prefix] { + context = current + } else { + context = CloudDataPrefixContext(prefix: prefix) } - changesOperation.recordZoneWithIDWasDeletedBlock = { _ in - - } - changesOperation.changeTokenUpdatedBlock = { _ in - print("changeTokenUpdatedBlock") - } - changesOperation.fetchDatabaseChangesCompletionBlock = { serverChangeToken, isMoreComing, error in - print("done") - } - publicDatabase.add(changesOperation)*/ + return context.get() } } public protocol CloudDataContext { - + func get(phoneNumber: Signal) -> Signal } @available(iOS 10.0, *) @@ -119,4 +127,29 @@ public final class CloudDataContextImpl: CloudDataContext { return CloudDataContextObject(queue: queue) }) } + + public func get(phoneNumber: Signal) -> Signal { + return phoneNumber + |> take(1) + |> mapToSignal { phoneNumber -> Signal in + var prefix = "" + if let phoneNumber = phoneNumber, phoneNumber.count >= 1 { + prefix = String(phoneNumber[phoneNumber.startIndex ..< phoneNumber.index(after: phoneNumber.startIndex)]) + } + return Signal { subscriber in + let disposable = MetaDisposable() + self.impl.with { impl in + disposable.set(impl.get(prefix: prefix).start(next: { data in + if let data = data, let datacenterData = MTIPDataDecode(data, phoneNumber ?? "") { + subscriber.putNext(datacenterData) + subscriber.putCompletion() + } else { + subscriber.putCompletion() + } + })) + } + return disposable + } + } + } } diff --git a/submodules/ComposePollUI/Sources/CreatePollController.swift b/submodules/ComposePollUI/Sources/CreatePollController.swift index 160152c04c..59df335199 100644 --- a/submodules/ComposePollUI/Sources/CreatePollController.swift +++ b/submodules/ComposePollUI/Sources/CreatePollController.swift @@ -392,7 +392,7 @@ public func createPollController(context: AccountContext, peerId: PeerId, comple controller?.present(c, in: .window(.root), with: a) } dismissImpl = { [weak controller] in - controller?.view.endEditing(true) + //controller?.view.endEditing(true) controller?.dismiss() } ensureTextVisibleImpl = { [weak controller] in diff --git a/submodules/Display/Display/Navigation/NavigationController.swift b/submodules/Display/Display/Navigation/NavigationController.swift index ea862cf43e..429db1abae 100644 --- a/submodules/Display/Display/Navigation/NavigationController.swift +++ b/submodules/Display/Display/Navigation/NavigationController.swift @@ -401,8 +401,8 @@ open class NavigationController: UINavigationController, ContainableController, } if self.currentTopVisibleOverlayContainerStatusBar !== topVisibleOverlayContainerWithStatusBar { - self.currentTopVisibleOverlayContainerStatusBar = topVisibleOverlayContainerWithStatusBar animateStatusBarStyleTransition = true + self.currentTopVisibleOverlayContainerStatusBar = topVisibleOverlayContainerWithStatusBar } var previousModalContainer: NavigationModalContainer? diff --git a/submodules/GalleryUI/Sources/GalleryControllerNode.swift b/submodules/GalleryUI/Sources/GalleryControllerNode.swift index 6cdd05663a..31a920962c 100644 --- a/submodules/GalleryUI/Sources/GalleryControllerNode.swift +++ b/submodules/GalleryUI/Sources/GalleryControllerNode.swift @@ -375,9 +375,9 @@ open class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGesture if !self.areControlsHidden { if transition < 0.5 { - self.statusBar?.updateAlpha(0.0, transition: .animated(duration: 0.3, curve: .easeInOut)) + self.statusBar?.statusBarStyle = .Ignore } else { - self.statusBar?.updateAlpha(1.0, transition: .animated(duration: 0.3, curve: .easeInOut)) + self.statusBar?.statusBarStyle = .White } self.navigationBar?.alpha = transition self.footerNode.alpha = transition diff --git a/submodules/MtProtoKit/MTBackupAddressSignals.m b/submodules/MtProtoKit/MTBackupAddressSignals.m index 94dec7b1e7..e71cafdf18 100644 --- a/submodules/MtProtoKit/MTBackupAddressSignals.m +++ b/submodules/MtProtoKit/MTBackupAddressSignals.m @@ -307,7 +307,6 @@ static NSString *makeRandomPadding() { if (![datacenterData isKindOfClass:[MTBackupDatacenterData class]]) { return [MTSignal complete]; } - MTBackupDatacenterData *datacenterData = MTIPDataDecode(finalData, phoneNumber); if (datacenterData != nil && [self checkIpData:datacenterData timestamp:(int32_t)[currentContext globalTime] source:@"resolveExternal"]) { return [MTSignal single:datacenterData]; } else { diff --git a/submodules/MtProtoKit/MTProtoKit/MTEncryption.m b/submodules/MtProtoKit/MTProtoKit/MTEncryption.m index 4e778873f9..0d8e1ff568 100644 --- a/submodules/MtProtoKit/MTProtoKit/MTEncryption.m +++ b/submodules/MtProtoKit/MTProtoKit/MTEncryption.m @@ -964,6 +964,9 @@ static NSData *decrypt_TL_data(unsigned char buffer[256]) { @end MTBackupDatacenterData *MTIPDataDecode(NSData *data, NSString *phoneNumber) { + if (data.length < 256) { + return nil; + } unsigned char buffer[256]; memcpy(buffer, data.bytes, 256); NSData *result = decrypt_TL_data(buffer); diff --git a/submodules/MtProtoKit/TON/TON.h b/submodules/MtProtoKit/TON/TON.h index 5a53464b47..e385edf3d3 100644 --- a/submodules/MtProtoKit/TON/TON.h +++ b/submodules/MtProtoKit/TON/TON.h @@ -92,6 +92,7 @@ NS_ASSUME_NONNULL_BEGIN - (MTSignal *)exportKey:(TONKey *)key localPassword:(NSData *)localPassword; - (MTSignal *)importKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword wordList:(NSArray *)wordList; - (MTSignal *)deleteKey:(TONKey *)key; +- (MTSignal *)deleteAllKeys; - (MTSignal *)getTransactionListWithAddress:(NSString * _Nonnull)address lt:(int64_t)lt hash:(NSData * _Nonnull)hash; @end diff --git a/submodules/MtProtoKit/TON/TON.mm b/submodules/MtProtoKit/TON/TON.mm index 4624a00048..e76a4b01c1 100644 --- a/submodules/MtProtoKit/TON/TON.mm +++ b/submodules/MtProtoKit/TON/TON.mm @@ -328,7 +328,9 @@ typedef enum { false, false ), - keystoreDirectory.UTF8String + make_object( + keystoreDirectory.UTF8String + ) )); _client->send({ requestId, std::move(query) }); @@ -636,6 +638,28 @@ typedef enum { }] startOn:[MTQueue mainQueue]] deliverOn:[MTQueue mainQueue]]; } +- (MTSignal *)deleteAllKeys { + return [[[[MTSignal alloc] initWithGenerator:^id(MTSubscriber *subscriber) { + uint64_t requestId = _nextRequestId; + _nextRequestId += 1; + + _requestHandlers[@(requestId)] = [[TONRequestHandler alloc] initWithCompletion:^(tonlib_api::object_ptr &object) { + if (object->get_id() == tonlib_api::error::ID) { + auto error = tonlib_api::move_object_as(object); + [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; + } else { + [subscriber putCompletion]; + } + }]; + + auto query = make_object(); + _client->send({ requestId, std::move(query) }); + + return [[MTBlockDisposable alloc] initWithBlock:^{ + }]; + }] startOn:[MTQueue mainQueue]] deliverOn:[MTQueue mainQueue]]; +} + - (MTSignal *)getTransactionListWithAddress:(NSString * _Nonnull)address lt:(int64_t)lt hash:(NSData * _Nonnull)hash { return [[[[MTSignal alloc] initWithGenerator:^id(MTSubscriber *subscriber) { NSData *addressData = [address dataUsingEncoding:NSUTF8StringEncoding]; diff --git a/submodules/SSignalKit/SwiftSignalKit/Signal_Catch.swift b/submodules/SSignalKit/SwiftSignalKit/Signal_Catch.swift index 896b41b5ac..077c97d7ef 100644 --- a/submodules/SSignalKit/SwiftSignalKit/Signal_Catch.swift +++ b/submodules/SSignalKit/SwiftSignalKit/Signal_Catch.swift @@ -135,6 +135,55 @@ public func retry(_ delayIncrement: Double, maxDelay: Double, onQueue queu } } +public func retry(retryOnError: @escaping (E) -> Bool, delayIncrement: Double, maxDelay: Double, maxRetries: Int, onQueue queue: Queue) -> (_ signal: Signal) -> Signal { + return { signal in + return Signal { subscriber in + let shouldRetry = Atomic(value: true) + let currentDelay = Atomic<(Double, Int)>(value: (0.0, 0)) + let currentDisposable = MetaDisposable() + + let start = recursiveFunction { recurse in + let currentShouldRetry = shouldRetry.with { value in + return value + } + if currentShouldRetry { + let disposable = signal.start(next: { next in + subscriber.putNext(next) + }, error: { error in + if !retryOnError(error) { + subscriber.putError(error) + } else { + let (delay, count) = currentDelay.modify { value, count in + return (min(maxDelay, value + delayIncrement), count + 1) + } + + if count >= maxRetries { + subscriber.putError(error) + } else { + let time: DispatchTime = DispatchTime.now() + Double(delay) + queue.queue.asyncAfter(deadline: time, execute: { + recurse() + }) + } + } + }, completed: { + let _ = shouldRetry.swap(false) + subscriber.putCompletion() + }) + currentDisposable.set(disposable) + } + } + + start() + + return ActionDisposable { + currentDisposable.dispose() + let _ = shouldRetry.swap(false) + } + } + } +} + public func restartIfError(_ signal: Signal) -> Signal { return Signal { subscriber in let shouldRetry = Atomic(value: true) diff --git a/submodules/TelegramCore/TelegramCore/Network.swift b/submodules/TelegramCore/TelegramCore/Network.swift index 42ff256212..0ca9734570 100644 --- a/submodules/TelegramCore/TelegramCore/Network.swift +++ b/submodules/TelegramCore/TelegramCore/Network.swift @@ -417,6 +417,8 @@ public struct NetworkInitializationArguments { } } +private let cloudDataContext = makeCloudDataContext() + func initializedNetwork(arguments: NetworkInitializationArguments, supplementary: Bool, datacenterId: Int, keychain: Keychain, basePath: String, testingEnvironment: Bool, languageCode: String?, proxySettings: ProxySettings?, networkSettings: NetworkSettings?, phoneNumber: String?) -> Signal { return Signal { subscriber in let queue = Queue() @@ -484,17 +486,18 @@ func initializedNetwork(arguments: NetworkInitializationArguments, supplementary var wrappedAdditionalSource: MTSignal? if #available(iOS 10.0, *) { - let additionalSource = cloudDataAdditionalAddressSource(phoneNumber: .single(phoneNumber ?? "")) - wrappedAdditionalSource = MTSignal(generator: { subscriber in - let disposable = additionalSource.start(next: { value in - subscriber?.putNext(value) - }, completed: { - subscriber?.putCompletion() + if let cloudDataContext = cloudDataContext { + wrappedAdditionalSource = MTSignal(generator: { subscriber in + let disposable = cloudDataContext.get(phoneNumber: .single(phoneNumber)).start(next: { value in + subscriber?.putNext(value) + }, completed: { + subscriber?.putCompletion() + }) + return MTBlockDisposable(block: { + disposable.dispose() + }) }) - return MTBlockDisposable(block: { - disposable.dispose() - }) - }) + } } context.setDiscoverBackupAddressListSignal(MTBackupAddressSignals.fetchBackupIps(testingEnvironment, currentContext: context, additionalSource: wrappedAdditionalSource, phoneNumber: phoneNumber)) @@ -1010,7 +1013,8 @@ public final class Network: NSObject, MTRequestMessageServiceDelegate { } public func retryRequest(signal: Signal) -> Signal { - return signal |> retry(0.2, maxDelay: 5.0, onQueue: Queue.concurrentDefaultQueue()) + return signal + |> retry(0.2, maxDelay: 5.0, onQueue: Queue.concurrentDefaultQueue()) } class Keychain: NSObject, MTKeychain { @@ -1045,7 +1049,7 @@ class Keychain: NSObject, MTKeychain { } } -public func makeCloudDataContext() -> Any? { +func makeCloudDataContext() -> CloudDataContext? { if #available(iOS 10.0, *) { return CloudDataContextImpl() } else { diff --git a/submodules/TelegramCore/TelegramCore/Wallets.swift b/submodules/TelegramCore/TelegramCore/Wallets.swift index 64738ea8bd..163856e8bd 100644 --- a/submodules/TelegramCore/TelegramCore/Wallets.swift +++ b/submodules/TelegramCore/TelegramCore/Wallets.swift @@ -219,8 +219,16 @@ public final class TonInstance { return } subscriber.putNext(state) - }, error: { _ in - subscriber.putError(.generic) + }, error: { error in + if let error = error as? TONError { + if error.text.hasPrefix("LITE_SERVER_") { + subscriber.putError(.network) + } else { + subscriber.putError(.generic) + } + } else { + subscriber.putError(.generic) + } }, completed: { subscriber.putCompletion() }) @@ -241,7 +249,7 @@ public final class TonInstance { } } - fileprivate func walletLastTransactionId(address: String) -> Signal { + fileprivate func walletLastTransactionId(address: String) -> Signal { return Signal { subscriber in let disposable = MetaDisposable() @@ -253,7 +261,16 @@ public final class TonInstance { return } subscriber.putNext(state.lastTransactionId.flatMap(WalletTransactionId.init(tonTransactionId:))) - }, error: { _ in + }, error: { error in + if let error = error as? TONError { + if error.text.hasPrefix("ДITE_SERVER_") { + subscriber.putError(.network) + } else { + subscriber.putError(.generic) + } + } else { + subscriber.putError(.generic) + } }, completed: { subscriber.putCompletion() }) @@ -279,7 +296,16 @@ public final class TonInstance { return } subscriber.putNext(transactions.map(WalletTransaction.init(tonTransaction:))) - }, error: { _ in + }, error: { error in + if let error = error as? TONError { + if error.text.hasPrefix("LITE_SERVER_") { + subscriber.putError(.network) + } else { + subscriber.putError(.generic) + } + } else { + subscriber.putError(.generic) + } }, completed: { subscriber.putCompletion() }) @@ -308,10 +334,16 @@ public final class TonInstance { subscriber.putCompletion() }, error: { error in if let error = error as? TONError { - if error.text == "Failed to parse account address" { + if error.text.hasPrefix("INVALID_ACCOUNT_ADDRESS") { subscriber.putError(.invalidAddress) } else if error.text.hasPrefix("DANGEROUS_TRANSACTION") { subscriber.putError(.destinationIsNotInitialized) + } else if error.text.hasPrefix("MESSAGE_TOO_LONG") { + subscriber.putError(.messageTooLong) + } else if error.text.hasPrefix("NOT_ENOUGH_FUNDS") { + subscriber.putError(.notEnoughFunds) + } else if error.text.hasPrefix("LITE_SERVER_") { + subscriber.putError(.network) } else { subscriber.putError(.generic) } @@ -364,6 +396,29 @@ public final class TonInstance { } } + fileprivate func deleteAllLocalWalletsData() -> Signal { + return Signal { subscriber in + let disposable = MetaDisposable() + + self.impl.with { impl in + impl.withInstance { ton in + let cancel = ton.deleteAllKeys().start(next: { _ in + assertionFailure() + }, error: { _ in + subscriber.putError(.generic) + }, completed: { + subscriber.putCompletion() + }) + disposable.set(ActionDisposable { + cancel?.dispose() + }) + } + } + + return disposable + } + } + fileprivate func deleteLocalWalletData(walletInfo: WalletInfo, keychain: TonKeychain, serverSalt: Data) -> Signal { return keychain.decrypt(walletInfo.encryptedSecret) |> mapError { error -> DeleteLocalWalletDataError in @@ -580,6 +635,24 @@ public func importWallet(postbox: Postbox, network: Network, tonInstance: TonIns } } +public enum DeleteAllLocalWalletsDataError { + case generic +} + +public func deleteAllLocalWalletsData(postbox: Postbox, network: Network, tonInstance: TonInstance) -> Signal { + return tonInstance.deleteAllLocalWalletsData() + |> then( + postbox.transaction { transaction -> Void in + transaction.updatePreferencesEntry(key: PreferencesKeys.walletCollection, { current in + let walletCollection = (current as? WalletCollection) ?? WalletCollection(wallets: []) + return walletCollection + }) + } + |> castError(DeleteAllLocalWalletsDataError.self) + |> ignoreValues + ) +} + public enum DeleteLocalWalletDataError { case generic case secretDecryptionFailed(TonKeychainDecryptDataError) @@ -642,6 +715,7 @@ public func walletAddress(publicKey: WalletPublicKey, tonInstance: TonInstance) private enum GetWalletStateError { case generic + case network } private func getWalletState(address: String, tonInstance: TonInstance) -> Signal<(WalletState, Int64), GetWalletStateError> { @@ -650,6 +724,7 @@ private func getWalletState(address: String, tonInstance: TonInstance) -> Signal public enum GetCombinedWalletStateError { case generic + case network } public enum CombinedWalletStateResult { @@ -682,8 +757,19 @@ public func getCombinedWalletState(postbox: Postbox, subject: CombinedWalletStat |> castError(GetCombinedWalletStateError.self) |> mapToSignal { address -> Signal in return getWalletState(address: address, tonInstance: tonInstance) - |> mapError { _ -> GetCombinedWalletStateError in - return .generic + |> retryTonRequest(isNetworkError: { error in + if case .network = error { + return true + } else { + return false + } + }) + |> mapError { error -> GetCombinedWalletStateError in + if case .network = error { + return .network + } else { + return .generic + } } |> mapToSignal { walletState, syncUtime -> Signal in let topTransactions: Signal<[WalletTransaction], GetCombinedWalletStateError> @@ -691,8 +777,12 @@ public func getCombinedWalletState(postbox: Postbox, subject: CombinedWalletStat topTransactions = .single(cachedState?.topTransactions ?? []) } else { topTransactions = getWalletTransactions(address: address, previousId: nil, tonInstance: tonInstance) - |> mapError { _ -> GetCombinedWalletStateError in - return .generic + |> mapError { error -> GetCombinedWalletStateError in + if case .network = error { + return .network + } else { + return .generic + } } } return topTransactions @@ -744,6 +834,9 @@ public enum SendGramsFromWalletError { case secretDecryptionFailed case invalidAddress case destinationIsNotInitialized + case messageTooLong + case notEnoughFunds + case network } public func sendGramsFromWallet(network: Network, tonInstance: TonInstance, walletInfo: WalletInfo, decryptedSecret: Data, serverSalt: Data, toAddress: String, amount: Int64, textMessage: String, forceIfDestinationNotInitialized: Bool, timeout: Int32, randomId: Int64) -> Signal { @@ -862,6 +955,7 @@ private extension WalletTransaction { public enum GetWalletTransactionsError { case generic + case network } public func getWalletTransactions(address: String, previousId: WalletTransactionId?, tonInstance: TonInstance) -> Signal<[WalletTransaction], GetWalletTransactionsError> { @@ -885,18 +979,50 @@ public func getWalletTransactions(address: String, previousId: WalletTransaction } } +private func retryTonRequest(isNetworkError: @escaping (E) -> Bool) -> (Signal) -> Signal { + return { signal in + return signal + |> retry(retryOnError: isNetworkError, delayIncrement: 0.2, maxDelay: 5.0, maxRetries: 3, onQueue: Queue.concurrentDefaultQueue()) + } +} + +private enum WalletLastTransactionIdError { + case generic + case network +} + private func getWalletTransactionsOnce(address: String, previousId: WalletTransactionId?, tonInstance: TonInstance) -> Signal<[WalletTransaction], GetWalletTransactionsError> { let previousIdValue: Signal if let previousId = previousId { previousIdValue = .single(previousId) } else { previousIdValue = tonInstance.walletLastTransactionId(address: address) - |> castError(GetWalletTransactionsError.self) + |> retryTonRequest(isNetworkError: { error in + if case .network = error { + return true + } else { + return false + } + }) + |> mapError { error -> GetWalletTransactionsError in + if case .network = error { + return .network + } else { + return .generic + } + } } return previousIdValue |> mapToSignal { previousId in if let previousId = previousId { return tonInstance.getWalletTransactions(address: address, previousId: previousId) + |> retryTonRequest(isNetworkError: { error in + if case .network = error { + return true + } else { + return false + } + }) } else { return .single([]) } diff --git a/submodules/TelegramPresentationData/Sources/PresentationStrings.swift b/submodules/TelegramPresentationData/Sources/PresentationStrings.swift index 6f15434f38..249d2dce77 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationStrings.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationStrings.swift @@ -1717,3196 +1717,3201 @@ public final class PresentationStrings { return formatWithArgumentRanges(self._s[1427]!, self._r[1427]!, [_1, _2]) } public var Passport_Phone_UseTelegramNumberHelp: String { return self._s[1428]! } - public var SettingsSearch_Synonyms_Data_Title: String { return self._s[1431]! } - public var Passport_DeletePassport: String { return self._s[1432]! } - public var Appearance_AppIconFilled: String { return self._s[1433]! } - public var Privacy_Calls_P2PAlways: String { return self._s[1434]! } - public var Month_ShortDecember: String { return self._s[1435]! } - public var Channel_AdminLog_CanEditMessages: String { return self._s[1437]! } + public var Wallet_Send_ErrorNotEnoughFunds: String { return self._s[1431]! } + public var SettingsSearch_Synonyms_Data_Title: String { return self._s[1432]! } + public var Passport_DeletePassport: String { return self._s[1433]! } + public var Appearance_AppIconFilled: String { return self._s[1434]! } + public var Privacy_Calls_P2PAlways: String { return self._s[1435]! } + public var Month_ShortDecember: String { return self._s[1436]! } + public var Channel_AdminLog_CanEditMessages: String { return self._s[1438]! } public func Contacts_AccessDeniedHelpLandscape(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1438]!, self._r[1438]!, [_0]) + return formatWithArgumentRanges(self._s[1439]!, self._r[1439]!, [_0]) } - public var Channel_Stickers_Searching: String { return self._s[1439]! } - public var Conversation_EncryptedDescription1: String { return self._s[1440]! } - public var Conversation_EncryptedDescription2: String { return self._s[1441]! } - public var PasscodeSettings_PasscodeOptions: String { return self._s[1442]! } - public var Conversation_EncryptedDescription3: String { return self._s[1443]! } - public var PhotoEditor_SharpenTool: String { return self._s[1444]! } + public var Channel_Stickers_Searching: String { return self._s[1440]! } + public var Conversation_EncryptedDescription1: String { return self._s[1441]! } + public var Conversation_EncryptedDescription2: String { return self._s[1442]! } + public var PasscodeSettings_PasscodeOptions: String { return self._s[1443]! } + public var Conversation_EncryptedDescription3: String { return self._s[1444]! } + public var PhotoEditor_SharpenTool: String { return self._s[1445]! } public func Conversation_AddNameToContacts(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1445]!, self._r[1445]!, [_0]) + return formatWithArgumentRanges(self._s[1446]!, self._r[1446]!, [_0]) } - public var Conversation_EncryptedDescription4: String { return self._s[1447]! } - public var Channel_Members_AddMembers: String { return self._s[1448]! } - public var Wallpaper_Search: String { return self._s[1449]! } - public var Weekday_Friday: String { return self._s[1450]! } - public var Privacy_ContactsSync: String { return self._s[1451]! } - public var SettingsSearch_Synonyms_Privacy_Data_ContactsReset: String { return self._s[1452]! } - public var ApplyLanguage_ChangeLanguageAction: String { return self._s[1453]! } + public var Conversation_EncryptedDescription4: String { return self._s[1448]! } + public var Channel_Members_AddMembers: String { return self._s[1449]! } + public var Wallpaper_Search: String { return self._s[1450]! } + public var Weekday_Friday: String { return self._s[1451]! } + public var Privacy_ContactsSync: String { return self._s[1452]! } + public var SettingsSearch_Synonyms_Privacy_Data_ContactsReset: String { return self._s[1453]! } + public var ApplyLanguage_ChangeLanguageAction: String { return self._s[1454]! } public func Channel_Management_RestrictedBy(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1454]!, self._r[1454]!, [_0]) + return formatWithArgumentRanges(self._s[1455]!, self._r[1455]!, [_0]) } - public var GroupInfo_Permissions_Removed: String { return self._s[1455]! } - public var Passport_Identity_GenderMale: String { return self._s[1456]! } + public var GroupInfo_Permissions_Removed: String { return self._s[1456]! } + public var Passport_Identity_GenderMale: String { return self._s[1457]! } public func Call_StatusBar(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1457]!, self._r[1457]!, [_0]) + return formatWithArgumentRanges(self._s[1458]!, self._r[1458]!, [_0]) } - public var Updated_JustNow: String { return self._s[1458]! } - public var Notifications_PermissionsKeepDisabled: String { return self._s[1459]! } - public var Conversation_JumpToDate: String { return self._s[1460]! } - public var Contacts_GlobalSearch: String { return self._s[1461]! } - public var AutoDownloadSettings_ResetHelp: String { return self._s[1462]! } - public var SettingsSearch_Synonyms_FAQ: String { return self._s[1463]! } - public var Profile_MessageLifetime1d: String { return self._s[1464]! } + public var Updated_JustNow: String { return self._s[1459]! } + public var Notifications_PermissionsKeepDisabled: String { return self._s[1460]! } + public var Conversation_JumpToDate: String { return self._s[1461]! } + public var Contacts_GlobalSearch: String { return self._s[1462]! } + public var AutoDownloadSettings_ResetHelp: String { return self._s[1463]! } + public var SettingsSearch_Synonyms_FAQ: String { return self._s[1464]! } + public var Profile_MessageLifetime1d: String { return self._s[1465]! } public func MESSAGE_INVOICE(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1465]!, self._r[1465]!, [_1, _2]) + return formatWithArgumentRanges(self._s[1466]!, self._r[1466]!, [_1, _2]) } - public var StickerPack_BuiltinPackName: String { return self._s[1468]! } + public var StickerPack_BuiltinPackName: String { return self._s[1469]! } public func PUSH_CHAT_MESSAGE_AUDIO(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1469]!, self._r[1469]!, [_1, _2]) + return formatWithArgumentRanges(self._s[1470]!, self._r[1470]!, [_1, _2]) } - public var VoiceOver_Chat_RecordModeVoiceMessageInfo: String { return self._s[1470]! } - public var Passport_InfoTitle: String { return self._s[1472]! } - public var Notifications_PermissionsUnreachableText: String { return self._s[1473]! } + public var VoiceOver_Chat_RecordModeVoiceMessageInfo: String { return self._s[1471]! } + public var Passport_InfoTitle: String { return self._s[1473]! } + public var Notifications_PermissionsUnreachableText: String { return self._s[1474]! } public func NetworkUsageSettings_CellularUsageSince(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1477]!, self._r[1477]!, [_0]) + return formatWithArgumentRanges(self._s[1478]!, self._r[1478]!, [_0]) } public func PUSH_CHAT_MESSAGE_GEO(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1478]!, self._r[1478]!, [_1, _2]) + return formatWithArgumentRanges(self._s[1479]!, self._r[1479]!, [_1, _2]) } - public var Passport_Address_TypePassportRegistrationUploadScan: String { return self._s[1479]! } - public var Profile_BotInfo: String { return self._s[1480]! } - public var Watch_Compose_CreateMessage: String { return self._s[1481]! } - public var AutoDownloadSettings_VoiceMessagesInfo: String { return self._s[1482]! } - public var Month_ShortNovember: String { return self._s[1483]! } - public var Conversation_ScamWarning: String { return self._s[1484]! } - public var Wallpaper_SetCustomBackground: String { return self._s[1485]! } - public var Passport_Identity_TranslationsHelp: String { return self._s[1486]! } - public var NotificationsSound_Chime: String { return self._s[1487]! } - public var Passport_Language_ko: String { return self._s[1489]! } - public var InviteText_URL: String { return self._s[1490]! } - public var TextFormat_Monospace: String { return self._s[1491]! } + public var Passport_Address_TypePassportRegistrationUploadScan: String { return self._s[1480]! } + public var Profile_BotInfo: String { return self._s[1481]! } + public var Watch_Compose_CreateMessage: String { return self._s[1482]! } + public var AutoDownloadSettings_VoiceMessagesInfo: String { return self._s[1483]! } + public var Month_ShortNovember: String { return self._s[1484]! } + public var Conversation_ScamWarning: String { return self._s[1485]! } + public var Wallpaper_SetCustomBackground: String { return self._s[1486]! } + public var Passport_Identity_TranslationsHelp: String { return self._s[1487]! } + public var NotificationsSound_Chime: String { return self._s[1488]! } + public var Passport_Language_ko: String { return self._s[1490]! } + public var InviteText_URL: String { return self._s[1491]! } + public var TextFormat_Monospace: String { return self._s[1492]! } public func Time_PreciseDate_m11(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1492]!, self._r[1492]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[1493]!, self._r[1493]!, [_1, _2, _3]) } - public var EditTheme_Edit_BottomInfo: String { return self._s[1493]! } + public var EditTheme_Edit_BottomInfo: String { return self._s[1494]! } public func Login_WillSendSms(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1494]!, self._r[1494]!, [_0]) + return formatWithArgumentRanges(self._s[1495]!, self._r[1495]!, [_0]) } public func Watch_Time_ShortWeekdayAt(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1495]!, self._r[1495]!, [_1, _2]) + return formatWithArgumentRanges(self._s[1496]!, self._r[1496]!, [_1, _2]) } - public var Wallet_Words_Title: String { return self._s[1497]! } - public var EditTheme_CreateTitle: String { return self._s[1499]! } - public var Passport_InfoLearnMore: String { return self._s[1500]! } - public var TwoStepAuth_EmailPlaceholder: String { return self._s[1501]! } - public var Passport_Identity_AddIdentityCard: String { return self._s[1502]! } - public var Your_card_has_expired: String { return self._s[1503]! } - public var StickerPacksSettings_StickerPacksSection: String { return self._s[1504]! } - public var GroupInfo_InviteLink_Help: String { return self._s[1505]! } - public var Conversation_Report: String { return self._s[1509]! } - public var Notifications_MessageNotificationsSound: String { return self._s[1510]! } - public var Notification_MessageLifetime1m: String { return self._s[1511]! } - public var Privacy_ContactsTitle: String { return self._s[1512]! } - public var Conversation_ShareMyContactInfo: String { return self._s[1513]! } - public var Wallet_WordCheck_Title: String { return self._s[1514]! } - public var ChannelMembers_WhoCanAddMembersAdminsHelp: String { return self._s[1515]! } - public var Channel_Members_Title: String { return self._s[1516]! } - public var Map_OpenInWaze: String { return self._s[1517]! } - public var Login_PhoneBannedError: String { return self._s[1518]! } + public var Wallet_Words_Title: String { return self._s[1498]! } + public var EditTheme_CreateTitle: String { return self._s[1500]! } + public var Passport_InfoLearnMore: String { return self._s[1501]! } + public var TwoStepAuth_EmailPlaceholder: String { return self._s[1502]! } + public var Passport_Identity_AddIdentityCard: String { return self._s[1503]! } + public var Your_card_has_expired: String { return self._s[1504]! } + public var StickerPacksSettings_StickerPacksSection: String { return self._s[1505]! } + public var GroupInfo_InviteLink_Help: String { return self._s[1506]! } + public var Conversation_Report: String { return self._s[1510]! } + public var Notifications_MessageNotificationsSound: String { return self._s[1511]! } + public var Notification_MessageLifetime1m: String { return self._s[1512]! } + public var Privacy_ContactsTitle: String { return self._s[1513]! } + public var Conversation_ShareMyContactInfo: String { return self._s[1514]! } + public var Wallet_WordCheck_Title: String { return self._s[1515]! } + public var ChannelMembers_WhoCanAddMembersAdminsHelp: String { return self._s[1516]! } + public var Channel_Members_Title: String { return self._s[1517]! } + public var Map_OpenInWaze: String { return self._s[1518]! } + public var Login_PhoneBannedError: String { return self._s[1519]! } public func LiveLocationUpdated_YesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1519]!, self._r[1519]!, [_0]) + return formatWithArgumentRanges(self._s[1520]!, self._r[1520]!, [_0]) } - public var Group_Management_AddModeratorHelp: String { return self._s[1520]! } - public var AutoDownloadSettings_WifiTitle: String { return self._s[1521]! } - public var Common_OK: String { return self._s[1522]! } - public var Passport_Address_TypeBankStatementUploadScan: String { return self._s[1523]! } - public var Wallet_Words_NotDoneResponse: String { return self._s[1524]! } - public var Cache_Music: String { return self._s[1525]! } - public var SettingsSearch_Synonyms_EditProfile_PhoneNumber: String { return self._s[1526]! } - public var PasscodeSettings_UnlockWithTouchId: String { return self._s[1527]! } - public var TwoStepAuth_HintPlaceholder: String { return self._s[1528]! } + public var Group_Management_AddModeratorHelp: String { return self._s[1521]! } + public var AutoDownloadSettings_WifiTitle: String { return self._s[1522]! } + public var Common_OK: String { return self._s[1523]! } + public var Passport_Address_TypeBankStatementUploadScan: String { return self._s[1524]! } + public var Wallet_Words_NotDoneResponse: String { return self._s[1525]! } + public var Cache_Music: String { return self._s[1526]! } + public var SettingsSearch_Synonyms_EditProfile_PhoneNumber: String { return self._s[1527]! } + public var PasscodeSettings_UnlockWithTouchId: String { return self._s[1528]! } + public var TwoStepAuth_HintPlaceholder: String { return self._s[1529]! } public func PUSH_PINNED_INVOICE(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1529]!, self._r[1529]!, [_1]) + return formatWithArgumentRanges(self._s[1530]!, self._r[1530]!, [_1]) } public func Passport_RequestHeader(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1530]!, self._r[1530]!, [_0]) - } - public func VoiceOver_Chat_ContactOrganization(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[1531]!, self._r[1531]!, [_0]) } - public var Watch_MessageView_ViewOnPhone: String { return self._s[1533]! } - public var Privacy_Calls_CustomShareHelp: String { return self._s[1534]! } - public var Wallet_Receive_CreateInvoiceInfo: String { return self._s[1536]! } - public var ChangePhoneNumberNumber_Title: String { return self._s[1537]! } - public var State_ConnectingToProxyInfo: String { return self._s[1538]! } - public var Message_VideoMessage: String { return self._s[1540]! } - public var ChannelInfo_DeleteChannel: String { return self._s[1541]! } - public var ContactInfo_PhoneLabelOther: String { return self._s[1542]! } - public var Channel_EditAdmin_CannotEdit: String { return self._s[1543]! } - public var Passport_DeleteAddressConfirmation: String { return self._s[1544]! } - public var WallpaperPreview_SwipeBottomText: String { return self._s[1545]! } - public var Activity_RecordingAudio: String { return self._s[1546]! } - public var SettingsSearch_Synonyms_Watch: String { return self._s[1547]! } - public var PasscodeSettings_TryAgainIn1Minute: String { return self._s[1548]! } - public var Wallet_Info_Address: String { return self._s[1549]! } + public func VoiceOver_Chat_ContactOrganization(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[1532]!, self._r[1532]!, [_0]) + } + public var Watch_MessageView_ViewOnPhone: String { return self._s[1534]! } + public var Privacy_Calls_CustomShareHelp: String { return self._s[1535]! } + public var Wallet_Receive_CreateInvoiceInfo: String { return self._s[1537]! } + public var ChangePhoneNumberNumber_Title: String { return self._s[1538]! } + public var State_ConnectingToProxyInfo: String { return self._s[1539]! } + public var Message_VideoMessage: String { return self._s[1541]! } + public var ChannelInfo_DeleteChannel: String { return self._s[1542]! } + public var ContactInfo_PhoneLabelOther: String { return self._s[1543]! } + public var Channel_EditAdmin_CannotEdit: String { return self._s[1544]! } + public var Passport_DeleteAddressConfirmation: String { return self._s[1545]! } + public var WallpaperPreview_SwipeBottomText: String { return self._s[1546]! } + public var Activity_RecordingAudio: String { return self._s[1547]! } + public var SettingsSearch_Synonyms_Watch: String { return self._s[1548]! } + public var PasscodeSettings_TryAgainIn1Minute: String { return self._s[1549]! } + public var Wallet_Info_Address: String { return self._s[1550]! } public func Notification_ChangedGroupName(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1551]!, self._r[1551]!, [_0, _1]) + return formatWithArgumentRanges(self._s[1552]!, self._r[1552]!, [_0, _1]) } public func EmptyGroupInfo_Line1(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1555]!, self._r[1555]!, [_0]) + return formatWithArgumentRanges(self._s[1556]!, self._r[1556]!, [_0]) } - public var Conversation_ApplyLocalization: String { return self._s[1556]! } - public var UserInfo_AddPhone: String { return self._s[1557]! } - public var Map_ShareLiveLocationHelp: String { return self._s[1558]! } + public var Conversation_ApplyLocalization: String { return self._s[1557]! } + public var UserInfo_AddPhone: String { return self._s[1558]! } + public var Map_ShareLiveLocationHelp: String { return self._s[1559]! } public func Passport_Identity_NativeNameGenericHelp(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1559]!, self._r[1559]!, [_0]) + return formatWithArgumentRanges(self._s[1560]!, self._r[1560]!, [_0]) } - public var Passport_Scans: String { return self._s[1561]! } - public var BlockedUsers_Unblock: String { return self._s[1562]! } + public var Passport_Scans: String { return self._s[1562]! } + public var BlockedUsers_Unblock: String { return self._s[1563]! } public func PUSH_ENCRYPTION_REQUEST(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1563]!, self._r[1563]!, [_1]) + return formatWithArgumentRanges(self._s[1564]!, self._r[1564]!, [_1]) } - public var Channel_Management_LabelCreator: String { return self._s[1564]! } - public var Conversation_ReportSpamAndLeave: String { return self._s[1565]! } - public var SettingsSearch_Synonyms_EditProfile_Bio: String { return self._s[1566]! } - public var ChatList_UndoArchiveMultipleTitle: String { return self._s[1567]! } - public var Passport_Identity_NativeNameGenericTitle: String { return self._s[1568]! } + public var Channel_Management_LabelCreator: String { return self._s[1565]! } + public var Conversation_ReportSpamAndLeave: String { return self._s[1566]! } + public var SettingsSearch_Synonyms_EditProfile_Bio: String { return self._s[1567]! } + public var ChatList_UndoArchiveMultipleTitle: String { return self._s[1568]! } + public var Passport_Identity_NativeNameGenericTitle: String { return self._s[1569]! } public func Login_EmailPhoneBody(_ _0: String, _ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1569]!, self._r[1569]!, [_0, _1, _2]) + return formatWithArgumentRanges(self._s[1570]!, self._r[1570]!, [_0, _1, _2]) } - public var Login_PhoneNumberHelp: String { return self._s[1570]! } - public var LastSeen_ALongTimeAgo: String { return self._s[1571]! } - public var Channel_AdminLog_CanPinMessages: String { return self._s[1572]! } - public var ChannelIntro_CreateChannel: String { return self._s[1573]! } - public var Conversation_UnreadMessages: String { return self._s[1574]! } - public var SettingsSearch_Synonyms_Stickers_ArchivedPacks: String { return self._s[1575]! } - public var Channel_AdminLog_EmptyText: String { return self._s[1576]! } - public var Theme_Context_Apply: String { return self._s[1577]! } - public var Notification_GroupActivated: String { return self._s[1578]! } - public var NotificationSettings_ContactJoinedInfo: String { return self._s[1579]! } - public var Wallet_Intro_CreateWallet: String { return self._s[1580]! } + public var Login_PhoneNumberHelp: String { return self._s[1571]! } + public var LastSeen_ALongTimeAgo: String { return self._s[1572]! } + public var Channel_AdminLog_CanPinMessages: String { return self._s[1573]! } + public var ChannelIntro_CreateChannel: String { return self._s[1574]! } + public var Conversation_UnreadMessages: String { return self._s[1575]! } + public var SettingsSearch_Synonyms_Stickers_ArchivedPacks: String { return self._s[1576]! } + public var Channel_AdminLog_EmptyText: String { return self._s[1577]! } + public var Theme_Context_Apply: String { return self._s[1578]! } + public var Notification_GroupActivated: String { return self._s[1579]! } + public var NotificationSettings_ContactJoinedInfo: String { return self._s[1580]! } + public var Wallet_Intro_CreateWallet: String { return self._s[1581]! } public func Notification_PinnedContactMessage(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1581]!, self._r[1581]!, [_0]) + return formatWithArgumentRanges(self._s[1582]!, self._r[1582]!, [_0]) } public func DownloadingStatus(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1582]!, self._r[1582]!, [_0, _1]) + return formatWithArgumentRanges(self._s[1583]!, self._r[1583]!, [_0, _1]) } - public var GroupInfo_ConvertToSupergroup: String { return self._s[1584]! } + public var GroupInfo_ConvertToSupergroup: String { return self._s[1585]! } public func PrivacyPolicy_AgeVerificationMessage(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1585]!, self._r[1585]!, [_0]) + return formatWithArgumentRanges(self._s[1586]!, self._r[1586]!, [_0]) } - public var Undo_DeletedChannel: String { return self._s[1586]! } - public var CallFeedback_AddComment: String { return self._s[1587]! } + public var Undo_DeletedChannel: String { return self._s[1587]! } + public var CallFeedback_AddComment: String { return self._s[1588]! } public func Conversation_OpenBotLinkAllowMessages(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1588]!, self._r[1588]!, [_0]) + return formatWithArgumentRanges(self._s[1589]!, self._r[1589]!, [_0]) } - public var Document_TargetConfirmationFormat: String { return self._s[1589]! } + public var Document_TargetConfirmationFormat: String { return self._s[1590]! } public func Call_StatusOngoing(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1590]!, self._r[1590]!, [_0]) + return formatWithArgumentRanges(self._s[1591]!, self._r[1591]!, [_0]) } - public var LogoutOptions_SetPasscodeTitle: String { return self._s[1591]! } + public var LogoutOptions_SetPasscodeTitle: String { return self._s[1592]! } public func PUSH_CHAT_MESSAGE_GAME_SCORE(_ _1: String, _ _2: String, _ _3: String, _ _4: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1592]!, self._r[1592]!, [_1, _2, _3, _4]) + return formatWithArgumentRanges(self._s[1593]!, self._r[1593]!, [_1, _2, _3, _4]) } - public var Wallet_SecureStorageChanged_PasscodeText: String { return self._s[1593]! } - public var Theme_ErrorNotFound: String { return self._s[1594]! } - public var Contacts_SortByName: String { return self._s[1595]! } - public var SettingsSearch_Synonyms_Privacy_Forwards: String { return self._s[1596]! } + public var Wallet_SecureStorageChanged_PasscodeText: String { return self._s[1594]! } + public var Theme_ErrorNotFound: String { return self._s[1595]! } + public var Contacts_SortByName: String { return self._s[1596]! } + public var SettingsSearch_Synonyms_Privacy_Forwards: String { return self._s[1597]! } public func CHAT_MESSAGE_INVOICE(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1598]!, self._r[1598]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[1599]!, self._r[1599]!, [_1, _2, _3]) } - public var Notification_Exceptions_RemoveFromExceptions: String { return self._s[1599]! } - public var ScheduledMessages_EditTime: String { return self._s[1600]! } - public var Conversation_ClearSelfHistory: String { return self._s[1601]! } - public var Checkout_NewCard_PostcodePlaceholder: String { return self._s[1602]! } - public var PasscodeSettings_DoNotMatch: String { return self._s[1603]! } - public var Stickers_SuggestNone: String { return self._s[1604]! } - public var ChatSettings_Cache: String { return self._s[1605]! } - public var Settings_SaveIncomingPhotos: String { return self._s[1606]! } - public var Media_ShareThisPhoto: String { return self._s[1607]! } - public var Chat_SlowmodeTooltipPending: String { return self._s[1608]! } - public var InfoPlist_NSContactsUsageDescription: String { return self._s[1609]! } - public var Conversation_ContextMenuCopyLink: String { return self._s[1610]! } - public var PrivacyPolicy_AgeVerificationTitle: String { return self._s[1611]! } - public var SettingsSearch_Synonyms_Stickers_Masks: String { return self._s[1612]! } - public var TwoStepAuth_SetupPasswordEnterPasswordNew: String { return self._s[1613]! } + public var Notification_Exceptions_RemoveFromExceptions: String { return self._s[1600]! } + public var ScheduledMessages_EditTime: String { return self._s[1601]! } + public var Conversation_ClearSelfHistory: String { return self._s[1602]! } + public var Checkout_NewCard_PostcodePlaceholder: String { return self._s[1603]! } + public var PasscodeSettings_DoNotMatch: String { return self._s[1604]! } + public var Stickers_SuggestNone: String { return self._s[1605]! } + public var ChatSettings_Cache: String { return self._s[1606]! } + public var Settings_SaveIncomingPhotos: String { return self._s[1607]! } + public var Media_ShareThisPhoto: String { return self._s[1608]! } + public var Chat_SlowmodeTooltipPending: String { return self._s[1609]! } + public var InfoPlist_NSContactsUsageDescription: String { return self._s[1610]! } + public var Conversation_ContextMenuCopyLink: String { return self._s[1611]! } + public var PrivacyPolicy_AgeVerificationTitle: String { return self._s[1612]! } + public var SettingsSearch_Synonyms_Stickers_Masks: String { return self._s[1613]! } + public var TwoStepAuth_SetupPasswordEnterPasswordNew: String { return self._s[1614]! } public func Wallet_SecureStorageReset_BiometryText(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1614]!, self._r[1614]!, [_0]) + return formatWithArgumentRanges(self._s[1615]!, self._r[1615]!, [_0]) } - public var Permissions_CellularDataTitle_v0: String { return self._s[1615]! } - public var WallpaperSearch_ColorWhite: String { return self._s[1617]! } - public var Channel_AdminLog_DefaultRestrictionsUpdated: String { return self._s[1618]! } - public var Conversation_ErrorInaccessibleMessage: String { return self._s[1619]! } - public var Map_OpenIn: String { return self._s[1620]! } + public var Permissions_CellularDataTitle_v0: String { return self._s[1616]! } + public var WallpaperSearch_ColorWhite: String { return self._s[1618]! } + public var Channel_AdminLog_DefaultRestrictionsUpdated: String { return self._s[1619]! } + public var Conversation_ErrorInaccessibleMessage: String { return self._s[1620]! } + public var Map_OpenIn: String { return self._s[1621]! } public func PUSH_PHONE_CALL_MISSED(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1623]!, self._r[1623]!, [_1]) + return formatWithArgumentRanges(self._s[1624]!, self._r[1624]!, [_1]) } public func ChannelInfo_AddParticipantConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1624]!, self._r[1624]!, [_0]) + return formatWithArgumentRanges(self._s[1625]!, self._r[1625]!, [_0]) } - public var GroupInfo_Permissions_SlowmodeHeader: String { return self._s[1625]! } - public var MessagePoll_LabelClosed: String { return self._s[1626]! } - public var GroupPermission_PermissionGloballyDisabled: String { return self._s[1628]! } - public var Wallet_Send_SendAnyway: String { return self._s[1629]! } - public var Passport_Identity_MiddleNamePlaceholder: String { return self._s[1630]! } - public var UserInfo_FirstNamePlaceholder: String { return self._s[1631]! } - public var PrivacyLastSeenSettings_WhoCanSeeMyTimestamp: String { return self._s[1632]! } - public var Login_SelectCountry_Title: String { return self._s[1634]! } - public var Channel_EditAdmin_PermissionBanUsers: String { return self._s[1635]! } + public var GroupInfo_Permissions_SlowmodeHeader: String { return self._s[1626]! } + public var MessagePoll_LabelClosed: String { return self._s[1627]! } + public var GroupPermission_PermissionGloballyDisabled: String { return self._s[1629]! } + public var Wallet_Send_SendAnyway: String { return self._s[1630]! } + public var Passport_Identity_MiddleNamePlaceholder: String { return self._s[1631]! } + public var UserInfo_FirstNamePlaceholder: String { return self._s[1632]! } + public var PrivacyLastSeenSettings_WhoCanSeeMyTimestamp: String { return self._s[1633]! } + public var Login_SelectCountry_Title: String { return self._s[1635]! } + public var Channel_EditAdmin_PermissionBanUsers: String { return self._s[1636]! } public func Conversation_OpenBotLinkLogin(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1636]!, self._r[1636]!, [_1, _2]) + return formatWithArgumentRanges(self._s[1637]!, self._r[1637]!, [_1, _2]) } - public var Channel_AdminLog_ChangeInfo: String { return self._s[1637]! } - public var Watch_Suggestion_BRB: String { return self._s[1638]! } - public var Passport_Identity_EditIdentityCard: String { return self._s[1639]! } - public var Contacts_PermissionsTitle: String { return self._s[1640]! } - public var Conversation_RestrictedInline: String { return self._s[1641]! } - public var StickerPack_ViewPack: String { return self._s[1643]! } + public var Channel_AdminLog_ChangeInfo: String { return self._s[1638]! } + public var Watch_Suggestion_BRB: String { return self._s[1639]! } + public var Passport_Identity_EditIdentityCard: String { return self._s[1640]! } + public var Contacts_PermissionsTitle: String { return self._s[1641]! } + public var Conversation_RestrictedInline: String { return self._s[1642]! } + public var StickerPack_ViewPack: String { return self._s[1644]! } public func Update_AppVersion(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1644]!, self._r[1644]!, [_0]) + return formatWithArgumentRanges(self._s[1645]!, self._r[1645]!, [_0]) } - public var Compose_NewChannel: String { return self._s[1646]! } - public var ChatSettings_AutoDownloadSettings_TypePhoto: String { return self._s[1649]! } - public var Conversation_ReportSpamGroupConfirmation: String { return self._s[1651]! } - public var Channel_Info_Stickers: String { return self._s[1652]! } - public var AutoNightTheme_PreferredTheme: String { return self._s[1653]! } - public var PrivacyPolicy_AgeVerificationAgree: String { return self._s[1654]! } - public var Passport_DeletePersonalDetails: String { return self._s[1655]! } - public var LogoutOptions_AddAccountTitle: String { return self._s[1656]! } - public var Channel_DiscussionGroupInfo: String { return self._s[1657]! } - public var Group_EditAdmin_RankOwnerPlaceholder: String { return self._s[1658]! } - public var Conversation_SearchNoResults: String { return self._s[1660]! } - public var MessagePoll_LabelAnonymous: String { return self._s[1661]! } - public var Channel_Members_AddAdminErrorNotAMember: String { return self._s[1662]! } - public var Login_Code: String { return self._s[1663]! } - public var EditTheme_Create_BottomInfo: String { return self._s[1664]! } - public var Watch_Suggestion_WhatsUp: String { return self._s[1665]! } - public var Weekday_ShortThursday: String { return self._s[1666]! } - public var Resolve_ErrorNotFound: String { return self._s[1668]! } - public var LastSeen_Offline: String { return self._s[1670]! } - public var PeopleNearby_NoMembers: String { return self._s[1671]! } - public var GroupPermission_AddMembersNotAvailable: String { return self._s[1672]! } - public var Privacy_Calls_AlwaysAllow_Title: String { return self._s[1673]! } - public var GroupInfo_Title: String { return self._s[1675]! } - public var NotificationsSound_Note: String { return self._s[1676]! } - public var Conversation_EditingMessagePanelTitle: String { return self._s[1677]! } - public var Watch_Message_Poll: String { return self._s[1679]! } - public var Privacy_Calls: String { return self._s[1680]! } + public var Compose_NewChannel: String { return self._s[1647]! } + public var ChatSettings_AutoDownloadSettings_TypePhoto: String { return self._s[1650]! } + public var Conversation_ReportSpamGroupConfirmation: String { return self._s[1652]! } + public var Channel_Info_Stickers: String { return self._s[1653]! } + public var AutoNightTheme_PreferredTheme: String { return self._s[1654]! } + public var PrivacyPolicy_AgeVerificationAgree: String { return self._s[1655]! } + public var Passport_DeletePersonalDetails: String { return self._s[1656]! } + public var LogoutOptions_AddAccountTitle: String { return self._s[1657]! } + public var Channel_DiscussionGroupInfo: String { return self._s[1658]! } + public var Group_EditAdmin_RankOwnerPlaceholder: String { return self._s[1659]! } + public var Conversation_SearchNoResults: String { return self._s[1661]! } + public var MessagePoll_LabelAnonymous: String { return self._s[1662]! } + public var Channel_Members_AddAdminErrorNotAMember: String { return self._s[1663]! } + public var Login_Code: String { return self._s[1664]! } + public var EditTheme_Create_BottomInfo: String { return self._s[1665]! } + public var Watch_Suggestion_WhatsUp: String { return self._s[1666]! } + public var Weekday_ShortThursday: String { return self._s[1667]! } + public var Resolve_ErrorNotFound: String { return self._s[1669]! } + public var LastSeen_Offline: String { return self._s[1671]! } + public var PeopleNearby_NoMembers: String { return self._s[1672]! } + public var GroupPermission_AddMembersNotAvailable: String { return self._s[1673]! } + public var Privacy_Calls_AlwaysAllow_Title: String { return self._s[1674]! } + public var GroupInfo_Title: String { return self._s[1676]! } + public var NotificationsSound_Note: String { return self._s[1677]! } + public var Conversation_EditingMessagePanelTitle: String { return self._s[1678]! } + public var Watch_Message_Poll: String { return self._s[1680]! } + public var Privacy_Calls: String { return self._s[1681]! } public func Channel_AdminLog_MessageRankUsername(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1681]!, self._r[1681]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[1682]!, self._r[1682]!, [_1, _2, _3]) } - public var Month_ShortAugust: String { return self._s[1682]! } - public var TwoStepAuth_SetPasswordHelp: String { return self._s[1683]! } - public var Notifications_Reset: String { return self._s[1684]! } - public var Conversation_Pin: String { return self._s[1685]! } - public var Passport_Language_lv: String { return self._s[1686]! } - public var Permissions_PeopleNearbyAllowInSettings_v0: String { return self._s[1687]! } - public var BlockedUsers_Info: String { return self._s[1688]! } - public var SettingsSearch_Synonyms_Data_AutoplayVideos: String { return self._s[1690]! } - public var Watch_Conversation_Unblock: String { return self._s[1692]! } + public var Month_ShortAugust: String { return self._s[1683]! } + public var TwoStepAuth_SetPasswordHelp: String { return self._s[1684]! } + public var Notifications_Reset: String { return self._s[1685]! } + public var Conversation_Pin: String { return self._s[1686]! } + public var Passport_Language_lv: String { return self._s[1687]! } + public var Permissions_PeopleNearbyAllowInSettings_v0: String { return self._s[1688]! } + public var BlockedUsers_Info: String { return self._s[1689]! } + public var SettingsSearch_Synonyms_Data_AutoplayVideos: String { return self._s[1691]! } + public var Watch_Conversation_Unblock: String { return self._s[1693]! } public func Time_MonthOfYear_m9(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1693]!, self._r[1693]!, [_0]) + return formatWithArgumentRanges(self._s[1694]!, self._r[1694]!, [_0]) } - public var CloudStorage_Title: String { return self._s[1694]! } - public var GroupInfo_DeleteAndExitConfirmation: String { return self._s[1695]! } + public var CloudStorage_Title: String { return self._s[1695]! } + public var GroupInfo_DeleteAndExitConfirmation: String { return self._s[1696]! } public func NetworkUsageSettings_WifiUsageSince(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1696]!, self._r[1696]!, [_0]) + return formatWithArgumentRanges(self._s[1697]!, self._r[1697]!, [_0]) } - public var Channel_AdminLogFilter_AdminsTitle: String { return self._s[1697]! } - public var Watch_Suggestion_OnMyWay: String { return self._s[1698]! } - public var TwoStepAuth_RecoveryEmailTitle: String { return self._s[1699]! } - public var Passport_Address_EditBankStatement: String { return self._s[1700]! } + public var Channel_AdminLogFilter_AdminsTitle: String { return self._s[1698]! } + public var Watch_Suggestion_OnMyWay: String { return self._s[1699]! } + public var TwoStepAuth_RecoveryEmailTitle: String { return self._s[1700]! } + public var Passport_Address_EditBankStatement: String { return self._s[1701]! } public func Channel_AdminLog_MessageChangedUnlinkedGroup(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1701]!, self._r[1701]!, [_1, _2]) + return formatWithArgumentRanges(self._s[1702]!, self._r[1702]!, [_1, _2]) } - public var ChatSettings_DownloadInBackgroundInfo: String { return self._s[1702]! } - public var ShareMenu_Comment: String { return self._s[1703]! } - public var Permissions_ContactsTitle_v0: String { return self._s[1704]! } - public var Notifications_PermissionsTitle: String { return self._s[1705]! } - public var GroupPermission_NoSendLinks: String { return self._s[1706]! } - public var Privacy_Forwards_NeverAllow_Title: String { return self._s[1707]! } - public var Wallet_SecureStorageChanged_ImportWallet: String { return self._s[1708]! } - public var Settings_Support: String { return self._s[1709]! } - public var Notifications_ChannelNotificationsSound: String { return self._s[1710]! } - public var SettingsSearch_Synonyms_Data_AutoDownloadReset: String { return self._s[1711]! } - public var Privacy_Forwards_Preview: String { return self._s[1712]! } - public var GroupPermission_ApplyAlertAction: String { return self._s[1713]! } - public var Watch_Stickers_StickerPacks: String { return self._s[1714]! } - public var Common_Select: String { return self._s[1716]! } - public var CheckoutInfo_ErrorEmailInvalid: String { return self._s[1717]! } - public var WallpaperSearch_ColorGray: String { return self._s[1719]! } - public var ChatAdmins_AllMembersAreAdminsOffHelp: String { return self._s[1720]! } - public var PasscodeSettings_AutoLock_IfAwayFor_5hours: String { return self._s[1721]! } - public var Appearance_PreviewReplyAuthor: String { return self._s[1722]! } - public var TwoStepAuth_RecoveryTitle: String { return self._s[1723]! } - public var Widget_AuthRequired: String { return self._s[1724]! } - public var Camera_FlashOn: String { return self._s[1725]! } - public var Conversation_ContextMenuLookUp: String { return self._s[1726]! } - public var Channel_Stickers_NotFoundHelp: String { return self._s[1727]! } - public var Watch_Suggestion_OK: String { return self._s[1728]! } + public var ChatSettings_DownloadInBackgroundInfo: String { return self._s[1703]! } + public var ShareMenu_Comment: String { return self._s[1704]! } + public var Permissions_ContactsTitle_v0: String { return self._s[1705]! } + public var Notifications_PermissionsTitle: String { return self._s[1706]! } + public var GroupPermission_NoSendLinks: String { return self._s[1707]! } + public var Privacy_Forwards_NeverAllow_Title: String { return self._s[1708]! } + public var Wallet_SecureStorageChanged_ImportWallet: String { return self._s[1709]! } + public var Settings_Support: String { return self._s[1710]! } + public var Notifications_ChannelNotificationsSound: String { return self._s[1711]! } + public var SettingsSearch_Synonyms_Data_AutoDownloadReset: String { return self._s[1712]! } + public var Privacy_Forwards_Preview: String { return self._s[1713]! } + public var GroupPermission_ApplyAlertAction: String { return self._s[1714]! } + public var Watch_Stickers_StickerPacks: String { return self._s[1715]! } + public var Common_Select: String { return self._s[1717]! } + public var CheckoutInfo_ErrorEmailInvalid: String { return self._s[1718]! } + public var WallpaperSearch_ColorGray: String { return self._s[1720]! } + public var ChatAdmins_AllMembersAreAdminsOffHelp: String { return self._s[1721]! } + public var PasscodeSettings_AutoLock_IfAwayFor_5hours: String { return self._s[1722]! } + public var Appearance_PreviewReplyAuthor: String { return self._s[1723]! } + public var TwoStepAuth_RecoveryTitle: String { return self._s[1724]! } + public var Widget_AuthRequired: String { return self._s[1725]! } + public var Camera_FlashOn: String { return self._s[1726]! } + public var Conversation_ContextMenuLookUp: String { return self._s[1727]! } + public var Channel_Stickers_NotFoundHelp: String { return self._s[1728]! } + public var Watch_Suggestion_OK: String { return self._s[1729]! } public func Username_LinkHint(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1730]!, self._r[1730]!, [_0]) + return formatWithArgumentRanges(self._s[1731]!, self._r[1731]!, [_0]) } public func Notification_PinnedLiveLocationMessage(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1732]!, self._r[1732]!, [_0]) + return formatWithArgumentRanges(self._s[1733]!, self._r[1733]!, [_0]) } - public var TextFormat_Strikethrough: String { return self._s[1733]! } - public var DialogList_AdLabel: String { return self._s[1734]! } - public var WatchRemote_NotificationText: String { return self._s[1735]! } - public var SettingsSearch_Synonyms_Notifications_MessageNotificationsAlert: String { return self._s[1736]! } - public var Conversation_ReportSpam: String { return self._s[1737]! } - public var SettingsSearch_Synonyms_Privacy_Data_TopPeers: String { return self._s[1738]! } - public var Settings_LogoutConfirmationTitle: String { return self._s[1740]! } - public var PhoneLabel_Title: String { return self._s[1741]! } - public var Passport_Address_EditRentalAgreement: String { return self._s[1742]! } - public var Settings_ChangePhoneNumber: String { return self._s[1743]! } - public var Notifications_ExceptionsTitle: String { return self._s[1744]! } - public var Notifications_AlertTones: String { return self._s[1745]! } - public var Call_ReportIncludeLogDescription: String { return self._s[1746]! } - public var SettingsSearch_Synonyms_Notifications_ResetAllNotifications: String { return self._s[1747]! } - public var AutoDownloadSettings_PrivateChats: String { return self._s[1748]! } - public var VoiceOver_Chat_Photo: String { return self._s[1750]! } - public var TwoStepAuth_AddHintTitle: String { return self._s[1751]! } - public var ReportPeer_ReasonOther: String { return self._s[1752]! } - public var ChatList_Context_JoinChannel: String { return self._s[1753]! } - public var KeyCommand_ScrollDown: String { return self._s[1755]! } - public var Conversation_ScheduleMessage_Title: String { return self._s[1756]! } + public var TextFormat_Strikethrough: String { return self._s[1734]! } + public var DialogList_AdLabel: String { return self._s[1735]! } + public var WatchRemote_NotificationText: String { return self._s[1736]! } + public var SettingsSearch_Synonyms_Notifications_MessageNotificationsAlert: String { return self._s[1737]! } + public var Conversation_ReportSpam: String { return self._s[1738]! } + public var SettingsSearch_Synonyms_Privacy_Data_TopPeers: String { return self._s[1739]! } + public var Settings_LogoutConfirmationTitle: String { return self._s[1741]! } + public var PhoneLabel_Title: String { return self._s[1742]! } + public var Passport_Address_EditRentalAgreement: String { return self._s[1743]! } + public var Settings_ChangePhoneNumber: String { return self._s[1744]! } + public var Notifications_ExceptionsTitle: String { return self._s[1745]! } + public var Notifications_AlertTones: String { return self._s[1746]! } + public var Call_ReportIncludeLogDescription: String { return self._s[1747]! } + public var SettingsSearch_Synonyms_Notifications_ResetAllNotifications: String { return self._s[1748]! } + public var AutoDownloadSettings_PrivateChats: String { return self._s[1749]! } + public var VoiceOver_Chat_Photo: String { return self._s[1751]! } + public var TwoStepAuth_AddHintTitle: String { return self._s[1752]! } + public var ReportPeer_ReasonOther: String { return self._s[1753]! } + public var ChatList_Context_JoinChannel: String { return self._s[1754]! } + public var KeyCommand_ScrollDown: String { return self._s[1756]! } + public var Conversation_ScheduleMessage_Title: String { return self._s[1757]! } public func Login_BannedPhoneSubject(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1757]!, self._r[1757]!, [_0]) + return formatWithArgumentRanges(self._s[1758]!, self._r[1758]!, [_0]) } - public var NetworkUsageSettings_MediaVideoDataSection: String { return self._s[1758]! } - public var ChannelInfo_DeleteGroupConfirmation: String { return self._s[1759]! } - public var AuthSessions_LogOut: String { return self._s[1760]! } - public var Passport_Identity_TypeInternalPassport: String { return self._s[1761]! } - public var ChatSettings_AutoDownloadVoiceMessages: String { return self._s[1762]! } - public var Passport_Phone_Title: String { return self._s[1763]! } - public var ContactList_Context_StartSecretChat: String { return self._s[1764]! } - public var Settings_PhoneNumber: String { return self._s[1765]! } + public var NetworkUsageSettings_MediaVideoDataSection: String { return self._s[1759]! } + public var ChannelInfo_DeleteGroupConfirmation: String { return self._s[1760]! } + public var AuthSessions_LogOut: String { return self._s[1761]! } + public var Passport_Identity_TypeInternalPassport: String { return self._s[1762]! } + public var ChatSettings_AutoDownloadVoiceMessages: String { return self._s[1763]! } + public var Passport_Phone_Title: String { return self._s[1764]! } + public var ContactList_Context_StartSecretChat: String { return self._s[1765]! } + public var Settings_PhoneNumber: String { return self._s[1766]! } public func Conversation_ScheduleMessage_SendToday(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1766]!, self._r[1766]!, [_0]) + return formatWithArgumentRanges(self._s[1767]!, self._r[1767]!, [_0]) } - public var NotificationsSound_Alert: String { return self._s[1767]! } - public var Wallet_SecureStorageChanged_CreateWallet: String { return self._s[1768]! } - public var WebSearch_SearchNoResults: String { return self._s[1769]! } - public var Privacy_ProfilePhoto_AlwaysShareWith_Title: String { return self._s[1771]! } - public var LogoutOptions_AlternativeOptionsSection: String { return self._s[1772]! } - public var SettingsSearch_Synonyms_Passport: String { return self._s[1773]! } - public var PhotoEditor_CurvesTool: String { return self._s[1774]! } - public var Checkout_PaymentMethod: String { return self._s[1776]! } + public var NotificationsSound_Alert: String { return self._s[1768]! } + public var Wallet_SecureStorageChanged_CreateWallet: String { return self._s[1769]! } + public var WebSearch_SearchNoResults: String { return self._s[1770]! } + public var Privacy_ProfilePhoto_AlwaysShareWith_Title: String { return self._s[1772]! } + public var LogoutOptions_AlternativeOptionsSection: String { return self._s[1773]! } + public var SettingsSearch_Synonyms_Passport: String { return self._s[1774]! } + public var PhotoEditor_CurvesTool: String { return self._s[1775]! } + public var Checkout_PaymentMethod: String { return self._s[1777]! } public func PUSH_CHAT_ADD_YOU(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1777]!, self._r[1777]!, [_1, _2]) + return formatWithArgumentRanges(self._s[1778]!, self._r[1778]!, [_1, _2]) } - public var Contacts_AccessDeniedError: String { return self._s[1778]! } - public var Camera_PhotoMode: String { return self._s[1781]! } - public var EditTheme_Expand_Preview_IncomingText: String { return self._s[1782]! } + public var Contacts_AccessDeniedError: String { return self._s[1779]! } + public var Camera_PhotoMode: String { return self._s[1782]! } + public var EditTheme_Expand_Preview_IncomingText: String { return self._s[1783]! } public func Updated_TodayAt(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1783]!, self._r[1783]!, [_0]) + return formatWithArgumentRanges(self._s[1784]!, self._r[1784]!, [_0]) } - public var Passport_Address_AddUtilityBill: String { return self._s[1785]! } - public var CallSettings_OnMobile: String { return self._s[1786]! } - public var Tour_Text2: String { return self._s[1787]! } + public var Passport_Address_AddUtilityBill: String { return self._s[1786]! } + public var CallSettings_OnMobile: String { return self._s[1787]! } + public var Tour_Text2: String { return self._s[1788]! } public func PUSH_CHAT_MESSAGE_ROUND(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1788]!, self._r[1788]!, [_1, _2]) + return formatWithArgumentRanges(self._s[1789]!, self._r[1789]!, [_1, _2]) } - public var DialogList_EncryptionProcessing: String { return self._s[1790]! } - public var Permissions_Skip: String { return self._s[1791]! } - public var Wallet_Words_NotDoneOk: String { return self._s[1792]! } - public var SecretImage_Title: String { return self._s[1793]! } - public var Watch_MessageView_Title: String { return self._s[1794]! } - public var Channel_DiscussionGroupAdd: String { return self._s[1795]! } - public var AttachmentMenu_Poll: String { return self._s[1796]! } + public var DialogList_EncryptionProcessing: String { return self._s[1791]! } + public var Permissions_Skip: String { return self._s[1792]! } + public var Wallet_Words_NotDoneOk: String { return self._s[1793]! } + public var SecretImage_Title: String { return self._s[1794]! } + public var Watch_MessageView_Title: String { return self._s[1795]! } + public var Channel_DiscussionGroupAdd: String { return self._s[1796]! } + public var AttachmentMenu_Poll: String { return self._s[1797]! } public func Notification_GroupInviter(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1797]!, self._r[1797]!, [_0]) + return formatWithArgumentRanges(self._s[1798]!, self._r[1798]!, [_0]) } public func Channel_DiscussionGroup_PrivateChannelLink(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1798]!, self._r[1798]!, [_1, _2]) + return formatWithArgumentRanges(self._s[1799]!, self._r[1799]!, [_1, _2]) } - public var Notification_CallCanceled: String { return self._s[1799]! } - public var WallpaperPreview_Title: String { return self._s[1800]! } - public var Privacy_PaymentsClear_PaymentInfo: String { return self._s[1801]! } - public var Settings_ProxyConnecting: String { return self._s[1802]! } - public var Settings_CheckPhoneNumberText: String { return self._s[1804]! } - public var VoiceOver_Chat_YourVideo: String { return self._s[1805]! } - public var Wallet_Intro_Title: String { return self._s[1806]! } - public var Profile_MessageLifetime5s: String { return self._s[1807]! } - public var Username_InvalidCharacters: String { return self._s[1808]! } - public var VoiceOver_Media_PlaybackRateFast: String { return self._s[1809]! } - public var ScheduledMessages_ClearAll: String { return self._s[1810]! } - public var WallpaperPreview_CropBottomText: String { return self._s[1811]! } - public var AutoDownloadSettings_LimitBySize: String { return self._s[1812]! } - public var Settings_AddAccount: String { return self._s[1813]! } - public var Notification_CreatedChannel: String { return self._s[1816]! } + public var Notification_CallCanceled: String { return self._s[1800]! } + public var WallpaperPreview_Title: String { return self._s[1801]! } + public var Privacy_PaymentsClear_PaymentInfo: String { return self._s[1802]! } + public var Settings_ProxyConnecting: String { return self._s[1803]! } + public var Settings_CheckPhoneNumberText: String { return self._s[1805]! } + public var VoiceOver_Chat_YourVideo: String { return self._s[1806]! } + public var Wallet_Intro_Title: String { return self._s[1807]! } + public var Profile_MessageLifetime5s: String { return self._s[1808]! } + public var Username_InvalidCharacters: String { return self._s[1809]! } + public var VoiceOver_Media_PlaybackRateFast: String { return self._s[1810]! } + public var ScheduledMessages_ClearAll: String { return self._s[1811]! } + public var WallpaperPreview_CropBottomText: String { return self._s[1812]! } + public var AutoDownloadSettings_LimitBySize: String { return self._s[1813]! } + public var Settings_AddAccount: String { return self._s[1814]! } + public var Notification_CreatedChannel: String { return self._s[1817]! } public func PUSH_CHAT_DELETE_MEMBER(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1817]!, self._r[1817]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[1818]!, self._r[1818]!, [_1, _2, _3]) } - public var Passcode_AppLockedAlert: String { return self._s[1819]! } - public var StickerPacksSettings_AnimatedStickersInfo: String { return self._s[1820]! } - public var VoiceOver_Media_PlaybackStop: String { return self._s[1821]! } - public var Contacts_TopSection: String { return self._s[1822]! } + public var Passcode_AppLockedAlert: String { return self._s[1820]! } + public var StickerPacksSettings_AnimatedStickersInfo: String { return self._s[1821]! } + public var VoiceOver_Media_PlaybackStop: String { return self._s[1822]! } + public var Contacts_TopSection: String { return self._s[1823]! } public func Conversation_SetReminder_RemindOn(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1823]!, self._r[1823]!, [_0, _1]) + return formatWithArgumentRanges(self._s[1824]!, self._r[1824]!, [_0, _1]) } - public var Wallet_Info_Receive: String { return self._s[1824]! } - public var Wallet_Completed_ViewWallet: String { return self._s[1825]! } + public var Wallet_Info_Receive: String { return self._s[1825]! } + public var Wallet_Completed_ViewWallet: String { return self._s[1826]! } public func Time_MonthOfYear_m6(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1826]!, self._r[1826]!, [_0]) + return formatWithArgumentRanges(self._s[1827]!, self._r[1827]!, [_0]) } - public var ReportPeer_ReasonSpam: String { return self._s[1827]! } - public var UserInfo_TapToCall: String { return self._s[1828]! } - public var Conversation_ForwardAuthorHiddenTooltip: String { return self._s[1830]! } - public var AutoDownloadSettings_DataUsageCustom: String { return self._s[1831]! } - public var Common_Search: String { return self._s[1832]! } - public var ScheduledMessages_EmptyPlaceholder: String { return self._s[1833]! } + public var ReportPeer_ReasonSpam: String { return self._s[1828]! } + public var UserInfo_TapToCall: String { return self._s[1829]! } + public var Conversation_ForwardAuthorHiddenTooltip: String { return self._s[1831]! } + public var AutoDownloadSettings_DataUsageCustom: String { return self._s[1832]! } + public var Common_Search: String { return self._s[1833]! } + public var ScheduledMessages_EmptyPlaceholder: String { return self._s[1834]! } public func Channel_AdminLog_MessageChangedGroupGeoLocation(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1834]!, self._r[1834]!, [_0]) + return formatWithArgumentRanges(self._s[1835]!, self._r[1835]!, [_0]) } - public var AuthSessions_IncompleteAttemptsInfo: String { return self._s[1835]! } - public var Message_InvoiceLabel: String { return self._s[1836]! } - public var Conversation_InputTextPlaceholder: String { return self._s[1837]! } - public var NetworkUsageSettings_MediaImageDataSection: String { return self._s[1838]! } + public var AuthSessions_IncompleteAttemptsInfo: String { return self._s[1836]! } + public var Message_InvoiceLabel: String { return self._s[1837]! } + public var Conversation_InputTextPlaceholder: String { return self._s[1838]! } + public var NetworkUsageSettings_MediaImageDataSection: String { return self._s[1839]! } public func Passport_Address_UploadOneOfScan(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1839]!, self._r[1839]!, [_0]) + return formatWithArgumentRanges(self._s[1840]!, self._r[1840]!, [_0]) } - public var Conversation_Info: String { return self._s[1840]! } - public var Login_InfoDeletePhoto: String { return self._s[1841]! } - public var Passport_Language_vi: String { return self._s[1843]! } - public var UserInfo_ScamUserWarning: String { return self._s[1844]! } - public var Conversation_Search: String { return self._s[1845]! } - public var DialogList_DeleteBotConversationConfirmation: String { return self._s[1847]! } + public var Conversation_Info: String { return self._s[1841]! } + public var Login_InfoDeletePhoto: String { return self._s[1842]! } + public var Passport_Language_vi: String { return self._s[1844]! } + public var UserInfo_ScamUserWarning: String { return self._s[1845]! } + public var Conversation_Search: String { return self._s[1846]! } + public var DialogList_DeleteBotConversationConfirmation: String { return self._s[1848]! } public func Updated_AtDate(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1848]!, self._r[1848]!, [_0]) + return formatWithArgumentRanges(self._s[1849]!, self._r[1849]!, [_0]) } - public var ReportPeer_ReasonPornography: String { return self._s[1849]! } - public var AutoDownloadSettings_PhotosTitle: String { return self._s[1850]! } - public var Conversation_SendMessageErrorGroupRestricted: String { return self._s[1851]! } - public var Map_LiveLocationGroupDescription: String { return self._s[1852]! } - public var Channel_Setup_TypeHeader: String { return self._s[1853]! } - public var AuthSessions_LoggedIn: String { return self._s[1854]! } - public var Privacy_Forwards_AlwaysAllow_Title: String { return self._s[1855]! } - public var Login_SmsRequestState3: String { return self._s[1856]! } - public var Passport_Address_EditUtilityBill: String { return self._s[1857]! } - public var Appearance_ReduceMotionInfo: String { return self._s[1858]! } - public var Join_ChannelsTooMuch: String { return self._s[1859]! } - public var Channel_Edit_LinkItem: String { return self._s[1860]! } - public var Privacy_Calls_P2PNever: String { return self._s[1861]! } - public var Conversation_AddToReadingList: String { return self._s[1863]! } - public var Share_MultipleMessagesDisabled: String { return self._s[1864]! } - public var Message_Animation: String { return self._s[1865]! } - public var Conversation_DefaultRestrictedMedia: String { return self._s[1866]! } - public var Map_Unknown: String { return self._s[1867]! } - public var AutoDownloadSettings_LastDelimeter: String { return self._s[1868]! } + public var ReportPeer_ReasonPornography: String { return self._s[1850]! } + public var AutoDownloadSettings_PhotosTitle: String { return self._s[1851]! } + public var Conversation_SendMessageErrorGroupRestricted: String { return self._s[1852]! } + public var Map_LiveLocationGroupDescription: String { return self._s[1853]! } + public var Channel_Setup_TypeHeader: String { return self._s[1854]! } + public var AuthSessions_LoggedIn: String { return self._s[1855]! } + public var Privacy_Forwards_AlwaysAllow_Title: String { return self._s[1856]! } + public var Login_SmsRequestState3: String { return self._s[1857]! } + public var Passport_Address_EditUtilityBill: String { return self._s[1858]! } + public var Appearance_ReduceMotionInfo: String { return self._s[1859]! } + public var Join_ChannelsTooMuch: String { return self._s[1860]! } + public var Channel_Edit_LinkItem: String { return self._s[1861]! } + public var Privacy_Calls_P2PNever: String { return self._s[1862]! } + public var Conversation_AddToReadingList: String { return self._s[1864]! } + public var Share_MultipleMessagesDisabled: String { return self._s[1865]! } + public var Message_Animation: String { return self._s[1866]! } + public var Conversation_DefaultRestrictedMedia: String { return self._s[1867]! } + public var Map_Unknown: String { return self._s[1868]! } + public var AutoDownloadSettings_LastDelimeter: String { return self._s[1869]! } public func PUSH_PINNED_TEXT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1869]!, self._r[1869]!, [_1, _2]) - } - public func Passport_FieldOneOf_Or(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[1870]!, self._r[1870]!, [_1, _2]) } - public var Call_StatusRequesting: String { return self._s[1871]! } - public var Conversation_SecretChatContextBotAlert: String { return self._s[1872]! } - public var SocksProxySetup_ProxyStatusChecking: String { return self._s[1873]! } + public func Passport_FieldOneOf_Or(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[1871]!, self._r[1871]!, [_1, _2]) + } + public var Call_StatusRequesting: String { return self._s[1872]! } + public var Conversation_SecretChatContextBotAlert: String { return self._s[1873]! } + public var SocksProxySetup_ProxyStatusChecking: String { return self._s[1874]! } public func PUSH_CHAT_MESSAGE_DOC(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1874]!, self._r[1874]!, [_1, _2]) + return formatWithArgumentRanges(self._s[1875]!, self._r[1875]!, [_1, _2]) } public func Notification_PinnedLocationMessage(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1875]!, self._r[1875]!, [_0]) + return formatWithArgumentRanges(self._s[1876]!, self._r[1876]!, [_0]) } - public var Update_Skip: String { return self._s[1876]! } - public var Group_Username_RemoveExistingUsernamesInfo: String { return self._s[1877]! } - public var Message_PinnedPollMessage: String { return self._s[1878]! } - public var BlockedUsers_Title: String { return self._s[1879]! } + public var Update_Skip: String { return self._s[1877]! } + public var Group_Username_RemoveExistingUsernamesInfo: String { return self._s[1878]! } + public var Message_PinnedPollMessage: String { return self._s[1879]! } + public var BlockedUsers_Title: String { return self._s[1880]! } public func PUSH_CHANNEL_MESSAGE_AUDIO(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1880]!, self._r[1880]!, [_1]) + return formatWithArgumentRanges(self._s[1881]!, self._r[1881]!, [_1]) } - public var Username_CheckingUsername: String { return self._s[1881]! } - public var NotificationsSound_Bell: String { return self._s[1882]! } - public var Conversation_SendMessageErrorFlood: String { return self._s[1883]! } - public var Weekday_Monday: String { return self._s[1884]! } - public var SettingsSearch_Synonyms_Notifications_DisplayNamesOnLockScreen: String { return self._s[1885]! } - public var ChannelMembers_ChannelAdminsTitle: String { return self._s[1886]! } - public var ChatSettings_Groups: String { return self._s[1887]! } + public var Username_CheckingUsername: String { return self._s[1882]! } + public var NotificationsSound_Bell: String { return self._s[1883]! } + public var Conversation_SendMessageErrorFlood: String { return self._s[1884]! } + public var Weekday_Monday: String { return self._s[1885]! } + public var SettingsSearch_Synonyms_Notifications_DisplayNamesOnLockScreen: String { return self._s[1886]! } + public var ChannelMembers_ChannelAdminsTitle: String { return self._s[1887]! } + public var ChatSettings_Groups: String { return self._s[1888]! } public func Conversation_SetReminder_RemindTomorrow(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1888]!, self._r[1888]!, [_0]) + return formatWithArgumentRanges(self._s[1889]!, self._r[1889]!, [_0]) } - public var Your_card_was_declined: String { return self._s[1889]! } - public var TwoStepAuth_EnterPasswordHelp: String { return self._s[1891]! } - public var ChatList_Unmute: String { return self._s[1892]! } - public var PhotoEditor_CurvesAll: String { return self._s[1893]! } - public var Weekday_ShortTuesday: String { return self._s[1894]! } - public var DialogList_Read: String { return self._s[1895]! } - public var Appearance_AppIconClassic: String { return self._s[1896]! } - public var ChannelMembers_WhoCanAddMembers_AllMembers: String { return self._s[1897]! } - public var Passport_Identity_Gender: String { return self._s[1898]! } + public var Your_card_was_declined: String { return self._s[1890]! } + public var TwoStepAuth_EnterPasswordHelp: String { return self._s[1892]! } + public var ChatList_Unmute: String { return self._s[1893]! } + public var PhotoEditor_CurvesAll: String { return self._s[1894]! } + public var Weekday_ShortTuesday: String { return self._s[1895]! } + public var DialogList_Read: String { return self._s[1896]! } + public var Appearance_AppIconClassic: String { return self._s[1897]! } + public var ChannelMembers_WhoCanAddMembers_AllMembers: String { return self._s[1898]! } + public var Passport_Identity_Gender: String { return self._s[1899]! } public func Target_ShareGameConfirmationPrivate(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1899]!, self._r[1899]!, [_0]) + return formatWithArgumentRanges(self._s[1900]!, self._r[1900]!, [_0]) } - public var Target_SelectGroup: String { return self._s[1900]! } + public var Target_SelectGroup: String { return self._s[1901]! } public func DialogList_EncryptedChatStartedIncoming(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1902]!, self._r[1902]!, [_0]) + return formatWithArgumentRanges(self._s[1903]!, self._r[1903]!, [_0]) } - public var Passport_Language_en: String { return self._s[1903]! } - public var AutoDownloadSettings_AutodownloadPhotos: String { return self._s[1904]! } - public var Channel_Username_CreatePublicLinkHelp: String { return self._s[1905]! } - public var Login_CancelPhoneVerificationContinue: String { return self._s[1906]! } - public var ScheduledMessages_SendNow: String { return self._s[1907]! } - public var Checkout_NewCard_PaymentCard: String { return self._s[1909]! } - public var Login_InfoHelp: String { return self._s[1910]! } - public var Contacts_PermissionsSuppressWarningTitle: String { return self._s[1911]! } - public var SettingsSearch_Synonyms_Stickers_FeaturedPacks: String { return self._s[1912]! } + public var Passport_Language_en: String { return self._s[1904]! } + public var AutoDownloadSettings_AutodownloadPhotos: String { return self._s[1905]! } + public var Channel_Username_CreatePublicLinkHelp: String { return self._s[1906]! } + public var Login_CancelPhoneVerificationContinue: String { return self._s[1907]! } + public var ScheduledMessages_SendNow: String { return self._s[1908]! } + public var Checkout_NewCard_PaymentCard: String { return self._s[1910]! } + public var Login_InfoHelp: String { return self._s[1911]! } + public var Contacts_PermissionsSuppressWarningTitle: String { return self._s[1912]! } + public var SettingsSearch_Synonyms_Stickers_FeaturedPacks: String { return self._s[1913]! } public func Channel_AdminLog_MessageChangedLinkedChannel(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1913]!, self._r[1913]!, [_1, _2]) + return formatWithArgumentRanges(self._s[1914]!, self._r[1914]!, [_1, _2]) } - public var SocksProxySetup_AddProxy: String { return self._s[1916]! } - public var CreatePoll_Title: String { return self._s[1917]! } - public var Conversation_ViewTheme: String { return self._s[1918]! } - public var SettingsSearch_Synonyms_Privacy_Data_SecretChatLinkPreview: String { return self._s[1919]! } - public var PasscodeSettings_SimplePasscodeHelp: String { return self._s[1920]! } - public var UserInfo_GroupsInCommon: String { return self._s[1921]! } - public var Call_AudioRouteHide: String { return self._s[1922]! } - public var ContactInfo_PhoneLabelMobile: String { return self._s[1924]! } + public var SocksProxySetup_AddProxy: String { return self._s[1917]! } + public var CreatePoll_Title: String { return self._s[1918]! } + public var Conversation_ViewTheme: String { return self._s[1919]! } + public var SettingsSearch_Synonyms_Privacy_Data_SecretChatLinkPreview: String { return self._s[1920]! } + public var PasscodeSettings_SimplePasscodeHelp: String { return self._s[1921]! } + public var UserInfo_GroupsInCommon: String { return self._s[1922]! } + public var Call_AudioRouteHide: String { return self._s[1923]! } + public var ContactInfo_PhoneLabelMobile: String { return self._s[1925]! } public func ChatList_LeaveGroupConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1925]!, self._r[1925]!, [_0]) + return formatWithArgumentRanges(self._s[1926]!, self._r[1926]!, [_0]) } - public var TextFormat_Bold: String { return self._s[1926]! } - public var FastTwoStepSetup_EmailSection: String { return self._s[1927]! } - public var Notifications_Title: String { return self._s[1928]! } - public var Group_Username_InvalidTooShort: String { return self._s[1929]! } - public var Channel_ErrorAddTooMuch: String { return self._s[1930]! } + public var TextFormat_Bold: String { return self._s[1927]! } + public var FastTwoStepSetup_EmailSection: String { return self._s[1928]! } + public var Notifications_Title: String { return self._s[1929]! } + public var Group_Username_InvalidTooShort: String { return self._s[1930]! } + public var Channel_ErrorAddTooMuch: String { return self._s[1931]! } public func DialogList_MultipleTypingSuffix(_ _0: Int) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1931]!, self._r[1931]!, ["\(_0)"]) + return formatWithArgumentRanges(self._s[1932]!, self._r[1932]!, ["\(_0)"]) } - public var VoiceOver_DiscardPreparedContent: String { return self._s[1933]! } - public var Stickers_SuggestAdded: String { return self._s[1934]! } - public var Login_CountryCode: String { return self._s[1935]! } - public var ChatSettings_AutoPlayVideos: String { return self._s[1936]! } - public var Map_GetDirections: String { return self._s[1937]! } - public var Wallet_Receive_ShareInvoiceUrl: String { return self._s[1938]! } - public var Login_PhoneFloodError: String { return self._s[1939]! } + public var VoiceOver_DiscardPreparedContent: String { return self._s[1934]! } + public var Stickers_SuggestAdded: String { return self._s[1935]! } + public var Login_CountryCode: String { return self._s[1936]! } + public var ChatSettings_AutoPlayVideos: String { return self._s[1937]! } + public var Map_GetDirections: String { return self._s[1938]! } + public var Wallet_Receive_ShareInvoiceUrl: String { return self._s[1939]! } + public var Login_PhoneFloodError: String { return self._s[1940]! } public func Time_MonthOfYear_m3(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1940]!, self._r[1940]!, [_0]) + return formatWithArgumentRanges(self._s[1941]!, self._r[1941]!, [_0]) } - public var Settings_SetUsername: String { return self._s[1942]! } - public var Group_Location_ChangeLocation: String { return self._s[1943]! } - public var Notification_GroupInviterSelf: String { return self._s[1944]! } - public var InstantPage_TapToOpenLink: String { return self._s[1945]! } + public var Settings_SetUsername: String { return self._s[1943]! } + public var Group_Location_ChangeLocation: String { return self._s[1944]! } + public var Notification_GroupInviterSelf: String { return self._s[1945]! } + public var InstantPage_TapToOpenLink: String { return self._s[1946]! } public func Notification_ChannelInviter(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1946]!, self._r[1946]!, [_0]) + return formatWithArgumentRanges(self._s[1947]!, self._r[1947]!, [_0]) } - public var Watch_Suggestion_TalkLater: String { return self._s[1947]! } - public var SecretChat_Title: String { return self._s[1948]! } - public var Group_UpgradeNoticeText1: String { return self._s[1949]! } - public var AuthSessions_Title: String { return self._s[1950]! } + public var Watch_Suggestion_TalkLater: String { return self._s[1948]! } + public var SecretChat_Title: String { return self._s[1949]! } + public var Group_UpgradeNoticeText1: String { return self._s[1950]! } + public var AuthSessions_Title: String { return self._s[1951]! } public func TextFormat_AddLinkText(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1951]!, self._r[1951]!, [_0]) + return formatWithArgumentRanges(self._s[1952]!, self._r[1952]!, [_0]) } - public var PhotoEditor_CropAuto: String { return self._s[1952]! } - public var Channel_About_Title: String { return self._s[1953]! } - public var FastTwoStepSetup_EmailHelp: String { return self._s[1954]! } + public var PhotoEditor_CropAuto: String { return self._s[1953]! } + public var Channel_About_Title: String { return self._s[1954]! } + public var FastTwoStepSetup_EmailHelp: String { return self._s[1955]! } public func Conversation_Bytes(_ _0: Int) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1956]!, self._r[1956]!, ["\(_0)"]) + return formatWithArgumentRanges(self._s[1957]!, self._r[1957]!, ["\(_0)"]) } - public var VoiceOver_MessageContextReport: String { return self._s[1957]! } - public var Conversation_PinMessageAlert_OnlyPin: String { return self._s[1959]! } - public var Group_Setup_HistoryVisibleHelp: String { return self._s[1960]! } + public var VoiceOver_MessageContextReport: String { return self._s[1958]! } + public var Conversation_PinMessageAlert_OnlyPin: String { return self._s[1960]! } + public var Group_Setup_HistoryVisibleHelp: String { return self._s[1961]! } public func PUSH_MESSAGE_GIF(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1961]!, self._r[1961]!, [_1]) + return formatWithArgumentRanges(self._s[1962]!, self._r[1962]!, [_1]) } public func SharedMedia_SearchNoResultsDescription(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1963]!, self._r[1963]!, [_0]) - } - public func TwoStepAuth_RecoveryEmailUnavailable(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[1964]!, self._r[1964]!, [_0]) } - public var Privacy_PaymentsClearInfoHelp: String { return self._s[1965]! } - public var Presence_online: String { return self._s[1967]! } - public var PasscodeSettings_Title: String { return self._s[1968]! } - public var Passport_Identity_ExpiryDatePlaceholder: String { return self._s[1969]! } - public var Web_OpenExternal: String { return self._s[1970]! } - public var AutoDownloadSettings_AutoDownload: String { return self._s[1972]! } - public var Channel_OwnershipTransfer_EnterPasswordText: String { return self._s[1973]! } - public var LocalGroup_Title: String { return self._s[1974]! } + public func TwoStepAuth_RecoveryEmailUnavailable(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[1965]!, self._r[1965]!, [_0]) + } + public var Privacy_PaymentsClearInfoHelp: String { return self._s[1966]! } + public var Presence_online: String { return self._s[1968]! } + public var PasscodeSettings_Title: String { return self._s[1969]! } + public var Passport_Identity_ExpiryDatePlaceholder: String { return self._s[1970]! } + public var Web_OpenExternal: String { return self._s[1971]! } + public var AutoDownloadSettings_AutoDownload: String { return self._s[1973]! } + public var Channel_OwnershipTransfer_EnterPasswordText: String { return self._s[1974]! } + public var LocalGroup_Title: String { return self._s[1975]! } public func AutoNightTheme_AutomaticHelp(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1975]!, self._r[1975]!, [_0]) + return formatWithArgumentRanges(self._s[1976]!, self._r[1976]!, [_0]) } - public var FastTwoStepSetup_PasswordConfirmationPlaceholder: String { return self._s[1976]! } - public var Map_YouAreHere: String { return self._s[1977]! } + public var FastTwoStepSetup_PasswordConfirmationPlaceholder: String { return self._s[1977]! } + public var Map_YouAreHere: String { return self._s[1978]! } public func AuthSessions_Message(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1978]!, self._r[1978]!, [_0]) - } - public func ChatList_DeleteChatConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[1979]!, self._r[1979]!, [_0]) } - public var PrivacyLastSeenSettings_AlwaysShareWith: String { return self._s[1980]! } - public var Target_InviteToGroupErrorAlreadyInvited: String { return self._s[1981]! } - public func AuthSessions_AppUnofficial(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1982]!, self._r[1982]!, [_0]) + public func ChatList_DeleteChatConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[1980]!, self._r[1980]!, [_0]) } - public func DialogList_LiveLocationSharingTo(_ _0: String) -> (String, [(Int, NSRange)]) { + public var PrivacyLastSeenSettings_AlwaysShareWith: String { return self._s[1981]! } + public var Target_InviteToGroupErrorAlreadyInvited: String { return self._s[1982]! } + public func AuthSessions_AppUnofficial(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[1983]!, self._r[1983]!, [_0]) } - public var SocksProxySetup_Username: String { return self._s[1984]! } - public var Bot_Start: String { return self._s[1985]! } - public func Channel_AdminLog_EmptyFilterQueryText(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1986]!, self._r[1986]!, [_0]) + public func DialogList_LiveLocationSharingTo(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[1984]!, self._r[1984]!, [_0]) } - public func Channel_AdminLog_MessagePinned(_ _0: String) -> (String, [(Int, NSRange)]) { + public var SocksProxySetup_Username: String { return self._s[1985]! } + public var Bot_Start: String { return self._s[1986]! } + public func Channel_AdminLog_EmptyFilterQueryText(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[1987]!, self._r[1987]!, [_0]) } - public var Contacts_SortByPresence: String { return self._s[1988]! } - public var AccentColor_Title: String { return self._s[1990]! } - public var Conversation_DiscardVoiceMessageTitle: String { return self._s[1991]! } + public func Channel_AdminLog_MessagePinned(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[1988]!, self._r[1988]!, [_0]) + } + public var Contacts_SortByPresence: String { return self._s[1989]! } + public var AccentColor_Title: String { return self._s[1991]! } + public var Conversation_DiscardVoiceMessageTitle: String { return self._s[1992]! } public func PUSH_CHAT_CREATED(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1992]!, self._r[1992]!, [_1, _2]) + return formatWithArgumentRanges(self._s[1993]!, self._r[1993]!, [_1, _2]) } public func PrivacySettings_LastSeenContactsMinus(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1993]!, self._r[1993]!, [_0]) + return formatWithArgumentRanges(self._s[1994]!, self._r[1994]!, [_0]) } public func Channel_AdminLog_MessageChangedLinkedGroup(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[1994]!, self._r[1994]!, [_1, _2]) + return formatWithArgumentRanges(self._s[1995]!, self._r[1995]!, [_1, _2]) } - public var Passport_Email_EnterOtherEmail: String { return self._s[1995]! } - public var Login_InfoAvatarPhoto: String { return self._s[1996]! } - public var Privacy_PaymentsClear_ShippingInfo: String { return self._s[1997]! } - public var Tour_Title4: String { return self._s[1998]! } - public var Passport_Identity_Translation: String { return self._s[1999]! } - public var SettingsSearch_Synonyms_Notifications_ContactJoined: String { return self._s[2000]! } - public var Login_TermsOfServiceLabel: String { return self._s[2002]! } - public var Passport_Language_it: String { return self._s[2003]! } - public var KeyCommand_JumpToNextUnreadChat: String { return self._s[2004]! } - public var Passport_Identity_SelfieHelp: String { return self._s[2005]! } - public var Conversation_ClearAll: String { return self._s[2007]! } - public var Channel_OwnershipTransfer_Title: String { return self._s[2009]! } - public var TwoStepAuth_FloodError: String { return self._s[2010]! } + public var Passport_Email_EnterOtherEmail: String { return self._s[1996]! } + public var Login_InfoAvatarPhoto: String { return self._s[1997]! } + public var Privacy_PaymentsClear_ShippingInfo: String { return self._s[1998]! } + public var Tour_Title4: String { return self._s[1999]! } + public var Passport_Identity_Translation: String { return self._s[2000]! } + public var SettingsSearch_Synonyms_Notifications_ContactJoined: String { return self._s[2001]! } + public var Login_TermsOfServiceLabel: String { return self._s[2003]! } + public var Passport_Language_it: String { return self._s[2004]! } + public var KeyCommand_JumpToNextUnreadChat: String { return self._s[2005]! } + public var Passport_Identity_SelfieHelp: String { return self._s[2006]! } + public var Conversation_ClearAll: String { return self._s[2008]! } + public var Wallet_Send_UninitializedText: String { return self._s[2010]! } + public var Channel_OwnershipTransfer_Title: String { return self._s[2011]! } + public var TwoStepAuth_FloodError: String { return self._s[2012]! } public func PUSH_CHANNEL_MESSAGE_GEO(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2011]!, self._r[2011]!, [_1]) + return formatWithArgumentRanges(self._s[2013]!, self._r[2013]!, [_1]) } - public var Paint_Delete: String { return self._s[2012]! } + public var Paint_Delete: String { return self._s[2014]! } public func Wallet_Sent_Text(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2013]!, self._r[2013]!, [_0]) + return formatWithArgumentRanges(self._s[2015]!, self._r[2015]!, [_0]) } - public var Privacy_AddNewPeer: String { return self._s[2014]! } + public var Privacy_AddNewPeer: String { return self._s[2016]! } public func Channel_AdminLog_MessageRank(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2015]!, self._r[2015]!, [_1]) + return formatWithArgumentRanges(self._s[2017]!, self._r[2017]!, [_1]) } - public var LogoutOptions_SetPasscodeText: String { return self._s[2016]! } + public var LogoutOptions_SetPasscodeText: String { return self._s[2018]! } public func Passport_AcceptHelp(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2017]!, self._r[2017]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2019]!, self._r[2019]!, [_1, _2]) } - public var Message_PinnedAudioMessage: String { return self._s[2018]! } + public var Message_PinnedAudioMessage: String { return self._s[2020]! } public func Watch_Time_ShortTodayAt(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2019]!, self._r[2019]!, [_0]) + return formatWithArgumentRanges(self._s[2021]!, self._r[2021]!, [_0]) } - public var Notification_Mute1hMin: String { return self._s[2020]! } - public var Notifications_GroupNotificationsSound: String { return self._s[2021]! } - public var SocksProxySetup_ShareProxyList: String { return self._s[2022]! } - public var Conversation_MessageEditedLabel: String { return self._s[2023]! } - public var Notification_Exceptions_AlwaysOff: String { return self._s[2024]! } - public var Notification_Exceptions_NewException_MessagePreviewHeader: String { return self._s[2025]! } + public var Notification_Mute1hMin: String { return self._s[2022]! } + public var Notifications_GroupNotificationsSound: String { return self._s[2023]! } + public var SocksProxySetup_ShareProxyList: String { return self._s[2024]! } + public var Conversation_MessageEditedLabel: String { return self._s[2025]! } + public var Notification_Exceptions_AlwaysOff: String { return self._s[2026]! } + public var Notification_Exceptions_NewException_MessagePreviewHeader: String { return self._s[2027]! } public func Channel_AdminLog_MessageAdmin(_ _0: String, _ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2026]!, self._r[2026]!, [_0, _1, _2]) + return formatWithArgumentRanges(self._s[2028]!, self._r[2028]!, [_0, _1, _2]) } - public var NetworkUsageSettings_ResetStats: String { return self._s[2027]! } + public var NetworkUsageSettings_ResetStats: String { return self._s[2029]! } public func PUSH_MESSAGE_GEOLIVE(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2028]!, self._r[2028]!, [_1]) + return formatWithArgumentRanges(self._s[2030]!, self._r[2030]!, [_1]) } - public var AccessDenied_LocationTracking: String { return self._s[2029]! } - public var Month_GenOctober: String { return self._s[2030]! } - public var GroupInfo_InviteLink_RevokeAlert_Revoke: String { return self._s[2031]! } - public var EnterPasscode_EnterPasscode: String { return self._s[2032]! } - public var MediaPicker_TimerTooltip: String { return self._s[2034]! } - public var SharedMedia_TitleAll: String { return self._s[2035]! } - public var SettingsSearch_Synonyms_Notifications_ChannelNotificationsExceptions: String { return self._s[2038]! } - public var Conversation_RestrictedMedia: String { return self._s[2039]! } - public var AccessDenied_PhotosRestricted: String { return self._s[2040]! } - public var Privacy_Forwards_WhoCanForward: String { return self._s[2042]! } - public var ChangePhoneNumberCode_Called: String { return self._s[2043]! } + public var AccessDenied_LocationTracking: String { return self._s[2031]! } + public var Month_GenOctober: String { return self._s[2032]! } + public var GroupInfo_InviteLink_RevokeAlert_Revoke: String { return self._s[2033]! } + public var EnterPasscode_EnterPasscode: String { return self._s[2034]! } + public var MediaPicker_TimerTooltip: String { return self._s[2036]! } + public var SharedMedia_TitleAll: String { return self._s[2037]! } + public var SettingsSearch_Synonyms_Notifications_ChannelNotificationsExceptions: String { return self._s[2040]! } + public var Conversation_RestrictedMedia: String { return self._s[2041]! } + public var AccessDenied_PhotosRestricted: String { return self._s[2042]! } + public var Privacy_Forwards_WhoCanForward: String { return self._s[2044]! } + public var ChangePhoneNumberCode_Called: String { return self._s[2045]! } public func Notification_PinnedDocumentMessage(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2044]!, self._r[2044]!, [_0]) + return formatWithArgumentRanges(self._s[2046]!, self._r[2046]!, [_0]) } - public var Conversation_SavedMessages: String { return self._s[2047]! } - public var Your_cards_expiration_month_is_invalid: String { return self._s[2049]! } - public var FastTwoStepSetup_PasswordPlaceholder: String { return self._s[2050]! } + public var Conversation_SavedMessages: String { return self._s[2049]! } + public var Your_cards_expiration_month_is_invalid: String { return self._s[2051]! } + public var FastTwoStepSetup_PasswordPlaceholder: String { return self._s[2052]! } public func Target_ShareGameConfirmationGroup(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2052]!, self._r[2052]!, [_0]) - } - public var VoiceOver_Chat_YourMessage: String { return self._s[2053]! } - public func VoiceOver_Chat_Title(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[2054]!, self._r[2054]!, [_0]) } - public var ReportPeer_AlertSuccess: String { return self._s[2055]! } - public var PhotoEditor_CropAspectRatioOriginal: String { return self._s[2056]! } + public var VoiceOver_Chat_YourMessage: String { return self._s[2055]! } + public func VoiceOver_Chat_Title(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[2056]!, self._r[2056]!, [_0]) + } + public var ReportPeer_AlertSuccess: String { return self._s[2057]! } + public var PhotoEditor_CropAspectRatioOriginal: String { return self._s[2058]! } public func InstantPage_RelatedArticleAuthorAndDateTitle(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2057]!, self._r[2057]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2059]!, self._r[2059]!, [_1, _2]) } - public var Checkout_PasswordEntry_Title: String { return self._s[2058]! } - public var PhotoEditor_FadeTool: String { return self._s[2059]! } - public var Privacy_ContactsReset: String { return self._s[2060]! } + public var Checkout_PasswordEntry_Title: String { return self._s[2060]! } + public var PhotoEditor_FadeTool: String { return self._s[2061]! } + public var Privacy_ContactsReset: String { return self._s[2062]! } public func Channel_AdminLog_MessageRestrictedUntil(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2062]!, self._r[2062]!, [_0]) + return formatWithArgumentRanges(self._s[2064]!, self._r[2064]!, [_0]) } - public var Message_PinnedVideoMessage: String { return self._s[2063]! } - public var ChatList_Mute: String { return self._s[2064]! } - public var Permissions_CellularDataText_v0: String { return self._s[2065]! } - public var ShareMenu_SelectChats: String { return self._s[2068]! } - public var ChatList_Context_Unarchive: String { return self._s[2069]! } - public var MusicPlayer_VoiceNote: String { return self._s[2070]! } - public var Conversation_RestrictedText: String { return self._s[2071]! } - public var SettingsSearch_Synonyms_Privacy_Data_DeleteDrafts: String { return self._s[2072]! } - public var TwoStepAuth_DisableSuccess: String { return self._s[2073]! } - public var Cache_Videos: String { return self._s[2074]! } - public var PrivacySettings_PhoneNumber: String { return self._s[2075]! } - public var FeatureDisabled_Oops: String { return self._s[2077]! } - public var Passport_Address_PostcodePlaceholder: String { return self._s[2078]! } + public var Message_PinnedVideoMessage: String { return self._s[2065]! } + public var ChatList_Mute: String { return self._s[2066]! } + public var Permissions_CellularDataText_v0: String { return self._s[2067]! } + public var ShareMenu_SelectChats: String { return self._s[2070]! } + public var ChatList_Context_Unarchive: String { return self._s[2071]! } + public var MusicPlayer_VoiceNote: String { return self._s[2072]! } + public var Conversation_RestrictedText: String { return self._s[2073]! } + public var SettingsSearch_Synonyms_Privacy_Data_DeleteDrafts: String { return self._s[2074]! } + public var TwoStepAuth_DisableSuccess: String { return self._s[2075]! } + public var Cache_Videos: String { return self._s[2076]! } + public var PrivacySettings_PhoneNumber: String { return self._s[2077]! } + public var FeatureDisabled_Oops: String { return self._s[2079]! } + public var Passport_Address_PostcodePlaceholder: String { return self._s[2080]! } public func AddContact_StatusSuccess(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2079]!, self._r[2079]!, [_0]) + return formatWithArgumentRanges(self._s[2081]!, self._r[2081]!, [_0]) } - public var Stickers_GroupStickersHelp: String { return self._s[2080]! } - public var GroupPermission_NoSendPolls: String { return self._s[2081]! } - public var Wallet_Qr_ScanCode: String { return self._s[2082]! } - public var Message_VideoExpired: String { return self._s[2084]! } - public var Notifications_Badge: String { return self._s[2085]! } - public var GroupInfo_GroupHistoryVisible: String { return self._s[2086]! } - public var Wallet_Receive_AddressCopied: String { return self._s[2087]! } - public var CreatePoll_OptionPlaceholder: String { return self._s[2088]! } - public var Username_InvalidTooShort: String { return self._s[2089]! } - public var EnterPasscode_EnterNewPasscodeChange: String { return self._s[2090]! } - public var Channel_AdminLog_PinMessages: String { return self._s[2091]! } - public var ArchivedChats_IntroTitle3: String { return self._s[2092]! } + public var Stickers_GroupStickersHelp: String { return self._s[2082]! } + public var GroupPermission_NoSendPolls: String { return self._s[2083]! } + public var Wallet_Qr_ScanCode: String { return self._s[2084]! } + public var Message_VideoExpired: String { return self._s[2086]! } + public var Notifications_Badge: String { return self._s[2087]! } + public var GroupInfo_GroupHistoryVisible: String { return self._s[2088]! } + public var Wallet_Receive_AddressCopied: String { return self._s[2089]! } + public var CreatePoll_OptionPlaceholder: String { return self._s[2090]! } + public var Username_InvalidTooShort: String { return self._s[2091]! } + public var EnterPasscode_EnterNewPasscodeChange: String { return self._s[2092]! } + public var Channel_AdminLog_PinMessages: String { return self._s[2093]! } + public var ArchivedChats_IntroTitle3: String { return self._s[2094]! } public func Notification_MessageLifetimeRemoved(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2093]!, self._r[2093]!, [_1]) + return formatWithArgumentRanges(self._s[2095]!, self._r[2095]!, [_1]) } - public var Permissions_SiriAllowInSettings_v0: String { return self._s[2094]! } - public var Conversation_DefaultRestrictedText: String { return self._s[2095]! } - public var SharedMedia_CategoryDocs: String { return self._s[2098]! } + public var Permissions_SiriAllowInSettings_v0: String { return self._s[2096]! } + public var Conversation_DefaultRestrictedText: String { return self._s[2097]! } + public var SharedMedia_CategoryDocs: String { return self._s[2100]! } public func PUSH_MESSAGE_CONTACT(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2099]!, self._r[2099]!, [_1]) + return formatWithArgumentRanges(self._s[2101]!, self._r[2101]!, [_1]) } - public var Privacy_Forwards_NeverLink: String { return self._s[2101]! } + public var Wallet_Send_UninitializedTitle: String { return self._s[2102]! } + public var Privacy_Forwards_NeverLink: String { return self._s[2104]! } public func Notification_MessageLifetimeChangedOutgoing(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2102]!, self._r[2102]!, [_1]) + return formatWithArgumentRanges(self._s[2105]!, self._r[2105]!, [_1]) } - public var CheckoutInfo_ErrorShippingNotAvailable: String { return self._s[2103]! } + public var CheckoutInfo_ErrorShippingNotAvailable: String { return self._s[2106]! } public func Time_MonthOfYear_m12(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2104]!, self._r[2104]!, [_0]) + return formatWithArgumentRanges(self._s[2107]!, self._r[2107]!, [_0]) } - public var ChatSettings_PrivateChats: String { return self._s[2105]! } - public var SettingsSearch_Synonyms_EditProfile_Logout: String { return self._s[2106]! } - public var Conversation_PrivateMessageLinkCopied: String { return self._s[2107]! } - public var Channel_UpdatePhotoItem: String { return self._s[2108]! } - public var GroupInfo_LeftStatus: String { return self._s[2109]! } - public var Watch_MessageView_Forward: String { return self._s[2111]! } - public var ReportPeer_ReasonChildAbuse: String { return self._s[2112]! } - public var Cache_ClearEmpty: String { return self._s[2114]! } - public var Localization_LanguageName: String { return self._s[2115]! } - public var WebSearch_GIFs: String { return self._s[2116]! } - public var Notifications_DisplayNamesOnLockScreenInfoWithLink: String { return self._s[2117]! } - public var Username_InvalidStartsWithNumber: String { return self._s[2118]! } - public var Common_Back: String { return self._s[2119]! } - public var Passport_Identity_DateOfBirthPlaceholder: String { return self._s[2120]! } - public var Wallet_Send_Send: String { return self._s[2121]! } + public var ChatSettings_PrivateChats: String { return self._s[2108]! } + public var SettingsSearch_Synonyms_EditProfile_Logout: String { return self._s[2109]! } + public var Conversation_PrivateMessageLinkCopied: String { return self._s[2110]! } + public var Channel_UpdatePhotoItem: String { return self._s[2111]! } + public var GroupInfo_LeftStatus: String { return self._s[2112]! } + public var Watch_MessageView_Forward: String { return self._s[2114]! } + public var ReportPeer_ReasonChildAbuse: String { return self._s[2115]! } + public var Cache_ClearEmpty: String { return self._s[2117]! } + public var Localization_LanguageName: String { return self._s[2118]! } + public var WebSearch_GIFs: String { return self._s[2119]! } + public var Notifications_DisplayNamesOnLockScreenInfoWithLink: String { return self._s[2120]! } + public var Username_InvalidStartsWithNumber: String { return self._s[2121]! } + public var Common_Back: String { return self._s[2122]! } + public var Passport_Identity_DateOfBirthPlaceholder: String { return self._s[2123]! } + public var Wallet_Send_Send: String { return self._s[2124]! } public func PUSH_CHANNEL_MESSAGE_STICKER(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2122]!, self._r[2122]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2125]!, self._r[2125]!, [_1, _2]) } - public var Wallet_Info_RefreshErrorTitle: String { return self._s[2123]! } - public var Passport_Email_Help: String { return self._s[2124]! } - public var Watch_Conversation_Reply: String { return self._s[2126]! } - public var Conversation_EditingMessageMediaChange: String { return self._s[2128]! } - public var Passport_Identity_IssueDatePlaceholder: String { return self._s[2129]! } - public var Channel_BanUser_Unban: String { return self._s[2131]! } - public var Channel_EditAdmin_PermissionPostMessages: String { return self._s[2132]! } - public var Group_Username_CreatePublicLinkHelp: String { return self._s[2133]! } - public var TwoStepAuth_ConfirmEmailCodePlaceholder: String { return self._s[2135]! } - public var Wallet_Send_AddressHeader: String { return self._s[2136]! } - public var Passport_Identity_Name: String { return self._s[2137]! } + public var Wallet_Info_RefreshErrorTitle: String { return self._s[2126]! } + public var Passport_Email_Help: String { return self._s[2127]! } + public var Watch_Conversation_Reply: String { return self._s[2129]! } + public var Conversation_EditingMessageMediaChange: String { return self._s[2131]! } + public var Passport_Identity_IssueDatePlaceholder: String { return self._s[2132]! } + public var Channel_BanUser_Unban: String { return self._s[2134]! } + public var Channel_EditAdmin_PermissionPostMessages: String { return self._s[2135]! } + public var Group_Username_CreatePublicLinkHelp: String { return self._s[2136]! } + public var TwoStepAuth_ConfirmEmailCodePlaceholder: String { return self._s[2138]! } + public var Wallet_Send_AddressHeader: String { return self._s[2139]! } + public var Passport_Identity_Name: String { return self._s[2140]! } public func Channel_DiscussionGroup_HeaderGroupSet(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2138]!, self._r[2138]!, [_0]) + return formatWithArgumentRanges(self._s[2141]!, self._r[2141]!, [_0]) } - public var GroupRemoved_ViewUserInfo: String { return self._s[2139]! } - public var Conversation_BlockUser: String { return self._s[2140]! } - public var Month_GenJanuary: String { return self._s[2141]! } - public var ChatSettings_TextSize: String { return self._s[2142]! } - public var Notification_PassportValuePhone: String { return self._s[2143]! } - public var Passport_Language_ne: String { return self._s[2144]! } - public var Notification_CallBack: String { return self._s[2145]! } - public var Wallet_SecureStorageReset_BiometryTouchId: String { return self._s[2146]! } - public var TwoStepAuth_EmailHelp: String { return self._s[2147]! } + public var GroupRemoved_ViewUserInfo: String { return self._s[2142]! } + public var Conversation_BlockUser: String { return self._s[2143]! } + public var Month_GenJanuary: String { return self._s[2144]! } + public var ChatSettings_TextSize: String { return self._s[2145]! } + public var Notification_PassportValuePhone: String { return self._s[2146]! } + public var Passport_Language_ne: String { return self._s[2147]! } + public var Notification_CallBack: String { return self._s[2148]! } + public var Wallet_SecureStorageReset_BiometryTouchId: String { return self._s[2149]! } + public var TwoStepAuth_EmailHelp: String { return self._s[2150]! } public func Time_YesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2148]!, self._r[2148]!, [_0]) + return formatWithArgumentRanges(self._s[2151]!, self._r[2151]!, [_0]) } - public var Channel_Info_Management: String { return self._s[2149]! } - public var Passport_FieldIdentityUploadHelp: String { return self._s[2150]! } - public var Stickers_FrequentlyUsed: String { return self._s[2151]! } - public var Channel_BanUser_PermissionSendMessages: String { return self._s[2152]! } - public var Passport_Address_OneOfTypeUtilityBill: String { return self._s[2154]! } + public var Channel_Info_Management: String { return self._s[2152]! } + public var Passport_FieldIdentityUploadHelp: String { return self._s[2153]! } + public var Stickers_FrequentlyUsed: String { return self._s[2154]! } + public var Channel_BanUser_PermissionSendMessages: String { return self._s[2155]! } + public var Passport_Address_OneOfTypeUtilityBill: String { return self._s[2157]! } public func LOCAL_CHANNEL_MESSAGE_FWDS(_ _1: String, _ _2: Int) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2155]!, self._r[2155]!, [_1, "\(_2)"]) + return formatWithArgumentRanges(self._s[2158]!, self._r[2158]!, [_1, "\(_2)"]) } - public var Passport_Address_EditResidentialAddress: String { return self._s[2156]! } - public var PrivacyPolicy_DeclineTitle: String { return self._s[2157]! } - public var CreatePoll_TextHeader: String { return self._s[2158]! } + public var Passport_Address_EditResidentialAddress: String { return self._s[2159]! } + public var PrivacyPolicy_DeclineTitle: String { return self._s[2160]! } + public var CreatePoll_TextHeader: String { return self._s[2161]! } public func Checkout_SavePasswordTimeoutAndTouchId(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2159]!, self._r[2159]!, [_0]) + return formatWithArgumentRanges(self._s[2162]!, self._r[2162]!, [_0]) } - public var PhotoEditor_QualityMedium: String { return self._s[2160]! } - public var InfoPlist_NSMicrophoneUsageDescription: String { return self._s[2161]! } - public var Conversation_StatusKickedFromChannel: String { return self._s[2163]! } - public var CheckoutInfo_ReceiverInfoName: String { return self._s[2164]! } - public var Group_ErrorSendRestrictedStickers: String { return self._s[2165]! } + public var PhotoEditor_QualityMedium: String { return self._s[2163]! } + public var InfoPlist_NSMicrophoneUsageDescription: String { return self._s[2164]! } + public var Conversation_StatusKickedFromChannel: String { return self._s[2166]! } + public var CheckoutInfo_ReceiverInfoName: String { return self._s[2167]! } + public var Group_ErrorSendRestrictedStickers: String { return self._s[2168]! } public func Conversation_RestrictedInlineTimed(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2166]!, self._r[2166]!, [_0]) + return formatWithArgumentRanges(self._s[2169]!, self._r[2169]!, [_0]) } public func Channel_AdminLog_MessageTransferedName(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2167]!, self._r[2167]!, [_1]) + return formatWithArgumentRanges(self._s[2170]!, self._r[2170]!, [_1]) } - public var Conversation_LinkDialogOpen: String { return self._s[2169]! } - public var VoiceOver_Chat_PollNoVotes: String { return self._s[2170]! } - public var Settings_Username: String { return self._s[2172]! } - public var Conversation_Block: String { return self._s[2174]! } - public var Wallpaper_Wallpaper: String { return self._s[2175]! } - public var SocksProxySetup_UseProxy: String { return self._s[2177]! } - public var Wallet_Send_Confirmation: String { return self._s[2178]! } - public var EditTheme_UploadEditedTheme: String { return self._s[2179]! } - public var UserInfo_ShareMyContactInfo: String { return self._s[2180]! } - public var MessageTimer_Forever: String { return self._s[2181]! } - public var Privacy_Calls_WhoCanCallMe: String { return self._s[2182]! } - public var PhotoEditor_DiscardChanges: String { return self._s[2183]! } - public var AuthSessions_TerminateOtherSessionsHelp: String { return self._s[2184]! } - public var Passport_Language_da: String { return self._s[2185]! } - public var SocksProxySetup_PortPlaceholder: String { return self._s[2186]! } + public var Conversation_LinkDialogOpen: String { return self._s[2172]! } + public var VoiceOver_Chat_PollNoVotes: String { return self._s[2173]! } + public var Settings_Username: String { return self._s[2175]! } + public var Conversation_Block: String { return self._s[2177]! } + public var Wallpaper_Wallpaper: String { return self._s[2178]! } + public var SocksProxySetup_UseProxy: String { return self._s[2180]! } + public var Wallet_Send_Confirmation: String { return self._s[2181]! } + public var EditTheme_UploadEditedTheme: String { return self._s[2182]! } + public var UserInfo_ShareMyContactInfo: String { return self._s[2183]! } + public var MessageTimer_Forever: String { return self._s[2184]! } + public var Privacy_Calls_WhoCanCallMe: String { return self._s[2185]! } + public var PhotoEditor_DiscardChanges: String { return self._s[2186]! } + public var AuthSessions_TerminateOtherSessionsHelp: String { return self._s[2187]! } + public var Passport_Language_da: String { return self._s[2188]! } + public var SocksProxySetup_PortPlaceholder: String { return self._s[2189]! } public func SecretGIF_NotViewedYet(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2187]!, self._r[2187]!, [_0]) - } - public var Passport_Address_EditPassportRegistration: String { return self._s[2188]! } - public func Channel_AdminLog_MessageChangedGroupAbout(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[2190]!, self._r[2190]!, [_0]) } - public var Passport_Identity_ResidenceCountryPlaceholder: String { return self._s[2192]! } - public var Conversation_SearchByName_Prefix: String { return self._s[2193]! } - public var Conversation_PinnedPoll: String { return self._s[2194]! } - public var Conversation_EmptyGifPanelPlaceholder: String { return self._s[2195]! } + public var Passport_Address_EditPassportRegistration: String { return self._s[2191]! } + public func Channel_AdminLog_MessageChangedGroupAbout(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[2193]!, self._r[2193]!, [_0]) + } + public var Passport_Identity_ResidenceCountryPlaceholder: String { return self._s[2195]! } + public var Conversation_SearchByName_Prefix: String { return self._s[2196]! } + public var Conversation_PinnedPoll: String { return self._s[2197]! } + public var Conversation_EmptyGifPanelPlaceholder: String { return self._s[2198]! } public func PUSH_ENCRYPTION_ACCEPT(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2196]!, self._r[2196]!, [_1]) + return formatWithArgumentRanges(self._s[2199]!, self._r[2199]!, [_1]) } - public var WallpaperSearch_ColorPurple: String { return self._s[2197]! } - public var Cache_ByPeerHeader: String { return self._s[2198]! } + public var WallpaperSearch_ColorPurple: String { return self._s[2200]! } + public var Cache_ByPeerHeader: String { return self._s[2201]! } public func Conversation_EncryptedPlaceholderTitleIncoming(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2199]!, self._r[2199]!, [_0]) + return formatWithArgumentRanges(self._s[2202]!, self._r[2202]!, [_0]) } - public var ChatSettings_AutoDownloadDocuments: String { return self._s[2200]! } - public var Appearance_ThemePreview_Chat_3_Text: String { return self._s[2203]! } - public var Wallet_Completed_Title: String { return self._s[2204]! } - public var Notification_PinnedMessage: String { return self._s[2205]! } - public var VoiceOver_Chat_RecordModeVideoMessage: String { return self._s[2207]! } - public var Contacts_SortBy: String { return self._s[2208]! } + public var ChatSettings_AutoDownloadDocuments: String { return self._s[2203]! } + public var Appearance_ThemePreview_Chat_3_Text: String { return self._s[2206]! } + public var Wallet_Completed_Title: String { return self._s[2207]! } + public var Notification_PinnedMessage: String { return self._s[2208]! } + public var VoiceOver_Chat_RecordModeVideoMessage: String { return self._s[2210]! } + public var Contacts_SortBy: String { return self._s[2211]! } public func PUSH_CHANNEL_MESSAGE_NOTEXT(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2209]!, self._r[2209]!, [_1]) + return formatWithArgumentRanges(self._s[2212]!, self._r[2212]!, [_1]) } public func PUSH_MESSAGE_GAME(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2211]!, self._r[2211]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2214]!, self._r[2214]!, [_1, _2]) } - public var Call_EncryptionKey_Title: String { return self._s[2212]! } - public var Watch_UserInfo_Service: String { return self._s[2213]! } - public var SettingsSearch_Synonyms_Data_SaveEditedPhotos: String { return self._s[2215]! } - public var Conversation_Unpin: String { return self._s[2217]! } - public var CancelResetAccount_Title: String { return self._s[2218]! } - public var Map_LiveLocationFor15Minutes: String { return self._s[2219]! } + public var Call_EncryptionKey_Title: String { return self._s[2215]! } + public var Watch_UserInfo_Service: String { return self._s[2216]! } + public var SettingsSearch_Synonyms_Data_SaveEditedPhotos: String { return self._s[2218]! } + public var Conversation_Unpin: String { return self._s[2220]! } + public var CancelResetAccount_Title: String { return self._s[2221]! } + public var Map_LiveLocationFor15Minutes: String { return self._s[2222]! } public func Time_PreciseDate_m8(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2221]!, self._r[2221]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[2224]!, self._r[2224]!, [_1, _2, _3]) } - public var Group_Members_AddMemberBotErrorNotAllowed: String { return self._s[2222]! } - public var CallSettings_Title: String { return self._s[2223]! } - public var SettingsSearch_Synonyms_Appearance_ChatBackground: String { return self._s[2224]! } - public var PasscodeSettings_EncryptDataHelp: String { return self._s[2226]! } - public var AutoDownloadSettings_Contacts: String { return self._s[2227]! } + public var Group_Members_AddMemberBotErrorNotAllowed: String { return self._s[2225]! } + public var CallSettings_Title: String { return self._s[2226]! } + public var SettingsSearch_Synonyms_Appearance_ChatBackground: String { return self._s[2227]! } + public var PasscodeSettings_EncryptDataHelp: String { return self._s[2229]! } + public var AutoDownloadSettings_Contacts: String { return self._s[2230]! } public func Channel_AdminLog_MessageRankName(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2228]!, self._r[2228]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2231]!, self._r[2231]!, [_1, _2]) } - public var Passport_Identity_DocumentDetails: String { return self._s[2229]! } - public var LoginPassword_PasswordHelp: String { return self._s[2230]! } - public var SettingsSearch_Synonyms_Data_AutoDownloadUsingWifi: String { return self._s[2231]! } - public var PrivacyLastSeenSettings_CustomShareSettings_Delete: String { return self._s[2232]! } - public var Checkout_TotalPaidAmount: String { return self._s[2233]! } + public var Passport_Identity_DocumentDetails: String { return self._s[2232]! } + public var LoginPassword_PasswordHelp: String { return self._s[2233]! } + public var SettingsSearch_Synonyms_Data_AutoDownloadUsingWifi: String { return self._s[2234]! } + public var PrivacyLastSeenSettings_CustomShareSettings_Delete: String { return self._s[2235]! } + public var Checkout_TotalPaidAmount: String { return self._s[2236]! } public func FileSize_KB(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2234]!, self._r[2234]!, [_0]) + return formatWithArgumentRanges(self._s[2237]!, self._r[2237]!, [_0]) } - public var PasscodeSettings_ChangePasscode: String { return self._s[2235]! } - public var Conversation_SecretLinkPreviewAlert: String { return self._s[2237]! } - public var Privacy_SecretChatsLinkPreviews: String { return self._s[2238]! } + public var PasscodeSettings_ChangePasscode: String { return self._s[2238]! } + public var Conversation_SecretLinkPreviewAlert: String { return self._s[2240]! } + public var Privacy_SecretChatsLinkPreviews: String { return self._s[2241]! } public func PUSH_CHANNEL_MESSAGE_DOC(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2239]!, self._r[2239]!, [_1]) + return formatWithArgumentRanges(self._s[2242]!, self._r[2242]!, [_1]) } - public var VoiceOver_Chat_ReplyToYourMessage: String { return self._s[2240]! } - public var Contacts_InviteFriends: String { return self._s[2242]! } - public var Map_ChooseLocationTitle: String { return self._s[2243]! } - public var Conversation_StopPoll: String { return self._s[2245]! } + public var VoiceOver_Chat_ReplyToYourMessage: String { return self._s[2243]! } + public var Contacts_InviteFriends: String { return self._s[2245]! } + public var Map_ChooseLocationTitle: String { return self._s[2246]! } + public var Conversation_StopPoll: String { return self._s[2248]! } public func WebSearch_SearchNoResultsDescription(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2246]!, self._r[2246]!, [_0]) + return formatWithArgumentRanges(self._s[2249]!, self._r[2249]!, [_0]) } - public var Call_Camera: String { return self._s[2247]! } - public var LogoutOptions_ChangePhoneNumberTitle: String { return self._s[2248]! } - public var Calls_RatingFeedback: String { return self._s[2249]! } - public var GroupInfo_BroadcastListNamePlaceholder: String { return self._s[2250]! } - public var NotificationsSound_Pulse: String { return self._s[2251]! } - public var Watch_LastSeen_Lately: String { return self._s[2252]! } - public var ReportGroupLocation_Report: String { return self._s[2255]! } - public var Widget_NoUsers: String { return self._s[2256]! } - public var Conversation_UnvotePoll: String { return self._s[2257]! } - public var SettingsSearch_Synonyms_Privacy_ProfilePhoto: String { return self._s[2259]! } - public var Privacy_ProfilePhoto_WhoCanSeeMyPhoto: String { return self._s[2260]! } - public var NotificationsSound_Circles: String { return self._s[2261]! } - public var PrivacyLastSeenSettings_AlwaysShareWith_Title: String { return self._s[2264]! } - public var Wallet_Settings_DeleteWallet: String { return self._s[2265]! } - public var TwoStepAuth_RecoveryCodeExpired: String { return self._s[2266]! } - public var Proxy_TooltipUnavailable: String { return self._s[2267]! } - public var Passport_Identity_CountryPlaceholder: String { return self._s[2269]! } - public var GroupInfo_Permissions_SlowmodeInfo: String { return self._s[2271]! } - public var Conversation_FileDropbox: String { return self._s[2272]! } - public var Notifications_ExceptionsUnmuted: String { return self._s[2273]! } - public var Tour_Text3: String { return self._s[2275]! } - public var Login_ResetAccountProtected_Title: String { return self._s[2277]! } - public var GroupPermission_NoSendMessages: String { return self._s[2278]! } - public var WallpaperSearch_ColorTitle: String { return self._s[2279]! } - public var ChatAdmins_AllMembersAreAdminsOnHelp: String { return self._s[2280]! } + public var Call_Camera: String { return self._s[2250]! } + public var LogoutOptions_ChangePhoneNumberTitle: String { return self._s[2251]! } + public var Calls_RatingFeedback: String { return self._s[2252]! } + public var GroupInfo_BroadcastListNamePlaceholder: String { return self._s[2253]! } + public var NotificationsSound_Pulse: String { return self._s[2254]! } + public var Watch_LastSeen_Lately: String { return self._s[2255]! } + public var ReportGroupLocation_Report: String { return self._s[2258]! } + public var Widget_NoUsers: String { return self._s[2259]! } + public var Conversation_UnvotePoll: String { return self._s[2260]! } + public var SettingsSearch_Synonyms_Privacy_ProfilePhoto: String { return self._s[2262]! } + public var Privacy_ProfilePhoto_WhoCanSeeMyPhoto: String { return self._s[2263]! } + public var NotificationsSound_Circles: String { return self._s[2264]! } + public var PrivacyLastSeenSettings_AlwaysShareWith_Title: String { return self._s[2267]! } + public var Wallet_Settings_DeleteWallet: String { return self._s[2268]! } + public var TwoStepAuth_RecoveryCodeExpired: String { return self._s[2269]! } + public var Proxy_TooltipUnavailable: String { return self._s[2270]! } + public var Passport_Identity_CountryPlaceholder: String { return self._s[2272]! } + public var GroupInfo_Permissions_SlowmodeInfo: String { return self._s[2274]! } + public var Conversation_FileDropbox: String { return self._s[2275]! } + public var Notifications_ExceptionsUnmuted: String { return self._s[2276]! } + public var Tour_Text3: String { return self._s[2278]! } + public var Login_ResetAccountProtected_Title: String { return self._s[2280]! } + public var GroupPermission_NoSendMessages: String { return self._s[2281]! } + public var WallpaperSearch_ColorTitle: String { return self._s[2282]! } + public var ChatAdmins_AllMembersAreAdminsOnHelp: String { return self._s[2283]! } public func Conversation_LiveLocationYouAnd(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2282]!, self._r[2282]!, [_0]) + return formatWithArgumentRanges(self._s[2285]!, self._r[2285]!, [_0]) } - public var GroupInfo_AddParticipantTitle: String { return self._s[2283]! } - public var Checkout_ShippingOption_Title: String { return self._s[2284]! } - public var ChatSettings_AutoDownloadTitle: String { return self._s[2285]! } + public var GroupInfo_AddParticipantTitle: String { return self._s[2286]! } + public var Checkout_ShippingOption_Title: String { return self._s[2287]! } + public var ChatSettings_AutoDownloadTitle: String { return self._s[2288]! } public func DialogList_SingleTypingSuffix(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2286]!, self._r[2286]!, [_0]) + return formatWithArgumentRanges(self._s[2289]!, self._r[2289]!, [_0]) } public func ChatSettings_AutoDownloadSettings_TypeVideo(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2287]!, self._r[2287]!, [_0]) + return formatWithArgumentRanges(self._s[2290]!, self._r[2290]!, [_0]) } - public var Channel_Management_LabelAdministrator: String { return self._s[2288]! } - public var EditTheme_FileReadError: String { return self._s[2289]! } - public var OwnershipTransfer_ComeBackLater: String { return self._s[2290]! } - public var PrivacyLastSeenSettings_NeverShareWith_Placeholder: String { return self._s[2291]! } - public var AutoDownloadSettings_Photos: String { return self._s[2293]! } - public var Appearance_PreviewIncomingText: String { return self._s[2294]! } - public var ChatList_Context_MarkAllAsRead: String { return self._s[2295]! } - public var ChannelInfo_ConfirmLeave: String { return self._s[2296]! } - public var MediaPicker_MomentsDateRangeSameMonthYearFormat: String { return self._s[2297]! } - public var Passport_Identity_DocumentNumberPlaceholder: String { return self._s[2298]! } - public var Channel_AdminLogFilter_EventsNewMembers: String { return self._s[2299]! } - public var PasscodeSettings_AutoLock_IfAwayFor_5minutes: String { return self._s[2300]! } - public var GroupInfo_SetGroupPhotoStop: String { return self._s[2301]! } - public var Notification_SecretChatScreenshot: String { return self._s[2302]! } - public var AccessDenied_Wallpapers: String { return self._s[2303]! } - public var ChatList_Context_Mute: String { return self._s[2305]! } - public var Passport_Address_City: String { return self._s[2306]! } - public var InfoPlist_NSPhotoLibraryAddUsageDescription: String { return self._s[2307]! } - public var Appearance_ThemeCarouselClassic: String { return self._s[2308]! } - public var SocksProxySetup_SecretPlaceholder: String { return self._s[2309]! } - public var AccessDenied_LocationDisabled: String { return self._s[2310]! } - public var Group_Location_Title: String { return self._s[2311]! } - public var SocksProxySetup_HostnamePlaceholder: String { return self._s[2313]! } - public var GroupInfo_Sound: String { return self._s[2314]! } - public var ChannelInfo_ScamChannelWarning: String { return self._s[2315]! } - public var Stickers_RemoveFromFavorites: String { return self._s[2316]! } - public var Contacts_Title: String { return self._s[2317]! } - public var EditTheme_ThemeTemplateAlertText: String { return self._s[2318]! } - public var Passport_Language_fr: String { return self._s[2319]! } - public var Notifications_ResetAllNotifications: String { return self._s[2320]! } - public var PrivacySettings_SecurityTitle: String { return self._s[2323]! } - public var Checkout_NewCard_Title: String { return self._s[2324]! } - public var Login_HaveNotReceivedCodeInternal: String { return self._s[2325]! } - public var Conversation_ForwardChats: String { return self._s[2326]! } - public var Wallet_SecureStorageReset_PasscodeText: String { return self._s[2328]! } - public var PasscodeSettings_4DigitCode: String { return self._s[2329]! } - public var Settings_FAQ: String { return self._s[2331]! } - public var AutoDownloadSettings_DocumentsTitle: String { return self._s[2332]! } - public var Conversation_ContextMenuForward: String { return self._s[2333]! } - public var VoiceOver_Chat_YourPhoto: String { return self._s[2336]! } - public var PrivacyPolicy_Title: String { return self._s[2339]! } - public var Notifications_TextTone: String { return self._s[2340]! } - public var Profile_CreateNewContact: String { return self._s[2341]! } - public var PrivacyPhoneNumberSettings_WhoCanSeeMyPhoneNumber: String { return self._s[2342]! } - public var Call_Speaker: String { return self._s[2344]! } - public var AutoNightTheme_AutomaticSection: String { return self._s[2345]! } - public var Channel_OwnershipTransfer_EnterPassword: String { return self._s[2347]! } - public var Channel_Username_InvalidCharacters: String { return self._s[2348]! } + public var Channel_Management_LabelAdministrator: String { return self._s[2291]! } + public var EditTheme_FileReadError: String { return self._s[2292]! } + public var OwnershipTransfer_ComeBackLater: String { return self._s[2293]! } + public var PrivacyLastSeenSettings_NeverShareWith_Placeholder: String { return self._s[2294]! } + public var AutoDownloadSettings_Photos: String { return self._s[2296]! } + public var Appearance_PreviewIncomingText: String { return self._s[2297]! } + public var ChatList_Context_MarkAllAsRead: String { return self._s[2298]! } + public var ChannelInfo_ConfirmLeave: String { return self._s[2299]! } + public var MediaPicker_MomentsDateRangeSameMonthYearFormat: String { return self._s[2300]! } + public var Passport_Identity_DocumentNumberPlaceholder: String { return self._s[2301]! } + public var Channel_AdminLogFilter_EventsNewMembers: String { return self._s[2302]! } + public var PasscodeSettings_AutoLock_IfAwayFor_5minutes: String { return self._s[2303]! } + public var GroupInfo_SetGroupPhotoStop: String { return self._s[2304]! } + public var Notification_SecretChatScreenshot: String { return self._s[2305]! } + public var AccessDenied_Wallpapers: String { return self._s[2306]! } + public var ChatList_Context_Mute: String { return self._s[2308]! } + public var Passport_Address_City: String { return self._s[2309]! } + public var InfoPlist_NSPhotoLibraryAddUsageDescription: String { return self._s[2310]! } + public var Appearance_ThemeCarouselClassic: String { return self._s[2311]! } + public var SocksProxySetup_SecretPlaceholder: String { return self._s[2312]! } + public var AccessDenied_LocationDisabled: String { return self._s[2313]! } + public var Group_Location_Title: String { return self._s[2314]! } + public var SocksProxySetup_HostnamePlaceholder: String { return self._s[2316]! } + public var GroupInfo_Sound: String { return self._s[2317]! } + public var ChannelInfo_ScamChannelWarning: String { return self._s[2318]! } + public var Stickers_RemoveFromFavorites: String { return self._s[2319]! } + public var Contacts_Title: String { return self._s[2320]! } + public var EditTheme_ThemeTemplateAlertText: String { return self._s[2321]! } + public var Passport_Language_fr: String { return self._s[2322]! } + public var Notifications_ResetAllNotifications: String { return self._s[2323]! } + public var PrivacySettings_SecurityTitle: String { return self._s[2326]! } + public var Checkout_NewCard_Title: String { return self._s[2327]! } + public var Login_HaveNotReceivedCodeInternal: String { return self._s[2328]! } + public var Conversation_ForwardChats: String { return self._s[2329]! } + public var Wallet_SecureStorageReset_PasscodeText: String { return self._s[2331]! } + public var PasscodeSettings_4DigitCode: String { return self._s[2332]! } + public var Settings_FAQ: String { return self._s[2334]! } + public var AutoDownloadSettings_DocumentsTitle: String { return self._s[2335]! } + public var Conversation_ContextMenuForward: String { return self._s[2336]! } + public var VoiceOver_Chat_YourPhoto: String { return self._s[2339]! } + public var PrivacyPolicy_Title: String { return self._s[2342]! } + public var Notifications_TextTone: String { return self._s[2343]! } + public var Profile_CreateNewContact: String { return self._s[2344]! } + public var PrivacyPhoneNumberSettings_WhoCanSeeMyPhoneNumber: String { return self._s[2345]! } + public var Call_Speaker: String { return self._s[2347]! } + public var AutoNightTheme_AutomaticSection: String { return self._s[2348]! } + public var Channel_OwnershipTransfer_EnterPassword: String { return self._s[2350]! } + public var Channel_Username_InvalidCharacters: String { return self._s[2351]! } public func Channel_AdminLog_MessageChangedChannelUsername(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2349]!, self._r[2349]!, [_0]) + return formatWithArgumentRanges(self._s[2352]!, self._r[2352]!, [_0]) } - public var AutoDownloadSettings_AutodownloadFiles: String { return self._s[2350]! } - public var PrivacySettings_LastSeenTitle: String { return self._s[2351]! } - public var Channel_AdminLog_CanInviteUsers: String { return self._s[2352]! } - public var SettingsSearch_Synonyms_Privacy_Data_ClearPaymentsInfo: String { return self._s[2353]! } - public var OwnershipTransfer_SecurityCheck: String { return self._s[2354]! } - public var Conversation_MessageDeliveryFailed: String { return self._s[2355]! } - public var Watch_ChatList_NoConversationsText: String { return self._s[2356]! } - public var Bot_Unblock: String { return self._s[2357]! } - public var TextFormat_Italic: String { return self._s[2358]! } - public var WallpaperSearch_ColorPink: String { return self._s[2359]! } - public var Settings_About_Help: String { return self._s[2360]! } - public var SearchImages_Title: String { return self._s[2361]! } - public var Weekday_Wednesday: String { return self._s[2362]! } - public var Conversation_ClousStorageInfo_Description1: String { return self._s[2363]! } - public var ExplicitContent_AlertTitle: String { return self._s[2364]! } + public var AutoDownloadSettings_AutodownloadFiles: String { return self._s[2353]! } + public var PrivacySettings_LastSeenTitle: String { return self._s[2354]! } + public var Channel_AdminLog_CanInviteUsers: String { return self._s[2355]! } + public var SettingsSearch_Synonyms_Privacy_Data_ClearPaymentsInfo: String { return self._s[2356]! } + public var OwnershipTransfer_SecurityCheck: String { return self._s[2357]! } + public var Conversation_MessageDeliveryFailed: String { return self._s[2358]! } + public var Watch_ChatList_NoConversationsText: String { return self._s[2359]! } + public var Bot_Unblock: String { return self._s[2360]! } + public var TextFormat_Italic: String { return self._s[2361]! } + public var WallpaperSearch_ColorPink: String { return self._s[2362]! } + public var Settings_About_Help: String { return self._s[2363]! } + public var SearchImages_Title: String { return self._s[2364]! } + public var Weekday_Wednesday: String { return self._s[2365]! } + public var Conversation_ClousStorageInfo_Description1: String { return self._s[2366]! } + public var ExplicitContent_AlertTitle: String { return self._s[2367]! } public func Time_PreciseDate_m5(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2365]!, self._r[2365]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[2368]!, self._r[2368]!, [_1, _2, _3]) } - public var Channel_DiscussionGroup_Create: String { return self._s[2366]! } - public var Weekday_Thursday: String { return self._s[2367]! } - public var Channel_BanUser_PermissionChangeGroupInfo: String { return self._s[2368]! } - public var Channel_Members_AddMembersHelp: String { return self._s[2369]! } + public var Channel_DiscussionGroup_Create: String { return self._s[2369]! } + public var Weekday_Thursday: String { return self._s[2370]! } + public var Channel_BanUser_PermissionChangeGroupInfo: String { return self._s[2371]! } + public var Channel_Members_AddMembersHelp: String { return self._s[2372]! } public func Checkout_SavePasswordTimeout(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2370]!, self._r[2370]!, [_0]) + return formatWithArgumentRanges(self._s[2373]!, self._r[2373]!, [_0]) } - public var Channel_DiscussionGroup_LinkGroup: String { return self._s[2371]! } - public var SettingsSearch_Synonyms_Notifications_InAppNotificationsVibrate: String { return self._s[2372]! } - public var Passport_RequestedInformation: String { return self._s[2373]! } - public var Login_PhoneAndCountryHelp: String { return self._s[2374]! } - public var Conversation_EncryptionProcessing: String { return self._s[2376]! } - public var Notifications_PermissionsSuppressWarningTitle: String { return self._s[2377]! } - public var PhotoEditor_EnhanceTool: String { return self._s[2379]! } - public var Channel_Setup_Title: String { return self._s[2380]! } - public var Conversation_SearchPlaceholder: String { return self._s[2381]! } - public var AccessDenied_LocationAlwaysDenied: String { return self._s[2382]! } - public var Checkout_ErrorGeneric: String { return self._s[2383]! } - public var Passport_Language_hu: String { return self._s[2384]! } + public var Channel_DiscussionGroup_LinkGroup: String { return self._s[2374]! } + public var SettingsSearch_Synonyms_Notifications_InAppNotificationsVibrate: String { return self._s[2375]! } + public var Passport_RequestedInformation: String { return self._s[2376]! } + public var Login_PhoneAndCountryHelp: String { return self._s[2377]! } + public var Conversation_EncryptionProcessing: String { return self._s[2379]! } + public var Notifications_PermissionsSuppressWarningTitle: String { return self._s[2380]! } + public var PhotoEditor_EnhanceTool: String { return self._s[2382]! } + public var Channel_Setup_Title: String { return self._s[2383]! } + public var Conversation_SearchPlaceholder: String { return self._s[2384]! } + public var AccessDenied_LocationAlwaysDenied: String { return self._s[2385]! } + public var Checkout_ErrorGeneric: String { return self._s[2386]! } + public var Passport_Language_hu: String { return self._s[2387]! } public func Passport_Identity_UploadOneOfScan(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2386]!, self._r[2386]!, [_0]) + return formatWithArgumentRanges(self._s[2389]!, self._r[2389]!, [_0]) } public func PUSH_MESSAGE(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2389]!, self._r[2389]!, [_1]) + return formatWithArgumentRanges(self._s[2392]!, self._r[2392]!, [_1]) } public func UserInfo_BlockConfirmationTitle(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2390]!, self._r[2390]!, [_0]) + return formatWithArgumentRanges(self._s[2393]!, self._r[2393]!, [_0]) } - public var Group_Location_Info: String { return self._s[2391]! } - public var Conversation_CloudStorageInfo_Title: String { return self._s[2392]! } - public var Permissions_PeopleNearbyAllow_v0: String { return self._s[2393]! } - public var PhotoEditor_CropAspectRatioSquare: String { return self._s[2394]! } + public var Group_Location_Info: String { return self._s[2394]! } + public var Conversation_CloudStorageInfo_Title: String { return self._s[2395]! } + public var Permissions_PeopleNearbyAllow_v0: String { return self._s[2396]! } + public var PhotoEditor_CropAspectRatioSquare: String { return self._s[2397]! } public func Notification_Exceptions_MutedUntil(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2395]!, self._r[2395]!, [_0]) + return formatWithArgumentRanges(self._s[2398]!, self._r[2398]!, [_0]) } - public var Conversation_ClearPrivateHistory: String { return self._s[2396]! } - public var ContactInfo_PhoneLabelHome: String { return self._s[2397]! } - public var Appearance_RemoveThemeConfirmation: String { return self._s[2398]! } - public var PrivacySettings_LastSeenContacts: String { return self._s[2399]! } + public var Conversation_ClearPrivateHistory: String { return self._s[2399]! } + public var ContactInfo_PhoneLabelHome: String { return self._s[2400]! } + public var Appearance_RemoveThemeConfirmation: String { return self._s[2401]! } + public var PrivacySettings_LastSeenContacts: String { return self._s[2402]! } public func ChangePhone_ErrorOccupied(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2400]!, self._r[2400]!, [_0]) + return formatWithArgumentRanges(self._s[2403]!, self._r[2403]!, [_0]) } - public var Passport_Language_cs: String { return self._s[2401]! } - public var Message_PinnedAnimationMessage: String { return self._s[2403]! } - public var Passport_Identity_ReverseSideHelp: String { return self._s[2405]! } - public var SettingsSearch_Synonyms_Data_Storage_Title: String { return self._s[2406]! } - public var Wallet_Info_TransactionTo: String { return self._s[2408]! } - public var SettingsSearch_Synonyms_Privacy_PasscodeAndTouchId: String { return self._s[2409]! } - public var Embed_PlayingInPIP: String { return self._s[2410]! } - public var AutoNightTheme_ScheduleSection: String { return self._s[2411]! } + public var Passport_Language_cs: String { return self._s[2404]! } + public var Message_PinnedAnimationMessage: String { return self._s[2406]! } + public var Passport_Identity_ReverseSideHelp: String { return self._s[2408]! } + public var SettingsSearch_Synonyms_Data_Storage_Title: String { return self._s[2409]! } + public var Wallet_Info_TransactionTo: String { return self._s[2411]! } + public var SettingsSearch_Synonyms_Privacy_PasscodeAndTouchId: String { return self._s[2412]! } + public var Embed_PlayingInPIP: String { return self._s[2413]! } + public var AutoNightTheme_ScheduleSection: String { return self._s[2414]! } public func Call_EmojiDescription(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2412]!, self._r[2412]!, [_0]) + return formatWithArgumentRanges(self._s[2415]!, self._r[2415]!, [_0]) } - public var MediaPicker_LivePhotoDescription: String { return self._s[2413]! } + public var MediaPicker_LivePhotoDescription: String { return self._s[2416]! } public func Channel_AdminLog_MessageRestrictedName(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2414]!, self._r[2414]!, [_1]) + return formatWithArgumentRanges(self._s[2417]!, self._r[2417]!, [_1]) } - public var Notification_PaymentSent: String { return self._s[2415]! } - public var PhotoEditor_CurvesGreen: String { return self._s[2416]! } - public var Notification_Exceptions_PreviewAlwaysOff: String { return self._s[2417]! } - public var SaveIncomingPhotosSettings_Title: String { return self._s[2418]! } - public var NotificationSettings_ShowNotificationsAllAccounts: String { return self._s[2419]! } - public var VoiceOver_Chat_PagePreview: String { return self._s[2420]! } + public var Notification_PaymentSent: String { return self._s[2418]! } + public var PhotoEditor_CurvesGreen: String { return self._s[2419]! } + public var Notification_Exceptions_PreviewAlwaysOff: String { return self._s[2420]! } + public var SaveIncomingPhotosSettings_Title: String { return self._s[2421]! } + public var NotificationSettings_ShowNotificationsAllAccounts: String { return self._s[2422]! } + public var VoiceOver_Chat_PagePreview: String { return self._s[2423]! } public func PUSH_MESSAGE_SCREENSHOT(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2423]!, self._r[2423]!, [_1]) + return formatWithArgumentRanges(self._s[2426]!, self._r[2426]!, [_1]) } public func PUSH_MESSAGE_PHOTO_SECRET(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2424]!, self._r[2424]!, [_1]) + return formatWithArgumentRanges(self._s[2427]!, self._r[2427]!, [_1]) } public func ApplyLanguage_UnsufficientDataText(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2425]!, self._r[2425]!, [_1]) + return formatWithArgumentRanges(self._s[2428]!, self._r[2428]!, [_1]) } - public var NetworkUsageSettings_CallDataSection: String { return self._s[2427]! } - public var PasscodeSettings_HelpTop: String { return self._s[2428]! } - public var Group_OwnershipTransfer_ErrorAdminsTooMuch: String { return self._s[2429]! } - public var Passport_Address_TypeRentalAgreement: String { return self._s[2430]! } - public var EditTheme_ShortLink: String { return self._s[2431]! } - public var ProxyServer_VoiceOver_Active: String { return self._s[2432]! } - public var ReportPeer_ReasonOther_Placeholder: String { return self._s[2433]! } - public var CheckoutInfo_ErrorPhoneInvalid: String { return self._s[2434]! } - public var Call_Accept: String { return self._s[2436]! } - public var GroupRemoved_RemoveInfo: String { return self._s[2437]! } - public var Month_GenMarch: String { return self._s[2439]! } - public var PhotoEditor_ShadowsTool: String { return self._s[2440]! } - public var LoginPassword_Title: String { return self._s[2441]! } - public var Call_End: String { return self._s[2442]! } - public var Watch_Conversation_GroupInfo: String { return self._s[2443]! } - public var VoiceOver_Chat_Contact: String { return self._s[2444]! } - public var EditTheme_Create_Preview_IncomingText: String { return self._s[2445]! } - public var CallSettings_Always: String { return self._s[2446]! } - public var CallFeedback_Success: String { return self._s[2447]! } - public var TwoStepAuth_SetupHint: String { return self._s[2448]! } + public var NetworkUsageSettings_CallDataSection: String { return self._s[2430]! } + public var PasscodeSettings_HelpTop: String { return self._s[2431]! } + public var Group_OwnershipTransfer_ErrorAdminsTooMuch: String { return self._s[2432]! } + public var Passport_Address_TypeRentalAgreement: String { return self._s[2433]! } + public var EditTheme_ShortLink: String { return self._s[2434]! } + public var ProxyServer_VoiceOver_Active: String { return self._s[2435]! } + public var ReportPeer_ReasonOther_Placeholder: String { return self._s[2436]! } + public var CheckoutInfo_ErrorPhoneInvalid: String { return self._s[2437]! } + public var Call_Accept: String { return self._s[2439]! } + public var GroupRemoved_RemoveInfo: String { return self._s[2440]! } + public var Month_GenMarch: String { return self._s[2442]! } + public var PhotoEditor_ShadowsTool: String { return self._s[2443]! } + public var LoginPassword_Title: String { return self._s[2444]! } + public var Call_End: String { return self._s[2445]! } + public var Watch_Conversation_GroupInfo: String { return self._s[2446]! } + public var VoiceOver_Chat_Contact: String { return self._s[2447]! } + public var EditTheme_Create_Preview_IncomingText: String { return self._s[2448]! } + public var CallSettings_Always: String { return self._s[2449]! } + public var CallFeedback_Success: String { return self._s[2450]! } + public var TwoStepAuth_SetupHint: String { return self._s[2451]! } public func AddContact_ContactWillBeSharedAfterMutual(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2449]!, self._r[2449]!, [_1]) + return formatWithArgumentRanges(self._s[2452]!, self._r[2452]!, [_1]) } - public var ConversationProfile_UsersTooMuchError: String { return self._s[2450]! } - public var Login_PhoneTitle: String { return self._s[2451]! } - public var Passport_FieldPhoneHelp: String { return self._s[2452]! } - public var Weekday_ShortSunday: String { return self._s[2453]! } - public var Passport_InfoFAQ_URL: String { return self._s[2454]! } - public var ContactInfo_Job: String { return self._s[2456]! } - public var UserInfo_InviteBotToGroup: String { return self._s[2457]! } - public var Appearance_ThemeCarouselNightBlue: String { return self._s[2458]! } - public var TwoStepAuth_PasswordRemovePassportConfirmation: String { return self._s[2459]! } - public var Invite_ChannelsTooMuch: String { return self._s[2460]! } - public var Wallet_Send_ConfirmationConfirm: String { return self._s[2461]! } - public var SettingsSearch_Synonyms_Notifications_InAppNotificationsPreview: String { return self._s[2462]! } - public var Wallet_Receive_AmountText: String { return self._s[2463]! } - public var Passport_DeletePersonalDetailsConfirmation: String { return self._s[2464]! } - public var CallFeedback_ReasonNoise: String { return self._s[2465]! } - public var Appearance_AppIconDefault: String { return self._s[2467]! } - public var Passport_Identity_AddInternalPassport: String { return self._s[2468]! } - public var MediaPicker_AddCaption: String { return self._s[2469]! } - public var CallSettings_TabIconDescription: String { return self._s[2470]! } + public var ConversationProfile_UsersTooMuchError: String { return self._s[2453]! } + public var Login_PhoneTitle: String { return self._s[2454]! } + public var Passport_FieldPhoneHelp: String { return self._s[2455]! } + public var Weekday_ShortSunday: String { return self._s[2456]! } + public var Passport_InfoFAQ_URL: String { return self._s[2457]! } + public var ContactInfo_Job: String { return self._s[2459]! } + public var UserInfo_InviteBotToGroup: String { return self._s[2460]! } + public var Appearance_ThemeCarouselNightBlue: String { return self._s[2461]! } + public var TwoStepAuth_PasswordRemovePassportConfirmation: String { return self._s[2462]! } + public var Invite_ChannelsTooMuch: String { return self._s[2463]! } + public var Wallet_Send_ConfirmationConfirm: String { return self._s[2464]! } + public var SettingsSearch_Synonyms_Notifications_InAppNotificationsPreview: String { return self._s[2465]! } + public var Wallet_Receive_AmountText: String { return self._s[2466]! } + public var Passport_DeletePersonalDetailsConfirmation: String { return self._s[2467]! } + public var CallFeedback_ReasonNoise: String { return self._s[2468]! } + public var Appearance_AppIconDefault: String { return self._s[2470]! } + public var Passport_Identity_AddInternalPassport: String { return self._s[2471]! } + public var MediaPicker_AddCaption: String { return self._s[2472]! } + public var CallSettings_TabIconDescription: String { return self._s[2473]! } public func VoiceOver_Chat_Caption(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2471]!, self._r[2471]!, [_0]) + return formatWithArgumentRanges(self._s[2474]!, self._r[2474]!, [_0]) } - public var ChatList_UndoArchiveHiddenTitle: String { return self._s[2472]! } - public var Privacy_GroupsAndChannels_AlwaysAllow: String { return self._s[2473]! } - public var Passport_Identity_TypePersonalDetails: String { return self._s[2474]! } - public var DialogList_SearchSectionRecent: String { return self._s[2475]! } - public var PrivacyPolicy_DeclineMessage: String { return self._s[2476]! } - public var LogoutOptions_ClearCacheText: String { return self._s[2479]! } - public var LastSeen_WithinAWeek: String { return self._s[2480]! } - public var ChannelMembers_GroupAdminsTitle: String { return self._s[2481]! } - public var Conversation_CloudStorage_ChatStatus: String { return self._s[2483]! } - public var VoiceOver_Media_PlaybackRateNormal: String { return self._s[2484]! } + public var ChatList_UndoArchiveHiddenTitle: String { return self._s[2475]! } + public var Privacy_GroupsAndChannels_AlwaysAllow: String { return self._s[2476]! } + public var Passport_Identity_TypePersonalDetails: String { return self._s[2477]! } + public var DialogList_SearchSectionRecent: String { return self._s[2478]! } + public var PrivacyPolicy_DeclineMessage: String { return self._s[2479]! } + public var LogoutOptions_ClearCacheText: String { return self._s[2482]! } + public var LastSeen_WithinAWeek: String { return self._s[2483]! } + public var ChannelMembers_GroupAdminsTitle: String { return self._s[2484]! } + public var Conversation_CloudStorage_ChatStatus: String { return self._s[2486]! } + public var VoiceOver_Media_PlaybackRateNormal: String { return self._s[2487]! } public func AddContact_SharedContactExceptionInfo(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2485]!, self._r[2485]!, [_0]) + return formatWithArgumentRanges(self._s[2488]!, self._r[2488]!, [_0]) } - public var Passport_Address_TypeResidentialAddress: String { return self._s[2486]! } - public var Conversation_StatusLeftGroup: String { return self._s[2487]! } - public var SocksProxySetup_ProxyDetailsTitle: String { return self._s[2488]! } - public var SettingsSearch_Synonyms_Calls_Title: String { return self._s[2490]! } - public var GroupPermission_AddSuccess: String { return self._s[2491]! } - public var PhotoEditor_BlurToolRadial: String { return self._s[2493]! } - public var Conversation_ContextMenuCopy: String { return self._s[2494]! } - public var AccessDenied_CallMicrophone: String { return self._s[2495]! } + public var Passport_Address_TypeResidentialAddress: String { return self._s[2489]! } + public var Conversation_StatusLeftGroup: String { return self._s[2490]! } + public var SocksProxySetup_ProxyDetailsTitle: String { return self._s[2491]! } + public var SettingsSearch_Synonyms_Calls_Title: String { return self._s[2493]! } + public var GroupPermission_AddSuccess: String { return self._s[2494]! } + public var PhotoEditor_BlurToolRadial: String { return self._s[2496]! } + public var Conversation_ContextMenuCopy: String { return self._s[2497]! } + public var AccessDenied_CallMicrophone: String { return self._s[2498]! } public func Time_PreciseDate_m2(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2496]!, self._r[2496]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[2499]!, self._r[2499]!, [_1, _2, _3]) } - public var Login_InvalidFirstNameError: String { return self._s[2497]! } - public var Notifications_Badge_CountUnreadMessages_InfoOn: String { return self._s[2498]! } - public var Checkout_PaymentMethod_New: String { return self._s[2499]! } - public var ShareMenu_CopyShareLinkGame: String { return self._s[2500]! } - public var PhotoEditor_QualityTool: String { return self._s[2501]! } - public var Login_SendCodeViaSms: String { return self._s[2502]! } - public var SettingsSearch_Synonyms_Privacy_DeleteAccountIfAwayFor: String { return self._s[2503]! } - public var Chat_SlowmodeAttachmentLimitReached: String { return self._s[2504]! } - public var Wallet_Receive_CopyAddress: String { return self._s[2505]! } - public var Login_EmailNotConfiguredError: String { return self._s[2506]! } - public var SocksProxySetup_Status: String { return self._s[2507]! } - public var PrivacyPolicy_Accept: String { return self._s[2508]! } - public var Notifications_ExceptionsMessagePlaceholder: String { return self._s[2509]! } - public var Appearance_AppIconClassicX: String { return self._s[2510]! } + public var Login_InvalidFirstNameError: String { return self._s[2500]! } + public var Notifications_Badge_CountUnreadMessages_InfoOn: String { return self._s[2501]! } + public var Checkout_PaymentMethod_New: String { return self._s[2502]! } + public var ShareMenu_CopyShareLinkGame: String { return self._s[2503]! } + public var PhotoEditor_QualityTool: String { return self._s[2504]! } + public var Login_SendCodeViaSms: String { return self._s[2505]! } + public var SettingsSearch_Synonyms_Privacy_DeleteAccountIfAwayFor: String { return self._s[2506]! } + public var Chat_SlowmodeAttachmentLimitReached: String { return self._s[2507]! } + public var Wallet_Receive_CopyAddress: String { return self._s[2508]! } + public var Login_EmailNotConfiguredError: String { return self._s[2509]! } + public var SocksProxySetup_Status: String { return self._s[2510]! } + public var PrivacyPolicy_Accept: String { return self._s[2511]! } + public var Notifications_ExceptionsMessagePlaceholder: String { return self._s[2512]! } + public var Appearance_AppIconClassicX: String { return self._s[2513]! } public func PUSH_CHAT_MESSAGE_TEXT(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2511]!, self._r[2511]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[2514]!, self._r[2514]!, [_1, _2, _3]) } - public var OwnershipTransfer_SecurityRequirements: String { return self._s[2512]! } - public var InfoPlist_NSLocationAlwaysUsageDescription: String { return self._s[2513]! } - public var AutoNightTheme_Automatic: String { return self._s[2514]! } - public var Channel_Username_InvalidStartsWithNumber: String { return self._s[2515]! } - public var Privacy_ContactsSyncHelp: String { return self._s[2516]! } - public var Cache_Help: String { return self._s[2517]! } - public var Group_ErrorAccessDenied: String { return self._s[2518]! } - public var Passport_Language_fa: String { return self._s[2519]! } - public var Wallet_Intro_Text: String { return self._s[2520]! } - public var Login_ResetAccountProtected_TimerTitle: String { return self._s[2521]! } - public var VoiceOver_Chat_YourVideoMessage: String { return self._s[2522]! } - public var PrivacySettings_LastSeen: String { return self._s[2523]! } + public var OwnershipTransfer_SecurityRequirements: String { return self._s[2515]! } + public var InfoPlist_NSLocationAlwaysUsageDescription: String { return self._s[2516]! } + public var AutoNightTheme_Automatic: String { return self._s[2517]! } + public var Channel_Username_InvalidStartsWithNumber: String { return self._s[2518]! } + public var Privacy_ContactsSyncHelp: String { return self._s[2519]! } + public var Cache_Help: String { return self._s[2520]! } + public var Group_ErrorAccessDenied: String { return self._s[2521]! } + public var Passport_Language_fa: String { return self._s[2522]! } + public var Wallet_Intro_Text: String { return self._s[2523]! } + public var Login_ResetAccountProtected_TimerTitle: String { return self._s[2524]! } + public var VoiceOver_Chat_YourVideoMessage: String { return self._s[2525]! } + public var PrivacySettings_LastSeen: String { return self._s[2526]! } public func DialogList_MultipleTyping(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2524]!, self._r[2524]!, [_0, _1]) + return formatWithArgumentRanges(self._s[2527]!, self._r[2527]!, [_0, _1]) } - public var Preview_SaveGif: String { return self._s[2528]! } - public var SettingsSearch_Synonyms_Privacy_TwoStepAuth: String { return self._s[2529]! } - public var Profile_About: String { return self._s[2530]! } - public var Channel_About_Placeholder: String { return self._s[2531]! } - public var Login_InfoTitle: String { return self._s[2532]! } + public var Preview_SaveGif: String { return self._s[2531]! } + public var SettingsSearch_Synonyms_Privacy_TwoStepAuth: String { return self._s[2532]! } + public var Profile_About: String { return self._s[2533]! } + public var Channel_About_Placeholder: String { return self._s[2534]! } + public var Login_InfoTitle: String { return self._s[2535]! } public func TwoStepAuth_SetupPendingEmail(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2533]!, self._r[2533]!, [_0]) + return formatWithArgumentRanges(self._s[2536]!, self._r[2536]!, [_0]) } - public var EditTheme_Expand_Preview_IncomingReplyText: String { return self._s[2534]! } - public var Watch_Suggestion_CantTalk: String { return self._s[2536]! } - public var ContactInfo_Title: String { return self._s[2537]! } - public var Media_ShareThisVideo: String { return self._s[2538]! } - public var Weekday_ShortFriday: String { return self._s[2539]! } - public var AccessDenied_Contacts: String { return self._s[2541]! } - public var Notification_CallIncomingShort: String { return self._s[2542]! } - public var Group_Setup_TypePublic: String { return self._s[2543]! } - public var Notifications_MessageNotificationsExceptions: String { return self._s[2544]! } - public var Notifications_Badge_IncludeChannels: String { return self._s[2545]! } - public var Notifications_MessageNotificationsPreview: String { return self._s[2548]! } - public var ConversationProfile_ErrorCreatingConversation: String { return self._s[2549]! } - public var Group_ErrorAddTooMuchBots: String { return self._s[2550]! } - public var Privacy_GroupsAndChannels_CustomShareHelp: String { return self._s[2551]! } - public var Permissions_CellularDataAllowInSettings_v0: String { return self._s[2552]! } + public var EditTheme_Expand_Preview_IncomingReplyText: String { return self._s[2537]! } + public var Watch_Suggestion_CantTalk: String { return self._s[2539]! } + public var ContactInfo_Title: String { return self._s[2540]! } + public var Media_ShareThisVideo: String { return self._s[2541]! } + public var Weekday_ShortFriday: String { return self._s[2542]! } + public var AccessDenied_Contacts: String { return self._s[2544]! } + public var Notification_CallIncomingShort: String { return self._s[2545]! } + public var Group_Setup_TypePublic: String { return self._s[2546]! } + public var Notifications_MessageNotificationsExceptions: String { return self._s[2547]! } + public var Notifications_Badge_IncludeChannels: String { return self._s[2548]! } + public var Notifications_MessageNotificationsPreview: String { return self._s[2551]! } + public var ConversationProfile_ErrorCreatingConversation: String { return self._s[2552]! } + public var Group_ErrorAddTooMuchBots: String { return self._s[2553]! } + public var Privacy_GroupsAndChannels_CustomShareHelp: String { return self._s[2554]! } + public var Permissions_CellularDataAllowInSettings_v0: String { return self._s[2555]! } public func Wallet_SecureStorageChanged_BiometryText(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2553]!, self._r[2553]!, [_0]) + return formatWithArgumentRanges(self._s[2556]!, self._r[2556]!, [_0]) } - public var DialogList_Typing: String { return self._s[2554]! } - public var CallFeedback_IncludeLogs: String { return self._s[2556]! } - public var Checkout_Phone: String { return self._s[2558]! } - public var Login_InfoFirstNamePlaceholder: String { return self._s[2561]! } - public var Privacy_Calls_Integration: String { return self._s[2562]! } - public var Notifications_PermissionsAllow: String { return self._s[2563]! } - public var TwoStepAuth_AddHintDescription: String { return self._s[2567]! } - public var Settings_ChatSettings: String { return self._s[2568]! } + public var DialogList_Typing: String { return self._s[2557]! } + public var CallFeedback_IncludeLogs: String { return self._s[2559]! } + public var Checkout_Phone: String { return self._s[2561]! } + public var Login_InfoFirstNamePlaceholder: String { return self._s[2564]! } + public var Privacy_Calls_Integration: String { return self._s[2565]! } + public var Notifications_PermissionsAllow: String { return self._s[2566]! } + public var TwoStepAuth_AddHintDescription: String { return self._s[2570]! } + public var Settings_ChatSettings: String { return self._s[2571]! } public func Channel_AdminLog_MessageInvitedNameUsername(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2569]!, self._r[2569]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2572]!, self._r[2572]!, [_1, _2]) } - public var GroupRemoved_DeleteUser: String { return self._s[2571]! } + public var GroupRemoved_DeleteUser: String { return self._s[2574]! } public func Channel_AdminLog_PollStopped(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2572]!, self._r[2572]!, [_0]) + return formatWithArgumentRanges(self._s[2575]!, self._r[2575]!, [_0]) } public func PUSH_MESSAGE_PHOTO(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2573]!, self._r[2573]!, [_1]) + return formatWithArgumentRanges(self._s[2576]!, self._r[2576]!, [_1]) } - public var Login_ContinueWithLocalization: String { return self._s[2574]! } - public var Watch_Message_ForwardedFrom: String { return self._s[2575]! } - public var TwoStepAuth_EnterEmailCode: String { return self._s[2577]! } - public var Conversation_Unblock: String { return self._s[2578]! } - public var PrivacySettings_DataSettings: String { return self._s[2579]! } - public var Group_PublicLink_Info: String { return self._s[2580]! } - public var Notifications_InAppNotificationsVibrate: String { return self._s[2581]! } + public var Login_ContinueWithLocalization: String { return self._s[2577]! } + public var Watch_Message_ForwardedFrom: String { return self._s[2578]! } + public var TwoStepAuth_EnterEmailCode: String { return self._s[2580]! } + public var Conversation_Unblock: String { return self._s[2581]! } + public var PrivacySettings_DataSettings: String { return self._s[2582]! } + public var Group_PublicLink_Info: String { return self._s[2583]! } + public var Notifications_InAppNotificationsVibrate: String { return self._s[2584]! } public func Privacy_GroupsAndChannels_InviteToChannelError(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2582]!, self._r[2582]!, [_0, _1]) + return formatWithArgumentRanges(self._s[2585]!, self._r[2585]!, [_0, _1]) } - public var Wallet_RestoreFailed_CreateWallet: String { return self._s[2584]! } - public var PrivacySettings_Passcode: String { return self._s[2586]! } - public var Call_Mute: String { return self._s[2587]! } - public var Passport_Language_dz: String { return self._s[2588]! } - public var Wallet_Receive_AmountHeader: String { return self._s[2589]! } - public var Passport_Language_tk: String { return self._s[2590]! } + public var Wallet_RestoreFailed_CreateWallet: String { return self._s[2587]! } + public var PrivacySettings_Passcode: String { return self._s[2589]! } + public var Call_Mute: String { return self._s[2590]! } + public var Passport_Language_dz: String { return self._s[2591]! } + public var Wallet_Receive_AmountHeader: String { return self._s[2592]! } + public var Passport_Language_tk: String { return self._s[2593]! } public func Login_EmailCodeSubject(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2591]!, self._r[2591]!, [_0]) + return formatWithArgumentRanges(self._s[2594]!, self._r[2594]!, [_0]) } - public var Settings_Search: String { return self._s[2592]! } - public var InfoPlist_NSPhotoLibraryUsageDescription: String { return self._s[2593]! } - public var Conversation_ContextMenuReply: String { return self._s[2594]! } - public var WallpaperSearch_ColorBrown: String { return self._s[2595]! } - public var Chat_AttachmentMultipleForwardDisabled: String { return self._s[2596]! } - public var Tour_Title1: String { return self._s[2597]! } - public var Conversation_ClearGroupHistory: String { return self._s[2599]! } - public var Wallet_TransactionInfo_RecipientHeader: String { return self._s[2600]! } - public var WallpaperPreview_Motion: String { return self._s[2601]! } + public var Settings_Search: String { return self._s[2595]! } + public var InfoPlist_NSPhotoLibraryUsageDescription: String { return self._s[2596]! } + public var Conversation_ContextMenuReply: String { return self._s[2597]! } + public var WallpaperSearch_ColorBrown: String { return self._s[2598]! } + public var Chat_AttachmentMultipleForwardDisabled: String { return self._s[2599]! } + public var Tour_Title1: String { return self._s[2600]! } + public var Conversation_ClearGroupHistory: String { return self._s[2602]! } + public var Wallet_TransactionInfo_RecipientHeader: String { return self._s[2603]! } + public var WallpaperPreview_Motion: String { return self._s[2604]! } public func Checkout_PasswordEntry_Text(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2602]!, self._r[2602]!, [_0]) + return formatWithArgumentRanges(self._s[2605]!, self._r[2605]!, [_0]) } - public var Call_RateCall: String { return self._s[2603]! } - public var Channel_AdminLog_BanSendStickersAndGifs: String { return self._s[2604]! } - public var Passport_PasswordCompleteSetup: String { return self._s[2605]! } - public var Conversation_InputTextSilentBroadcastPlaceholder: String { return self._s[2606]! } - public var UserInfo_LastNamePlaceholder: String { return self._s[2608]! } + public var Call_RateCall: String { return self._s[2606]! } + public var Channel_AdminLog_BanSendStickersAndGifs: String { return self._s[2607]! } + public var Passport_PasswordCompleteSetup: String { return self._s[2608]! } + public var Conversation_InputTextSilentBroadcastPlaceholder: String { return self._s[2609]! } + public var UserInfo_LastNamePlaceholder: String { return self._s[2611]! } public func Login_WillCallYou(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2610]!, self._r[2610]!, [_0]) + return formatWithArgumentRanges(self._s[2613]!, self._r[2613]!, [_0]) } - public var Compose_Create: String { return self._s[2611]! } - public var Contacts_InviteToTelegram: String { return self._s[2612]! } - public var GroupInfo_Notifications: String { return self._s[2613]! } - public var Message_PinnedLiveLocationMessage: String { return self._s[2615]! } - public var Month_GenApril: String { return self._s[2616]! } - public var Appearance_AutoNightTheme: String { return self._s[2617]! } - public var ChatSettings_AutomaticAudioDownload: String { return self._s[2619]! } - public var Login_CodeSentSms: String { return self._s[2621]! } + public var Compose_Create: String { return self._s[2614]! } + public var Contacts_InviteToTelegram: String { return self._s[2615]! } + public var GroupInfo_Notifications: String { return self._s[2616]! } + public var Message_PinnedLiveLocationMessage: String { return self._s[2618]! } + public var Month_GenApril: String { return self._s[2619]! } + public var Appearance_AutoNightTheme: String { return self._s[2620]! } + public var ChatSettings_AutomaticAudioDownload: String { return self._s[2622]! } + public var Login_CodeSentSms: String { return self._s[2624]! } public func UserInfo_UnblockConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2622]!, self._r[2622]!, [_0]) + return formatWithArgumentRanges(self._s[2625]!, self._r[2625]!, [_0]) } - public var EmptyGroupInfo_Line3: String { return self._s[2623]! } - public var LogoutOptions_ContactSupportText: String { return self._s[2624]! } - public var Passport_Language_hr: String { return self._s[2625]! } - public var Common_ActionNotAllowedError: String { return self._s[2626]! } + public var EmptyGroupInfo_Line3: String { return self._s[2626]! } + public var LogoutOptions_ContactSupportText: String { return self._s[2627]! } + public var Passport_Language_hr: String { return self._s[2628]! } + public var Common_ActionNotAllowedError: String { return self._s[2629]! } public func Channel_AdminLog_MessageRestrictedNewSetting(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2627]!, self._r[2627]!, [_0]) + return formatWithArgumentRanges(self._s[2630]!, self._r[2630]!, [_0]) } - public var GroupInfo_InviteLink_CopyLink: String { return self._s[2628]! } - public var Wallet_Info_TransactionFrom: String { return self._s[2629]! } - public var Wallet_Send_ErrorDecryptionFailed: String { return self._s[2630]! } - public var Conversation_InputTextBroadcastPlaceholder: String { return self._s[2631]! } - public var Privacy_SecretChatsTitle: String { return self._s[2632]! } - public var Notification_SecretChatMessageScreenshotSelf: String { return self._s[2634]! } - public var GroupInfo_AddUserLeftError: String { return self._s[2635]! } - public var AutoDownloadSettings_TypePrivateChats: String { return self._s[2636]! } - public var LogoutOptions_ContactSupportTitle: String { return self._s[2637]! } - public var Channel_AddBotErrorHaveRights: String { return self._s[2638]! } - public var Preview_DeleteGif: String { return self._s[2639]! } - public var GroupInfo_Permissions_Exceptions: String { return self._s[2640]! } - public var Group_ErrorNotMutualContact: String { return self._s[2641]! } - public var Notification_MessageLifetime5s: String { return self._s[2642]! } + public var GroupInfo_InviteLink_CopyLink: String { return self._s[2631]! } + public var Wallet_Info_TransactionFrom: String { return self._s[2632]! } + public var Wallet_Send_ErrorDecryptionFailed: String { return self._s[2633]! } + public var Conversation_InputTextBroadcastPlaceholder: String { return self._s[2634]! } + public var Privacy_SecretChatsTitle: String { return self._s[2635]! } + public var Notification_SecretChatMessageScreenshotSelf: String { return self._s[2637]! } + public var GroupInfo_AddUserLeftError: String { return self._s[2638]! } + public var AutoDownloadSettings_TypePrivateChats: String { return self._s[2639]! } + public var LogoutOptions_ContactSupportTitle: String { return self._s[2640]! } + public var Channel_AddBotErrorHaveRights: String { return self._s[2641]! } + public var Preview_DeleteGif: String { return self._s[2642]! } + public var GroupInfo_Permissions_Exceptions: String { return self._s[2643]! } + public var Group_ErrorNotMutualContact: String { return self._s[2644]! } + public var Notification_MessageLifetime5s: String { return self._s[2645]! } public func Watch_LastSeen_AtDate(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2643]!, self._r[2643]!, [_0]) + return formatWithArgumentRanges(self._s[2646]!, self._r[2646]!, [_0]) } - public var VoiceOver_Chat_Video: String { return self._s[2644]! } - public var Channel_OwnershipTransfer_ErrorPublicChannelsTooMuch: String { return self._s[2646]! } - public var ReportSpam_DeleteThisChat: String { return self._s[2647]! } - public var Passport_Address_AddBankStatement: String { return self._s[2648]! } - public var Notification_CallIncoming: String { return self._s[2649]! } - public var Wallet_Words_NotDoneTitle: String { return self._s[2650]! } - public var Compose_NewGroupTitle: String { return self._s[2651]! } - public var TwoStepAuth_RecoveryCodeHelp: String { return self._s[2653]! } - public var Passport_Address_Postcode: String { return self._s[2655]! } + public var VoiceOver_Chat_Video: String { return self._s[2647]! } + public var Channel_OwnershipTransfer_ErrorPublicChannelsTooMuch: String { return self._s[2649]! } + public var ReportSpam_DeleteThisChat: String { return self._s[2650]! } + public var Passport_Address_AddBankStatement: String { return self._s[2651]! } + public var Notification_CallIncoming: String { return self._s[2652]! } + public var Wallet_Words_NotDoneTitle: String { return self._s[2653]! } + public var Compose_NewGroupTitle: String { return self._s[2654]! } + public var TwoStepAuth_RecoveryCodeHelp: String { return self._s[2656]! } + public var Passport_Address_Postcode: String { return self._s[2658]! } public func LastSeen_YesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2656]!, self._r[2656]!, [_0]) + return formatWithArgumentRanges(self._s[2659]!, self._r[2659]!, [_0]) } - public var Checkout_NewCard_SaveInfoHelp: String { return self._s[2657]! } - public var VoiceOver_Chat_YourMusic: String { return self._s[2658]! } - public var WallpaperColors_Title: String { return self._s[2659]! } - public var SocksProxySetup_ShareQRCodeInfo: String { return self._s[2660]! } - public var VoiceOver_MessageContextForward: String { return self._s[2661]! } - public var GroupPermission_Duration: String { return self._s[2662]! } + public var Checkout_NewCard_SaveInfoHelp: String { return self._s[2660]! } + public var VoiceOver_Chat_YourMusic: String { return self._s[2661]! } + public var WallpaperColors_Title: String { return self._s[2662]! } + public var SocksProxySetup_ShareQRCodeInfo: String { return self._s[2663]! } + public var VoiceOver_MessageContextForward: String { return self._s[2664]! } + public var GroupPermission_Duration: String { return self._s[2665]! } public func Cache_Clear(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2663]!, self._r[2663]!, [_0]) + return formatWithArgumentRanges(self._s[2666]!, self._r[2666]!, [_0]) } - public var Bot_GroupStatusDoesNotReadHistory: String { return self._s[2664]! } - public var Username_Placeholder: String { return self._s[2665]! } - public var CallFeedback_WhatWentWrong: String { return self._s[2666]! } - public var Passport_FieldAddressUploadHelp: String { return self._s[2667]! } - public var Permissions_NotificationsAllowInSettings_v0: String { return self._s[2668]! } + public var Bot_GroupStatusDoesNotReadHistory: String { return self._s[2667]! } + public var Username_Placeholder: String { return self._s[2668]! } + public var CallFeedback_WhatWentWrong: String { return self._s[2669]! } + public var Passport_FieldAddressUploadHelp: String { return self._s[2670]! } + public var Permissions_NotificationsAllowInSettings_v0: String { return self._s[2671]! } public func Channel_AdminLog_MessageChangedUnlinkedChannel(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2670]!, self._r[2670]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2673]!, self._r[2673]!, [_1, _2]) } - public var Passport_PasswordDescription: String { return self._s[2671]! } - public var Channel_MessagePhotoUpdated: String { return self._s[2672]! } - public var MediaPicker_TapToUngroupDescription: String { return self._s[2673]! } - public var SettingsSearch_Synonyms_Notifications_BadgeCountUnreadMessages: String { return self._s[2674]! } - public var AttachmentMenu_PhotoOrVideo: String { return self._s[2675]! } - public var Conversation_ContextMenuMore: String { return self._s[2676]! } - public var Privacy_PaymentsClearInfo: String { return self._s[2677]! } - public var CallSettings_TabIcon: String { return self._s[2678]! } - public var KeyCommand_Find: String { return self._s[2679]! } - public var Appearance_ThemePreview_ChatList_7_Text: String { return self._s[2680]! } - public var EditTheme_Edit_Preview_IncomingText: String { return self._s[2681]! } - public var Message_PinnedGame: String { return self._s[2682]! } - public var VoiceOver_Chat_ForwardedFromYou: String { return self._s[2683]! } - public var Notifications_Badge_CountUnreadMessages_InfoOff: String { return self._s[2685]! } - public var Login_CallRequestState2: String { return self._s[2687]! } - public var CheckoutInfo_ReceiverInfoNamePlaceholder: String { return self._s[2689]! } + public var Passport_PasswordDescription: String { return self._s[2674]! } + public var Channel_MessagePhotoUpdated: String { return self._s[2675]! } + public var MediaPicker_TapToUngroupDescription: String { return self._s[2676]! } + public var SettingsSearch_Synonyms_Notifications_BadgeCountUnreadMessages: String { return self._s[2677]! } + public var AttachmentMenu_PhotoOrVideo: String { return self._s[2678]! } + public var Conversation_ContextMenuMore: String { return self._s[2679]! } + public var Privacy_PaymentsClearInfo: String { return self._s[2680]! } + public var CallSettings_TabIcon: String { return self._s[2681]! } + public var KeyCommand_Find: String { return self._s[2682]! } + public var Appearance_ThemePreview_ChatList_7_Text: String { return self._s[2683]! } + public var EditTheme_Edit_Preview_IncomingText: String { return self._s[2684]! } + public var Message_PinnedGame: String { return self._s[2685]! } + public var VoiceOver_Chat_ForwardedFromYou: String { return self._s[2686]! } + public var Notifications_Badge_CountUnreadMessages_InfoOff: String { return self._s[2688]! } + public var Login_CallRequestState2: String { return self._s[2690]! } + public var CheckoutInfo_ReceiverInfoNamePlaceholder: String { return self._s[2692]! } public func VoiceOver_Chat_PhotoFrom(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2690]!, self._r[2690]!, [_0]) + return formatWithArgumentRanges(self._s[2693]!, self._r[2693]!, [_0]) } public func Checkout_PayPrice(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2692]!, self._r[2692]!, [_0]) - } - public var WallpaperPreview_Blurred: String { return self._s[2693]! } - public var Conversation_InstantPagePreview: String { return self._s[2694]! } - public func DialogList_SingleUploadingVideoSuffix(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[2695]!, self._r[2695]!, [_0]) } - public var SecretTimer_VideoDescription: String { return self._s[2698]! } - public var WallpaperSearch_ColorRed: String { return self._s[2699]! } - public var GroupPermission_NoPinMessages: String { return self._s[2700]! } - public var Passport_Language_es: String { return self._s[2701]! } - public var Permissions_ContactsAllow_v0: String { return self._s[2703]! } - public var Conversation_EditingMessageMediaEditCurrentVideo: String { return self._s[2704]! } + public var WallpaperPreview_Blurred: String { return self._s[2696]! } + public var Conversation_InstantPagePreview: String { return self._s[2697]! } + public func DialogList_SingleUploadingVideoSuffix(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[2698]!, self._r[2698]!, [_0]) + } + public var SecretTimer_VideoDescription: String { return self._s[2701]! } + public var WallpaperSearch_ColorRed: String { return self._s[2702]! } + public var GroupPermission_NoPinMessages: String { return self._s[2703]! } + public var Passport_Language_es: String { return self._s[2704]! } + public var Permissions_ContactsAllow_v0: String { return self._s[2706]! } + public var Conversation_EditingMessageMediaEditCurrentVideo: String { return self._s[2707]! } public func PUSH_CHAT_MESSAGE_CONTACT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2705]!, self._r[2705]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2708]!, self._r[2708]!, [_1, _2]) } - public var Privacy_Forwards_CustomHelp: String { return self._s[2706]! } - public var WebPreview_GettingLinkInfo: String { return self._s[2707]! } - public var Watch_UserInfo_Unmute: String { return self._s[2708]! } - public var GroupInfo_ChannelListNamePlaceholder: String { return self._s[2709]! } - public var AccessDenied_CameraRestricted: String { return self._s[2711]! } + public var Privacy_Forwards_CustomHelp: String { return self._s[2709]! } + public var WebPreview_GettingLinkInfo: String { return self._s[2710]! } + public var Watch_UserInfo_Unmute: String { return self._s[2711]! } + public var GroupInfo_ChannelListNamePlaceholder: String { return self._s[2712]! } + public var AccessDenied_CameraRestricted: String { return self._s[2714]! } public func Conversation_Kilobytes(_ _0: Int) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2712]!, self._r[2712]!, ["\(_0)"]) + return formatWithArgumentRanges(self._s[2715]!, self._r[2715]!, ["\(_0)"]) } - public var ChatList_ReadAll: String { return self._s[2714]! } - public var Settings_CopyUsername: String { return self._s[2715]! } - public var Contacts_SearchLabel: String { return self._s[2716]! } - public var Map_OpenInYandexNavigator: String { return self._s[2718]! } - public var PasscodeSettings_EncryptData: String { return self._s[2719]! } - public var WallpaperSearch_ColorPrefix: String { return self._s[2720]! } - public var Notifications_GroupNotificationsPreview: String { return self._s[2721]! } - public var DialogList_AdNoticeAlert: String { return self._s[2722]! } - public var CheckoutInfo_ShippingInfoAddress1: String { return self._s[2724]! } - public var CheckoutInfo_ShippingInfoAddress2: String { return self._s[2725]! } - public var Localization_LanguageCustom: String { return self._s[2726]! } - public var Passport_Identity_TypeDriversLicenseUploadScan: String { return self._s[2727]! } - public var CallFeedback_Title: String { return self._s[2728]! } - public var VoiceOver_Chat_RecordPreviewVoiceMessage: String { return self._s[2731]! } - public var Passport_Address_OneOfTypePassportRegistration: String { return self._s[2732]! } - public var Wallet_Intro_CreateErrorTitle: String { return self._s[2733]! } - public var Conversation_InfoGroup: String { return self._s[2734]! } - public var Compose_NewMessage: String { return self._s[2735]! } - public var FastTwoStepSetup_HintPlaceholder: String { return self._s[2736]! } - public var ChatSettings_AutoDownloadVideoMessages: String { return self._s[2737]! } - public var Wallet_SecureStorageReset_BiometryFaceId: String { return self._s[2738]! } - public var Channel_DiscussionGroup_UnlinkChannel: String { return self._s[2739]! } + public var ChatList_ReadAll: String { return self._s[2717]! } + public var Settings_CopyUsername: String { return self._s[2718]! } + public var Contacts_SearchLabel: String { return self._s[2719]! } + public var Map_OpenInYandexNavigator: String { return self._s[2721]! } + public var PasscodeSettings_EncryptData: String { return self._s[2722]! } + public var WallpaperSearch_ColorPrefix: String { return self._s[2723]! } + public var Notifications_GroupNotificationsPreview: String { return self._s[2724]! } + public var DialogList_AdNoticeAlert: String { return self._s[2725]! } + public var CheckoutInfo_ShippingInfoAddress1: String { return self._s[2727]! } + public var CheckoutInfo_ShippingInfoAddress2: String { return self._s[2728]! } + public var Localization_LanguageCustom: String { return self._s[2729]! } + public var Passport_Identity_TypeDriversLicenseUploadScan: String { return self._s[2730]! } + public var CallFeedback_Title: String { return self._s[2731]! } + public var VoiceOver_Chat_RecordPreviewVoiceMessage: String { return self._s[2734]! } + public var Passport_Address_OneOfTypePassportRegistration: String { return self._s[2735]! } + public var Wallet_Intro_CreateErrorTitle: String { return self._s[2736]! } + public var Conversation_InfoGroup: String { return self._s[2737]! } + public var Compose_NewMessage: String { return self._s[2738]! } + public var FastTwoStepSetup_HintPlaceholder: String { return self._s[2739]! } + public var ChatSettings_AutoDownloadVideoMessages: String { return self._s[2740]! } + public var Wallet_SecureStorageReset_BiometryFaceId: String { return self._s[2741]! } + public var Channel_DiscussionGroup_UnlinkChannel: String { return self._s[2742]! } public func Passport_Scans_ScanIndex(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2740]!, self._r[2740]!, [_0]) + return formatWithArgumentRanges(self._s[2743]!, self._r[2743]!, [_0]) } - public var Channel_AdminLog_CanDeleteMessages: String { return self._s[2741]! } - public var Login_CancelSignUpConfirmation: String { return self._s[2742]! } - public var ChangePhoneNumberCode_Help: String { return self._s[2743]! } - public var PrivacySettings_DeleteAccountHelp: String { return self._s[2744]! } - public var Channel_BlackList_Title: String { return self._s[2745]! } - public var UserInfo_PhoneCall: String { return self._s[2746]! } - public var Passport_Address_OneOfTypeBankStatement: String { return self._s[2748]! } - public var State_connecting: String { return self._s[2749]! } - public var Appearance_ThemePreview_ChatList_6_Text: String { return self._s[2750]! } - public var EditTheme_Expand_BottomInfo: String { return self._s[2751]! } + public var Channel_AdminLog_CanDeleteMessages: String { return self._s[2744]! } + public var Login_CancelSignUpConfirmation: String { return self._s[2745]! } + public var ChangePhoneNumberCode_Help: String { return self._s[2746]! } + public var PrivacySettings_DeleteAccountHelp: String { return self._s[2747]! } + public var Channel_BlackList_Title: String { return self._s[2748]! } + public var UserInfo_PhoneCall: String { return self._s[2749]! } + public var Passport_Address_OneOfTypeBankStatement: String { return self._s[2751]! } + public var State_connecting: String { return self._s[2752]! } + public var Appearance_ThemePreview_ChatList_6_Text: String { return self._s[2753]! } + public var EditTheme_Expand_BottomInfo: String { return self._s[2754]! } public func LastSeen_TodayAt(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2752]!, self._r[2752]!, [_0]) + return formatWithArgumentRanges(self._s[2755]!, self._r[2755]!, [_0]) } public func DialogList_SingleRecordingAudioSuffix(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2753]!, self._r[2753]!, [_0]) + return formatWithArgumentRanges(self._s[2756]!, self._r[2756]!, [_0]) } - public var Notifications_GroupNotifications: String { return self._s[2754]! } - public var Conversation_SendMessageErrorTooMuchScheduled: String { return self._s[2755]! } - public var Passport_Identity_EditPassport: String { return self._s[2756]! } - public var EnterPasscode_RepeatNewPasscode: String { return self._s[2758]! } - public var Localization_EnglishLanguageName: String { return self._s[2759]! } - public var Share_AuthDescription: String { return self._s[2760]! } - public var SettingsSearch_Synonyms_Notifications_ChannelNotificationsAlert: String { return self._s[2761]! } - public var Passport_Identity_Surname: String { return self._s[2762]! } - public var Compose_TokenListPlaceholder: String { return self._s[2763]! } - public var Passport_Identity_OneOfTypePassport: String { return self._s[2764]! } - public var Settings_AboutEmpty: String { return self._s[2765]! } - public var Conversation_Unmute: String { return self._s[2766]! } - public var CreateGroup_ChannelsTooMuch: String { return self._s[2768]! } - public var Wallet_Sending_Text: String { return self._s[2769]! } + public var Notifications_GroupNotifications: String { return self._s[2757]! } + public var Conversation_SendMessageErrorTooMuchScheduled: String { return self._s[2758]! } + public var Passport_Identity_EditPassport: String { return self._s[2759]! } + public var EnterPasscode_RepeatNewPasscode: String { return self._s[2761]! } + public var Localization_EnglishLanguageName: String { return self._s[2762]! } + public var Share_AuthDescription: String { return self._s[2763]! } + public var SettingsSearch_Synonyms_Notifications_ChannelNotificationsAlert: String { return self._s[2764]! } + public var Passport_Identity_Surname: String { return self._s[2765]! } + public var Compose_TokenListPlaceholder: String { return self._s[2766]! } + public var Passport_Identity_OneOfTypePassport: String { return self._s[2767]! } + public var Settings_AboutEmpty: String { return self._s[2768]! } + public var Conversation_Unmute: String { return self._s[2769]! } + public var CreateGroup_ChannelsTooMuch: String { return self._s[2771]! } + public var Wallet_Sending_Text: String { return self._s[2772]! } public func PUSH_CONTACT_JOINED(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2770]!, self._r[2770]!, [_1]) + return formatWithArgumentRanges(self._s[2773]!, self._r[2773]!, [_1]) } - public var Login_CodeSentCall: String { return self._s[2771]! } - public var ContactInfo_PhoneLabelHomeFax: String { return self._s[2773]! } - public var ChatSettings_Appearance: String { return self._s[2774]! } - public var Appearance_PickAccentColor: String { return self._s[2775]! } + public var Login_CodeSentCall: String { return self._s[2774]! } + public var ContactInfo_PhoneLabelHomeFax: String { return self._s[2776]! } + public var ChatSettings_Appearance: String { return self._s[2777]! } + public var Appearance_PickAccentColor: String { return self._s[2778]! } public func PUSH_CHAT_MESSAGE_NOTEXT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2776]!, self._r[2776]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2779]!, self._r[2779]!, [_1, _2]) } public func PUSH_MESSAGE_GEO(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2777]!, self._r[2777]!, [_1]) + return formatWithArgumentRanges(self._s[2780]!, self._r[2780]!, [_1]) } - public var Notification_CallMissed: String { return self._s[2778]! } - public var SettingsSearch_Synonyms_Appearance_ChatBackground_Custom: String { return self._s[2779]! } - public var Channel_AdminLogFilter_EventsInfo: String { return self._s[2780]! } - public var ChatAdmins_AdminLabel: String { return self._s[2782]! } - public var KeyCommand_JumpToNextChat: String { return self._s[2783]! } - public var Conversation_StopPollConfirmationTitle: String { return self._s[2785]! } - public var ChangePhoneNumberCode_CodePlaceholder: String { return self._s[2786]! } - public var Month_GenJune: String { return self._s[2787]! } - public var Watch_Location_Current: String { return self._s[2788]! } - public var Wallet_Receive_CopyInvoiceUrl: String { return self._s[2789]! } - public var Conversation_TitleMute: String { return self._s[2790]! } + public var Notification_CallMissed: String { return self._s[2781]! } + public var SettingsSearch_Synonyms_Appearance_ChatBackground_Custom: String { return self._s[2782]! } + public var Channel_AdminLogFilter_EventsInfo: String { return self._s[2783]! } + public var ChatAdmins_AdminLabel: String { return self._s[2785]! } + public var KeyCommand_JumpToNextChat: String { return self._s[2786]! } + public var Conversation_StopPollConfirmationTitle: String { return self._s[2788]! } + public var ChangePhoneNumberCode_CodePlaceholder: String { return self._s[2789]! } + public var Month_GenJune: String { return self._s[2790]! } + public var Watch_Location_Current: String { return self._s[2791]! } + public var Wallet_Receive_CopyInvoiceUrl: String { return self._s[2792]! } + public var Conversation_TitleMute: String { return self._s[2793]! } public func PUSH_CHANNEL_MESSAGE_ROUND(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2791]!, self._r[2791]!, [_1]) + return formatWithArgumentRanges(self._s[2794]!, self._r[2794]!, [_1]) } - public var GroupInfo_DeleteAndExit: String { return self._s[2792]! } + public var GroupInfo_DeleteAndExit: String { return self._s[2795]! } public func Conversation_Moderate_DeleteAllMessages(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2793]!, self._r[2793]!, [_0]) + return formatWithArgumentRanges(self._s[2796]!, self._r[2796]!, [_0]) } - public var Call_ReportPlaceholder: String { return self._s[2794]! } - public var Chat_SlowmodeSendError: String { return self._s[2795]! } - public var MaskStickerSettings_Info: String { return self._s[2796]! } - public var EditTheme_Expand_TopInfo: String { return self._s[2797]! } + public var Call_ReportPlaceholder: String { return self._s[2797]! } + public var Chat_SlowmodeSendError: String { return self._s[2798]! } + public var MaskStickerSettings_Info: String { return self._s[2799]! } + public var EditTheme_Expand_TopInfo: String { return self._s[2800]! } public func GroupInfo_AddParticipantConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2798]!, self._r[2798]!, [_0]) + return formatWithArgumentRanges(self._s[2801]!, self._r[2801]!, [_0]) } - public var Checkout_NewCard_PostcodeTitle: String { return self._s[2799]! } - public var Passport_Address_RegionPlaceholder: String { return self._s[2801]! } - public var Contacts_ShareTelegram: String { return self._s[2802]! } - public var EnterPasscode_EnterNewPasscodeNew: String { return self._s[2803]! } - public var Channel_ErrorAccessDenied: String { return self._s[2804]! } - public var UserInfo_ScamBotWarning: String { return self._s[2806]! } - public var Stickers_GroupChooseStickerPack: String { return self._s[2807]! } - public var Call_ConnectionErrorTitle: String { return self._s[2808]! } - public var UserInfo_NotificationsEnable: String { return self._s[2809]! } - public var ArchivedChats_IntroText1: String { return self._s[2810]! } - public var Tour_Text4: String { return self._s[2813]! } - public var WallpaperSearch_Recent: String { return self._s[2814]! } - public var GroupInfo_ScamGroupWarning: String { return self._s[2815]! } - public var Profile_MessageLifetime2s: String { return self._s[2817]! } - public var Appearance_ThemePreview_ChatList_5_Text: String { return self._s[2818]! } - public var Notification_MessageLifetime2s: String { return self._s[2819]! } + public var Checkout_NewCard_PostcodeTitle: String { return self._s[2802]! } + public var Passport_Address_RegionPlaceholder: String { return self._s[2804]! } + public var Contacts_ShareTelegram: String { return self._s[2805]! } + public var EnterPasscode_EnterNewPasscodeNew: String { return self._s[2806]! } + public var Channel_ErrorAccessDenied: String { return self._s[2807]! } + public var UserInfo_ScamBotWarning: String { return self._s[2809]! } + public var Stickers_GroupChooseStickerPack: String { return self._s[2810]! } + public var Call_ConnectionErrorTitle: String { return self._s[2811]! } + public var UserInfo_NotificationsEnable: String { return self._s[2812]! } + public var ArchivedChats_IntroText1: String { return self._s[2813]! } + public var Tour_Text4: String { return self._s[2816]! } + public var WallpaperSearch_Recent: String { return self._s[2817]! } + public var GroupInfo_ScamGroupWarning: String { return self._s[2818]! } + public var Profile_MessageLifetime2s: String { return self._s[2820]! } + public var Appearance_ThemePreview_ChatList_5_Text: String { return self._s[2821]! } + public var Notification_MessageLifetime2s: String { return self._s[2822]! } public func Time_PreciseDate_m10(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2820]!, self._r[2820]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[2823]!, self._r[2823]!, [_1, _2, _3]) } - public var Cache_ClearCache: String { return self._s[2821]! } - public var AutoNightTheme_UpdateLocation: String { return self._s[2822]! } - public var Permissions_NotificationsUnreachableText_v0: String { return self._s[2823]! } + public var Cache_ClearCache: String { return self._s[2824]! } + public var AutoNightTheme_UpdateLocation: String { return self._s[2825]! } + public var Permissions_NotificationsUnreachableText_v0: String { return self._s[2826]! } public func Channel_AdminLog_MessageChangedGroupUsername(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2828]!, self._r[2828]!, [_0]) + return formatWithArgumentRanges(self._s[2831]!, self._r[2831]!, [_0]) } public func Conversation_ShareMyPhoneNumber_StatusSuccess(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2830]!, self._r[2830]!, [_0]) + return formatWithArgumentRanges(self._s[2833]!, self._r[2833]!, [_0]) } - public var LocalGroup_Text: String { return self._s[2831]! } - public var Channel_AdminLog_EmptyFilterTitle: String { return self._s[2832]! } - public var SocksProxySetup_TypeSocks: String { return self._s[2833]! } - public var ChatList_UnarchiveAction: String { return self._s[2834]! } - public var AutoNightTheme_Title: String { return self._s[2835]! } - public var InstantPage_FeedbackButton: String { return self._s[2836]! } - public var Passport_FieldAddress: String { return self._s[2837]! } + public var LocalGroup_Text: String { return self._s[2834]! } + public var Channel_AdminLog_EmptyFilterTitle: String { return self._s[2835]! } + public var SocksProxySetup_TypeSocks: String { return self._s[2836]! } + public var ChatList_UnarchiveAction: String { return self._s[2837]! } + public var AutoNightTheme_Title: String { return self._s[2838]! } + public var InstantPage_FeedbackButton: String { return self._s[2839]! } + public var Passport_FieldAddress: String { return self._s[2840]! } public func Channel_AdminLog_SetSlowmode(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2838]!, self._r[2838]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2841]!, self._r[2841]!, [_1, _2]) } - public var Month_ShortMarch: String { return self._s[2839]! } + public var Month_ShortMarch: String { return self._s[2842]! } public func PUSH_MESSAGE_INVOICE(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2840]!, self._r[2840]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2843]!, self._r[2843]!, [_1, _2]) } - public var SocksProxySetup_UsernamePlaceholder: String { return self._s[2841]! } - public var Conversation_ShareInlineBotLocationConfirmation: String { return self._s[2842]! } - public var Passport_FloodError: String { return self._s[2843]! } - public var SecretGif_Title: String { return self._s[2844]! } - public var NotificationSettings_ShowNotificationsAllAccountsInfoOn: String { return self._s[2845]! } - public var ChatList_Context_UnhideArchive: String { return self._s[2846]! } - public var Passport_Language_th: String { return self._s[2848]! } - public var Passport_Address_Address: String { return self._s[2849]! } - public var Login_InvalidLastNameError: String { return self._s[2850]! } - public var Notifications_InAppNotificationsPreview: String { return self._s[2851]! } - public var Notifications_PermissionsUnreachableTitle: String { return self._s[2852]! } - public var ChatList_Context_Archive: String { return self._s[2853]! } - public var SettingsSearch_FAQ: String { return self._s[2854]! } - public var ShareMenu_Send: String { return self._s[2855]! } - public var WallpaperSearch_ColorYellow: String { return self._s[2857]! } - public var Month_GenNovember: String { return self._s[2859]! } - public var SettingsSearch_Synonyms_Appearance_LargeEmoji: String { return self._s[2861]! } + public var SocksProxySetup_UsernamePlaceholder: String { return self._s[2844]! } + public var Conversation_ShareInlineBotLocationConfirmation: String { return self._s[2845]! } + public var Passport_FloodError: String { return self._s[2846]! } + public var SecretGif_Title: String { return self._s[2847]! } + public var NotificationSettings_ShowNotificationsAllAccountsInfoOn: String { return self._s[2848]! } + public var ChatList_Context_UnhideArchive: String { return self._s[2849]! } + public var Passport_Language_th: String { return self._s[2851]! } + public var Passport_Address_Address: String { return self._s[2852]! } + public var Login_InvalidLastNameError: String { return self._s[2853]! } + public var Notifications_InAppNotificationsPreview: String { return self._s[2854]! } + public var Notifications_PermissionsUnreachableTitle: String { return self._s[2855]! } + public var ChatList_Context_Archive: String { return self._s[2856]! } + public var SettingsSearch_FAQ: String { return self._s[2857]! } + public var ShareMenu_Send: String { return self._s[2858]! } + public var WallpaperSearch_ColorYellow: String { return self._s[2860]! } + public var Month_GenNovember: String { return self._s[2862]! } + public var SettingsSearch_Synonyms_Appearance_LargeEmoji: String { return self._s[2864]! } public func Conversation_ShareMyPhoneNumberConfirmation(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2862]!, self._r[2862]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2865]!, self._r[2865]!, [_1, _2]) } - public var Checkout_Email: String { return self._s[2864]! } - public var NotificationsSound_Tritone: String { return self._s[2865]! } - public var StickerPacksSettings_ManagingHelp: String { return self._s[2867]! } + public var Checkout_Email: String { return self._s[2867]! } + public var NotificationsSound_Tritone: String { return self._s[2868]! } + public var StickerPacksSettings_ManagingHelp: String { return self._s[2870]! } public func PUSH_PINNED_ROUND(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2870]!, self._r[2870]!, [_1]) + return formatWithArgumentRanges(self._s[2873]!, self._r[2873]!, [_1]) } - public var ChangePhoneNumberNumber_Help: String { return self._s[2871]! } + public var ChangePhoneNumberNumber_Help: String { return self._s[2874]! } public func Checkout_LiabilityAlert(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2872]!, self._r[2872]!, [_1, _1, _1, _2]) + return formatWithArgumentRanges(self._s[2875]!, self._r[2875]!, [_1, _1, _1, _2]) } - public var ChatList_UndoArchiveTitle: String { return self._s[2873]! } - public var Notification_Exceptions_Add: String { return self._s[2874]! } - public var DialogList_You: String { return self._s[2875]! } - public var MediaPicker_Send: String { return self._s[2878]! } - public var SettingsSearch_Synonyms_Stickers_Title: String { return self._s[2879]! } - public var Appearance_ThemePreview_ChatList_4_Text: String { return self._s[2880]! } - public var Call_AudioRouteSpeaker: String { return self._s[2881]! } - public var Watch_UserInfo_Title: String { return self._s[2882]! } - public var VoiceOver_Chat_PollFinalResults: String { return self._s[2883]! } - public var Appearance_AccentColor: String { return self._s[2884]! } + public var ChatList_UndoArchiveTitle: String { return self._s[2876]! } + public var Notification_Exceptions_Add: String { return self._s[2877]! } + public var DialogList_You: String { return self._s[2878]! } + public var MediaPicker_Send: String { return self._s[2881]! } + public var SettingsSearch_Synonyms_Stickers_Title: String { return self._s[2882]! } + public var Appearance_ThemePreview_ChatList_4_Text: String { return self._s[2883]! } + public var Call_AudioRouteSpeaker: String { return self._s[2884]! } + public var Watch_UserInfo_Title: String { return self._s[2885]! } + public var VoiceOver_Chat_PollFinalResults: String { return self._s[2886]! } + public var Appearance_AccentColor: String { return self._s[2887]! } public func Login_EmailPhoneSubject(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2885]!, self._r[2885]!, [_0]) + return formatWithArgumentRanges(self._s[2888]!, self._r[2888]!, [_0]) } - public var Permissions_ContactsAllowInSettings_v0: String { return self._s[2886]! } + public var Permissions_ContactsAllowInSettings_v0: String { return self._s[2889]! } public func PUSH_CHANNEL_MESSAGE_GAME(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2887]!, self._r[2887]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2890]!, self._r[2890]!, [_1, _2]) } - public var Conversation_ClousStorageInfo_Description2: String { return self._s[2888]! } - public var WebSearch_RecentClearConfirmation: String { return self._s[2889]! } - public var Notification_CallOutgoing: String { return self._s[2890]! } - public var PrivacySettings_PasscodeAndFaceId: String { return self._s[2891]! } - public var Channel_DiscussionGroup_MakeHistoryPublic: String { return self._s[2892]! } - public var Call_RecordingDisabledMessage: String { return self._s[2893]! } - public var Message_Game: String { return self._s[2894]! } - public var Conversation_PressVolumeButtonForSound: String { return self._s[2895]! } - public var PrivacyLastSeenSettings_CustomHelp: String { return self._s[2896]! } - public var Channel_DiscussionGroup_PrivateGroup: String { return self._s[2897]! } - public var Channel_EditAdmin_PermissionAddAdmins: String { return self._s[2898]! } - public var Date_DialogDateFormat: String { return self._s[2899]! } - public var WallpaperColors_SetCustomColor: String { return self._s[2900]! } - public var Notifications_InAppNotifications: String { return self._s[2901]! } + public var Conversation_ClousStorageInfo_Description2: String { return self._s[2891]! } + public var WebSearch_RecentClearConfirmation: String { return self._s[2892]! } + public var Notification_CallOutgoing: String { return self._s[2893]! } + public var PrivacySettings_PasscodeAndFaceId: String { return self._s[2894]! } + public var Channel_DiscussionGroup_MakeHistoryPublic: String { return self._s[2895]! } + public var Call_RecordingDisabledMessage: String { return self._s[2896]! } + public var Message_Game: String { return self._s[2897]! } + public var Conversation_PressVolumeButtonForSound: String { return self._s[2898]! } + public var PrivacyLastSeenSettings_CustomHelp: String { return self._s[2899]! } + public var Channel_DiscussionGroup_PrivateGroup: String { return self._s[2900]! } + public var Channel_EditAdmin_PermissionAddAdmins: String { return self._s[2901]! } + public var Date_DialogDateFormat: String { return self._s[2902]! } + public var WallpaperColors_SetCustomColor: String { return self._s[2903]! } + public var Notifications_InAppNotifications: String { return self._s[2904]! } public func Channel_Management_RemovedBy(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2902]!, self._r[2902]!, [_0]) - } - public func Settings_ApplyProxyAlert(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2903]!, self._r[2903]!, [_1, _2]) - } - public var NewContact_Title: String { return self._s[2904]! } - public func AutoDownloadSettings_UpToForAll(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[2905]!, self._r[2905]!, [_0]) } - public var Conversation_ViewContactDetails: String { return self._s[2906]! } + public func Settings_ApplyProxyAlert(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[2906]!, self._r[2906]!, [_1, _2]) + } + public var NewContact_Title: String { return self._s[2907]! } + public func AutoDownloadSettings_UpToForAll(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[2908]!, self._r[2908]!, [_0]) + } + public var Conversation_ViewContactDetails: String { return self._s[2909]! } public func PUSH_CHANNEL_MESSAGE_CONTACT(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2908]!, self._r[2908]!, [_1]) + return formatWithArgumentRanges(self._s[2911]!, self._r[2911]!, [_1]) } - public var Checkout_NewCard_CardholderNameTitle: String { return self._s[2909]! } - public var Passport_Identity_ExpiryDateNone: String { return self._s[2910]! } - public var PrivacySettings_Title: String { return self._s[2911]! } - public var Conversation_SilentBroadcastTooltipOff: String { return self._s[2914]! } - public var GroupRemoved_UsersSectionTitle: String { return self._s[2915]! } - public var VoiceOver_Chat_ContactEmail: String { return self._s[2916]! } - public var Contacts_PhoneNumber: String { return self._s[2917]! } - public var Map_ShowPlaces: String { return self._s[2919]! } - public var ChatAdmins_Title: String { return self._s[2920]! } - public var InstantPage_Reference: String { return self._s[2922]! } - public var Wallet_Info_Updating: String { return self._s[2923]! } - public var ReportGroupLocation_Text: String { return self._s[2924]! } + public var Checkout_NewCard_CardholderNameTitle: String { return self._s[2912]! } + public var Passport_Identity_ExpiryDateNone: String { return self._s[2913]! } + public var PrivacySettings_Title: String { return self._s[2914]! } + public var Conversation_SilentBroadcastTooltipOff: String { return self._s[2917]! } + public var GroupRemoved_UsersSectionTitle: String { return self._s[2918]! } + public var VoiceOver_Chat_ContactEmail: String { return self._s[2919]! } + public var Contacts_PhoneNumber: String { return self._s[2920]! } + public var Map_ShowPlaces: String { return self._s[2922]! } + public var ChatAdmins_Title: String { return self._s[2923]! } + public var InstantPage_Reference: String { return self._s[2925]! } + public var Wallet_Info_Updating: String { return self._s[2926]! } + public var ReportGroupLocation_Text: String { return self._s[2927]! } public func PUSH_CHAT_MESSAGE_FWD(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2925]!, self._r[2925]!, [_1, _2]) + return formatWithArgumentRanges(self._s[2928]!, self._r[2928]!, [_1, _2]) } - public var Camera_FlashOff: String { return self._s[2926]! } - public var Wallet_Intro_TermsUrl: String { return self._s[2927]! } - public var Watch_UserInfo_Block: String { return self._s[2928]! } - public var ChatSettings_Stickers: String { return self._s[2929]! } - public var ChatSettings_DownloadInBackground: String { return self._s[2930]! } - public var Appearance_ThemeCarouselTintedNight: String { return self._s[2931]! } + public var Camera_FlashOff: String { return self._s[2929]! } + public var Wallet_Intro_TermsUrl: String { return self._s[2930]! } + public var Watch_UserInfo_Block: String { return self._s[2931]! } + public var ChatSettings_Stickers: String { return self._s[2932]! } + public var ChatSettings_DownloadInBackground: String { return self._s[2933]! } + public var Appearance_ThemeCarouselTintedNight: String { return self._s[2934]! } public func UserInfo_BlockConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2932]!, self._r[2932]!, [_0]) + return formatWithArgumentRanges(self._s[2935]!, self._r[2935]!, [_0]) } - public var Settings_ViewPhoto: String { return self._s[2933]! } - public var Login_CheckOtherSessionMessages: String { return self._s[2934]! } - public var AutoDownloadSettings_Cellular: String { return self._s[2935]! } - public var Wallet_Created_ExportErrorTitle: String { return self._s[2936]! } - public var SettingsSearch_Synonyms_Notifications_GroupNotificationsExceptions: String { return self._s[2937]! } - public var VoiceOver_MessageContextShare: String { return self._s[2938]! } + public var Settings_ViewPhoto: String { return self._s[2936]! } + public var Login_CheckOtherSessionMessages: String { return self._s[2937]! } + public var AutoDownloadSettings_Cellular: String { return self._s[2938]! } + public var Wallet_Created_ExportErrorTitle: String { return self._s[2939]! } + public var SettingsSearch_Synonyms_Notifications_GroupNotificationsExceptions: String { return self._s[2940]! } + public var VoiceOver_MessageContextShare: String { return self._s[2941]! } public func Target_InviteToGroupConfirmation(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2940]!, self._r[2940]!, [_0]) - } - public var Privacy_DeleteDrafts: String { return self._s[2941]! } - public var Wallpaper_SetCustomBackgroundInfo: String { return self._s[2942]! } - public func LastSeen_AtDate(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[2943]!, self._r[2943]!, [_0]) } - public var DialogList_SavedMessagesHelp: String { return self._s[2944]! } - public var Wallet_SecureStorageNotAvailable_Title: String { return self._s[2945]! } - public var DialogList_SavedMessages: String { return self._s[2946]! } - public var GroupInfo_UpgradeButton: String { return self._s[2947]! } - public var Appearance_ThemePreview_ChatList_3_Text: String { return self._s[2949]! } - public var DialogList_Pin: String { return self._s[2950]! } + public var Privacy_DeleteDrafts: String { return self._s[2944]! } + public var Wallpaper_SetCustomBackgroundInfo: String { return self._s[2945]! } + public func LastSeen_AtDate(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[2946]!, self._r[2946]!, [_0]) + } + public var DialogList_SavedMessagesHelp: String { return self._s[2947]! } + public var Wallet_SecureStorageNotAvailable_Title: String { return self._s[2948]! } + public var DialogList_SavedMessages: String { return self._s[2949]! } + public var GroupInfo_UpgradeButton: String { return self._s[2950]! } + public var Appearance_ThemePreview_ChatList_3_Text: String { return self._s[2952]! } + public var DialogList_Pin: String { return self._s[2953]! } public func ForwardedAuthors2(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2951]!, self._r[2951]!, [_0, _1]) + return formatWithArgumentRanges(self._s[2954]!, self._r[2954]!, [_0, _1]) } public func Login_PhoneGenericEmailSubject(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2952]!, self._r[2952]!, [_0]) + return formatWithArgumentRanges(self._s[2955]!, self._r[2955]!, [_0]) } - public var Notification_Exceptions_AlwaysOn: String { return self._s[2953]! } - public var UserInfo_NotificationsDisable: String { return self._s[2954]! } - public var Paint_Outlined: String { return self._s[2955]! } - public var Activity_PlayingGame: String { return self._s[2956]! } - public var SearchImages_NoImagesFound: String { return self._s[2957]! } - public var SocksProxySetup_ProxyType: String { return self._s[2958]! } - public var AppleWatch_ReplyPresetsHelp: String { return self._s[2960]! } - public var Conversation_ContextMenuCancelSending: String { return self._s[2961]! } - public var Settings_AppLanguage: String { return self._s[2962]! } - public var TwoStepAuth_ResetAccountHelp: String { return self._s[2963]! } - public var Common_ChoosePhoto: String { return self._s[2964]! } - public var CallFeedback_ReasonEcho: String { return self._s[2965]! } + public var Notification_Exceptions_AlwaysOn: String { return self._s[2956]! } + public var UserInfo_NotificationsDisable: String { return self._s[2957]! } + public var Paint_Outlined: String { return self._s[2958]! } + public var Activity_PlayingGame: String { return self._s[2959]! } + public var SearchImages_NoImagesFound: String { return self._s[2960]! } + public var SocksProxySetup_ProxyType: String { return self._s[2961]! } + public var AppleWatch_ReplyPresetsHelp: String { return self._s[2963]! } + public var Conversation_ContextMenuCancelSending: String { return self._s[2964]! } + public var Settings_AppLanguage: String { return self._s[2965]! } + public var TwoStepAuth_ResetAccountHelp: String { return self._s[2966]! } + public var Common_ChoosePhoto: String { return self._s[2967]! } + public var CallFeedback_ReasonEcho: String { return self._s[2968]! } public func PUSH_PINNED_AUDIO(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2966]!, self._r[2966]!, [_1]) + return formatWithArgumentRanges(self._s[2969]!, self._r[2969]!, [_1]) } - public var Privacy_Calls_AlwaysAllow: String { return self._s[2967]! } - public var Activity_UploadingVideo: String { return self._s[2968]! } - public var ChannelInfo_DeleteChannelConfirmation: String { return self._s[2969]! } - public var NetworkUsageSettings_Wifi: String { return self._s[2970]! } - public var VoiceOver_Editing_ClearText: String { return self._s[2971]! } - public var PUSH_SENDER_YOU: String { return self._s[2972]! } - public var Channel_BanUser_PermissionReadMessages: String { return self._s[2973]! } - public var Checkout_PayWithTouchId: String { return self._s[2974]! } - public var Wallpaper_ResetWallpapersConfirmation: String { return self._s[2975]! } + public var Privacy_Calls_AlwaysAllow: String { return self._s[2970]! } + public var Activity_UploadingVideo: String { return self._s[2971]! } + public var ChannelInfo_DeleteChannelConfirmation: String { return self._s[2972]! } + public var NetworkUsageSettings_Wifi: String { return self._s[2973]! } + public var VoiceOver_Editing_ClearText: String { return self._s[2974]! } + public var PUSH_SENDER_YOU: String { return self._s[2975]! } + public var Channel_BanUser_PermissionReadMessages: String { return self._s[2976]! } + public var Checkout_PayWithTouchId: String { return self._s[2977]! } + public var Wallpaper_ResetWallpapersConfirmation: String { return self._s[2978]! } public func PUSH_LOCKED_MESSAGE(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2977]!, self._r[2977]!, [_1]) - } - public var Notifications_ExceptionsNone: String { return self._s[2978]! } - public func Message_ForwardedMessageShort(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[2979]!, self._r[2979]!, [_0]) - } - public func PUSH_PINNED_GEO(_ _1: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[2980]!, self._r[2980]!, [_1]) } - public var AuthSessions_IncompleteAttempts: String { return self._s[2982]! } - public var Passport_Address_Region: String { return self._s[2985]! } - public var ChatList_DeleteChat: String { return self._s[2986]! } - public var LogoutOptions_ClearCacheTitle: String { return self._s[2987]! } - public var PhotoEditor_TiltShift: String { return self._s[2988]! } - public var Settings_FAQ_URL: String { return self._s[2989]! } - public var Passport_Language_sl: String { return self._s[2990]! } - public var Settings_PrivacySettings: String { return self._s[2992]! } - public var SharedMedia_TitleLink: String { return self._s[2993]! } - public var Passport_Identity_TypePassportUploadScan: String { return self._s[2994]! } - public var Settings_SetProfilePhoto: String { return self._s[2995]! } - public var Channel_About_Help: String { return self._s[2996]! } - public var Contacts_PermissionsEnable: String { return self._s[2997]! } - public var Wallet_Sending_Title: String { return self._s[2998]! } - public var SettingsSearch_Synonyms_Notifications_GroupNotificationsAlert: String { return self._s[2999]! } - public var AttachmentMenu_SendAsFiles: String { return self._s[3000]! } - public var CallFeedback_ReasonInterruption: String { return self._s[3002]! } - public var Passport_Address_AddTemporaryRegistration: String { return self._s[3003]! } - public var AutoDownloadSettings_AutodownloadVideos: String { return self._s[3004]! } - public var ChatSettings_AutoDownloadSettings_Delimeter: String { return self._s[3005]! } - public var PrivacySettings_DeleteAccountTitle: String { return self._s[3006]! } - public var AccessDenied_VideoMessageCamera: String { return self._s[3008]! } - public var Map_OpenInYandexMaps: String { return self._s[3010]! } - public var CreateGroup_ErrorLocatedGroupsTooMuch: String { return self._s[3011]! } - public var VoiceOver_MessageContextReply: String { return self._s[3012]! } - public var PhotoEditor_SaturationTool: String { return self._s[3013]! } + public var Notifications_ExceptionsNone: String { return self._s[2981]! } + public func Message_ForwardedMessageShort(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[2982]!, self._r[2982]!, [_0]) + } + public func PUSH_PINNED_GEO(_ _1: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[2983]!, self._r[2983]!, [_1]) + } + public var AuthSessions_IncompleteAttempts: String { return self._s[2985]! } + public var Passport_Address_Region: String { return self._s[2988]! } + public var ChatList_DeleteChat: String { return self._s[2989]! } + public var LogoutOptions_ClearCacheTitle: String { return self._s[2990]! } + public var PhotoEditor_TiltShift: String { return self._s[2991]! } + public var Settings_FAQ_URL: String { return self._s[2992]! } + public var Passport_Language_sl: String { return self._s[2993]! } + public var Settings_PrivacySettings: String { return self._s[2995]! } + public var SharedMedia_TitleLink: String { return self._s[2996]! } + public var Passport_Identity_TypePassportUploadScan: String { return self._s[2997]! } + public var Settings_SetProfilePhoto: String { return self._s[2998]! } + public var Channel_About_Help: String { return self._s[2999]! } + public var Contacts_PermissionsEnable: String { return self._s[3000]! } + public var Wallet_Sending_Title: String { return self._s[3001]! } + public var SettingsSearch_Synonyms_Notifications_GroupNotificationsAlert: String { return self._s[3002]! } + public var AttachmentMenu_SendAsFiles: String { return self._s[3003]! } + public var CallFeedback_ReasonInterruption: String { return self._s[3005]! } + public var Passport_Address_AddTemporaryRegistration: String { return self._s[3006]! } + public var AutoDownloadSettings_AutodownloadVideos: String { return self._s[3007]! } + public var ChatSettings_AutoDownloadSettings_Delimeter: String { return self._s[3008]! } + public var PrivacySettings_DeleteAccountTitle: String { return self._s[3009]! } + public var AccessDenied_VideoMessageCamera: String { return self._s[3011]! } + public var Map_OpenInYandexMaps: String { return self._s[3013]! } + public var CreateGroup_ErrorLocatedGroupsTooMuch: String { return self._s[3014]! } + public var VoiceOver_MessageContextReply: String { return self._s[3015]! } + public var PhotoEditor_SaturationTool: String { return self._s[3016]! } public func PUSH_MESSAGE_STICKER(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3014]!, self._r[3014]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3017]!, self._r[3017]!, [_1, _2]) } - public var PrivacyPhoneNumberSettings_CustomHelp: String { return self._s[3015]! } - public var Notification_Exceptions_NewException_NotificationHeader: String { return self._s[3016]! } - public var Group_OwnershipTransfer_ErrorLocatedGroupsTooMuch: String { return self._s[3017]! } - public var Appearance_TextSize: String { return self._s[3018]! } + public var PrivacyPhoneNumberSettings_CustomHelp: String { return self._s[3018]! } + public var Notification_Exceptions_NewException_NotificationHeader: String { return self._s[3019]! } + public var Wallet_Send_NetworkError: String { return self._s[3020]! } + public var Group_OwnershipTransfer_ErrorLocatedGroupsTooMuch: String { return self._s[3021]! } + public var Appearance_TextSize: String { return self._s[3022]! } public func LOCAL_MESSAGE_FWDS(_ _1: String, _ _2: Int) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3019]!, self._r[3019]!, [_1, "\(_2)"]) + return formatWithArgumentRanges(self._s[3023]!, self._r[3023]!, [_1, "\(_2)"]) } - public var Appearance_ThemePreview_ChatList_2_Text: String { return self._s[3020]! } - public var Channel_Username_InvalidTooShort: String { return self._s[3022]! } + public var Appearance_ThemePreview_ChatList_2_Text: String { return self._s[3024]! } + public var Channel_Username_InvalidTooShort: String { return self._s[3026]! } public func Group_OwnershipTransfer_DescriptionInfo(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3023]!, self._r[3023]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3027]!, self._r[3027]!, [_1, _2]) } public func PUSH_CHAT_MESSAGE_GAME(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3024]!, self._r[3024]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[3028]!, self._r[3028]!, [_1, _2, _3]) } - public var GroupInfo_PublicLinkAdd: String { return self._s[3025]! } - public var Passport_PassportInformation: String { return self._s[3028]! } - public var Theme_Unsupported: String { return self._s[3029]! } - public var WatchRemote_AlertTitle: String { return self._s[3030]! } - public var Privacy_GroupsAndChannels_NeverAllow: String { return self._s[3031]! } - public var ConvertToSupergroup_HelpText: String { return self._s[3033]! } + public var GroupInfo_PublicLinkAdd: String { return self._s[3029]! } + public var Passport_PassportInformation: String { return self._s[3032]! } + public var Theme_Unsupported: String { return self._s[3033]! } + public var WatchRemote_AlertTitle: String { return self._s[3034]! } + public var Privacy_GroupsAndChannels_NeverAllow: String { return self._s[3035]! } + public var ConvertToSupergroup_HelpText: String { return self._s[3037]! } public func Time_MonthOfYear_m7(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3034]!, self._r[3034]!, [_0]) + return formatWithArgumentRanges(self._s[3038]!, self._r[3038]!, [_0]) } public func PUSH_PHONE_CALL_REQUEST(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3035]!, self._r[3035]!, [_1]) + return formatWithArgumentRanges(self._s[3039]!, self._r[3039]!, [_1]) } - public var Privacy_GroupsAndChannels_CustomHelp: String { return self._s[3036]! } - public var TwoStepAuth_RecoveryCodeInvalid: String { return self._s[3038]! } - public var AccessDenied_CameraDisabled: String { return self._s[3039]! } + public var Privacy_GroupsAndChannels_CustomHelp: String { return self._s[3040]! } + public var TwoStepAuth_RecoveryCodeInvalid: String { return self._s[3042]! } + public var AccessDenied_CameraDisabled: String { return self._s[3043]! } public func Channel_Username_UsernameIsAvailable(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3040]!, self._r[3040]!, [_0]) + return formatWithArgumentRanges(self._s[3044]!, self._r[3044]!, [_0]) } - public var PhotoEditor_ContrastTool: String { return self._s[3043]! } + public var PhotoEditor_ContrastTool: String { return self._s[3047]! } public func PUSH_PINNED_DOC(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3044]!, self._r[3044]!, [_1]) + return formatWithArgumentRanges(self._s[3048]!, self._r[3048]!, [_1]) } - public var DialogList_Draft: String { return self._s[3045]! } - public var Privacy_TopPeersDelete: String { return self._s[3047]! } - public var LoginPassword_PasswordPlaceholder: String { return self._s[3048]! } - public var Passport_Identity_TypeIdentityCardUploadScan: String { return self._s[3049]! } - public var WebSearch_RecentSectionClear: String { return self._s[3050]! } - public var EditTheme_ErrorInvalidCharacters: String { return self._s[3051]! } - public var Watch_ChatList_NoConversationsTitle: String { return self._s[3053]! } - public var Common_Done: String { return self._s[3055]! } - public var AuthSessions_EmptyText: String { return self._s[3056]! } - public var Conversation_ShareBotContactConfirmation: String { return self._s[3057]! } - public var Tour_Title5: String { return self._s[3058]! } - public var Wallet_Settings_Title: String { return self._s[3059]! } + public var DialogList_Draft: String { return self._s[3049]! } + public var Privacy_TopPeersDelete: String { return self._s[3051]! } + public var LoginPassword_PasswordPlaceholder: String { return self._s[3052]! } + public var Passport_Identity_TypeIdentityCardUploadScan: String { return self._s[3053]! } + public var WebSearch_RecentSectionClear: String { return self._s[3054]! } + public var EditTheme_ErrorInvalidCharacters: String { return self._s[3055]! } + public var Watch_ChatList_NoConversationsTitle: String { return self._s[3057]! } + public var Common_Done: String { return self._s[3059]! } + public var AuthSessions_EmptyText: String { return self._s[3060]! } + public var Conversation_ShareBotContactConfirmation: String { return self._s[3061]! } + public var Tour_Title5: String { return self._s[3062]! } + public var Wallet_Settings_Title: String { return self._s[3063]! } public func Map_DirectionsDriveEta(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3060]!, self._r[3060]!, [_0]) + return formatWithArgumentRanges(self._s[3064]!, self._r[3064]!, [_0]) } - public var ApplyLanguage_UnsufficientDataTitle: String { return self._s[3061]! } - public var Conversation_LinkDialogSave: String { return self._s[3062]! } - public var GroupInfo_ActionRestrict: String { return self._s[3063]! } - public var Checkout_Title: String { return self._s[3064]! } - public var Channel_DiscussionGroup_HeaderLabel: String { return self._s[3066]! } - public var Channel_AdminLog_CanChangeInfo: String { return self._s[3068]! } - public var Notification_RenamedGroup: String { return self._s[3069]! } - public var PeopleNearby_Groups: String { return self._s[3070]! } - public var Checkout_PayWithFaceId: String { return self._s[3071]! } - public var Channel_BanList_BlockedTitle: String { return self._s[3072]! } - public var SettingsSearch_Synonyms_Notifications_InAppNotificationsSound: String { return self._s[3074]! } - public var Checkout_WebConfirmation_Title: String { return self._s[3075]! } - public var Notifications_MessageNotificationsAlert: String { return self._s[3076]! } + public var ApplyLanguage_UnsufficientDataTitle: String { return self._s[3065]! } + public var Conversation_LinkDialogSave: String { return self._s[3066]! } + public var GroupInfo_ActionRestrict: String { return self._s[3067]! } + public var Checkout_Title: String { return self._s[3068]! } + public var Channel_DiscussionGroup_HeaderLabel: String { return self._s[3070]! } + public var Channel_AdminLog_CanChangeInfo: String { return self._s[3072]! } + public var Notification_RenamedGroup: String { return self._s[3073]! } + public var PeopleNearby_Groups: String { return self._s[3074]! } + public var Checkout_PayWithFaceId: String { return self._s[3075]! } + public var Channel_BanList_BlockedTitle: String { return self._s[3076]! } + public var SettingsSearch_Synonyms_Notifications_InAppNotificationsSound: String { return self._s[3078]! } + public var Checkout_WebConfirmation_Title: String { return self._s[3079]! } + public var Notifications_MessageNotificationsAlert: String { return self._s[3080]! } public func Activity_RemindAboutGroup(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3077]!, self._r[3077]!, [_0]) + return formatWithArgumentRanges(self._s[3081]!, self._r[3081]!, [_0]) } - public var Profile_AddToExisting: String { return self._s[3079]! } + public var Profile_AddToExisting: String { return self._s[3083]! } public func Profile_CreateEncryptedChatOutdatedError(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3080]!, self._r[3080]!, [_0, _1]) + return formatWithArgumentRanges(self._s[3084]!, self._r[3084]!, [_0, _1]) } - public var Cache_Files: String { return self._s[3082]! } - public var Permissions_PrivacyPolicy: String { return self._s[3083]! } - public var SocksProxySetup_ConnectAndSave: String { return self._s[3084]! } - public var UserInfo_NotificationsDefaultDisabled: String { return self._s[3085]! } - public var AutoDownloadSettings_TypeContacts: String { return self._s[3087]! } - public var Appearance_ThemePreview_ChatList_1_Text: String { return self._s[3089]! } - public var Calls_NoCallsPlaceholder: String { return self._s[3090]! } - public var Channel_Username_RevokeExistingUsernamesInfo: String { return self._s[3091]! } - public var VoiceOver_AttachMedia: String { return self._s[3093]! } - public var Notifications_ExceptionsGroupPlaceholder: String { return self._s[3094]! } + public var Cache_Files: String { return self._s[3086]! } + public var Permissions_PrivacyPolicy: String { return self._s[3087]! } + public var SocksProxySetup_ConnectAndSave: String { return self._s[3088]! } + public var UserInfo_NotificationsDefaultDisabled: String { return self._s[3089]! } + public var AutoDownloadSettings_TypeContacts: String { return self._s[3091]! } + public var Appearance_ThemePreview_ChatList_1_Text: String { return self._s[3093]! } + public var Calls_NoCallsPlaceholder: String { return self._s[3094]! } + public var Channel_Username_RevokeExistingUsernamesInfo: String { return self._s[3095]! } + public var VoiceOver_AttachMedia: String { return self._s[3097]! } + public var Notifications_ExceptionsGroupPlaceholder: String { return self._s[3098]! } public func PUSH_CHAT_MESSAGE_INVOICE(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3095]!, self._r[3095]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[3099]!, self._r[3099]!, [_1, _2, _3]) } - public var SettingsSearch_Synonyms_Notifications_GroupNotificationsSound: String { return self._s[3096]! } - public var Conversation_SetReminder_Title: String { return self._s[3097]! } - public var Passport_FieldAddressHelp: String { return self._s[3098]! } - public var Privacy_GroupsAndChannels_InviteToChannelMultipleError: String { return self._s[3099]! } - public var PUSH_REMINDER_TITLE: String { return self._s[3100]! } + public var SettingsSearch_Synonyms_Notifications_GroupNotificationsSound: String { return self._s[3100]! } + public var Conversation_SetReminder_Title: String { return self._s[3101]! } + public var Passport_FieldAddressHelp: String { return self._s[3102]! } + public var Privacy_GroupsAndChannels_InviteToChannelMultipleError: String { return self._s[3103]! } + public var PUSH_REMINDER_TITLE: String { return self._s[3104]! } public func Login_TermsOfService_ProceedBot(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3101]!, self._r[3101]!, [_0]) + return formatWithArgumentRanges(self._s[3105]!, self._r[3105]!, [_0]) } - public var Channel_AdminLog_EmptyTitle: String { return self._s[3102]! } - public var Privacy_Calls_NeverAllow_Title: String { return self._s[3103]! } - public var Login_UnknownError: String { return self._s[3104]! } - public var Group_UpgradeNoticeText2: String { return self._s[3107]! } - public var Watch_Compose_AddContact: String { return self._s[3108]! } - public var Web_Error: String { return self._s[3109]! } - public var Gif_Search: String { return self._s[3110]! } - public var Profile_MessageLifetime1h: String { return self._s[3111]! } - public var CheckoutInfo_ReceiverInfoEmailPlaceholder: String { return self._s[3112]! } - public var Channel_Username_CheckingUsername: String { return self._s[3113]! } - public var CallFeedback_ReasonSilentRemote: String { return self._s[3114]! } - public var AutoDownloadSettings_TypeChannels: String { return self._s[3115]! } - public var Channel_AboutItem: String { return self._s[3116]! } - public var Privacy_GroupsAndChannels_AlwaysAllow_Placeholder: String { return self._s[3118]! } - public var VoiceOver_Chat_VoiceMessage: String { return self._s[3119]! } - public var GroupInfo_SharedMedia: String { return self._s[3120]! } + public var Channel_AdminLog_EmptyTitle: String { return self._s[3106]! } + public var Privacy_Calls_NeverAllow_Title: String { return self._s[3107]! } + public var Login_UnknownError: String { return self._s[3108]! } + public var Group_UpgradeNoticeText2: String { return self._s[3111]! } + public var Watch_Compose_AddContact: String { return self._s[3112]! } + public var Web_Error: String { return self._s[3113]! } + public var Gif_Search: String { return self._s[3114]! } + public var Profile_MessageLifetime1h: String { return self._s[3115]! } + public var CheckoutInfo_ReceiverInfoEmailPlaceholder: String { return self._s[3116]! } + public var Channel_Username_CheckingUsername: String { return self._s[3117]! } + public var CallFeedback_ReasonSilentRemote: String { return self._s[3118]! } + public var AutoDownloadSettings_TypeChannels: String { return self._s[3119]! } + public var Channel_AboutItem: String { return self._s[3120]! } + public var Privacy_GroupsAndChannels_AlwaysAllow_Placeholder: String { return self._s[3122]! } + public var VoiceOver_Chat_VoiceMessage: String { return self._s[3123]! } + public var GroupInfo_SharedMedia: String { return self._s[3124]! } public func Channel_AdminLog_MessagePromotedName(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3121]!, self._r[3121]!, [_1]) + return formatWithArgumentRanges(self._s[3125]!, self._r[3125]!, [_1]) } - public var Call_PhoneCallInProgressMessage: String { return self._s[3122]! } + public var Call_PhoneCallInProgressMessage: String { return self._s[3126]! } public func PUSH_CHANNEL_ALBUM(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3123]!, self._r[3123]!, [_1]) + return formatWithArgumentRanges(self._s[3127]!, self._r[3127]!, [_1]) } - public var ChatList_UndoArchiveRevealedText: String { return self._s[3124]! } - public var GroupInfo_InviteLink_RevokeAlert_Text: String { return self._s[3125]! } - public var Conversation_SearchByName_Placeholder: String { return self._s[3126]! } - public var CreatePoll_AddOption: String { return self._s[3127]! } - public var GroupInfo_Permissions_SearchPlaceholder: String { return self._s[3128]! } - public var Group_UpgradeNoticeHeader: String { return self._s[3129]! } - public var Channel_Management_AddModerator: String { return self._s[3130]! } - public var AutoDownloadSettings_MaxFileSize: String { return self._s[3131]! } - public var StickerPacksSettings_ShowStickersButton: String { return self._s[3132]! } - public var NotificationsSound_Hello: String { return self._s[3133]! } - public var SocksProxySetup_SavedProxies: String { return self._s[3134]! } - public var Channel_Stickers_Placeholder: String { return self._s[3136]! } + public var ChatList_UndoArchiveRevealedText: String { return self._s[3128]! } + public var GroupInfo_InviteLink_RevokeAlert_Text: String { return self._s[3129]! } + public var Conversation_SearchByName_Placeholder: String { return self._s[3130]! } + public var CreatePoll_AddOption: String { return self._s[3131]! } + public var GroupInfo_Permissions_SearchPlaceholder: String { return self._s[3132]! } + public var Group_UpgradeNoticeHeader: String { return self._s[3133]! } + public var Channel_Management_AddModerator: String { return self._s[3134]! } + public var AutoDownloadSettings_MaxFileSize: String { return self._s[3135]! } + public var StickerPacksSettings_ShowStickersButton: String { return self._s[3136]! } + public var Wallet_Info_RefreshErrorNetworkText: String { return self._s[3137]! } + public var NotificationsSound_Hello: String { return self._s[3138]! } + public var SocksProxySetup_SavedProxies: String { return self._s[3139]! } + public var Channel_Stickers_Placeholder: String { return self._s[3141]! } public func Login_EmailCodeBody(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3137]!, self._r[3137]!, [_0]) + return formatWithArgumentRanges(self._s[3142]!, self._r[3142]!, [_0]) } - public var PrivacyPolicy_DeclineDeclineAndDelete: String { return self._s[3138]! } - public var Channel_Management_AddModeratorHelp: String { return self._s[3139]! } - public var ContactInfo_BirthdayLabel: String { return self._s[3140]! } - public var ChangePhoneNumberCode_RequestingACall: String { return self._s[3141]! } - public var AutoDownloadSettings_Channels: String { return self._s[3142]! } - public var Passport_Language_mn: String { return self._s[3143]! } - public var Notifications_ResetAllNotificationsHelp: String { return self._s[3146]! } - public var GroupInfo_Permissions_SlowmodeValue_Off: String { return self._s[3147]! } - public var Passport_Language_ja: String { return self._s[3149]! } - public var Settings_About_Title: String { return self._s[3150]! } - public var Settings_NotificationsAndSounds: String { return self._s[3151]! } - public var ChannelInfo_DeleteGroup: String { return self._s[3152]! } - public var Settings_BlockedUsers: String { return self._s[3153]! } + public var PrivacyPolicy_DeclineDeclineAndDelete: String { return self._s[3143]! } + public var Channel_Management_AddModeratorHelp: String { return self._s[3144]! } + public var ContactInfo_BirthdayLabel: String { return self._s[3145]! } + public var ChangePhoneNumberCode_RequestingACall: String { return self._s[3146]! } + public var AutoDownloadSettings_Channels: String { return self._s[3147]! } + public var Passport_Language_mn: String { return self._s[3148]! } + public var Notifications_ResetAllNotificationsHelp: String { return self._s[3151]! } + public var GroupInfo_Permissions_SlowmodeValue_Off: String { return self._s[3152]! } + public var Passport_Language_ja: String { return self._s[3154]! } + public var Settings_About_Title: String { return self._s[3155]! } + public var Settings_NotificationsAndSounds: String { return self._s[3156]! } + public var ChannelInfo_DeleteGroup: String { return self._s[3157]! } + public var Settings_BlockedUsers: String { return self._s[3158]! } public func Time_MonthOfYear_m4(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3154]!, self._r[3154]!, [_0]) - } - public var EditTheme_Create_Preview_OutgoingText: String { return self._s[3155]! } - public var AutoDownloadSettings_PreloadVideo: String { return self._s[3156]! } - public var Passport_Address_AddResidentialAddress: String { return self._s[3157]! } - public var Channel_Username_Title: String { return self._s[3158]! } - public func Notification_RemovedGroupPhoto(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[3159]!, self._r[3159]!, [_0]) } - public var AttachmentMenu_File: String { return self._s[3161]! } - public var AppleWatch_Title: String { return self._s[3162]! } - public var Activity_RecordingVideoMessage: String { return self._s[3163]! } + public var EditTheme_Create_Preview_OutgoingText: String { return self._s[3160]! } + public var AutoDownloadSettings_PreloadVideo: String { return self._s[3161]! } + public var Passport_Address_AddResidentialAddress: String { return self._s[3162]! } + public var Channel_Username_Title: String { return self._s[3163]! } + public func Notification_RemovedGroupPhoto(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3164]!, self._r[3164]!, [_0]) + } + public var AttachmentMenu_File: String { return self._s[3166]! } + public var AppleWatch_Title: String { return self._s[3167]! } + public var Activity_RecordingVideoMessage: String { return self._s[3168]! } public func Channel_DiscussionGroup_PublicChannelLink(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3164]!, self._r[3164]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3169]!, self._r[3169]!, [_1, _2]) } - public var Weekday_Saturday: String { return self._s[3165]! } - public var WallpaperPreview_SwipeColorsTopText: String { return self._s[3166]! } - public var Profile_CreateEncryptedChatError: String { return self._s[3167]! } - public var Common_Next: String { return self._s[3169]! } - public var Channel_Stickers_YourStickers: String { return self._s[3171]! } - public var Message_Theme: String { return self._s[3172]! } - public var Call_AudioRouteHeadphones: String { return self._s[3173]! } - public var TwoStepAuth_EnterPasswordForgot: String { return self._s[3175]! } - public var Watch_Contacts_NoResults: String { return self._s[3177]! } - public var PhotoEditor_TintTool: String { return self._s[3180]! } - public var LoginPassword_ResetAccount: String { return self._s[3182]! } - public var Settings_SavedMessages: String { return self._s[3183]! } - public var SettingsSearch_Synonyms_Appearance_Animations: String { return self._s[3184]! } - public var Bot_GenericSupportStatus: String { return self._s[3185]! } - public var StickerPack_Add: String { return self._s[3186]! } - public var Checkout_TotalAmount: String { return self._s[3187]! } - public var Your_cards_number_is_invalid: String { return self._s[3188]! } - public var SettingsSearch_Synonyms_Appearance_AutoNightTheme: String { return self._s[3189]! } - public var VoiceOver_Chat_VideoMessage: String { return self._s[3190]! } + public var Weekday_Saturday: String { return self._s[3170]! } + public var WallpaperPreview_SwipeColorsTopText: String { return self._s[3171]! } + public var Profile_CreateEncryptedChatError: String { return self._s[3172]! } + public var Common_Next: String { return self._s[3174]! } + public var Channel_Stickers_YourStickers: String { return self._s[3176]! } + public var Message_Theme: String { return self._s[3177]! } + public var Call_AudioRouteHeadphones: String { return self._s[3178]! } + public var TwoStepAuth_EnterPasswordForgot: String { return self._s[3180]! } + public var Watch_Contacts_NoResults: String { return self._s[3182]! } + public var PhotoEditor_TintTool: String { return self._s[3185]! } + public var LoginPassword_ResetAccount: String { return self._s[3187]! } + public var Settings_SavedMessages: String { return self._s[3188]! } + public var SettingsSearch_Synonyms_Appearance_Animations: String { return self._s[3189]! } + public var Bot_GenericSupportStatus: String { return self._s[3190]! } + public var StickerPack_Add: String { return self._s[3191]! } + public var Checkout_TotalAmount: String { return self._s[3192]! } + public var Your_cards_number_is_invalid: String { return self._s[3193]! } + public var SettingsSearch_Synonyms_Appearance_AutoNightTheme: String { return self._s[3194]! } + public var VoiceOver_Chat_VideoMessage: String { return self._s[3195]! } public func ChangePhoneNumberCode_CallTimer(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3191]!, self._r[3191]!, [_0]) - } - public func GroupPermission_AddedInfo(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3192]!, self._r[3192]!, [_1, _2]) - } - public var ChatSettings_ConnectionType_UseSocks5: String { return self._s[3193]! } - public func PUSH_CHAT_PHOTO_EDITED(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3195]!, self._r[3195]!, [_1, _2]) - } - public func Conversation_RestrictedTextTimed(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[3196]!, self._r[3196]!, [_0]) } - public var GroupInfo_InviteLink_ShareLink: String { return self._s[3197]! } - public var StickerPack_Share: String { return self._s[3198]! } - public var Passport_DeleteAddress: String { return self._s[3199]! } - public var Settings_Passport: String { return self._s[3200]! } - public var SharedMedia_EmptyFilesText: String { return self._s[3201]! } - public var Conversation_DeleteMessagesForMe: String { return self._s[3202]! } - public var PasscodeSettings_AutoLock_IfAwayFor_1hour: String { return self._s[3203]! } - public var Contacts_PermissionsText: String { return self._s[3204]! } - public var Group_Setup_HistoryVisible: String { return self._s[3205]! } - public var Passport_Address_AddRentalAgreement: String { return self._s[3207]! } - public var SocksProxySetup_Title: String { return self._s[3208]! } - public var Notification_Mute1h: String { return self._s[3209]! } + public func GroupPermission_AddedInfo(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3197]!, self._r[3197]!, [_1, _2]) + } + public var ChatSettings_ConnectionType_UseSocks5: String { return self._s[3198]! } + public func PUSH_CHAT_PHOTO_EDITED(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3200]!, self._r[3200]!, [_1, _2]) + } + public func Conversation_RestrictedTextTimed(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3201]!, self._r[3201]!, [_0]) + } + public var GroupInfo_InviteLink_ShareLink: String { return self._s[3202]! } + public var StickerPack_Share: String { return self._s[3203]! } + public var Passport_DeleteAddress: String { return self._s[3204]! } + public var Settings_Passport: String { return self._s[3205]! } + public var SharedMedia_EmptyFilesText: String { return self._s[3206]! } + public var Conversation_DeleteMessagesForMe: String { return self._s[3207]! } + public var PasscodeSettings_AutoLock_IfAwayFor_1hour: String { return self._s[3208]! } + public var Contacts_PermissionsText: String { return self._s[3209]! } + public var Group_Setup_HistoryVisible: String { return self._s[3210]! } + public var Passport_Address_AddRentalAgreement: String { return self._s[3212]! } + public var SocksProxySetup_Title: String { return self._s[3213]! } + public var Notification_Mute1h: String { return self._s[3214]! } public func Passport_Email_CodeHelp(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3210]!, self._r[3210]!, [_0]) + return formatWithArgumentRanges(self._s[3215]!, self._r[3215]!, [_0]) } - public var NotificationSettings_ShowNotificationsAllAccountsInfoOff: String { return self._s[3212]! } + public var NotificationSettings_ShowNotificationsAllAccountsInfoOff: String { return self._s[3217]! } public func PUSH_PINNED_GEOLIVE(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3213]!, self._r[3213]!, [_1]) + return formatWithArgumentRanges(self._s[3218]!, self._r[3218]!, [_1]) } - public var FastTwoStepSetup_PasswordSection: String { return self._s[3214]! } - public var NetworkUsageSettings_ResetStatsConfirmation: String { return self._s[3217]! } - public var InfoPlist_NSFaceIDUsageDescription: String { return self._s[3219]! } - public var DialogList_NoMessagesText: String { return self._s[3220]! } - public var Privacy_ContactsResetConfirmation: String { return self._s[3221]! } - public var Privacy_Calls_P2PHelp: String { return self._s[3222]! } - public var Channel_DiscussionGroup_SearchPlaceholder: String { return self._s[3224]! } - public var Your_cards_expiration_year_is_invalid: String { return self._s[3225]! } - public var Common_TakePhotoOrVideo: String { return self._s[3226]! } - public var Wallet_Words_Text: String { return self._s[3227]! } - public var Call_StatusBusy: String { return self._s[3228]! } - public var Conversation_PinnedMessage: String { return self._s[3229]! } - public var AutoDownloadSettings_VoiceMessagesTitle: String { return self._s[3230]! } - public var TwoStepAuth_SetupPasswordConfirmFailed: String { return self._s[3231]! } - public var Undo_ChatCleared: String { return self._s[3232]! } - public var AppleWatch_ReplyPresets: String { return self._s[3233]! } - public var Passport_DiscardMessageDescription: String { return self._s[3235]! } - public var Login_NetworkError: String { return self._s[3236]! } + public var FastTwoStepSetup_PasswordSection: String { return self._s[3219]! } + public var NetworkUsageSettings_ResetStatsConfirmation: String { return self._s[3222]! } + public var InfoPlist_NSFaceIDUsageDescription: String { return self._s[3224]! } + public var DialogList_NoMessagesText: String { return self._s[3225]! } + public var Privacy_ContactsResetConfirmation: String { return self._s[3226]! } + public var Privacy_Calls_P2PHelp: String { return self._s[3227]! } + public var Channel_DiscussionGroup_SearchPlaceholder: String { return self._s[3229]! } + public var Your_cards_expiration_year_is_invalid: String { return self._s[3230]! } + public var Common_TakePhotoOrVideo: String { return self._s[3231]! } + public var Wallet_Words_Text: String { return self._s[3232]! } + public var Call_StatusBusy: String { return self._s[3233]! } + public var Conversation_PinnedMessage: String { return self._s[3234]! } + public var AutoDownloadSettings_VoiceMessagesTitle: String { return self._s[3235]! } + public var TwoStepAuth_SetupPasswordConfirmFailed: String { return self._s[3236]! } + public var Undo_ChatCleared: String { return self._s[3237]! } + public var AppleWatch_ReplyPresets: String { return self._s[3238]! } + public var Passport_DiscardMessageDescription: String { return self._s[3240]! } + public var Login_NetworkError: String { return self._s[3241]! } public func Notification_PinnedRoundMessage(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3237]!, self._r[3237]!, [_0]) + return formatWithArgumentRanges(self._s[3242]!, self._r[3242]!, [_0]) } public func Channel_AdminLog_MessageRemovedChannelUsername(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3238]!, self._r[3238]!, [_0]) + return formatWithArgumentRanges(self._s[3243]!, self._r[3243]!, [_0]) } - public var SocksProxySetup_PasswordPlaceholder: String { return self._s[3239]! } - public var Wallet_WordCheck_ViewWords: String { return self._s[3241]! } - public var Login_ResetAccountProtected_LimitExceeded: String { return self._s[3242]! } + public var SocksProxySetup_PasswordPlaceholder: String { return self._s[3244]! } + public var Wallet_WordCheck_ViewWords: String { return self._s[3246]! } + public var Login_ResetAccountProtected_LimitExceeded: String { return self._s[3247]! } public func Watch_LastSeen_YesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3244]!, self._r[3244]!, [_0]) + return formatWithArgumentRanges(self._s[3249]!, self._r[3249]!, [_0]) } - public var Call_ConnectionErrorMessage: String { return self._s[3245]! } - public var VoiceOver_Chat_Music: String { return self._s[3246]! } - public var SettingsSearch_Synonyms_Notifications_MessageNotificationsSound: String { return self._s[3247]! } - public var Compose_GroupTokenListPlaceholder: String { return self._s[3249]! } - public var ConversationMedia_Title: String { return self._s[3250]! } - public var EncryptionKey_Title: String { return self._s[3252]! } - public var TwoStepAuth_EnterPasswordTitle: String { return self._s[3253]! } - public var Notification_Exceptions_AddException: String { return self._s[3254]! } - public var PrivacySettings_BlockedPeersEmpty: String { return self._s[3255]! } - public var Profile_MessageLifetime1m: String { return self._s[3256]! } + public var Call_ConnectionErrorMessage: String { return self._s[3250]! } + public var VoiceOver_Chat_Music: String { return self._s[3251]! } + public var SettingsSearch_Synonyms_Notifications_MessageNotificationsSound: String { return self._s[3252]! } + public var Compose_GroupTokenListPlaceholder: String { return self._s[3254]! } + public var ConversationMedia_Title: String { return self._s[3255]! } + public var EncryptionKey_Title: String { return self._s[3257]! } + public var TwoStepAuth_EnterPasswordTitle: String { return self._s[3258]! } + public var Notification_Exceptions_AddException: String { return self._s[3259]! } + public var PrivacySettings_BlockedPeersEmpty: String { return self._s[3260]! } + public var Profile_MessageLifetime1m: String { return self._s[3261]! } public func Channel_AdminLog_MessageUnkickedName(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3257]!, self._r[3257]!, [_1]) + return formatWithArgumentRanges(self._s[3262]!, self._r[3262]!, [_1]) } - public var Month_GenMay: String { return self._s[3258]! } + public var Month_GenMay: String { return self._s[3263]! } public func LiveLocationUpdated_TodayAt(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3259]!, self._r[3259]!, [_0]) + return formatWithArgumentRanges(self._s[3264]!, self._r[3264]!, [_0]) } - public var PeopleNearby_Users: String { return self._s[3260]! } - public var Wallet_Send_AddressInfo: String { return self._s[3261]! } - public var ChannelMembers_WhoCanAddMembersAllHelp: String { return self._s[3262]! } - public var AutoDownloadSettings_ResetSettings: String { return self._s[3263]! } - public var Conversation_EmptyPlaceholder: String { return self._s[3265]! } - public var Passport_Address_AddPassportRegistration: String { return self._s[3266]! } - public var Notifications_ChannelNotificationsAlert: String { return self._s[3267]! } - public var ChatSettings_AutoDownloadUsingCellular: String { return self._s[3268]! } - public var Camera_TapAndHoldForVideo: String { return self._s[3269]! } - public var Channel_JoinChannel: String { return self._s[3271]! } - public var Appearance_Animations: String { return self._s[3274]! } + public var PeopleNearby_Users: String { return self._s[3265]! } + public var Wallet_Send_AddressInfo: String { return self._s[3266]! } + public var ChannelMembers_WhoCanAddMembersAllHelp: String { return self._s[3267]! } + public var AutoDownloadSettings_ResetSettings: String { return self._s[3268]! } + public var Conversation_EmptyPlaceholder: String { return self._s[3270]! } + public var Passport_Address_AddPassportRegistration: String { return self._s[3271]! } + public var Notifications_ChannelNotificationsAlert: String { return self._s[3272]! } + public var ChatSettings_AutoDownloadUsingCellular: String { return self._s[3273]! } + public var Camera_TapAndHoldForVideo: String { return self._s[3274]! } + public var Channel_JoinChannel: String { return self._s[3276]! } + public var Appearance_Animations: String { return self._s[3279]! } public func Notification_MessageLifetimeChanged(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3275]!, self._r[3275]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3280]!, self._r[3280]!, [_1, _2]) } - public var Stickers_GroupStickers: String { return self._s[3277]! } - public var Appearance_ShareTheme: String { return self._s[3278]! } - public var ConvertToSupergroup_HelpTitle: String { return self._s[3280]! } - public var Passport_Address_Street: String { return self._s[3281]! } - public var Conversation_AddContact: String { return self._s[3282]! } - public var Login_PhonePlaceholder: String { return self._s[3283]! } - public var Channel_Members_InviteLink: String { return self._s[3285]! } - public var Bot_Stop: String { return self._s[3286]! } - public var SettingsSearch_Synonyms_Proxy_UseForCalls: String { return self._s[3288]! } - public var Notification_PassportValueAddress: String { return self._s[3289]! } - public var Month_ShortJuly: String { return self._s[3290]! } - public var Passport_Address_TypeTemporaryRegistrationUploadScan: String { return self._s[3291]! } - public var Channel_AdminLog_BanSendMedia: String { return self._s[3292]! } - public var Passport_Identity_ReverseSide: String { return self._s[3293]! } - public var Watch_Stickers_Recents: String { return self._s[3296]! } - public var PrivacyLastSeenSettings_EmpryUsersPlaceholder: String { return self._s[3298]! } - public var Map_SendThisLocation: String { return self._s[3299]! } + public var Stickers_GroupStickers: String { return self._s[3282]! } + public var Appearance_ShareTheme: String { return self._s[3283]! } + public var ConvertToSupergroup_HelpTitle: String { return self._s[3285]! } + public var Passport_Address_Street: String { return self._s[3286]! } + public var Conversation_AddContact: String { return self._s[3287]! } + public var Login_PhonePlaceholder: String { return self._s[3288]! } + public var Channel_Members_InviteLink: String { return self._s[3290]! } + public var Bot_Stop: String { return self._s[3291]! } + public var SettingsSearch_Synonyms_Proxy_UseForCalls: String { return self._s[3293]! } + public var Notification_PassportValueAddress: String { return self._s[3294]! } + public var Month_ShortJuly: String { return self._s[3295]! } + public var Passport_Address_TypeTemporaryRegistrationUploadScan: String { return self._s[3296]! } + public var Channel_AdminLog_BanSendMedia: String { return self._s[3297]! } + public var Passport_Identity_ReverseSide: String { return self._s[3298]! } + public var Watch_Stickers_Recents: String { return self._s[3301]! } + public var PrivacyLastSeenSettings_EmpryUsersPlaceholder: String { return self._s[3303]! } + public var Map_SendThisLocation: String { return self._s[3304]! } public func Time_MonthOfYear_m1(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3300]!, self._r[3300]!, [_0]) + return formatWithArgumentRanges(self._s[3305]!, self._r[3305]!, [_0]) } public func InviteText_SingleContact(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3301]!, self._r[3301]!, [_0]) + return formatWithArgumentRanges(self._s[3306]!, self._r[3306]!, [_0]) } - public var ConvertToSupergroup_Note: String { return self._s[3302]! } - public var Wallet_Intro_NotNow: String { return self._s[3303]! } + public var ConvertToSupergroup_Note: String { return self._s[3307]! } + public var Wallet_Intro_NotNow: String { return self._s[3308]! } public func FileSize_MB(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3304]!, self._r[3304]!, [_0]) + return formatWithArgumentRanges(self._s[3309]!, self._r[3309]!, [_0]) } - public var NetworkUsageSettings_GeneralDataSection: String { return self._s[3305]! } + public var NetworkUsageSettings_GeneralDataSection: String { return self._s[3310]! } public func Compatibility_SecretMediaVersionTooLow(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3306]!, self._r[3306]!, [_0, _1]) + return formatWithArgumentRanges(self._s[3311]!, self._r[3311]!, [_0, _1]) } - public var Login_CallRequestState3: String { return self._s[3308]! } - public var Wallpaper_SearchShort: String { return self._s[3309]! } - public var SettingsSearch_Synonyms_Appearance_ColorTheme: String { return self._s[3311]! } - public var PasscodeSettings_UnlockWithFaceId: String { return self._s[3312]! } - public var Channel_BotDoesntSupportGroups: String { return self._s[3313]! } + public var Login_CallRequestState3: String { return self._s[3313]! } + public var Wallpaper_SearchShort: String { return self._s[3314]! } + public var SettingsSearch_Synonyms_Appearance_ColorTheme: String { return self._s[3316]! } + public var PasscodeSettings_UnlockWithFaceId: String { return self._s[3317]! } + public var Channel_BotDoesntSupportGroups: String { return self._s[3318]! } public func PUSH_CHAT_MESSAGE_GEOLIVE(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3314]!, self._r[3314]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3319]!, self._r[3319]!, [_1, _2]) } - public var Channel_AdminLogFilter_Title: String { return self._s[3315]! } - public var Notifications_GroupNotificationsExceptions: String { return self._s[3320]! } + public var Channel_AdminLogFilter_Title: String { return self._s[3320]! } + public var Notifications_GroupNotificationsExceptions: String { return self._s[3325]! } public func FileSize_B(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3321]!, self._r[3321]!, [_0]) + return formatWithArgumentRanges(self._s[3326]!, self._r[3326]!, [_0]) } - public var Passport_CorrectErrors: String { return self._s[3322]! } - public var VoiceOver_Chat_YourAnonymousPoll: String { return self._s[3323]! } + public var Passport_CorrectErrors: String { return self._s[3327]! } + public var VoiceOver_Chat_YourAnonymousPoll: String { return self._s[3328]! } public func Channel_MessageTitleUpdated(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3324]!, self._r[3324]!, [_0]) + return formatWithArgumentRanges(self._s[3329]!, self._r[3329]!, [_0]) } - public var Map_SendMyCurrentLocation: String { return self._s[3325]! } - public var Channel_DiscussionGroup: String { return self._s[3326]! } + public var Map_SendMyCurrentLocation: String { return self._s[3330]! } + public var Channel_DiscussionGroup: String { return self._s[3331]! } public func PUSH_PINNED_CONTACT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3327]!, self._r[3327]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3332]!, self._r[3332]!, [_1, _2]) } - public var SharedMedia_SearchNoResults: String { return self._s[3328]! } - public var Permissions_NotificationsText_v0: String { return self._s[3329]! } - public var Channel_EditAdmin_PermissionDeleteMessagesOfOthers: String { return self._s[3330]! } - public var Appearance_AppIcon: String { return self._s[3331]! } - public var Appearance_ThemePreview_ChatList_3_AuthorName: String { return self._s[3332]! } - public var LoginPassword_FloodError: String { return self._s[3333]! } - public var Group_Setup_HistoryHiddenHelp: String { return self._s[3335]! } + public var SharedMedia_SearchNoResults: String { return self._s[3333]! } + public var Permissions_NotificationsText_v0: String { return self._s[3334]! } + public var Channel_EditAdmin_PermissionDeleteMessagesOfOthers: String { return self._s[3335]! } + public var Appearance_AppIcon: String { return self._s[3336]! } + public var Appearance_ThemePreview_ChatList_3_AuthorName: String { return self._s[3337]! } + public var LoginPassword_FloodError: String { return self._s[3338]! } + public var Group_Setup_HistoryHiddenHelp: String { return self._s[3340]! } public func TwoStepAuth_PendingEmailHelp(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3336]!, self._r[3336]!, [_0]) - } - public var Passport_Language_bn: String { return self._s[3337]! } - public func DialogList_SingleUploadingPhotoSuffix(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3338]!, self._r[3338]!, [_0]) - } - public var ChatList_Context_Pin: String { return self._s[3339]! } - public func Notification_PinnedAudioMessage(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3340]!, self._r[3340]!, [_0]) - } - public func Channel_AdminLog_MessageChangedGroupStickerPack(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[3341]!, self._r[3341]!, [_0]) } - public var GroupInfo_InvitationLinkGroupFull: String { return self._s[3344]! } - public var Group_EditAdmin_PermissionChangeInfo: String { return self._s[3346]! } - public var Contacts_PermissionsAllow: String { return self._s[3347]! } - public var ReportPeer_ReasonCopyright: String { return self._s[3348]! } - public var Channel_EditAdmin_PermissinAddAdminOn: String { return self._s[3349]! } - public var WallpaperPreview_Pattern: String { return self._s[3350]! } - public var Paint_Duplicate: String { return self._s[3351]! } - public var Passport_Address_Country: String { return self._s[3352]! } - public var Notification_RenamedChannel: String { return self._s[3354]! } - public var ChatList_Context_Unmute: String { return self._s[3355]! } - public var CheckoutInfo_ErrorPostcodeInvalid: String { return self._s[3356]! } - public var Group_MessagePhotoUpdated: String { return self._s[3357]! } - public var Channel_BanUser_PermissionSendMedia: String { return self._s[3358]! } - public var Conversation_ContextMenuBan: String { return self._s[3359]! } - public var TwoStepAuth_EmailSent: String { return self._s[3360]! } - public var MessagePoll_NoVotes: String { return self._s[3361]! } - public var Passport_Language_is: String { return self._s[3362]! } - public var PeopleNearby_UsersEmpty: String { return self._s[3364]! } - public var Tour_Text5: String { return self._s[3365]! } + public var Passport_Language_bn: String { return self._s[3342]! } + public func DialogList_SingleUploadingPhotoSuffix(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3343]!, self._r[3343]!, [_0]) + } + public var ChatList_Context_Pin: String { return self._s[3344]! } + public func Notification_PinnedAudioMessage(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3345]!, self._r[3345]!, [_0]) + } + public func Channel_AdminLog_MessageChangedGroupStickerPack(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3346]!, self._r[3346]!, [_0]) + } + public var GroupInfo_InvitationLinkGroupFull: String { return self._s[3349]! } + public var Group_EditAdmin_PermissionChangeInfo: String { return self._s[3351]! } + public var Contacts_PermissionsAllow: String { return self._s[3352]! } + public var ReportPeer_ReasonCopyright: String { return self._s[3353]! } + public var Channel_EditAdmin_PermissinAddAdminOn: String { return self._s[3354]! } + public var WallpaperPreview_Pattern: String { return self._s[3355]! } + public var Paint_Duplicate: String { return self._s[3356]! } + public var Passport_Address_Country: String { return self._s[3357]! } + public var Notification_RenamedChannel: String { return self._s[3359]! } + public var ChatList_Context_Unmute: String { return self._s[3360]! } + public var CheckoutInfo_ErrorPostcodeInvalid: String { return self._s[3361]! } + public var Group_MessagePhotoUpdated: String { return self._s[3362]! } + public var Channel_BanUser_PermissionSendMedia: String { return self._s[3363]! } + public var Conversation_ContextMenuBan: String { return self._s[3364]! } + public var TwoStepAuth_EmailSent: String { return self._s[3365]! } + public var MessagePoll_NoVotes: String { return self._s[3366]! } + public var Passport_Language_is: String { return self._s[3367]! } + public var PeopleNearby_UsersEmpty: String { return self._s[3369]! } + public var Tour_Text5: String { return self._s[3370]! } public func Call_GroupFormat(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3367]!, self._r[3367]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3372]!, self._r[3372]!, [_1, _2]) } - public var Undo_SecretChatDeleted: String { return self._s[3368]! } - public var SocksProxySetup_ShareQRCode: String { return self._s[3369]! } + public var Undo_SecretChatDeleted: String { return self._s[3373]! } + public var SocksProxySetup_ShareQRCode: String { return self._s[3374]! } public func VoiceOver_Chat_Size(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3370]!, self._r[3370]!, [_0]) + return formatWithArgumentRanges(self._s[3375]!, self._r[3375]!, [_0]) } - public var LogoutOptions_ChangePhoneNumberText: String { return self._s[3371]! } - public var Paint_Edit: String { return self._s[3373]! } - public var ScheduledMessages_ReminderNotification: String { return self._s[3375]! } - public var Undo_DeletedGroup: String { return self._s[3377]! } - public var LoginPassword_ForgotPassword: String { return self._s[3378]! } - public var Wallet_WordImport_IncorrectTitle: String { return self._s[3379]! } - public var GroupInfo_GroupNamePlaceholder: String { return self._s[3380]! } + public var LogoutOptions_ChangePhoneNumberText: String { return self._s[3376]! } + public var Paint_Edit: String { return self._s[3378]! } + public var ScheduledMessages_ReminderNotification: String { return self._s[3380]! } + public var Undo_DeletedGroup: String { return self._s[3382]! } + public var LoginPassword_ForgotPassword: String { return self._s[3383]! } + public var Wallet_WordImport_IncorrectTitle: String { return self._s[3384]! } + public var GroupInfo_GroupNamePlaceholder: String { return self._s[3385]! } public func Notification_Kicked(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3381]!, self._r[3381]!, [_0, _1]) + return formatWithArgumentRanges(self._s[3386]!, self._r[3386]!, [_0, _1]) } - public var Conversation_InputTextCaptionPlaceholder: String { return self._s[3382]! } - public var AutoDownloadSettings_VideoMessagesTitle: String { return self._s[3383]! } - public var Passport_Language_uz: String { return self._s[3384]! } - public var Conversation_PinMessageAlertGroup: String { return self._s[3385]! } - public var SettingsSearch_Synonyms_Privacy_GroupsAndChannels: String { return self._s[3386]! } - public var Map_StopLiveLocation: String { return self._s[3388]! } - public var VoiceOver_MessageContextSend: String { return self._s[3390]! } - public var PasscodeSettings_Help: String { return self._s[3391]! } - public var NotificationsSound_Input: String { return self._s[3392]! } - public var Share_Title: String { return self._s[3395]! } - public var LogoutOptions_Title: String { return self._s[3396]! } - public var Wallet_Send_AddressText: String { return self._s[3397]! } - public var Login_TermsOfServiceAgree: String { return self._s[3398]! } - public var Compose_NewEncryptedChatTitle: String { return self._s[3399]! } - public var Channel_AdminLog_TitleSelectedEvents: String { return self._s[3400]! } - public var Channel_EditAdmin_PermissionEditMessages: String { return self._s[3401]! } - public var EnterPasscode_EnterTitle: String { return self._s[3402]! } + public var Conversation_InputTextCaptionPlaceholder: String { return self._s[3387]! } + public var AutoDownloadSettings_VideoMessagesTitle: String { return self._s[3388]! } + public var Passport_Language_uz: String { return self._s[3389]! } + public var Conversation_PinMessageAlertGroup: String { return self._s[3390]! } + public var SettingsSearch_Synonyms_Privacy_GroupsAndChannels: String { return self._s[3391]! } + public var Map_StopLiveLocation: String { return self._s[3393]! } + public var VoiceOver_MessageContextSend: String { return self._s[3395]! } + public var PasscodeSettings_Help: String { return self._s[3396]! } + public var NotificationsSound_Input: String { return self._s[3397]! } + public var Share_Title: String { return self._s[3400]! } + public var LogoutOptions_Title: String { return self._s[3401]! } + public var Wallet_Send_AddressText: String { return self._s[3402]! } + public var Login_TermsOfServiceAgree: String { return self._s[3403]! } + public var Compose_NewEncryptedChatTitle: String { return self._s[3404]! } + public var Channel_AdminLog_TitleSelectedEvents: String { return self._s[3405]! } + public var Channel_EditAdmin_PermissionEditMessages: String { return self._s[3406]! } + public var EnterPasscode_EnterTitle: String { return self._s[3407]! } public func Call_PrivacyErrorMessage(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3403]!, self._r[3403]!, [_0]) - } - public var Settings_CopyPhoneNumber: String { return self._s[3404]! } - public var Conversation_AddToContacts: String { return self._s[3405]! } - public func VoiceOver_Chat_ReplyFrom(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3406]!, self._r[3406]!, [_0]) - } - public var NotificationsSound_Keys: String { return self._s[3407]! } - public func Call_ParticipantVersionOutdatedError(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[3408]!, self._r[3408]!, [_0]) } - public var Notification_MessageLifetime1w: String { return self._s[3409]! } - public var Message_Video: String { return self._s[3410]! } - public var AutoDownloadSettings_CellularTitle: String { return self._s[3411]! } - public func PUSH_CHANNEL_MESSAGE_PHOTO(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3412]!, self._r[3412]!, [_1]) + public var Settings_CopyPhoneNumber: String { return self._s[3409]! } + public var Conversation_AddToContacts: String { return self._s[3410]! } + public func VoiceOver_Chat_ReplyFrom(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3411]!, self._r[3411]!, [_0]) } - public var Wallet_Receive_AmountInfo: String { return self._s[3415]! } + public var NotificationsSound_Keys: String { return self._s[3412]! } + public func Call_ParticipantVersionOutdatedError(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3413]!, self._r[3413]!, [_0]) + } + public var Notification_MessageLifetime1w: String { return self._s[3414]! } + public var Message_Video: String { return self._s[3415]! } + public var AutoDownloadSettings_CellularTitle: String { return self._s[3416]! } + public func PUSH_CHANNEL_MESSAGE_PHOTO(_ _1: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3417]!, self._r[3417]!, [_1]) + } + public var Wallet_Receive_AmountInfo: String { return self._s[3420]! } public func Notification_JoinedChat(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3416]!, self._r[3416]!, [_0]) + return formatWithArgumentRanges(self._s[3421]!, self._r[3421]!, [_0]) } public func PrivacySettings_LastSeenContactsPlus(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3417]!, self._r[3417]!, [_0]) + return formatWithArgumentRanges(self._s[3422]!, self._r[3422]!, [_0]) } - public var Passport_Language_mk: String { return self._s[3418]! } - public var CreatePoll_CancelConfirmation: String { return self._s[3419]! } - public var Conversation_SilentBroadcastTooltipOn: String { return self._s[3421]! } - public var PrivacyPolicy_Decline: String { return self._s[3422]! } - public var Passport_Identity_DoesNotExpire: String { return self._s[3423]! } - public var Channel_AdminLogFilter_EventsRestrictions: String { return self._s[3424]! } - public var Permissions_SiriAllow_v0: String { return self._s[3426]! } - public var Appearance_ThemeCarouselNight: String { return self._s[3427]! } + public var Passport_Language_mk: String { return self._s[3423]! } + public var CreatePoll_CancelConfirmation: String { return self._s[3424]! } + public var Conversation_SilentBroadcastTooltipOn: String { return self._s[3426]! } + public var PrivacyPolicy_Decline: String { return self._s[3427]! } + public var Passport_Identity_DoesNotExpire: String { return self._s[3428]! } + public var Channel_AdminLogFilter_EventsRestrictions: String { return self._s[3429]! } + public var Permissions_SiriAllow_v0: String { return self._s[3431]! } + public var Appearance_ThemeCarouselNight: String { return self._s[3432]! } public func LOCAL_CHAT_MESSAGE_FWDS(_ _1: String, _ _2: Int) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3428]!, self._r[3428]!, [_1, "\(_2)"]) + return formatWithArgumentRanges(self._s[3433]!, self._r[3433]!, [_1, "\(_2)"]) } public func Notification_RenamedChat(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3429]!, self._r[3429]!, [_0]) + return formatWithArgumentRanges(self._s[3434]!, self._r[3434]!, [_0]) } - public var Paint_Regular: String { return self._s[3430]! } - public var ChatSettings_AutoDownloadReset: String { return self._s[3431]! } - public var SocksProxySetup_ShareLink: String { return self._s[3432]! } - public var Wallet_Qr_Title: String { return self._s[3433]! } - public var BlockedUsers_SelectUserTitle: String { return self._s[3434]! } - public var VoiceOver_Chat_RecordModeVoiceMessage: String { return self._s[3436]! } - public var GroupInfo_InviteByLink: String { return self._s[3437]! } - public var MessageTimer_Custom: String { return self._s[3438]! } - public var UserInfo_NotificationsDefaultEnabled: String { return self._s[3439]! } - public var Passport_Address_TypeTemporaryRegistration: String { return self._s[3441]! } - public var Conversation_SendMessage_SetReminder: String { return self._s[3442]! } - public var VoiceOver_Chat_Selected: String { return self._s[3443]! } - public var ChatSettings_AutoDownloadUsingWiFi: String { return self._s[3444]! } - public var Channel_Username_InvalidTaken: String { return self._s[3445]! } - public var Conversation_ClousStorageInfo_Description3: String { return self._s[3446]! } - public var Wallet_WordCheck_TryAgain: String { return self._s[3447]! } - public var Settings_ChatBackground: String { return self._s[3448]! } - public var Channel_Subscribers_Title: String { return self._s[3449]! } - public var Wallet_Receive_InvoiceUrlHeader: String { return self._s[3450]! } - public var ApplyLanguage_ChangeLanguageTitle: String { return self._s[3451]! } - public var Watch_ConnectionDescription: String { return self._s[3452]! } - public var ChatList_ArchivedChatsTitle: String { return self._s[3456]! } - public var Wallpaper_ResetWallpapers: String { return self._s[3457]! } - public var EditProfile_Title: String { return self._s[3458]! } - public var NotificationsSound_Bamboo: String { return self._s[3460]! } - public var Channel_AdminLog_MessagePreviousMessage: String { return self._s[3462]! } - public var Login_SmsRequestState2: String { return self._s[3463]! } - public var Passport_Language_ar: String { return self._s[3464]! } + public var Paint_Regular: String { return self._s[3435]! } + public var ChatSettings_AutoDownloadReset: String { return self._s[3436]! } + public var SocksProxySetup_ShareLink: String { return self._s[3437]! } + public var Wallet_Qr_Title: String { return self._s[3438]! } + public var BlockedUsers_SelectUserTitle: String { return self._s[3439]! } + public var VoiceOver_Chat_RecordModeVoiceMessage: String { return self._s[3441]! } + public var GroupInfo_InviteByLink: String { return self._s[3442]! } + public var MessageTimer_Custom: String { return self._s[3443]! } + public var UserInfo_NotificationsDefaultEnabled: String { return self._s[3444]! } + public var Passport_Address_TypeTemporaryRegistration: String { return self._s[3446]! } + public var Conversation_SendMessage_SetReminder: String { return self._s[3447]! } + public var VoiceOver_Chat_Selected: String { return self._s[3448]! } + public var ChatSettings_AutoDownloadUsingWiFi: String { return self._s[3449]! } + public var Channel_Username_InvalidTaken: String { return self._s[3450]! } + public var Conversation_ClousStorageInfo_Description3: String { return self._s[3451]! } + public var Wallet_WordCheck_TryAgain: String { return self._s[3452]! } + public var Settings_ChatBackground: String { return self._s[3453]! } + public var Channel_Subscribers_Title: String { return self._s[3454]! } + public var Wallet_Receive_InvoiceUrlHeader: String { return self._s[3455]! } + public var ApplyLanguage_ChangeLanguageTitle: String { return self._s[3456]! } + public var Watch_ConnectionDescription: String { return self._s[3457]! } + public var ChatList_ArchivedChatsTitle: String { return self._s[3461]! } + public var Wallpaper_ResetWallpapers: String { return self._s[3462]! } + public var EditProfile_Title: String { return self._s[3463]! } + public var NotificationsSound_Bamboo: String { return self._s[3465]! } + public var Channel_AdminLog_MessagePreviousMessage: String { return self._s[3467]! } + public var Login_SmsRequestState2: String { return self._s[3468]! } + public var Passport_Language_ar: String { return self._s[3469]! } public func Message_AuthorPinnedGame(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3465]!, self._r[3465]!, [_0]) + return formatWithArgumentRanges(self._s[3470]!, self._r[3470]!, [_0]) } - public var SettingsSearch_Synonyms_EditProfile_Title: String { return self._s[3466]! } - public var Wallet_Created_Text: String { return self._s[3467]! } - public var Conversation_MessageDialogEdit: String { return self._s[3468]! } - public var Wallet_Created_Proceed: String { return self._s[3469]! } - public var Wallet_Words_Done: String { return self._s[3470]! } - public var VoiceOver_Media_PlaybackPause: String { return self._s[3471]! } + public var SettingsSearch_Synonyms_EditProfile_Title: String { return self._s[3471]! } + public var Wallet_Created_Text: String { return self._s[3472]! } + public var Conversation_MessageDialogEdit: String { return self._s[3473]! } + public var Wallet_Created_Proceed: String { return self._s[3474]! } + public var Wallet_Words_Done: String { return self._s[3475]! } + public var VoiceOver_Media_PlaybackPause: String { return self._s[3476]! } public func PUSH_AUTH_UNKNOWN(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3472]!, self._r[3472]!, [_1]) + return formatWithArgumentRanges(self._s[3477]!, self._r[3477]!, [_1]) } - public var Common_Close: String { return self._s[3473]! } - public var GroupInfo_PublicLink: String { return self._s[3474]! } - public var Channel_OwnershipTransfer_ErrorPrivacyRestricted: String { return self._s[3475]! } - public var SettingsSearch_Synonyms_Notifications_GroupNotificationsPreview: String { return self._s[3476]! } + public var Common_Close: String { return self._s[3478]! } + public var GroupInfo_PublicLink: String { return self._s[3479]! } + public var Channel_OwnershipTransfer_ErrorPrivacyRestricted: String { return self._s[3480]! } + public var SettingsSearch_Synonyms_Notifications_GroupNotificationsPreview: String { return self._s[3481]! } public func Channel_AdminLog_MessageToggleInvitesOff(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3480]!, self._r[3480]!, [_0]) + return formatWithArgumentRanges(self._s[3485]!, self._r[3485]!, [_0]) } - public var UserInfo_About_Placeholder: String { return self._s[3481]! } + public var UserInfo_About_Placeholder: String { return self._s[3486]! } public func Conversation_FileHowToText(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3482]!, self._r[3482]!, [_0]) + return formatWithArgumentRanges(self._s[3487]!, self._r[3487]!, [_0]) } - public var GroupInfo_Permissions_SectionTitle: String { return self._s[3483]! } - public var Channel_Info_Banned: String { return self._s[3485]! } + public var GroupInfo_Permissions_SectionTitle: String { return self._s[3488]! } + public var Channel_Info_Banned: String { return self._s[3490]! } public func Time_MonthOfYear_m11(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3486]!, self._r[3486]!, [_0]) + return formatWithArgumentRanges(self._s[3491]!, self._r[3491]!, [_0]) } - public var Appearance_Other: String { return self._s[3487]! } - public var Passport_Language_my: String { return self._s[3488]! } - public var Group_Setup_BasicHistoryHiddenHelp: String { return self._s[3489]! } + public var Appearance_Other: String { return self._s[3492]! } + public var Passport_Language_my: String { return self._s[3493]! } + public var Group_Setup_BasicHistoryHiddenHelp: String { return self._s[3494]! } public func Time_PreciseDate_m9(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3490]!, self._r[3490]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[3495]!, self._r[3495]!, [_1, _2, _3]) } - public var SettingsSearch_Synonyms_Privacy_PasscodeAndFaceId: String { return self._s[3491]! } - public var Preview_CopyAddress: String { return self._s[3492]! } + public var SettingsSearch_Synonyms_Privacy_PasscodeAndFaceId: String { return self._s[3496]! } + public var Preview_CopyAddress: String { return self._s[3497]! } public func DialogList_SinglePlayingGameSuffix(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3493]!, self._r[3493]!, [_0]) + return formatWithArgumentRanges(self._s[3498]!, self._r[3498]!, [_0]) } - public var KeyCommand_JumpToPreviousChat: String { return self._s[3494]! } - public var UserInfo_BotSettings: String { return self._s[3495]! } - public var LiveLocation_MenuStopAll: String { return self._s[3497]! } - public var Passport_PasswordCreate: String { return self._s[3498]! } - public var StickerSettings_MaskContextInfo: String { return self._s[3499]! } - public var Message_PinnedLocationMessage: String { return self._s[3500]! } - public var Map_Satellite: String { return self._s[3501]! } - public var Watch_Message_Unsupported: String { return self._s[3502]! } - public var Username_TooManyPublicUsernamesError: String { return self._s[3503]! } - public var TwoStepAuth_EnterPasswordInvalid: String { return self._s[3504]! } + public var KeyCommand_JumpToPreviousChat: String { return self._s[3499]! } + public var UserInfo_BotSettings: String { return self._s[3500]! } + public var LiveLocation_MenuStopAll: String { return self._s[3502]! } + public var Passport_PasswordCreate: String { return self._s[3503]! } + public var StickerSettings_MaskContextInfo: String { return self._s[3504]! } + public var Message_PinnedLocationMessage: String { return self._s[3505]! } + public var Map_Satellite: String { return self._s[3506]! } + public var Watch_Message_Unsupported: String { return self._s[3507]! } + public var Username_TooManyPublicUsernamesError: String { return self._s[3508]! } + public var TwoStepAuth_EnterPasswordInvalid: String { return self._s[3509]! } public func Notification_PinnedTextMessage(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3505]!, self._r[3505]!, [_0, _1]) + return formatWithArgumentRanges(self._s[3510]!, self._r[3510]!, [_0, _1]) } public func Conversation_OpenBotLinkText(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3506]!, self._r[3506]!, [_0]) + return formatWithArgumentRanges(self._s[3511]!, self._r[3511]!, [_0]) } - public var Wallet_WordImport_Continue: String { return self._s[3507]! } - public var Notifications_ChannelNotificationsHelp: String { return self._s[3508]! } - public var Privacy_Calls_P2PContacts: String { return self._s[3509]! } - public var NotificationsSound_None: String { return self._s[3510]! } - public var Channel_DiscussionGroup_UnlinkGroup: String { return self._s[3512]! } - public var AccessDenied_VoiceMicrophone: String { return self._s[3513]! } + public var Wallet_WordImport_Continue: String { return self._s[3512]! } + public var Notifications_ChannelNotificationsHelp: String { return self._s[3513]! } + public var Privacy_Calls_P2PContacts: String { return self._s[3514]! } + public var NotificationsSound_None: String { return self._s[3515]! } + public var Channel_DiscussionGroup_UnlinkGroup: String { return self._s[3517]! } + public var AccessDenied_VoiceMicrophone: String { return self._s[3518]! } public func ApplyLanguage_ChangeLanguageAlreadyActive(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3514]!, self._r[3514]!, [_1]) + return formatWithArgumentRanges(self._s[3519]!, self._r[3519]!, [_1]) } - public var Cache_Indexing: String { return self._s[3515]! } - public var DialogList_RecentTitlePeople: String { return self._s[3517]! } - public var DialogList_EncryptionRejected: String { return self._s[3518]! } - public var GroupInfo_Administrators: String { return self._s[3519]! } - public var Passport_ScanPassportHelp: String { return self._s[3520]! } - public var Application_Name: String { return self._s[3521]! } - public var Channel_AdminLogFilter_ChannelEventsInfo: String { return self._s[3522]! } - public var Appearance_ThemeCarouselDay: String { return self._s[3524]! } - public var Passport_Identity_TranslationHelp: String { return self._s[3525]! } + public var Cache_Indexing: String { return self._s[3520]! } + public var DialogList_RecentTitlePeople: String { return self._s[3522]! } + public var DialogList_EncryptionRejected: String { return self._s[3523]! } + public var GroupInfo_Administrators: String { return self._s[3524]! } + public var Passport_ScanPassportHelp: String { return self._s[3525]! } + public var Application_Name: String { return self._s[3526]! } + public var Channel_AdminLogFilter_ChannelEventsInfo: String { return self._s[3527]! } + public var Appearance_ThemeCarouselDay: String { return self._s[3529]! } + public var Passport_Identity_TranslationHelp: String { return self._s[3530]! } public func VoiceOver_Chat_VideoMessageFrom(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3526]!, self._r[3526]!, [_0]) + return formatWithArgumentRanges(self._s[3531]!, self._r[3531]!, [_0]) } public func Notification_JoinedGroupByLink(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3527]!, self._r[3527]!, [_0]) + return formatWithArgumentRanges(self._s[3532]!, self._r[3532]!, [_0]) } public func DialogList_EncryptedChatStartedOutgoing(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3528]!, self._r[3528]!, [_0]) + return formatWithArgumentRanges(self._s[3533]!, self._r[3533]!, [_0]) } - public var Channel_EditAdmin_PermissionDeleteMessages: String { return self._s[3529]! } - public var Privacy_ChatsTitle: String { return self._s[3530]! } - public var DialogList_ClearHistoryConfirmation: String { return self._s[3531]! } - public var SettingsSearch_Synonyms_Data_Storage_ClearCache: String { return self._s[3532]! } - public var Watch_Suggestion_HoldOn: String { return self._s[3533]! } - public var Group_EditAdmin_TransferOwnership: String { return self._s[3534]! } - public var Group_LinkedChannel: String { return self._s[3535]! } - public var VoiceOver_Chat_SeenByRecipient: String { return self._s[3536]! } - public var SocksProxySetup_RequiredCredentials: String { return self._s[3537]! } - public var Passport_Address_TypeRentalAgreementUploadScan: String { return self._s[3538]! } - public var TwoStepAuth_EmailSkipAlert: String { return self._s[3539]! } - public var ScheduledMessages_RemindersTitle: String { return self._s[3541]! } - public var Channel_Setup_TypePublic: String { return self._s[3543]! } + public var Channel_EditAdmin_PermissionDeleteMessages: String { return self._s[3534]! } + public var Privacy_ChatsTitle: String { return self._s[3535]! } + public var DialogList_ClearHistoryConfirmation: String { return self._s[3536]! } + public var SettingsSearch_Synonyms_Data_Storage_ClearCache: String { return self._s[3537]! } + public var Watch_Suggestion_HoldOn: String { return self._s[3538]! } + public var Group_EditAdmin_TransferOwnership: String { return self._s[3539]! } + public var Group_LinkedChannel: String { return self._s[3540]! } + public var VoiceOver_Chat_SeenByRecipient: String { return self._s[3541]! } + public var SocksProxySetup_RequiredCredentials: String { return self._s[3542]! } + public var Passport_Address_TypeRentalAgreementUploadScan: String { return self._s[3543]! } + public var TwoStepAuth_EmailSkipAlert: String { return self._s[3544]! } + public var ScheduledMessages_RemindersTitle: String { return self._s[3546]! } + public var Channel_Setup_TypePublic: String { return self._s[3548]! } public func Channel_AdminLog_MessageToggleInvitesOn(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3544]!, self._r[3544]!, [_0]) + return formatWithArgumentRanges(self._s[3549]!, self._r[3549]!, [_0]) } - public var Channel_TypeSetup_Title: String { return self._s[3546]! } - public var Map_OpenInMaps: String { return self._s[3548]! } + public var Channel_TypeSetup_Title: String { return self._s[3551]! } + public var Map_OpenInMaps: String { return self._s[3553]! } public func PUSH_PINNED_NOTEXT(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3549]!, self._r[3549]!, [_1]) + return formatWithArgumentRanges(self._s[3554]!, self._r[3554]!, [_1]) } - public var NotificationsSound_Tremolo: String { return self._s[3551]! } + public var NotificationsSound_Tremolo: String { return self._s[3556]! } public func Date_ChatDateHeaderYear(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3552]!, self._r[3552]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[3557]!, self._r[3557]!, [_1, _2, _3]) } - public var ConversationProfile_UnknownAddMemberError: String { return self._s[3553]! } - public var Channel_OwnershipTransfer_PasswordPlaceholder: String { return self._s[3554]! } - public var Passport_PasswordHelp: String { return self._s[3555]! } - public var Login_CodeExpiredError: String { return self._s[3556]! } - public var Channel_EditAdmin_PermissionChangeInfo: String { return self._s[3557]! } - public var Conversation_TitleUnmute: String { return self._s[3558]! } - public var Passport_Identity_ScansHelp: String { return self._s[3559]! } - public var Passport_Language_lo: String { return self._s[3560]! } - public var Camera_FlashAuto: String { return self._s[3561]! } - public var Conversation_OpenBotLinkOpen: String { return self._s[3562]! } - public var Common_Cancel: String { return self._s[3563]! } - public var DialogList_SavedMessagesTooltip: String { return self._s[3564]! } - public var TwoStepAuth_SetupPasswordTitle: String { return self._s[3565]! } - public var Appearance_TintAllColors: String { return self._s[3566]! } + public var ConversationProfile_UnknownAddMemberError: String { return self._s[3558]! } + public var Channel_OwnershipTransfer_PasswordPlaceholder: String { return self._s[3559]! } + public var Passport_PasswordHelp: String { return self._s[3560]! } + public var Login_CodeExpiredError: String { return self._s[3561]! } + public var Channel_EditAdmin_PermissionChangeInfo: String { return self._s[3562]! } + public var Conversation_TitleUnmute: String { return self._s[3563]! } + public var Passport_Identity_ScansHelp: String { return self._s[3564]! } + public var Passport_Language_lo: String { return self._s[3565]! } + public var Camera_FlashAuto: String { return self._s[3566]! } + public var Conversation_OpenBotLinkOpen: String { return self._s[3567]! } + public var Common_Cancel: String { return self._s[3568]! } + public var DialogList_SavedMessagesTooltip: String { return self._s[3569]! } + public var TwoStepAuth_SetupPasswordTitle: String { return self._s[3570]! } + public var Appearance_TintAllColors: String { return self._s[3571]! } public func PUSH_MESSAGE_FWD(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3567]!, self._r[3567]!, [_1]) + return formatWithArgumentRanges(self._s[3572]!, self._r[3572]!, [_1]) } - public var Conversation_ReportSpamConfirmation: String { return self._s[3568]! } - public var ChatSettings_Title: String { return self._s[3570]! } - public var Passport_PasswordReset: String { return self._s[3571]! } - public var SocksProxySetup_TypeNone: String { return self._s[3572]! } - public var EditTheme_Title: String { return self._s[3574]! } - public var PhoneNumberHelp_Help: String { return self._s[3575]! } - public var Checkout_EnterPassword: String { return self._s[3576]! } - public var Share_AuthTitle: String { return self._s[3578]! } - public var Activity_UploadingDocument: String { return self._s[3579]! } - public var State_Connecting: String { return self._s[3580]! } - public var Profile_MessageLifetime1w: String { return self._s[3581]! } - public var Conversation_ContextMenuReport: String { return self._s[3582]! } - public var CheckoutInfo_ReceiverInfoPhone: String { return self._s[3583]! } - public var AutoNightTheme_ScheduledTo: String { return self._s[3584]! } + public var Conversation_ReportSpamConfirmation: String { return self._s[3573]! } + public var ChatSettings_Title: String { return self._s[3575]! } + public var Passport_PasswordReset: String { return self._s[3576]! } + public var SocksProxySetup_TypeNone: String { return self._s[3577]! } + public var EditTheme_Title: String { return self._s[3579]! } + public var PhoneNumberHelp_Help: String { return self._s[3580]! } + public var Checkout_EnterPassword: String { return self._s[3581]! } + public var Share_AuthTitle: String { return self._s[3583]! } + public var Activity_UploadingDocument: String { return self._s[3584]! } + public var State_Connecting: String { return self._s[3585]! } + public var Profile_MessageLifetime1w: String { return self._s[3586]! } + public var Conversation_ContextMenuReport: String { return self._s[3587]! } + public var CheckoutInfo_ReceiverInfoPhone: String { return self._s[3588]! } + public var AutoNightTheme_ScheduledTo: String { return self._s[3589]! } public func VoiceOver_Chat_AnonymousPollFrom(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3585]!, self._r[3585]!, [_0]) + return formatWithArgumentRanges(self._s[3590]!, self._r[3590]!, [_0]) } - public var AuthSessions_Terminate: String { return self._s[3586]! } - public var Wallet_WordImport_CanNotRemember: String { return self._s[3587]! } - public var Checkout_NewCard_CardholderNamePlaceholder: String { return self._s[3588]! } - public var KeyCommand_JumpToPreviousUnreadChat: String { return self._s[3589]! } - public var PhotoEditor_Set: String { return self._s[3590]! } - public var EmptyGroupInfo_Title: String { return self._s[3591]! } - public var Login_PadPhoneHelp: String { return self._s[3592]! } - public var AutoDownloadSettings_TypeGroupChats: String { return self._s[3595]! } - public var PrivacyPolicy_DeclineLastWarning: String { return self._s[3597]! } - public var NotificationsSound_Complete: String { return self._s[3598]! } - public var SettingsSearch_Synonyms_Privacy_Data_Title: String { return self._s[3599]! } - public var Group_Info_AdminLog: String { return self._s[3600]! } - public var GroupPermission_NotAvailableInPublicGroups: String { return self._s[3601]! } - public var Channel_AdminLog_InfoPanelAlertText: String { return self._s[3602]! } - public var Conversation_Admin: String { return self._s[3604]! } - public var Conversation_GifTooltip: String { return self._s[3605]! } - public var Passport_NotLoggedInMessage: String { return self._s[3606]! } + public var AuthSessions_Terminate: String { return self._s[3591]! } + public var Wallet_WordImport_CanNotRemember: String { return self._s[3592]! } + public var Checkout_NewCard_CardholderNamePlaceholder: String { return self._s[3593]! } + public var KeyCommand_JumpToPreviousUnreadChat: String { return self._s[3594]! } + public var PhotoEditor_Set: String { return self._s[3595]! } + public var EmptyGroupInfo_Title: String { return self._s[3596]! } + public var Login_PadPhoneHelp: String { return self._s[3597]! } + public var AutoDownloadSettings_TypeGroupChats: String { return self._s[3600]! } + public var PrivacyPolicy_DeclineLastWarning: String { return self._s[3602]! } + public var NotificationsSound_Complete: String { return self._s[3603]! } + public var SettingsSearch_Synonyms_Privacy_Data_Title: String { return self._s[3604]! } + public var Group_Info_AdminLog: String { return self._s[3605]! } + public var GroupPermission_NotAvailableInPublicGroups: String { return self._s[3606]! } + public var Channel_AdminLog_InfoPanelAlertText: String { return self._s[3607]! } + public var Conversation_Admin: String { return self._s[3609]! } + public var Conversation_GifTooltip: String { return self._s[3610]! } + public var Passport_NotLoggedInMessage: String { return self._s[3611]! } public func AutoDownloadSettings_OnFor(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3608]!, self._r[3608]!, [_0]) + return formatWithArgumentRanges(self._s[3613]!, self._r[3613]!, [_0]) } - public var Profile_MessageLifetimeForever: String { return self._s[3609]! } - public var SharedMedia_EmptyTitle: String { return self._s[3611]! } - public var Channel_Edit_PrivatePublicLinkAlert: String { return self._s[3613]! } - public var Username_Help: String { return self._s[3614]! } - public var DialogList_LanguageTooltip: String { return self._s[3616]! } - public var Map_LoadError: String { return self._s[3617]! } - public var Login_PhoneNumberAlreadyAuthorized: String { return self._s[3618]! } - public var Channel_AdminLog_AddMembers: String { return self._s[3619]! } - public var ArchivedChats_IntroTitle2: String { return self._s[3620]! } - public var Notification_Exceptions_NewException: String { return self._s[3621]! } - public var TwoStepAuth_EmailTitle: String { return self._s[3622]! } - public var WatchRemote_AlertText: String { return self._s[3623]! } + public var Profile_MessageLifetimeForever: String { return self._s[3614]! } + public var SharedMedia_EmptyTitle: String { return self._s[3616]! } + public var Channel_Edit_PrivatePublicLinkAlert: String { return self._s[3618]! } + public var Username_Help: String { return self._s[3619]! } + public var DialogList_LanguageTooltip: String { return self._s[3621]! } + public var Map_LoadError: String { return self._s[3622]! } + public var Login_PhoneNumberAlreadyAuthorized: String { return self._s[3623]! } + public var Channel_AdminLog_AddMembers: String { return self._s[3624]! } + public var ArchivedChats_IntroTitle2: String { return self._s[3625]! } + public var Notification_Exceptions_NewException: String { return self._s[3626]! } + public var TwoStepAuth_EmailTitle: String { return self._s[3627]! } + public var WatchRemote_AlertText: String { return self._s[3628]! } public func Wallet_Send_ConfirmationText(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3624]!, self._r[3624]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3629]!, self._r[3629]!, [_1, _2]) } - public var ChatSettings_ConnectionType_Title: String { return self._s[3627]! } + public var ChatSettings_ConnectionType_Title: String { return self._s[3632]! } public func Settings_CheckPhoneNumberTitle(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3628]!, self._r[3628]!, [_0]) + return formatWithArgumentRanges(self._s[3633]!, self._r[3633]!, [_0]) } - public var SettingsSearch_Synonyms_Calls_CallTab: String { return self._s[3629]! } - public var Passport_Address_CountryPlaceholder: String { return self._s[3630]! } + public var SettingsSearch_Synonyms_Calls_CallTab: String { return self._s[3634]! } + public var Passport_Address_CountryPlaceholder: String { return self._s[3635]! } public func DialogList_AwaitingEncryption(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3631]!, self._r[3631]!, [_0]) + return formatWithArgumentRanges(self._s[3636]!, self._r[3636]!, [_0]) } public func Time_PreciseDate_m6(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3632]!, self._r[3632]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[3637]!, self._r[3637]!, [_1, _2, _3]) } - public var Group_AdminLog_EmptyText: String { return self._s[3633]! } - public var SettingsSearch_Synonyms_Appearance_Title: String { return self._s[3634]! } - public var Conversation_PrivateChannelTooltip: String { return self._s[3636]! } - public var Wallet_Created_ExportErrorText: String { return self._s[3637]! } - public var ChatList_UndoArchiveText1: String { return self._s[3638]! } - public var AccessDenied_VideoMicrophone: String { return self._s[3639]! } - public var Conversation_ContextMenuStickerPackAdd: String { return self._s[3640]! } - public var Cache_ClearNone: String { return self._s[3641]! } - public var SocksProxySetup_FailedToConnect: String { return self._s[3642]! } - public var Permissions_NotificationsTitle_v0: String { return self._s[3643]! } + public var Group_AdminLog_EmptyText: String { return self._s[3638]! } + public var SettingsSearch_Synonyms_Appearance_Title: String { return self._s[3639]! } + public var Conversation_PrivateChannelTooltip: String { return self._s[3641]! } + public var Wallet_Created_ExportErrorText: String { return self._s[3642]! } + public var ChatList_UndoArchiveText1: String { return self._s[3643]! } + public var AccessDenied_VideoMicrophone: String { return self._s[3644]! } + public var Conversation_ContextMenuStickerPackAdd: String { return self._s[3645]! } + public var Cache_ClearNone: String { return self._s[3646]! } + public var SocksProxySetup_FailedToConnect: String { return self._s[3647]! } + public var Permissions_NotificationsTitle_v0: String { return self._s[3648]! } public func Channel_AdminLog_MessageEdited(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3644]!, self._r[3644]!, [_0]) + return formatWithArgumentRanges(self._s[3649]!, self._r[3649]!, [_0]) } - public var Passport_Identity_Country: String { return self._s[3645]! } + public var Passport_Identity_Country: String { return self._s[3650]! } public func ChatSettings_AutoDownloadSettings_TypeFile(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3646]!, self._r[3646]!, [_0]) + return formatWithArgumentRanges(self._s[3651]!, self._r[3651]!, [_0]) } public func Notification_CreatedChat(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3647]!, self._r[3647]!, [_0]) + return formatWithArgumentRanges(self._s[3652]!, self._r[3652]!, [_0]) } - public var Exceptions_AddToExceptions: String { return self._s[3648]! } - public var AccessDenied_Settings: String { return self._s[3649]! } - public var Passport_Address_TypeUtilityBillUploadScan: String { return self._s[3650]! } - public var Month_ShortMay: String { return self._s[3651]! } - public var Compose_NewGroup: String { return self._s[3653]! } - public var Group_Setup_TypePrivate: String { return self._s[3655]! } - public var Login_PadPhoneHelpTitle: String { return self._s[3657]! } - public var Appearance_ThemeDayClassic: String { return self._s[3658]! } - public var Channel_AdminLog_MessagePreviousCaption: String { return self._s[3659]! } - public var AutoDownloadSettings_OffForAll: String { return self._s[3660]! } - public var Privacy_GroupsAndChannels_WhoCanAddMe: String { return self._s[3661]! } - public var Conversation_typing: String { return self._s[3663]! } - public var Undo_ScheduledMessagesCleared: String { return self._s[3664]! } - public var Paint_Masks: String { return self._s[3665]! } - public var Contacts_DeselectAll: String { return self._s[3666]! } - public var Username_InvalidTaken: String { return self._s[3667]! } - public var Call_StatusNoAnswer: String { return self._s[3668]! } - public var TwoStepAuth_EmailAddSuccess: String { return self._s[3669]! } - public var SettingsSearch_Synonyms_Privacy_BlockedUsers: String { return self._s[3670]! } - public var Passport_Identity_Selfie: String { return self._s[3671]! } - public var Login_InfoLastNamePlaceholder: String { return self._s[3672]! } - public var Privacy_SecretChatsLinkPreviewsHelp: String { return self._s[3673]! } - public var Conversation_ClearSecretHistory: String { return self._s[3674]! } - public var PeopleNearby_Description: String { return self._s[3676]! } - public var NetworkUsageSettings_Title: String { return self._s[3677]! } - public var Your_cards_security_code_is_invalid: String { return self._s[3679]! } + public var Exceptions_AddToExceptions: String { return self._s[3653]! } + public var AccessDenied_Settings: String { return self._s[3654]! } + public var Passport_Address_TypeUtilityBillUploadScan: String { return self._s[3655]! } + public var Month_ShortMay: String { return self._s[3656]! } + public var Compose_NewGroup: String { return self._s[3658]! } + public var Group_Setup_TypePrivate: String { return self._s[3660]! } + public var Login_PadPhoneHelpTitle: String { return self._s[3662]! } + public var Appearance_ThemeDayClassic: String { return self._s[3663]! } + public var Channel_AdminLog_MessagePreviousCaption: String { return self._s[3664]! } + public var AutoDownloadSettings_OffForAll: String { return self._s[3665]! } + public var Privacy_GroupsAndChannels_WhoCanAddMe: String { return self._s[3666]! } + public var Conversation_typing: String { return self._s[3668]! } + public var Undo_ScheduledMessagesCleared: String { return self._s[3669]! } + public var Paint_Masks: String { return self._s[3670]! } + public var Contacts_DeselectAll: String { return self._s[3671]! } + public var Username_InvalidTaken: String { return self._s[3672]! } + public var Call_StatusNoAnswer: String { return self._s[3673]! } + public var TwoStepAuth_EmailAddSuccess: String { return self._s[3674]! } + public var SettingsSearch_Synonyms_Privacy_BlockedUsers: String { return self._s[3675]! } + public var Passport_Identity_Selfie: String { return self._s[3676]! } + public var Login_InfoLastNamePlaceholder: String { return self._s[3677]! } + public var Privacy_SecretChatsLinkPreviewsHelp: String { return self._s[3678]! } + public var Conversation_ClearSecretHistory: String { return self._s[3679]! } + public var PeopleNearby_Description: String { return self._s[3681]! } + public var NetworkUsageSettings_Title: String { return self._s[3682]! } + public var Your_cards_security_code_is_invalid: String { return self._s[3684]! } public func Notification_LeftChannel(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3681]!, self._r[3681]!, [_0]) + return formatWithArgumentRanges(self._s[3686]!, self._r[3686]!, [_0]) } public func Call_CallInProgressMessage(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3682]!, self._r[3682]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3687]!, self._r[3687]!, [_1, _2]) } - public var SaveIncomingPhotosSettings_From: String { return self._s[3684]! } - public var VoiceOver_Navigation_Search: String { return self._s[3685]! } - public var Map_LiveLocationTitle: String { return self._s[3686]! } - public var Login_InfoAvatarAdd: String { return self._s[3687]! } - public var Passport_Identity_FilesView: String { return self._s[3688]! } - public var UserInfo_GenericPhoneLabel: String { return self._s[3689]! } - public var Privacy_Calls_NeverAllow: String { return self._s[3690]! } - public var VoiceOver_Chat_File: String { return self._s[3691]! } - public var Wallet_Settings_DeleteWalletInfo: String { return self._s[3692]! } + public var SaveIncomingPhotosSettings_From: String { return self._s[3689]! } + public var VoiceOver_Navigation_Search: String { return self._s[3690]! } + public var Map_LiveLocationTitle: String { return self._s[3691]! } + public var Login_InfoAvatarAdd: String { return self._s[3692]! } + public var Passport_Identity_FilesView: String { return self._s[3693]! } + public var UserInfo_GenericPhoneLabel: String { return self._s[3694]! } + public var Privacy_Calls_NeverAllow: String { return self._s[3695]! } + public var VoiceOver_Chat_File: String { return self._s[3696]! } + public var Wallet_Settings_DeleteWalletInfo: String { return self._s[3697]! } public func Contacts_AddPhoneNumber(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3693]!, self._r[3693]!, [_0]) + return formatWithArgumentRanges(self._s[3698]!, self._r[3698]!, [_0]) } - public var ContactInfo_PhoneNumberHidden: String { return self._s[3694]! } - public var TwoStepAuth_ConfirmationText: String { return self._s[3695]! } - public var ChatSettings_AutomaticVideoMessageDownload: String { return self._s[3696]! } + public var ContactInfo_PhoneNumberHidden: String { return self._s[3699]! } + public var TwoStepAuth_ConfirmationText: String { return self._s[3700]! } + public var ChatSettings_AutomaticVideoMessageDownload: String { return self._s[3701]! } public func PUSH_CHAT_MESSAGE_VIDEOS(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3697]!, self._r[3697]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[3702]!, self._r[3702]!, [_1, _2, _3]) } - public var Channel_AdminLogFilter_AdminsAll: String { return self._s[3698]! } - public var Wallet_Intro_CreateErrorText: String { return self._s[3699]! } - public var Tour_Title2: String { return self._s[3700]! } - public var Wallet_Sent_ViewWallet: String { return self._s[3701]! } - public var Conversation_FileOpenIn: String { return self._s[3702]! } - public var Checkout_ErrorPrecheckoutFailed: String { return self._s[3703]! } - public var Wallet_Send_ErrorInvalidAddress: String { return self._s[3704]! } - public var Wallpaper_Set: String { return self._s[3705]! } - public var Passport_Identity_Translations: String { return self._s[3707]! } + public var Channel_AdminLogFilter_AdminsAll: String { return self._s[3703]! } + public var Wallet_Intro_CreateErrorText: String { return self._s[3704]! } + public var Tour_Title2: String { return self._s[3705]! } + public var Wallet_Sent_ViewWallet: String { return self._s[3706]! } + public var Conversation_FileOpenIn: String { return self._s[3707]! } + public var Checkout_ErrorPrecheckoutFailed: String { return self._s[3708]! } + public var Wallet_Send_ErrorInvalidAddress: String { return self._s[3709]! } + public var Wallpaper_Set: String { return self._s[3710]! } + public var Passport_Identity_Translations: String { return self._s[3712]! } public func Channel_AdminLog_MessageChangedChannelAbout(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3708]!, self._r[3708]!, [_0]) + return formatWithArgumentRanges(self._s[3713]!, self._r[3713]!, [_0]) } - public var Channel_LeaveChannel: String { return self._s[3709]! } + public var Channel_LeaveChannel: String { return self._s[3714]! } public func PINNED_INVOICE(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3710]!, self._r[3710]!, [_1]) + return formatWithArgumentRanges(self._s[3715]!, self._r[3715]!, [_1]) } - public var SettingsSearch_Synonyms_Proxy_AddProxy: String { return self._s[3712]! } - public var PhotoEditor_HighlightsTint: String { return self._s[3713]! } - public var Passport_Email_Delete: String { return self._s[3714]! } - public var Conversation_Mute: String { return self._s[3716]! } - public var Channel_AddBotAsAdmin: String { return self._s[3717]! } - public var Channel_AdminLog_CanSendMessages: String { return self._s[3719]! } - public var Channel_Management_LabelOwner: String { return self._s[3721]! } + public var SettingsSearch_Synonyms_Proxy_AddProxy: String { return self._s[3717]! } + public var PhotoEditor_HighlightsTint: String { return self._s[3718]! } + public var Passport_Email_Delete: String { return self._s[3719]! } + public var Conversation_Mute: String { return self._s[3721]! } + public var Channel_AddBotAsAdmin: String { return self._s[3722]! } + public var Channel_AdminLog_CanSendMessages: String { return self._s[3724]! } + public var Channel_Management_LabelOwner: String { return self._s[3726]! } public func Notification_PassportValuesSentMessage(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3722]!, self._r[3722]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3727]!, self._r[3727]!, [_1, _2]) } - public var Calls_CallTabDescription: String { return self._s[3723]! } - public var Passport_Identity_NativeNameHelp: String { return self._s[3724]! } - public var Common_No: String { return self._s[3725]! } - public var Weekday_Sunday: String { return self._s[3726]! } - public var Notification_Reply: String { return self._s[3727]! } - public var Conversation_ViewMessage: String { return self._s[3728]! } + public var Calls_CallTabDescription: String { return self._s[3728]! } + public var Passport_Identity_NativeNameHelp: String { return self._s[3729]! } + public var Common_No: String { return self._s[3730]! } + public var Weekday_Sunday: String { return self._s[3731]! } + public var Notification_Reply: String { return self._s[3732]! } + public var Conversation_ViewMessage: String { return self._s[3733]! } public func Checkout_SavePasswordTimeoutAndFaceId(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3729]!, self._r[3729]!, [_0]) + return formatWithArgumentRanges(self._s[3734]!, self._r[3734]!, [_0]) } public func Map_LiveLocationPrivateDescription(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3730]!, self._r[3730]!, [_0]) + return formatWithArgumentRanges(self._s[3735]!, self._r[3735]!, [_0]) } - public var SettingsSearch_Synonyms_EditProfile_AddAccount: String { return self._s[3731]! } - public var Wallet_Send_Title: String { return self._s[3732]! } - public var Message_PinnedDocumentMessage: String { return self._s[3733]! } - public var Wallet_Info_RefreshErrorText: String { return self._s[3734]! } - public var DialogList_TabTitle: String { return self._s[3736]! } - public var ChatSettings_AutoPlayTitle: String { return self._s[3737]! } - public var Passport_FieldEmail: String { return self._s[3738]! } - public var Conversation_UnpinMessageAlert: String { return self._s[3739]! } - public var Passport_Address_TypeBankStatement: String { return self._s[3740]! } - public var Wallet_SecureStorageReset_Title: String { return self._s[3741]! } - public var Passport_Identity_ExpiryDate: String { return self._s[3742]! } - public var Privacy_Calls_P2P: String { return self._s[3743]! } + public var SettingsSearch_Synonyms_EditProfile_AddAccount: String { return self._s[3736]! } + public var Wallet_Send_Title: String { return self._s[3737]! } + public var Message_PinnedDocumentMessage: String { return self._s[3738]! } + public var Wallet_Info_RefreshErrorText: String { return self._s[3739]! } + public var DialogList_TabTitle: String { return self._s[3741]! } + public var ChatSettings_AutoPlayTitle: String { return self._s[3742]! } + public var Passport_FieldEmail: String { return self._s[3743]! } + public var Conversation_UnpinMessageAlert: String { return self._s[3744]! } + public var Passport_Address_TypeBankStatement: String { return self._s[3745]! } + public var Wallet_SecureStorageReset_Title: String { return self._s[3746]! } + public var Passport_Identity_ExpiryDate: String { return self._s[3747]! } + public var Privacy_Calls_P2P: String { return self._s[3748]! } public func CancelResetAccount_Success(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3745]!, self._r[3745]!, [_0]) + return formatWithArgumentRanges(self._s[3750]!, self._r[3750]!, [_0]) } - public var SocksProxySetup_UseForCallsHelp: String { return self._s[3746]! } + public var SocksProxySetup_UseForCallsHelp: String { return self._s[3751]! } public func PUSH_CHAT_ALBUM(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3747]!, self._r[3747]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3752]!, self._r[3752]!, [_1, _2]) } - public var Stickers_ClearRecent: String { return self._s[3748]! } - public var EnterPasscode_ChangeTitle: String { return self._s[3749]! } - public var Passport_InfoText: String { return self._s[3750]! } - public var Checkout_NewCard_SaveInfoEnableHelp: String { return self._s[3751]! } + public var Stickers_ClearRecent: String { return self._s[3753]! } + public var EnterPasscode_ChangeTitle: String { return self._s[3754]! } + public var Passport_InfoText: String { return self._s[3755]! } + public var Checkout_NewCard_SaveInfoEnableHelp: String { return self._s[3756]! } public func Login_InvalidPhoneEmailSubject(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3752]!, self._r[3752]!, [_0]) + return formatWithArgumentRanges(self._s[3757]!, self._r[3757]!, [_0]) } public func Time_PreciseDate_m3(_ _1: String, _ _2: String, _ _3: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3753]!, self._r[3753]!, [_1, _2, _3]) + return formatWithArgumentRanges(self._s[3758]!, self._r[3758]!, [_1, _2, _3]) } - public var SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedChannels: String { return self._s[3754]! } - public var ScheduledMessages_PollUnavailable: String { return self._s[3755]! } - public var VoiceOver_Navigation_Compose: String { return self._s[3756]! } - public var Passport_Identity_EditDriversLicense: String { return self._s[3757]! } - public var Conversation_TapAndHoldToRecord: String { return self._s[3759]! } - public var SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedChats: String { return self._s[3760]! } + public var SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedChannels: String { return self._s[3759]! } + public var ScheduledMessages_PollUnavailable: String { return self._s[3760]! } + public var VoiceOver_Navigation_Compose: String { return self._s[3761]! } + public var Passport_Identity_EditDriversLicense: String { return self._s[3762]! } + public var Conversation_TapAndHoldToRecord: String { return self._s[3764]! } + public var SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedChats: String { return self._s[3765]! } public func Notification_CallTimeFormat(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3761]!, self._r[3761]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3766]!, self._r[3766]!, [_1, _2]) } - public var Channel_EditAdmin_PermissionInviteViaLink: String { return self._s[3763]! } + public var Channel_EditAdmin_PermissionInviteViaLink: String { return self._s[3768]! } public func Generic_OpenHiddenLinkAlert(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3765]!, self._r[3765]!, [_0]) + return formatWithArgumentRanges(self._s[3770]!, self._r[3770]!, [_0]) } - public var DialogList_Unread: String { return self._s[3766]! } + public var DialogList_Unread: String { return self._s[3771]! } public func PUSH_CHAT_MESSAGE_GIF(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3767]!, self._r[3767]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3772]!, self._r[3772]!, [_1, _2]) } public func Updated_YesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3768]!, self._r[3768]!, [_0]) + return formatWithArgumentRanges(self._s[3773]!, self._r[3773]!, [_0]) } - public var User_DeletedAccount: String { return self._s[3769]! } - public var OwnershipTransfer_SetupTwoStepAuth: String { return self._s[3770]! } + public var User_DeletedAccount: String { return self._s[3774]! } + public var OwnershipTransfer_SetupTwoStepAuth: String { return self._s[3775]! } public func Watch_Time_ShortYesterdayAt(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3771]!, self._r[3771]!, [_0]) + return formatWithArgumentRanges(self._s[3776]!, self._r[3776]!, [_0]) } - public var UserInfo_NotificationsDefault: String { return self._s[3772]! } - public var SharedMedia_CategoryMedia: String { return self._s[3773]! } - public var SocksProxySetup_ProxyStatusUnavailable: String { return self._s[3774]! } - public var Channel_AdminLog_MessageRestrictedForever: String { return self._s[3775]! } - public var Watch_ChatList_Compose: String { return self._s[3776]! } - public var Notifications_MessageNotificationsExceptionsHelp: String { return self._s[3777]! } - public var AutoDownloadSettings_Delimeter: String { return self._s[3778]! } - public var Watch_Microphone_Access: String { return self._s[3779]! } - public var Group_Setup_HistoryHeader: String { return self._s[3780]! } - public var Map_SetThisLocation: String { return self._s[3781]! } - public var Appearance_ThemePreview_Chat_2_ReplyName: String { return self._s[3782]! } - public var Activity_UploadingPhoto: String { return self._s[3783]! } - public var Conversation_Edit: String { return self._s[3785]! } - public var Group_ErrorSendRestrictedMedia: String { return self._s[3786]! } - public var Login_TermsOfServiceDecline: String { return self._s[3787]! } - public var Message_PinnedContactMessage: String { return self._s[3788]! } + public var UserInfo_NotificationsDefault: String { return self._s[3777]! } + public var SharedMedia_CategoryMedia: String { return self._s[3778]! } + public var SocksProxySetup_ProxyStatusUnavailable: String { return self._s[3779]! } + public var Channel_AdminLog_MessageRestrictedForever: String { return self._s[3780]! } + public var Watch_ChatList_Compose: String { return self._s[3781]! } + public var Notifications_MessageNotificationsExceptionsHelp: String { return self._s[3782]! } + public var AutoDownloadSettings_Delimeter: String { return self._s[3783]! } + public var Watch_Microphone_Access: String { return self._s[3784]! } + public var Group_Setup_HistoryHeader: String { return self._s[3785]! } + public var Map_SetThisLocation: String { return self._s[3786]! } + public var Appearance_ThemePreview_Chat_2_ReplyName: String { return self._s[3787]! } + public var Activity_UploadingPhoto: String { return self._s[3788]! } + public var Conversation_Edit: String { return self._s[3790]! } + public var Group_ErrorSendRestrictedMedia: String { return self._s[3791]! } + public var Login_TermsOfServiceDecline: String { return self._s[3792]! } + public var Message_PinnedContactMessage: String { return self._s[3793]! } public func Channel_AdminLog_MessageRestrictedNameUsername(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3789]!, self._r[3789]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3794]!, self._r[3794]!, [_1, _2]) } public func Login_PhoneBannedEmailBody(_ _1: String, _ _2: String, _ _3: String, _ _4: String, _ _5: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3790]!, self._r[3790]!, [_1, _2, _3, _4, _5]) + return formatWithArgumentRanges(self._s[3795]!, self._r[3795]!, [_1, _2, _3, _4, _5]) } - public var Appearance_LargeEmoji: String { return self._s[3791]! } - public var TwoStepAuth_AdditionalPassword: String { return self._s[3793]! } - public var EditTheme_Edit_Preview_IncomingReplyText: String { return self._s[3794]! } + public var Appearance_LargeEmoji: String { return self._s[3796]! } + public var TwoStepAuth_AdditionalPassword: String { return self._s[3798]! } + public var EditTheme_Edit_Preview_IncomingReplyText: String { return self._s[3799]! } public func PUSH_CHAT_DELETE_YOU(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3795]!, self._r[3795]!, [_1, _2]) + return formatWithArgumentRanges(self._s[3800]!, self._r[3800]!, [_1, _2]) } - public var Passport_Phone_EnterOtherNumber: String { return self._s[3796]! } - public var Message_PinnedPhotoMessage: String { return self._s[3797]! } - public var Passport_FieldPhone: String { return self._s[3798]! } - public var TwoStepAuth_RecoveryEmailAddDescription: String { return self._s[3799]! } - public var ChatSettings_AutoPlayGifs: String { return self._s[3800]! } - public var InfoPlist_NSCameraUsageDescription: String { return self._s[3802]! } - public var Conversation_Call: String { return self._s[3803]! } - public var Common_TakePhoto: String { return self._s[3805]! } - public var Group_EditAdmin_RankTitle: String { return self._s[3806]! } - public var Wallet_Receive_CommentHeader: String { return self._s[3807]! } - public var Channel_NotificationLoading: String { return self._s[3808]! } + public var Passport_Phone_EnterOtherNumber: String { return self._s[3801]! } + public var Message_PinnedPhotoMessage: String { return self._s[3802]! } + public var Passport_FieldPhone: String { return self._s[3803]! } + public var TwoStepAuth_RecoveryEmailAddDescription: String { return self._s[3804]! } + public var ChatSettings_AutoPlayGifs: String { return self._s[3805]! } + public var InfoPlist_NSCameraUsageDescription: String { return self._s[3807]! } + public var Conversation_Call: String { return self._s[3808]! } + public var Common_TakePhoto: String { return self._s[3810]! } + public var Group_EditAdmin_RankTitle: String { return self._s[3811]! } + public var Wallet_Receive_CommentHeader: String { return self._s[3812]! } + public var Channel_NotificationLoading: String { return self._s[3813]! } public func Notification_Exceptions_Sound(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3809]!, self._r[3809]!, [_0]) - } - public func ScheduledMessages_ScheduledDate(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3810]!, self._r[3810]!, [_0]) - } - public func PUSH_CHANNEL_MESSAGE_VIDEO(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3811]!, self._r[3811]!, [_1]) - } - public var Permissions_SiriTitle_v0: String { return self._s[3812]! } - public func VoiceOver_Chat_VoiceMessageFrom(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3813]!, self._r[3813]!, [_0]) - } - public func Login_ResetAccountProtected_Text(_ _0: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[3814]!, self._r[3814]!, [_0]) } - public var Channel_MessagePhotoRemoved: String { return self._s[3815]! } - public var Common_edit: String { return self._s[3816]! } - public var PrivacySettings_AuthSessions: String { return self._s[3817]! } - public var Month_ShortJune: String { return self._s[3818]! } - public var PrivacyLastSeenSettings_AlwaysShareWith_Placeholder: String { return self._s[3819]! } - public var Call_ReportSend: String { return self._s[3820]! } - public var Watch_LastSeen_JustNow: String { return self._s[3821]! } - public var Notifications_MessageNotifications: String { return self._s[3822]! } - public var WallpaperSearch_ColorGreen: String { return self._s[3823]! } - public var BroadcastListInfo_AddRecipient: String { return self._s[3825]! } - public var Group_Status: String { return self._s[3826]! } + public func ScheduledMessages_ScheduledDate(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3815]!, self._r[3815]!, [_0]) + } + public func PUSH_CHANNEL_MESSAGE_VIDEO(_ _1: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3816]!, self._r[3816]!, [_1]) + } + public var Permissions_SiriTitle_v0: String { return self._s[3817]! } + public func VoiceOver_Chat_VoiceMessageFrom(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3818]!, self._r[3818]!, [_0]) + } + public func Login_ResetAccountProtected_Text(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3819]!, self._r[3819]!, [_0]) + } + public var Channel_MessagePhotoRemoved: String { return self._s[3820]! } + public var Common_edit: String { return self._s[3821]! } + public var PrivacySettings_AuthSessions: String { return self._s[3822]! } + public var Month_ShortJune: String { return self._s[3823]! } + public var PrivacyLastSeenSettings_AlwaysShareWith_Placeholder: String { return self._s[3824]! } + public var Call_ReportSend: String { return self._s[3825]! } + public var Watch_LastSeen_JustNow: String { return self._s[3826]! } + public var Notifications_MessageNotifications: String { return self._s[3827]! } + public var WallpaperSearch_ColorGreen: String { return self._s[3828]! } + public var BroadcastListInfo_AddRecipient: String { return self._s[3830]! } + public var Group_Status: String { return self._s[3831]! } public func AutoNightTheme_LocationHelp(_ _0: String, _ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3827]!, self._r[3827]!, [_0, _1]) + return formatWithArgumentRanges(self._s[3832]!, self._r[3832]!, [_0, _1]) } - public var TextFormat_AddLinkTitle: String { return self._s[3828]! } - public var ShareMenu_ShareTo: String { return self._s[3829]! } - public var Conversation_Moderate_Ban: String { return self._s[3830]! } + public var TextFormat_AddLinkTitle: String { return self._s[3833]! } + public var ShareMenu_ShareTo: String { return self._s[3834]! } + public var Conversation_Moderate_Ban: String { return self._s[3835]! } public func Conversation_DeleteMessagesFor(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3831]!, self._r[3831]!, [_0]) + return formatWithArgumentRanges(self._s[3836]!, self._r[3836]!, [_0]) } - public var SharedMedia_ViewInChat: String { return self._s[3832]! } - public var Map_LiveLocationFor8Hours: String { return self._s[3833]! } + public var SharedMedia_ViewInChat: String { return self._s[3837]! } + public var Map_LiveLocationFor8Hours: String { return self._s[3838]! } public func PUSH_PINNED_PHOTO(_ _1: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3834]!, self._r[3834]!, [_1]) + return formatWithArgumentRanges(self._s[3839]!, self._r[3839]!, [_1]) } public func PUSH_PINNED_POLL(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3835]!, self._r[3835]!, [_1, _2]) - } - public func Map_AccurateTo(_ _0: String) -> (String, [(Int, NSRange)]) { - return formatWithArgumentRanges(self._s[3837]!, self._r[3837]!, [_0]) - } - public var Map_OpenInHereMaps: String { return self._s[3838]! } - public var Appearance_ReduceMotion: String { return self._s[3839]! } - public func PUSH_MESSAGE_TEXT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { return formatWithArgumentRanges(self._s[3840]!, self._r[3840]!, [_1, _2]) } - public var Channel_Setup_TypePublicHelp: String { return self._s[3841]! } - public var Passport_Identity_EditInternalPassport: String { return self._s[3842]! } - public var PhotoEditor_Skip: String { return self._s[3843]! } - public func MessageTimer_Seconds(_ value: Int32) -> String { + public func Map_AccurateTo(_ _0: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3842]!, self._r[3842]!, [_0]) + } + public var Map_OpenInHereMaps: String { return self._s[3843]! } + public var Appearance_ReduceMotion: String { return self._s[3844]! } + public func PUSH_MESSAGE_TEXT(_ _1: String, _ _2: String) -> (String, [(Int, NSRange)]) { + return formatWithArgumentRanges(self._s[3845]!, self._r[3845]!, [_1, _2]) + } + public var Channel_Setup_TypePublicHelp: String { return self._s[3846]! } + public var Passport_Identity_EditInternalPassport: String { return self._s[3847]! } + public var PhotoEditor_Skip: String { return self._s[3848]! } + public func ForwardedPhotos(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[0 * 6 + Int(form.rawValue)]!, stringValue) } - public func MessageTimer_Minutes(_ value: Int32) -> String { + public func Conversation_StatusMembers(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[1 * 6 + Int(form.rawValue)]!, stringValue) } - public func UserCount(_ value: Int32) -> String { + public func SharedMedia_DeleteItemsConfirmation(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[2 * 6 + Int(form.rawValue)]!, stringValue) } - public func SharedMedia_File(_ value: Int32) -> String { + public func SharedMedia_Generic(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[3 * 6 + Int(form.rawValue)]!, stringValue) } - public func ForwardedPhotos(_ value: Int32) -> String { + public func ChatList_DeleteConfirmation(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[4 * 6 + Int(form.rawValue)]!, stringValue) } - public func VoiceOver_Chat_PollOptionCount(_ value: Int32) -> String { + public func Conversation_StatusOnline(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[5 * 6 + Int(form.rawValue)]!, stringValue) } - public func ServiceMessage_GameScoreSimple(_ value: Int32) -> String { + public func ForwardedMessages(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[6 * 6 + Int(form.rawValue)]!, stringValue) } - public func MessageTimer_Weeks(_ value: Int32) -> String { + public func Watch_LastSeen_MinutesAgo(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[7 * 6 + Int(form.rawValue)]!, stringValue) } - public func PUSH_CHAT_MESSAGE_ROUNDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + public func Call_Seconds(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[8 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[8 * 6 + Int(form.rawValue)]!, _2, _1, _3) + return String(format: self._ps[9 * 6 + Int(form.rawValue)]!, _1, _2) } - public func Conversation_StatusSubscribers(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[9 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Hours(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[10 * 6 + Int(form.rawValue)]!, stringValue) - } - public func VoiceOver_Chat_ContactEmailCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[11 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PrivacyLastSeenSettings_AddUsers(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[12 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + public func PUSH_CHANNEL_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[13 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func InviteText_ContactsCountText(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[14 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_ShortSeconds(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[15 * 6 + Int(form.rawValue)]!, stringValue) - } - public func DialogList_LiveLocationChatsCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[16 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Theme_UsersCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[17 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MuteFor_Hours(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[18 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ChatList_DeleteConfirmation(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[19 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ServiceMessage_GameScoreSelfSimple(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[20 * 6 + Int(form.rawValue)]!, stringValue) - } - public func VoiceOver_Chat_ContactPhoneNumberCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[21 * 6 + Int(form.rawValue)]!, stringValue) - } - public func StickerPack_StickerCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[22 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MuteExpires_Minutes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[23 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MuteExpires_Hours(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[24 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Conversation_StatusMembers(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[25 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Media_ShareVideo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[26 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Media_ShareItem(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[27 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHANNEL_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[28 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func ForwardedAudios(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[29 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Days(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[30 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notification_GameScoreSimple(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[31 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Months(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[32 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MuteExpires_Days(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[33 * 6 + Int(form.rawValue)]!, stringValue) - } - public func SharedMedia_Video(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[34 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHANNEL_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[35 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func Passport_Scans(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[36 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notifications_ExceptionMuteExpires_Days(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[37 * 6 + Int(form.rawValue)]!, stringValue) - } - public func CreatePoll_AddMoreOptions(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[38 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Watch_LastSeen_HoursAgo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[39 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedGifs(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[40 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Watch_LastSeen_MinutesAgo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[41 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedMessages(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[42 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedVideoMessages(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[43 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ServiceMessage_GameScoreSelfExtended(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[44 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Conversation_SelectedMessages(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[45 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_ShortHours(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[46 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_ShortMinutes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[47 * 6 + Int(form.rawValue)]!, stringValue) - } - public func AttachmentMenu_SendItem(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[48 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHAT_MESSAGE_PHOTOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[49 * 6 + Int(form.rawValue)]!, _2, _1, _3) - } - public func Forward_ConfirmMultipleFiles(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[50 * 6 + Int(form.rawValue)]!, stringValue) - } - public func AttachmentMenu_SendVideo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[51 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHANNEL_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[52 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func Watch_UserInfo_Mute(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[53 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Invitation_Members(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[54 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[55 * 6 + Int(form.rawValue)]!, _1, _2) + return String(format: self._ps[10 * 6 + Int(form.rawValue)]!, _1, _2) } public func ForwardedStickers(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[56 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[11 * 6 + Int(form.rawValue)]!, stringValue) } - public func ChatList_SelectedChats(_ value: Int32) -> String { + public func Invitation_Members(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[57 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[58 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func Chat_DeleteMessagesConfirmation(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[59 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notification_GameScoreSelfSimple(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[60 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Call_ShortSeconds(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[61 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Updated_MinutesAgo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[62 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Conversation_LiveLocationMembersCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[63 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedVideos(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[64 * 6 + Int(form.rawValue)]!, stringValue) - } - public func StickerPack_AddStickerCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[65 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[66 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func ServiceMessage_GameScoreExtended(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[67 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notifications_Exceptions(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[68 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notifications_ExceptionMuteExpires_Hours(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[69 * 6 + Int(form.rawValue)]!, stringValue) - } - public func StickerPack_AddMaskCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[70 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Map_ETAHours(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[71 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Call_ShortMinutes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[72 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[73 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func Call_Minutes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[74 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_Years(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[75 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Notification_GameScoreExtended(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[76 * 6 + Int(form.rawValue)]!, stringValue) - } - public func LiveLocation_MenuChatsCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[77 * 6 + Int(form.rawValue)]!, stringValue) - } - public func QuickSend_Photos(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[78 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_ShortDays(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[79 * 6 + Int(form.rawValue)]!, stringValue) - } - public func VoiceOver_Chat_PollVotes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[80 * 6 + Int(form.rawValue)]!, stringValue) - } - public func LastSeen_MinutesAgo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[81 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Wallpaper_DeleteConfirmation(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[82 * 6 + Int(form.rawValue)]!, stringValue) - } - public func StickerPack_RemoveMaskCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[83 * 6 + Int(form.rawValue)]!, stringValue) - } - public func GroupInfo_ParticipantCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[84 * 6 + Int(form.rawValue)]!, stringValue) - } - public func AttachmentMenu_SendGif(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[85 * 6 + Int(form.rawValue)]!, stringValue) - } - public func SharedMedia_DeleteItemsConfirmation(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[86 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Contacts_ImportersCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[87 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedFiles(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[88 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Map_ETAMinutes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[89 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedPolls(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[90 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[12 * 6 + Int(form.rawValue)]!, stringValue) } public func LiveLocationUpdated_MinutesAgo(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[91 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[13 * 6 + Int(form.rawValue)]!, stringValue) } - public func SharedMedia_Generic(_ value: Int32) -> String { + public func MessageTimer_Years(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[92 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[14 * 6 + Int(form.rawValue)]!, stringValue) } - public func PUSH_CHAT_MESSAGES(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + public func Passport_Scans(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[15 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Media_ShareVideo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[16 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedPolls(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[17 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[93 * 6 + Int(form.rawValue)]!, _2, _1, _3) + return String(format: self._ps[18 * 6 + Int(form.rawValue)]!, _1, _2) } - public func PasscodeSettings_FailedAttempts(_ value: Int32) -> String { + public func ForwardedVideoMessages(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[94 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[19 * 6 + Int(form.rawValue)]!, stringValue) } - public func Media_SharePhoto(_ value: Int32) -> String { + public func VoiceOver_Chat_PollVotes(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[95 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[20 * 6 + Int(form.rawValue)]!, stringValue) } - public func SharedMedia_Link(_ value: Int32) -> String { + public func VoiceOver_Chat_ContactEmailCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[96 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[21 * 6 + Int(form.rawValue)]!, stringValue) + } + public func QuickSend_Photos(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[22 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Days(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[23 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedAudios(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[24 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHANNEL_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[25 * 6 + Int(form.rawValue)]!, _1, _2) } public func MessagePoll_VotedCount(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[97 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[26 * 6 + Int(form.rawValue)]!, stringValue) } - public func Notification_GameScoreSelfExtended(_ value: Int32) -> String { + public func Media_SharePhoto(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[98 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[27 * 6 + Int(form.rawValue)]!, stringValue) } - public func StickerPack_RemoveStickerCount(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[99 * 6 + Int(form.rawValue)]!, stringValue) - } - public func SharedMedia_Photo(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[100 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHANNEL_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + public func PUSH_CHAT_MESSAGE_PHOTOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[101 * 6 + Int(form.rawValue)]!, _1, _2) + return String(format: self._ps[28 * 6 + Int(form.rawValue)]!, _2, _1, _3) + } + public func StickerPack_AddStickerCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[29 * 6 + Int(form.rawValue)]!, stringValue) + } + public func StickerPack_AddMaskCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[30 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHAT_MESSAGES(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[31 * 6 + Int(form.rawValue)]!, _2, _1, _3) + } + public func CreatePoll_AddMoreOptions(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[32 * 6 + Int(form.rawValue)]!, stringValue) } public func ForwardedAuthorsOthers(_ selector: Int32, _ _0: String, _ _1: String) -> String { let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[102 * 6 + Int(form.rawValue)]!, _0, _1) + return String(format: self._ps[33 * 6 + Int(form.rawValue)]!, _0, _1) } - public func Notifications_ExceptionMuteExpires_Minutes(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[103 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHAT_MESSAGE_FWDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + public func PUSH_CHAT_MESSAGE_ROUNDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[104 * 6 + Int(form.rawValue)]!, _2, _1, _3) + return String(format: self._ps[34 * 6 + Int(form.rawValue)]!, _2, _1, _3) } - public func LastSeen_HoursAgo(_ value: Int32) -> String { + public func MessageTimer_ShortSeconds(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[105 * 6 + Int(form.rawValue)]!, stringValue) - } - public func ForwardedContacts(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[106 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Call_Seconds(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[107 * 6 + Int(form.rawValue)]!, stringValue) - } - public func Conversation_StatusOnline(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[108 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MuteFor_Days(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[109 * 6 + Int(form.rawValue)]!, stringValue) - } - public func PUSH_CHANNEL_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[110 * 6 + Int(form.rawValue)]!, _1, _2) - } - public func ForwardedLocations(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[111 * 6 + Int(form.rawValue)]!, stringValue) - } - public func MessageTimer_ShortWeeks(_ value: Int32) -> String { - let form = presentationStringsPluralizationForm(self.lc, value) - let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[112 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[35 * 6 + Int(form.rawValue)]!, stringValue) } public func AttachmentMenu_SendPhoto(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) - return String(format: self._ps[113 * 6 + Int(form.rawValue)]!, stringValue) + return String(format: self._ps[36 * 6 + Int(form.rawValue)]!, stringValue) + } + public func InviteText_ContactsCountText(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[37 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[38 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func UserCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[39 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MuteExpires_Days(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[40 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedVideos(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[41 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Updated_HoursAgo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[42 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notification_GameScoreSimple(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[43 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Wallpaper_DeleteConfirmation(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[44 * 6 + Int(form.rawValue)]!, stringValue) + } + public func LastSeen_HoursAgo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[45 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Months(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[46 * 6 + Int(form.rawValue)]!, stringValue) } public func PUSH_CHAT_MESSAGE_VIDEOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, selector) - return String(format: self._ps[114 * 6 + Int(form.rawValue)]!, _2, _1, _3) + return String(format: self._ps[47 * 6 + Int(form.rawValue)]!, _2, _1, _3) } - public func Updated_HoursAgo(_ value: Int32) -> String { + public func PUSH_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[48 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func AttachmentMenu_SendItem(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[49 * 6 + Int(form.rawValue)]!, stringValue) + } + public func AttachmentMenu_SendGif(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[50 * 6 + Int(form.rawValue)]!, stringValue) + } + public func LiveLocation_MenuChatsCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[51 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Call_ShortMinutes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[52 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Seconds(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[53 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MuteExpires_Minutes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[54 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHANNEL_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[55 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func StickerPack_RemoveMaskCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[56 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Call_Minutes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[57 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortDays(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[58 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Forward_ConfirmMultipleFiles(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[59 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHANNEL_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[60 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func Conversation_StatusSubscribers(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[61 * 6 + Int(form.rawValue)]!, stringValue) + } + public func DialogList_LiveLocationChatsCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[62 * 6 + Int(form.rawValue)]!, stringValue) + } + public func GroupInfo_ParticipantCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[63 * 6 + Int(form.rawValue)]!, stringValue) + } + public func StickerPack_RemoveStickerCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[64 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Contacts_ImportersCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[65 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortHours(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[66 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Updated_MinutesAgo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[67 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ChatList_SelectedChats(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[68 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Hours(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[69 * 6 + Int(form.rawValue)]!, stringValue) + } + public func LastSeen_MinutesAgo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[70 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notifications_ExceptionMuteExpires_Days(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[71 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notifications_ExceptionMuteExpires_Minutes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[72 * 6 + Int(form.rawValue)]!, stringValue) + } + public func SharedMedia_Photo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[73 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Minutes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[74 * 6 + Int(form.rawValue)]!, stringValue) + } + public func VoiceOver_Chat_ContactPhoneNumberCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[75 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ServiceMessage_GameScoreExtended(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[76 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortWeeks(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[77 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notification_GameScoreSelfSimple(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[78 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Map_ETAHours(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[79 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Media_ShareItem(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[80 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notification_GameScoreSelfExtended(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[81 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PasscodeSettings_FailedAttempts(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[82 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Watch_LastSeen_HoursAgo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[83 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MuteFor_Hours(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[84 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ServiceMessage_GameScoreSimple(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[85 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PrivacyLastSeenSettings_AddUsers(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[86 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_ShortMinutes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[87 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[88 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func Conversation_SelectedMessages(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[89 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Chat_DeleteMessagesConfirmation(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[90 * 6 + Int(form.rawValue)]!, stringValue) + } + public func SharedMedia_File(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[91 * 6 + Int(form.rawValue)]!, stringValue) + } + public func AttachmentMenu_SendVideo(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[92 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Call_ShortSeconds(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[93 * 6 + Int(form.rawValue)]!, stringValue) + } + public func SharedMedia_Video(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[94 * 6 + Int(form.rawValue)]!, stringValue) + } + public func SharedMedia_Link(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[95 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Conversation_LiveLocationMembersCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[96 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedContacts(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[97 * 6 + Int(form.rawValue)]!, stringValue) + } + public func VoiceOver_Chat_PollOptionCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[98 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Map_ETAMinutes(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[99 * 6 + Int(form.rawValue)]!, stringValue) + } + public func StickerPack_StickerCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[100 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Theme_UsersCount(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[101 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedLocations(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[102 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ServiceMessage_GameScoreSelfSimple(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[103 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MessageTimer_Weeks(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[104 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedFiles(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[105 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Watch_UserInfo_Mute(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[106 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notification_GameScoreExtended(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[107 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ServiceMessage_GameScoreSelfExtended(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[108 * 6 + Int(form.rawValue)]!, stringValue) + } + public func Notifications_Exceptions(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[109 * 6 + Int(form.rawValue)]!, stringValue) + } + public func MuteExpires_Hours(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[110 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHAT_MESSAGE_FWDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[111 * 6 + Int(form.rawValue)]!, _2, _1, _3) + } + public func MuteFor_Days(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[112 * 6 + Int(form.rawValue)]!, stringValue) + } + public func PUSH_CHANNEL_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, selector) + return String(format: self._ps[113 * 6 + Int(form.rawValue)]!, _1, _2) + } + public func Notifications_ExceptionMuteExpires_Hours(_ value: Int32) -> String { + let form = presentationStringsPluralizationForm(self.lc, value) + let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) + return String(format: self._ps[114 * 6 + Int(form.rawValue)]!, stringValue) + } + public func ForwardedGifs(_ value: Int32) -> String { let form = presentationStringsPluralizationForm(self.lc, value) let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator) return String(format: self._ps[115 * 6 + Int(form.rawValue)]!, stringValue) diff --git a/submodules/TelegramUI/TelegramUI/AppDelegate.swift b/submodules/TelegramUI/TelegramUI/AppDelegate.swift index bad165bda5..70c464b897 100644 --- a/submodules/TelegramUI/TelegramUI/AppDelegate.swift +++ b/submodules/TelegramUI/TelegramUI/AppDelegate.swift @@ -244,8 +244,6 @@ final class SharedApplicationContext { private let deviceToken = Promise(nil) - private var cloudDataContext: Any? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { precondition(!testIsLaunched) testIsLaunched = true @@ -262,8 +260,6 @@ final class SharedApplicationContext { self.window = window self.nativeWindow = window - self.cloudDataContext = makeCloudDataContext() - let clearNotificationsManager = ClearNotificationsManager(getNotificationIds: { completion in if #available(iOS 10.0, *) { UNUserNotificationCenter.current().getDeliveredNotifications(completionHandler: { notifications in diff --git a/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping b/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping index 8ea969f7a6..3deab5d7c9 100644 Binary files a/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping and b/submodules/TelegramUI/TelegramUI/Resources/PresentationStrings.mapping differ diff --git a/submodules/WalletUI/Sources/WalletInfoScreen.swift b/submodules/WalletUI/Sources/WalletInfoScreen.swift index cc1a73bafc..449a5c0fdd 100644 --- a/submodules/WalletUI/Sources/WalletInfoScreen.swift +++ b/submodules/WalletUI/Sources/WalletInfoScreen.swift @@ -751,7 +751,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { strongSelf.didSetContentReady = true strongSelf.contentReady.set(.single(true)) } - }, error: { [weak self] _ in + }, error: { [weak self] error in guard let strongSelf = self else { return } @@ -780,7 +780,14 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { strongSelf.contentReady.set(.single(true)) } - strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: strongSelf.presentationData.strings.Wallet_Info_RefreshErrorTitle, text: strongSelf.presentationData.strings.Wallet_Info_RefreshErrorText, actions: [ + let text: String + switch error { + case .generic: + text = strongSelf.presentationData.strings.Wallet_Info_RefreshErrorText + case .network: + text = strongSelf.presentationData.strings.Wallet_Info_RefreshErrorNetworkText + } + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: strongSelf.presentationData.strings.Wallet_Info_RefreshErrorTitle, text: text, actions: [ TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: { }) ], actionLayout: .vertical), nil) diff --git a/submodules/WalletUI/Sources/WalletSettingsScreen.swift b/submodules/WalletUI/Sources/WalletSettingsScreen.swift index 1f972444e8..8aa0c08c64 100644 --- a/submodules/WalletUI/Sources/WalletSettingsScreen.swift +++ b/submodules/WalletUI/Sources/WalletSettingsScreen.swift @@ -120,7 +120,7 @@ public func walletSettingsController(context: AccountContext, tonContext: TonCon actionSheet?.dismissAnimated() let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .loading(cancelled: nil)) presentControllerImpl?(controller, nil) - let _ = (deleteLocalWalletData(postbox: context.account.postbox, network: context.account.network, tonInstance: tonContext.instance, keychain: tonContext.keychain, walletInfo: walletInfo) + let _ = (deleteAllLocalWalletsData(postbox: context.account.postbox, network: context.account.network, tonInstance: tonContext.instance) |> deliverOnMainQueue).start(error: { [weak controller] _ in controller?.dismiss() }, completed: { [weak controller] in diff --git a/submodules/WalletUI/Sources/WalletSplashScreen.swift b/submodules/WalletUI/Sources/WalletSplashScreen.swift index afce794d44..a93b8fee3f 100644 --- a/submodules/WalletUI/Sources/WalletSplashScreen.swift +++ b/submodules/WalletUI/Sources/WalletSplashScreen.swift @@ -142,14 +142,20 @@ public final class WalletSplashScreen: ViewController { switch error { case .generic: text = strongSelf.presentationData.strings.Login_UnknownError + case .network: + text = strongSelf.presentationData.strings.Wallet_Send_NetworkError + case .notEnoughFunds: + text = strongSelf.presentationData.strings.Wallet_Send_ErrorNotEnoughFunds + case .messageTooLong: + text = strongSelf.presentationData.strings.Login_UnknownError case .invalidAddress: text = strongSelf.presentationData.strings.Wallet_Send_ErrorInvalidAddress case .secretDecryptionFailed: text = strongSelf.presentationData.strings.Wallet_Send_ErrorDecryptionFailed case .destinationIsNotInitialized: if !forceIfDestinationNotInitialized { - text = "This address belongs to an empty wallet. Are you sure you want to transfer grams to it?" - let controller = textAlertController(context: strongSelf.context, title: "Warning", text: text, actions: [ + text = strongSelf.presentationData.strings.Wallet_Send_UninitializedText + let controller = textAlertController(context: strongSelf.context, title: strongSelf.presentationData.strings.Wallet_Send_UninitializedTitle, text: text, actions: [ TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: { if let navigationController = strongSelf.navigationController as? NavigationController { navigationController.popViewController(animated: true) diff --git a/submodules/WalletUI/Sources/WalletUtils.swift b/submodules/WalletUI/Sources/WalletUtils.swift index 92cd45461c..8f63247cd5 100644 --- a/submodules/WalletUI/Sources/WalletUtils.swift +++ b/submodules/WalletUI/Sources/WalletUtils.swift @@ -3,7 +3,7 @@ import TelegramStringFormatting import UrlEscaping let walletAddressLength: Int = 48 -let walletTextLimit: Int = 124 +let walletTextLimit: Int = 1024 func formatAddress(_ address: String) -> String { var address = address diff --git a/submodules/ton/tonlib-src/crypto/CMakeLists.txt b/submodules/ton/tonlib-src/crypto/CMakeLists.txt index c76de707c9..acf88eeef6 100644 --- a/submodules/ton/tonlib-src/crypto/CMakeLists.txt +++ b/submodules/ton/tonlib-src/crypto/CMakeLists.txt @@ -315,6 +315,8 @@ if (NOT CMAKE_CROSSCOMPILING) GenFif(DEST smartcont/config-code.fif SOURCE smartcont/config-code.fc) GenFif(DEST smartcont/wallet-code.fif SOURCE smartcont/wallet-code.fc) GenFif(DEST smartcont/simple-wallet-code.fif SOURCE smartcont/simple-wallet-code.fc) + GenFif(DEST smartcont/highload-wallet-code.fif SOURCE smartcont/highload-wallet-code.fc) + GenFif(DEST smartcont/highload-wallet-v2-code.fif SOURCE smartcont/highload-wallet-v2-code.fc) GenFif(DEST smartcont/elector-code.fif SOURCE smartcont/elector-code.fc) endif() @@ -333,3 +335,6 @@ target_link_libraries(dump-block PUBLIC ton_crypto fift-lib ton_block) if (WINGETOPT_FOUND) target_link_libraries_system(dump-block wingetopt) endif() + +install(TARGETS fift func RUNTIME DESTINATION bin) +install(DIRECTORY fift/lib/ DESTINATION lib/fift) diff --git a/submodules/ton/tonlib-src/crypto/block/block-auto.cpp b/submodules/ton/tonlib-src/crypto/block/block-auto.cpp index 14b34ee6bf..75dd9f659e 100644 --- a/submodules/ton/tonlib-src/crypto/block/block-auto.cpp +++ b/submodules/ton/tonlib-src/crypto/block/block-auto.cpp @@ -8891,6 +8891,7 @@ bool TransactionDescr::skip(vm::CellSlice& cs) const { && cs.advance(2); case trans_split_prepare: return cs.advance(528) + && t_Maybe_TrStoragePhase.skip(cs) && t_TrComputePhase.skip(cs) && t_Maybe_Ref_TrActionPhase.skip(cs) && cs.advance(2); @@ -8902,6 +8903,7 @@ bool TransactionDescr::skip(vm::CellSlice& cs) const { && cs.advance(1); case trans_merge_install: return cs.advance_ext(0x10210) + && t_Maybe_TrStoragePhase.skip(cs) && t_Maybe_TrCreditPhase.skip(cs) && t_TrComputePhase.skip(cs) && t_Maybe_Ref_TrActionPhase.skip(cs) @@ -8932,6 +8934,7 @@ bool TransactionDescr::validate_skip(vm::CellSlice& cs, bool weak) const { && cs.advance(2); case trans_split_prepare: return cs.advance(528) + && t_Maybe_TrStoragePhase.validate_skip(cs, weak) && t_TrComputePhase.validate_skip(cs, weak) && t_Maybe_Ref_TrActionPhase.validate_skip(cs, weak) && cs.advance(2); @@ -8947,6 +8950,7 @@ bool TransactionDescr::validate_skip(vm::CellSlice& cs, bool weak) const { return cs.fetch_ulong(4) == 7 && cs.advance(524) && t_Transaction.validate_skip_ref(cs, weak) + && t_Maybe_TrStoragePhase.validate_skip(cs, weak) && t_Maybe_TrCreditPhase.validate_skip(cs, weak) && t_TrComputePhase.validate_skip(cs, weak) && t_Maybe_Ref_TrActionPhase.validate_skip(cs, weak) @@ -8998,7 +9002,7 @@ bool TransactionDescr::cell_unpack_trans_storage(Ref cell_ref, Ref cell_ref, TransactionDescr::Rec bool TransactionDescr::unpack(vm::CellSlice& cs, TransactionDescr::Record_trans_split_prepare& data) const { return cs.fetch_ulong(4) == 4 && cs.fetch_subslice_to(524, data.split_info) + && t_Maybe_TrStoragePhase.fetch_to(cs, data.storage_ph) && t_TrComputePhase.fetch_to(cs, data.compute_ph) && t_Maybe_Ref_TrActionPhase.fetch_to(cs, data.action) && cs.fetch_bool_to(data.aborted) @@ -9082,6 +9087,7 @@ bool TransactionDescr::unpack(vm::CellSlice& cs, TransactionDescr::Record_trans_ return cs.fetch_ulong(4) == 7 && cs.fetch_subslice_to(524, data.split_info) && cs.fetch_ref_to(data.prepare_transaction) + && t_Maybe_TrStoragePhase.fetch_to(cs, data.storage_ph) && t_Maybe_TrCreditPhase.fetch_to(cs, data.credit_ph) && t_TrComputePhase.fetch_to(cs, data.compute_ph) && t_Maybe_Ref_TrActionPhase.fetch_to(cs, data.action) @@ -9135,7 +9141,7 @@ bool TransactionDescr::cell_pack_trans_storage(Ref& cell_ref, Ref& cell_ref, const TransactionDescr bool TransactionDescr::pack(vm::CellBuilder& cb, const TransactionDescr::Record_trans_split_prepare& data) const { return cb.store_long_bool(4, 4) && cb.append_cellslice_chk(data.split_info, 524) + && t_Maybe_TrStoragePhase.store_from(cb, data.storage_ph) && t_TrComputePhase.store_from(cb, data.compute_ph) && t_Maybe_Ref_TrActionPhase.store_from(cb, data.action) && cb.store_ulong_rchk_bool(data.aborted, 1) @@ -9213,6 +9220,7 @@ bool TransactionDescr::pack(vm::CellBuilder& cb, const TransactionDescr::Record_ return cb.store_long_bool(7, 4) && cb.append_cellslice_chk(data.split_info, 524) && cb.store_ref_bool(data.prepare_transaction) + && t_Maybe_TrStoragePhase.store_from(cb, data.storage_ph) && t_Maybe_TrCreditPhase.store_from(cb, data.credit_ph) && t_TrComputePhase.store_from(cb, data.compute_ph) && t_Maybe_Ref_TrActionPhase.store_from(cb, data.action) @@ -9254,7 +9262,7 @@ bool TransactionDescr::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const { return cs.advance(3) && pp.open("trans_tick_tock") && pp.fetch_uint_field(cs, 1, "is_tock") - && pp.field("storage") + && pp.field("storage_ph") && t_TrStoragePhase.print_skip(pp, cs) && pp.field("compute_ph") && t_TrComputePhase.print_skip(pp, cs) @@ -9268,6 +9276,8 @@ bool TransactionDescr::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const { && pp.open("trans_split_prepare") && pp.field("split_info") && t_SplitMergeInfo.print_skip(pp, cs) + && pp.field("storage_ph") + && t_Maybe_TrStoragePhase.print_skip(pp, cs) && pp.field("compute_ph") && t_TrComputePhase.print_skip(pp, cs) && pp.field("action") @@ -9300,6 +9310,8 @@ bool TransactionDescr::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const { && t_SplitMergeInfo.print_skip(pp, cs) && pp.field("prepare_transaction") && t_Transaction.print_ref(pp, cs.fetch_ref()) + && pp.field("storage_ph") + && t_Maybe_TrStoragePhase.print_skip(pp, cs) && pp.field("credit_ph") && t_Maybe_TrCreditPhase.print_skip(pp, cs) && pp.field("compute_ph") @@ -14089,11 +14101,13 @@ const StoragePrices t_StoragePrices; // // code for type `GasLimitsPrices` // -constexpr unsigned char GasLimitsPrices::cons_tag[2]; +constexpr unsigned char GasLimitsPrices::cons_tag[3]; int GasLimitsPrices::get_tag(const vm::CellSlice& cs) const { - switch (cs.bselect(6, 0x180000000000000ULL)) { + switch (cs.bselect(6, 0x1b0000000000000ULL)) { case 0: + return gas_flat_pfx; + case 2: return cs.bit_at(6) ? gas_prices_ext : gas_prices; default: return -1; @@ -14106,6 +14120,8 @@ int GasLimitsPrices::check_tag(const vm::CellSlice& cs) const { return cs.prefetch_ulong(8) == 0xdd ? gas_prices : -1; case gas_prices_ext: return cs.prefetch_ulong(8) == 0xde ? gas_prices_ext : -1; + case gas_flat_pfx: + return cs.prefetch_ulong(8) == 0xd1 ? gas_flat_pfx : -1; } return -1; } @@ -14116,6 +14132,9 @@ bool GasLimitsPrices::skip(vm::CellSlice& cs) const { return cs.advance(392); case gas_prices_ext: return cs.advance(456); + case gas_flat_pfx: + return cs.advance(136) + && skip(cs); } return false; } @@ -14128,6 +14147,10 @@ bool GasLimitsPrices::validate_skip(vm::CellSlice& cs, bool weak) const { case gas_prices_ext: return cs.fetch_ulong(8) == 0xde && cs.advance(448); + case gas_flat_pfx: + return cs.fetch_ulong(8) == 0xd1 + && cs.advance(128) + && validate_skip(cs, weak); } return false; } @@ -14165,6 +14188,32 @@ bool GasLimitsPrices::cell_unpack(Ref cell_ref, GasLimitsPrices::Recor return unpack(cs, data) && cs.empty_ext(); } +bool GasLimitsPrices::unpack(vm::CellSlice& cs, GasLimitsPrices::Record_gas_flat_pfx& data) const { + return cs.fetch_ulong(8) == 0xd1 + && cs.fetch_uint_to(64, data.flat_gas_limit) + && cs.fetch_uint_to(64, data.flat_gas_price) + && fetch_to(cs, data.other); +} + +bool GasLimitsPrices::unpack_gas_flat_pfx(vm::CellSlice& cs, unsigned long long& flat_gas_limit, unsigned long long& flat_gas_price, Ref& other) const { + return cs.fetch_ulong(8) == 0xd1 + && cs.fetch_uint_to(64, flat_gas_limit) + && cs.fetch_uint_to(64, flat_gas_price) + && fetch_to(cs, other); +} + +bool GasLimitsPrices::cell_unpack(Ref cell_ref, GasLimitsPrices::Record_gas_flat_pfx& data) const { + if (cell_ref.is_null()) { return false; } + auto cs = load_cell_slice(std::move(cell_ref)); + return unpack(cs, data) && cs.empty_ext(); +} + +bool GasLimitsPrices::cell_unpack_gas_flat_pfx(Ref cell_ref, unsigned long long& flat_gas_limit, unsigned long long& flat_gas_price, Ref& other) const { + if (cell_ref.is_null()) { return false; } + auto cs = load_cell_slice(std::move(cell_ref)); + return unpack_gas_flat_pfx(cs, flat_gas_limit, flat_gas_price, other) && cs.empty_ext(); +} + bool GasLimitsPrices::pack(vm::CellBuilder& cb, const GasLimitsPrices::Record_gas_prices& data) const { return cb.store_long_bool(0xdd, 8) && cb.store_ulong_rchk_bool(data.gas_price, 64) @@ -14196,6 +14245,30 @@ bool GasLimitsPrices::cell_pack(Ref& cell_ref, const GasLimitsPrices:: return pack(cb, data) && std::move(cb).finalize_to(cell_ref); } +bool GasLimitsPrices::pack(vm::CellBuilder& cb, const GasLimitsPrices::Record_gas_flat_pfx& data) const { + return cb.store_long_bool(0xd1, 8) + && cb.store_ulong_rchk_bool(data.flat_gas_limit, 64) + && cb.store_ulong_rchk_bool(data.flat_gas_price, 64) + && store_from(cb, data.other); +} + +bool GasLimitsPrices::pack_gas_flat_pfx(vm::CellBuilder& cb, unsigned long long flat_gas_limit, unsigned long long flat_gas_price, Ref other) const { + return cb.store_long_bool(0xd1, 8) + && cb.store_ulong_rchk_bool(flat_gas_limit, 64) + && cb.store_ulong_rchk_bool(flat_gas_price, 64) + && store_from(cb, other); +} + +bool GasLimitsPrices::cell_pack(Ref& cell_ref, const GasLimitsPrices::Record_gas_flat_pfx& data) const { + vm::CellBuilder cb; + return pack(cb, data) && std::move(cb).finalize_to(cell_ref); +} + +bool GasLimitsPrices::cell_pack_gas_flat_pfx(Ref& cell_ref, unsigned long long flat_gas_limit, unsigned long long flat_gas_price, Ref other) const { + vm::CellBuilder cb; + return pack_gas_flat_pfx(cb, flat_gas_limit, flat_gas_price, std::move(other)) && std::move(cb).finalize_to(cell_ref); +} + bool GasLimitsPrices::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const { switch (get_tag(cs)) { case gas_prices: @@ -14219,6 +14292,14 @@ bool GasLimitsPrices::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const { && pp.fetch_uint_field(cs, 64, "freeze_due_limit") && pp.fetch_uint_field(cs, 64, "delete_due_limit") && pp.close(); + case gas_flat_pfx: + return cs.fetch_ulong(8) == 0xd1 + && pp.open("gas_flat_pfx") + && pp.fetch_uint_field(cs, 64, "flat_gas_limit") + && pp.fetch_uint_field(cs, 64, "flat_gas_price") + && pp.field("other") + && print_skip(pp, cs) + && pp.close(); } return pp.fail("unknown constructor for GasLimitsPrices"); } diff --git a/submodules/ton/tonlib-src/crypto/block/block-auto.h b/submodules/ton/tonlib-src/crypto/block/block-auto.h index 66b9700333..fb9e1770d6 100644 --- a/submodules/ton/tonlib-src/crypto/block/block-auto.h +++ b/submodules/ton/tonlib-src/crypto/block/block-auto.h @@ -3831,24 +3831,25 @@ struct TransactionDescr::Record_trans_ord { struct TransactionDescr::Record_trans_tick_tock { typedef TransactionDescr type_class; bool is_tock; // is_tock : Bool - Ref storage; // storage : TrStoragePhase + Ref storage_ph; // storage_ph : TrStoragePhase Ref compute_ph; // compute_ph : TrComputePhase Ref action; // action : Maybe ^TrActionPhase bool aborted; // aborted : Bool bool destroyed; // destroyed : Bool Record_trans_tick_tock() = default; - Record_trans_tick_tock(bool _is_tock, Ref _storage, Ref _compute_ph, Ref _action, bool _aborted, bool _destroyed) : is_tock(_is_tock), storage(std::move(_storage)), compute_ph(std::move(_compute_ph)), action(std::move(_action)), aborted(_aborted), destroyed(_destroyed) {} + Record_trans_tick_tock(bool _is_tock, Ref _storage_ph, Ref _compute_ph, Ref _action, bool _aborted, bool _destroyed) : is_tock(_is_tock), storage_ph(std::move(_storage_ph)), compute_ph(std::move(_compute_ph)), action(std::move(_action)), aborted(_aborted), destroyed(_destroyed) {} }; struct TransactionDescr::Record_trans_split_prepare { typedef TransactionDescr type_class; Ref split_info; // split_info : SplitMergeInfo + Ref storage_ph; // storage_ph : Maybe TrStoragePhase Ref compute_ph; // compute_ph : TrComputePhase Ref action; // action : Maybe ^TrActionPhase bool aborted; // aborted : Bool bool destroyed; // destroyed : Bool Record_trans_split_prepare() = default; - Record_trans_split_prepare(Ref _split_info, Ref _compute_ph, Ref _action, bool _aborted, bool _destroyed) : split_info(std::move(_split_info)), compute_ph(std::move(_compute_ph)), action(std::move(_action)), aborted(_aborted), destroyed(_destroyed) {} + Record_trans_split_prepare(Ref _split_info, Ref _storage_ph, Ref _compute_ph, Ref _action, bool _aborted, bool _destroyed) : split_info(std::move(_split_info)), storage_ph(std::move(_storage_ph)), compute_ph(std::move(_compute_ph)), action(std::move(_action)), aborted(_aborted), destroyed(_destroyed) {} }; struct TransactionDescr::Record_trans_split_install { @@ -3873,13 +3874,14 @@ struct TransactionDescr::Record_trans_merge_install { typedef TransactionDescr type_class; Ref split_info; // split_info : SplitMergeInfo Ref prepare_transaction; // prepare_transaction : ^Transaction + Ref storage_ph; // storage_ph : Maybe TrStoragePhase Ref credit_ph; // credit_ph : Maybe TrCreditPhase Ref compute_ph; // compute_ph : TrComputePhase Ref action; // action : Maybe ^TrActionPhase bool aborted; // aborted : Bool bool destroyed; // destroyed : Bool Record_trans_merge_install() = default; - Record_trans_merge_install(Ref _split_info, Ref _prepare_transaction, Ref _credit_ph, Ref _compute_ph, Ref _action, bool _aborted, bool _destroyed) : split_info(std::move(_split_info)), prepare_transaction(std::move(_prepare_transaction)), credit_ph(std::move(_credit_ph)), compute_ph(std::move(_compute_ph)), action(std::move(_action)), aborted(_aborted), destroyed(_destroyed) {} + Record_trans_merge_install(Ref _split_info, Ref _prepare_transaction, Ref _storage_ph, Ref _credit_ph, Ref _compute_ph, Ref _action, bool _aborted, bool _destroyed) : split_info(std::move(_split_info)), prepare_transaction(std::move(_prepare_transaction)), storage_ph(std::move(_storage_ph)), credit_ph(std::move(_credit_ph)), compute_ph(std::move(_compute_ph)), action(std::move(_action)), aborted(_aborted), destroyed(_destroyed) {} }; extern const TransactionDescr t_TransactionDescr; @@ -6166,11 +6168,12 @@ extern const StoragePrices t_StoragePrices; // struct GasLimitsPrices final : TLB_Complex { - enum { gas_prices, gas_prices_ext }; + enum { gas_flat_pfx, gas_prices, gas_prices_ext }; static constexpr int cons_len_exact = 8; - static constexpr unsigned char cons_tag[2] = { 0xdd, 0xde }; + static constexpr unsigned char cons_tag[3] = { 0xd1, 0xdd, 0xde }; struct Record_gas_prices; struct Record_gas_prices_ext; + struct Record_gas_flat_pfx; bool skip(vm::CellSlice& cs) const override; bool validate_skip(vm::CellSlice& cs, bool weak = false) const override; bool unpack(vm::CellSlice& cs, Record_gas_prices& data) const; @@ -6181,6 +6184,14 @@ struct GasLimitsPrices final : TLB_Complex { bool cell_unpack(Ref cell_ref, Record_gas_prices_ext& data) const; bool pack(vm::CellBuilder& cb, const Record_gas_prices_ext& data) const; bool cell_pack(Ref& cell_ref, const Record_gas_prices_ext& data) const; + bool unpack(vm::CellSlice& cs, Record_gas_flat_pfx& data) const; + bool unpack_gas_flat_pfx(vm::CellSlice& cs, unsigned long long& flat_gas_limit, unsigned long long& flat_gas_price, Ref& other) const; + bool cell_unpack(Ref cell_ref, Record_gas_flat_pfx& data) const; + bool cell_unpack_gas_flat_pfx(Ref cell_ref, unsigned long long& flat_gas_limit, unsigned long long& flat_gas_price, Ref& other) const; + bool pack(vm::CellBuilder& cb, const Record_gas_flat_pfx& data) const; + bool pack_gas_flat_pfx(vm::CellBuilder& cb, unsigned long long flat_gas_limit, unsigned long long flat_gas_price, Ref other) const; + bool cell_pack(Ref& cell_ref, const Record_gas_flat_pfx& data) const; + bool cell_pack_gas_flat_pfx(Ref& cell_ref, unsigned long long flat_gas_limit, unsigned long long flat_gas_price, Ref other) const; bool print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const override; std::ostream& print_type(std::ostream& os) const override { return os << "GasLimitsPrices"; @@ -6214,6 +6225,15 @@ struct GasLimitsPrices::Record_gas_prices_ext { Record_gas_prices_ext(unsigned long long _gas_price, unsigned long long _gas_limit, unsigned long long _special_gas_limit, unsigned long long _gas_credit, unsigned long long _block_gas_limit, unsigned long long _freeze_due_limit, unsigned long long _delete_due_limit) : gas_price(_gas_price), gas_limit(_gas_limit), special_gas_limit(_special_gas_limit), gas_credit(_gas_credit), block_gas_limit(_block_gas_limit), freeze_due_limit(_freeze_due_limit), delete_due_limit(_delete_due_limit) {} }; +struct GasLimitsPrices::Record_gas_flat_pfx { + typedef GasLimitsPrices type_class; + unsigned long long flat_gas_limit; // flat_gas_limit : uint64 + unsigned long long flat_gas_price; // flat_gas_price : uint64 + Ref other; // other : GasLimitsPrices + Record_gas_flat_pfx() = default; + Record_gas_flat_pfx(unsigned long long _flat_gas_limit, unsigned long long _flat_gas_price, Ref _other) : flat_gas_limit(_flat_gas_limit), flat_gas_price(_flat_gas_price), other(std::move(_other)) {} +}; + extern const GasLimitsPrices t_GasLimitsPrices; // @@ -6522,7 +6542,7 @@ extern const ValidatorSignedTempKey t_ValidatorSignedTempKey; // struct ConfigParam final : TLB_Complex { - enum { cons32, cons33, cons34, cons35, cons36, cons37, config_mc_block_limits, config_block_limits, cons14, cons0, cons1, cons2, cons3, cons4, cons6, cons7, cons9, cons12, cons15, cons16, cons17, cons18, cons31, cons39, cons28, cons8, cons29, config_mc_gas_prices, config_gas_prices, config_mc_fwd_prices, config_fwd_prices }; + enum { cons32, cons33, cons34, cons35, cons36, cons37, config_mc_block_limits, config_block_limits, cons14, cons0, cons1, cons2, cons3, cons4, cons6, cons7, cons9, cons12, cons15, cons16, cons17, cons18, cons31, cons39, cons28, cons8, config_mc_gas_prices, config_gas_prices, cons29, config_mc_fwd_prices, config_fwd_prices }; static constexpr int cons_len_exact = 0; int m_; ConfigParam(int m) : m_(m) {} diff --git a/submodules/ton/tonlib-src/crypto/block/block-parse.cpp b/submodules/ton/tonlib-src/crypto/block/block-parse.cpp index 89fc3d6f02..c410e2cb53 100644 --- a/submodules/ton/tonlib-src/crypto/block/block-parse.cpp +++ b/submodules/ton/tonlib-src/crypto/block/block-parse.cpp @@ -1143,6 +1143,20 @@ bool TrStoragePhase::validate_skip(vm::CellSlice& cs, bool weak) const { && t_AccStatusChange.validate_skip(cs, weak); // status_change:AccStatusChange } +bool TrStoragePhase::get_storage_fees(vm::CellSlice& cs, td::RefInt256& storage_fees) const { + return t_Grams.as_integer_skip_to(cs, storage_fees); // storage_fees_collected:Grams +} + +bool TrStoragePhase::maybe_get_storage_fees(vm::CellSlice& cs, td::RefInt256& storage_fees) const { + auto z = cs.fetch_ulong(1); + if (!z) { + storage_fees = td::make_refint(0); + return true; + } else { + return z == 1 && get_storage_fees(cs, storage_fees); + } +} + const TrStoragePhase t_TrStoragePhase; bool TrCreditPhase::skip(vm::CellSlice& cs) const { @@ -1322,13 +1336,14 @@ bool TransactionDescr::skip(vm::CellSlice& cs) const { && t_TrStoragePhase.skip(cs); // storage_ph:TrStoragePhase case trans_tick_tock: return cs.advance(4) // trans_tick_tock$001 is_tock:Bool - && t_TrStoragePhase.skip(cs) // storage:TrStoragePhase + && t_TrStoragePhase.skip(cs) // storage_ph:TrStoragePhase && t_TrComputePhase.skip(cs) // compute_ph:TrComputePhase && Maybe>{}.skip(cs) // action:(Maybe ^TrActionPhase) && cs.advance(2); // aborted:Bool destroyed:Bool case trans_split_prepare: return cs.advance(4) // trans_split_prepare$0100 && t_SplitMergeInfo.skip(cs) // split_info:SplitMergeInfo + && Maybe{}.skip(cs) // storage_ph:(Maybe TrStoragePhase) && t_TrComputePhase.skip(cs) // compute_ph:TrComputePhase && Maybe>{}.skip(cs) // action:(Maybe ^TrActionPhase) && cs.advance(2); // aborted:Bool destroyed:Bool @@ -1346,6 +1361,7 @@ bool TransactionDescr::skip(vm::CellSlice& cs) const { return cs.advance(4) // trans_merge_install$0111 && t_SplitMergeInfo.skip(cs) // split_info:SplitMergeInfo && t_Ref_Transaction.skip(cs) // prepare_transaction:^Transaction + && Maybe{}.skip(cs) // storage_ph:(Maybe TrStoragePhase) && Maybe{}.skip(cs) // credit_ph:(Maybe TrCreditPhase) && Maybe{}.skip(cs) // compute_ph:TrComputePhase && Maybe>{}.skip(cs) // action:(Maybe ^TrActionPhase) @@ -1370,13 +1386,14 @@ bool TransactionDescr::validate_skip(vm::CellSlice& cs, bool weak) const { && t_TrStoragePhase.validate_skip(cs, weak); // storage_ph:TrStoragePhase case trans_tick_tock: return cs.advance(4) // trans_tick_tock$001 is_tock:Bool - && t_TrStoragePhase.validate_skip(cs, weak) // storage:TrStoragePhase + && t_TrStoragePhase.validate_skip(cs, weak) // storage_ph:TrStoragePhase && t_TrComputePhase.validate_skip(cs, weak) // compute_ph:TrComputePhase && Maybe>{}.validate_skip(cs, weak) // action:(Maybe ^TrActionPhase) && cs.advance(2); // aborted:Bool destroyed:Bool case trans_split_prepare: return cs.advance(4) // trans_split_prepare$0100 && t_SplitMergeInfo.validate_skip(cs, weak) // split_info:SplitMergeInfo + && Maybe{}.validate_skip(cs, weak) // storage_ph:(Maybe TrStoragePhase) && t_TrComputePhase.validate_skip(cs, weak) // compute_ph:TrComputePhase && Maybe>{}.validate_skip(cs, weak) // action:(Maybe ^TrActionPhase) && cs.advance(2); // aborted:Bool destroyed:Bool @@ -1394,6 +1411,7 @@ bool TransactionDescr::validate_skip(vm::CellSlice& cs, bool weak) const { return cs.advance(4) // trans_merge_install$0111 && t_SplitMergeInfo.validate_skip(cs, weak) // split_info:SplitMergeInfo && t_Ref_Transaction.validate_skip(cs, weak) // prepare_transaction:^Transaction + && Maybe{}.validate_skip(cs, weak) // storage_ph:(Maybe TrStoragePhase) && Maybe{}.validate_skip(cs, weak) // credit_ph:(Maybe TrCreditPhase) && Maybe{}.validate_skip(cs, weak) // compute_ph:TrComputePhase && Maybe>{}.validate_skip(cs, weak) // action:(Maybe ^TrActionPhase) @@ -1407,6 +1425,53 @@ int TransactionDescr::get_tag(const vm::CellSlice& cs) const { return (t >= 0 && t <= 7) ? (t == 3 ? 2 : t) : -1; } +bool TransactionDescr::skip_to_storage_phase(vm::CellSlice& cs, bool& found) const { + found = false; + switch (get_tag(cs)) { + case trans_ord: + return cs.advance(4 + 1) // trans_ord$0000 storage_first:Bool + && cs.fetch_bool_to(found); // storage_ph:(Maybe TrStoragePhase) + case trans_storage: + return cs.advance(4) // trans_storage$0001 + && (found = true); // storage_ph:TrStoragePhase + case trans_tick_tock: + return cs.advance(4) // trans_tick_tock$001 is_tock:Bool + && (found = true); // storage_ph:TrStoragePhase + case trans_split_prepare: + return cs.advance(4) // trans_split_prepare$0100 + && t_SplitMergeInfo.skip(cs) // split_info:SplitMergeInfo + && cs.fetch_bool_to(found); // storage_ph:(Maybe TrStoragePhase) + case trans_split_install: + return true; + case trans_merge_prepare: + return cs.advance(4) // trans_merge_prepare$0110 + && t_SplitMergeInfo.skip(cs) // split_info:SplitMergeInfo + && (found = true); // storage_ph:TrStoragePhase + case trans_merge_install: + return cs.advance(4) // trans_merge_install$0111 + && t_SplitMergeInfo.skip(cs) // split_info:SplitMergeInfo + && t_Ref_Transaction.skip(cs) // prepare_transaction:^Transaction + && cs.fetch_bool_to(found); // storage_ph:(Maybe TrStoragePhase) + } + return false; +} + +bool TransactionDescr::get_storage_fees(Ref cell, td::RefInt256& storage_fees) const { + if (cell.is_null()) { + return false; + } + auto cs = vm::load_cell_slice(std::move(cell)); + bool found; + if (!skip_to_storage_phase(cs, found)) { + return false; + } else if (found) { + return t_TrStoragePhase.get_storage_fees(cs, storage_fees); + } else { + storage_fees = td::make_refint(0); + return true; + } +} + const TransactionDescr t_TransactionDescr; bool Transaction_aux::skip(vm::CellSlice& cs) const { @@ -1447,6 +1512,32 @@ bool Transaction::validate_skip(vm::CellSlice& cs, bool weak) const { && RefTo{}.validate_skip(cs, weak); // description:^TransactionDescr } +bool Transaction::get_storage_fees(Ref cell, td::RefInt256& storage_fees) const { + Ref tdescr; + return get_descr(std::move(cell), tdescr) && t_TransactionDescr.get_storage_fees(std::move(tdescr), storage_fees); +} + +bool Transaction::get_descr(Ref cell, Ref& tdescr) const { + if (cell.is_null()) { + return false; + } else { + auto cs = vm::load_cell_slice(std::move(cell)); + return cs.is_valid() && get_descr(cs, tdescr) && cs.empty_ext(); + } +} + +bool Transaction::get_descr(vm::CellSlice& cs, Ref& tdescr) const { + return cs.advance( + 4 + 256 + 64 + 256 + 64 + 32 + + 15) // transaction$0111 account_addr:uint256 lt:uint64 prev_trans_hash:bits256 prev_trans_lt:uint64 now:uint32 outmsg_cnt:uint15 + && t_AccountStatus.skip(cs) // orig_status:AccountStatus + && t_AccountStatus.skip(cs) // end_status:AccountStatus + && cs.advance_refs(1) // ^[ in_msg:(Maybe ^Message) out_msgs:(HashmapE 15 ^Message) ] + && t_CurrencyCollection.skip(cs) // total_fees:CurrencyCollection + && cs.advance_refs(1) // state_update:^(MERKLE_UPDATE Account) + && cs.fetch_ref_to(tdescr); // description:^TransactionDescr +} + bool Transaction::get_total_fees(vm::CellSlice&& cs, block::CurrencyCollection& total_fees) const { return cs.is_valid() && cs.fetch_ulong(4) == 7 // transaction$0111 && diff --git a/submodules/ton/tonlib-src/crypto/block/block-parse.h b/submodules/ton/tonlib-src/crypto/block/block-parse.h index 381dc149f3..acbe9dd426 100644 --- a/submodules/ton/tonlib-src/crypto/block/block-parse.h +++ b/submodules/ton/tonlib-src/crypto/block/block-parse.h @@ -614,6 +614,8 @@ extern const AccStatusChange t_AccStatusChange; struct TrStoragePhase final : TLB_Complex { bool skip(vm::CellSlice& cs) const override; bool validate_skip(vm::CellSlice& cs, bool weak = false) const override; + bool get_storage_fees(vm::CellSlice& cs, td::RefInt256& storage_fees) const; + bool maybe_get_storage_fees(vm::CellSlice& cs, td::RefInt256& storage_fees) const; }; extern const TrStoragePhase t_TrStoragePhase; @@ -693,6 +695,8 @@ struct TransactionDescr final : TLB_Complex { bool skip(vm::CellSlice& cs) const override; bool validate_skip(vm::CellSlice& cs, bool weak = false) const override; int get_tag(const vm::CellSlice& cs) const override; + bool skip_to_storage_phase(vm::CellSlice& cs, bool& found) const; + bool get_storage_fees(Ref cell, td::RefInt256& storage_fees) const; }; extern const TransactionDescr t_TransactionDescr; @@ -708,6 +712,9 @@ struct Transaction final : TLB_Complex { bool skip(vm::CellSlice& cs) const override; bool validate_skip(vm::CellSlice& cs, bool weak = false) const override; bool get_total_fees(vm::CellSlice&& cs, block::CurrencyCollection& total_fees) const; + bool get_descr(Ref cell, Ref& tdescr) const; + bool get_descr(vm::CellSlice& cs, Ref& tdescr) const; + bool get_storage_fees(Ref cell, td::RefInt256& storage_fees) const; }; extern const Transaction t_Transaction; diff --git a/submodules/ton/tonlib-src/crypto/block/block.cpp b/submodules/ton/tonlib-src/crypto/block/block.cpp index 6a0234f3ab..7b8074bfbc 100644 --- a/submodules/ton/tonlib-src/crypto/block/block.cpp +++ b/submodules/ton/tonlib-src/crypto/block/block.cpp @@ -368,14 +368,14 @@ std::unique_ptr MsgProcessedUptoCollection::unpack(t return v && v->valid ? std::move(v) : std::unique_ptr{}; } -bool MsgProcessedUpto::contains(const MsgProcessedUpto& other) const& { +bool MsgProcessedUpto::contains(const MsgProcessedUpto& other) const & { return ton::shard_is_ancestor(shard, other.shard) && mc_seqno >= other.mc_seqno && (last_inmsg_lt > other.last_inmsg_lt || (last_inmsg_lt == other.last_inmsg_lt && !(last_inmsg_hash < other.last_inmsg_hash))); } bool MsgProcessedUpto::contains(ton::ShardId other_shard, ton::LogicalTime other_lt, td::ConstBitPtr other_hash, - ton::BlockSeqno other_mc_seqno) const& { + ton::BlockSeqno other_mc_seqno) const & { return ton::shard_is_ancestor(shard, other_shard) && mc_seqno >= other_mc_seqno && (last_inmsg_lt > other_lt || (last_inmsg_lt == other_lt && !(last_inmsg_hash < other_hash))); } @@ -552,7 +552,9 @@ bool MsgProcessedUpto::already_processed(const EnqueuedMsgDescr& msg) const { if (msg.lt_ == last_inmsg_lt && last_inmsg_hash < msg.hash_) { return false; } - if (ton::shard_contains(shard, msg.cur_prefix_.account_id_prefix)) { + if (msg.same_workchain() && ton::shard_contains(shard, msg.cur_prefix_.account_id_prefix)) { + // this branch is needed only for messages generated in the same shard + // (such messages could have been processed without a reference from the masterchain) // ? enable this branch only if an extra boolean parameter is set ? return true; } diff --git a/submodules/ton/tonlib-src/crypto/block/block.h b/submodules/ton/tonlib-src/crypto/block/block.h index 377f99c2b8..9fbeedf29f 100644 --- a/submodules/ton/tonlib-src/crypto/block/block.h +++ b/submodules/ton/tonlib-src/crypto/block/block.h @@ -145,6 +145,9 @@ struct EnqueuedMsgDescr { return false; } bool unpack(vm::CellSlice& cs); + bool same_workchain() const { + return cur_prefix_.workchain == next_prefix_.workchain; + } }; using compute_shard_end_lt_func_t = std::function; diff --git a/submodules/ton/tonlib-src/crypto/block/block.tlb b/submodules/ton/tonlib-src/crypto/block/block.tlb index b9db5fe6ec..5108294770 100644 --- a/submodules/ton/tonlib-src/crypto/block/block.tlb +++ b/submodules/ton/tonlib-src/crypto/block/block.tlb @@ -325,7 +325,7 @@ trans_ord$0000 credit_first:Bool trans_storage$0001 storage_ph:TrStoragePhase = TransactionDescr; -trans_tick_tock$001 is_tock:Bool storage:TrStoragePhase +trans_tick_tock$001 is_tock:Bool storage_ph:TrStoragePhase compute_ph:TrComputePhase action:(Maybe ^TrActionPhase) aborted:Bool destroyed:Bool = TransactionDescr; // @@ -333,6 +333,7 @@ split_merge_info$_ cur_shard_pfx_len:(## 6) acc_split_depth:(## 6) this_addr:bits256 sibling_addr:bits256 = SplitMergeInfo; trans_split_prepare$0100 split_info:SplitMergeInfo + storage_ph:(Maybe TrStoragePhase) compute_ph:TrComputePhase action:(Maybe ^TrActionPhase) aborted:Bool destroyed:Bool = TransactionDescr; @@ -345,6 +346,7 @@ trans_merge_prepare$0110 split_info:SplitMergeInfo = TransactionDescr; trans_merge_install$0111 split_info:SplitMergeInfo prepare_transaction:^Transaction + storage_ph:(Maybe TrStoragePhase) credit_ph:(Maybe TrCreditPhase) compute_ph:TrComputePhase action:(Maybe ^TrActionPhase) aborted:Bool destroyed:Bool @@ -609,6 +611,9 @@ gas_prices_ext#de gas_price:uint64 gas_limit:uint64 special_gas_limit:uint64 gas block_gas_limit:uint64 freeze_due_limit:uint64 delete_due_limit:uint64 = GasLimitsPrices; +gas_flat_pfx#d1 flat_gas_limit:uint64 flat_gas_price:uint64 other:GasLimitsPrices + = GasLimitsPrices; + config_mc_gas_prices#_ GasLimitsPrices = ConfigParam 20; config_gas_prices#_ GasLimitsPrices = ConfigParam 21; diff --git a/submodules/ton/tonlib-src/crypto/block/transaction.cpp b/submodules/ton/tonlib-src/crypto/block/transaction.cpp index 11f118d4d3..24fc731ee4 100644 --- a/submodules/ton/tonlib-src/crypto/block/transaction.cpp +++ b/submodules/ton/tonlib-src/crypto/block/transaction.cpp @@ -672,9 +672,56 @@ bool Transaction::prepare_credit_phase() { return true; } +bool ComputePhaseConfig::parse_GasLimitsPrices(Ref cell, td::RefInt256& freeze_due_limit, + td::RefInt256& delete_due_limit) { + return cell.not_null() && + parse_GasLimitsPrices(vm::load_cell_slice_ref(std::move(cell)), freeze_due_limit, delete_due_limit); +} + +bool ComputePhaseConfig::parse_GasLimitsPrices(Ref cs, td::RefInt256& freeze_due_limit, + td::RefInt256& delete_due_limit) { + if (cs.is_null()) { + return false; + } + block::gen::GasLimitsPrices::Record_gas_flat_pfx flat; + if (tlb::csr_unpack(cs, flat)) { + bool ok = parse_GasLimitsPrices(std::move(flat.other), freeze_due_limit, delete_due_limit); + flat_gas_limit = flat.flat_gas_limit; + flat_gas_price = flat.flat_gas_price; + return ok; + } + flat_gas_limit = flat_gas_price = 0; + auto f = [&](const auto& r, td::uint64 spec_limit) { + gas_limit = r.gas_limit; + special_gas_limit = spec_limit; + gas_credit = r.gas_credit; + gas_price = r.gas_price; + freeze_due_limit = td::RefInt256{true, r.freeze_due_limit}; + delete_due_limit = td::RefInt256{true, r.delete_due_limit}; + }; + block::gen::GasLimitsPrices::Record_gas_prices_ext rec; + if (tlb::csr_unpack(cs, rec)) { + f(rec, rec.special_gas_limit); + } else { + block::gen::GasLimitsPrices::Record_gas_prices rec0; + if (tlb::csr_unpack(std::move(cs), rec0)) { + f(rec0, rec0.gas_limit); + } else { + return false; + } + } + compute_threshold(); + return true; +} + void ComputePhaseConfig::compute_threshold() { gas_price256 = td::RefInt256{true, gas_price}; - max_gas_threshold = td::rshift(gas_price256 * gas_limit, 16, 1); + if (gas_limit > flat_gas_limit) { + max_gas_threshold = + td::rshift(gas_price256 * (gas_limit - flat_gas_limit), 16, 1) + td::make_refint(flat_gas_price); + } else { + max_gas_threshold = td::make_refint(flat_gas_price); + } } td::uint64 ComputePhaseConfig::gas_bought_for(td::RefInt256 nanograms) const { @@ -684,8 +731,11 @@ td::uint64 ComputePhaseConfig::gas_bought_for(td::RefInt256 nanograms) const { if (nanograms >= max_gas_threshold) { return gas_limit; } - auto res = td::div(std::move(nanograms) << 16, gas_price256); - return res->to_long(); + if (nanograms < flat_gas_price) { + return 0; + } + auto res = td::div((std::move(nanograms) - flat_gas_price) << 16, gas_price256); + return res->to_long() + flat_gas_limit; } td::RefInt256 ComputePhaseConfig::compute_gas_price(td::uint64 gas_used) const { @@ -855,6 +905,16 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) { cp.skip_reason = ComputePhase::sk_no_gas; return true; } + // Compute gas limits + if (!compute_gas_limits(cp, cfg)) { + compute_phase.reset(); + return false; + } + if (!cp.gas_limit && !cp.gas_credit) { + // no gas + cp.skip_reason = ComputePhase::sk_no_gas; + return true; + } if (in_msg_state.not_null()) { LOG(DEBUG) << "HASH(in_msg_state) = " << in_msg_state->get_hash().bits().to_hex(256) << ", account_state_hash = " << account.state_hash.to_hex(); @@ -883,11 +943,6 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) { } else if (in_msg_state.not_null()) { unpack_msg_state(true); // use only libraries } - // Compute gas limits - if (!compute_gas_limits(cp, cfg)) { - compute_phase.reset(); - return false; - } // initialize VM Ref stack = prepare_vm_stack(cp); if (stack.is_null()) { diff --git a/submodules/ton/tonlib-src/crypto/block/transaction.h b/submodules/ton/tonlib-src/crypto/block/transaction.h index 45e824c1e8..015dc3f39e 100644 --- a/submodules/ton/tonlib-src/crypto/block/transaction.h +++ b/submodules/ton/tonlib-src/crypto/block/transaction.h @@ -98,6 +98,8 @@ struct ComputePhaseConfig { td::uint64 gas_limit; td::uint64 special_gas_limit; td::uint64 gas_credit; + td::uint64 flat_gas_limit = 0; + td::uint64 flat_gas_price = 0; static constexpr td::uint64 gas_infty = (1ULL << 63) - 1; td::RefInt256 gas_price256; td::RefInt256 max_gas_threshold; @@ -126,6 +128,8 @@ struct ComputePhaseConfig { Ref get_lib_root() const { return libraries ? libraries->get_root_cell() : Ref{}; } + bool parse_GasLimitsPrices(Ref cs, td::RefInt256& freeze_due_limit, td::RefInt256& delete_due_limit); + bool parse_GasLimitsPrices(Ref cell, td::RefInt256& freeze_due_limit, td::RefInt256& delete_due_limit); }; // msg_fwd_fees = (lump_price + ceil((bit_price * msg.bits + cell_price * msg.cells)/2^16)) nanograms diff --git a/submodules/ton/tonlib-src/crypto/fift/SourceLookup.h b/submodules/ton/tonlib-src/crypto/fift/SourceLookup.h index 33ee71d4ef..7d51396cb3 100644 --- a/submodules/ton/tonlib-src/crypto/fift/SourceLookup.h +++ b/submodules/ton/tonlib-src/crypto/fift/SourceLookup.h @@ -79,7 +79,7 @@ class SourceLookup { if (os_time_) { return os_time_->now(); } - return static_cast(td::Time::now()); + return static_cast(td::Clocks::system()); } protected: diff --git a/submodules/ton/tonlib-src/crypto/fift/lib/Fift.fif b/submodules/ton/tonlib-src/crypto/fift/lib/Fift.fif index 59cbcb713f..65fecb3116 100644 --- a/submodules/ton/tonlib-src/crypto/fift/lib/Fift.fif +++ b/submodules/ton/tonlib-src/crypto/fift/lib/Fift.fif @@ -25,7 +25,7 @@ { bl word 1 { -rot 2 'nop does swap 0 (create) } } :: 2=: { } : s>c -{ s>c hash } : shash +{ s>c hashB } : shash // to be more efficiently re-implemented in C++ in the future { dup 0< ' negate if } : abs { 2dup > ' swap if } : minmax diff --git a/submodules/ton/tonlib-src/crypto/fift/words.cpp b/submodules/ton/tonlib-src/crypto/fift/words.cpp index 01dcf802c8..0b97ece94e 100644 --- a/submodules/ton/tonlib-src/crypto/fift/words.cpp +++ b/submodules/ton/tonlib-src/crypto/fift/words.cpp @@ -764,13 +764,17 @@ void interpret_string_to_bytes(vm::Stack& stack) { stack.push_bytes(stack.pop_string()); } -void interpret_bytes_hash(vm::Stack& stack) { +void interpret_bytes_hash(vm::Stack& stack, bool as_uint) { std::string str = stack.pop_bytes(); unsigned char buffer[32]; digest::hash_str(buffer, str.c_str(), str.size()); - td::RefInt256 x{true}; - x.write().import_bytes(buffer, 32, false); - stack.push_int(std::move(x)); + if (as_uint) { + td::RefInt256 x{true}; + x.write().import_bytes(buffer, 32, false); + stack.push_int(std::move(x)); + } else { + stack.push_bytes(std::string{(char*)buffer, 32}); + } } void interpret_empty(vm::Stack& stack) { @@ -892,11 +896,15 @@ void interpret_builder_remaining_bitrefs(vm::Stack& stack, int mode) { } } -void interpret_cell_hash(vm::Stack& stack) { +void interpret_cell_hash(vm::Stack& stack, bool as_uint) { auto cell = stack.pop_cell(); - td::RefInt256 hash{true}; - hash.write().import_bytes(cell->get_hash().as_slice().ubegin(), 32, false); - stack.push_int(std::move(hash)); + if (as_uint) { + td::RefInt256 hash{true}; + hash.write().import_bytes(cell->get_hash().as_slice().ubegin(), 32, false); + stack.push_int(std::move(hash)); + } else { + stack.push_bytes(cell->get_hash().as_slice().str()); + } } void interpret_store_ref(vm::Stack& stack) { @@ -934,7 +942,9 @@ void interpret_fetch(vm::Stack& stack, int mode) { auto n = stack.pop_smallint_range(256 + (mode & 1)); auto cs = stack.pop_cellslice(); if (!cs->have(n)) { - stack.push(std::move(cs)); + if (mode & 2) { + stack.push(std::move(cs)); + } stack.push_bool(false); if (!(mode & 4)) { throw IntError{"end of data while reading integer from cell"}; @@ -959,7 +969,9 @@ void interpret_fetch_bytes(vm::Stack& stack, int mode) { unsigned n = stack.pop_smallint_range(127); auto cs = stack.pop_cellslice(); if (!cs->have(n * 8)) { - stack.push(std::move(cs)); + if (mode & 2) { + stack.push(std::move(cs)); + } stack.push_bool(false); if (!(mode & 4)) { throw IntError{"end of data while reading byte string from cell"}; @@ -970,7 +982,7 @@ void interpret_fetch_bytes(vm::Stack& stack, int mode) { if (mode & 2) { cs.write().fetch_bytes(tmp, n); } else { - cs.write().prefetch_bytes(tmp, n); + cs->prefetch_bytes(tmp, n); } std::string s{tmp, tmp + n}; if (mode & 1) { @@ -978,7 +990,9 @@ void interpret_fetch_bytes(vm::Stack& stack, int mode) { } else { stack.push_string(std::move(s)); } - stack.push(std::move(cs)); + if (mode & 2) { + stack.push(std::move(cs)); + } if (mode & 4) { stack.push_bool(true); } @@ -1009,13 +1023,15 @@ void interpret_cell_remaining(vm::Stack& stack) { void interpret_fetch_ref(vm::Stack& stack, int mode) { auto cs = stack.pop_cellslice(); if (!cs->have_refs(1)) { - stack.push(std::move(cs)); + if (mode & 2) { + stack.push(std::move(cs)); + } stack.push_bool(false); if (!(mode & 4)) { throw IntError{"end of data while reading reference from cell"}; } } else { - auto cell = (mode & 2) ? cs.write().fetch_ref() : cs.write().prefetch_ref(); + auto cell = (mode & 2) ? cs.write().fetch_ref() : cs->prefetch_ref(); if (mode & 2) { stack.push(std::move(cs)); } @@ -2474,7 +2490,9 @@ void init_words_common(Dictionary& d) { d.def_stack_word("B>Lu@+ ", std::bind(interpret_bytes_fetch_int, _1, 0x12)); d.def_stack_word("B>Li@+ ", std::bind(interpret_bytes_fetch_int, _1, 0x13)); d.def_stack_word("$>B ", interpret_string_to_bytes); - d.def_stack_word("Bhash ", interpret_bytes_hash); + d.def_stack_word("Bhash ", std::bind(interpret_bytes_hash, _1, true)); + d.def_stack_word("Bhashu ", std::bind(interpret_bytes_hash, _1, true)); + d.def_stack_word("BhashB ", std::bind(interpret_bytes_hash, _1, false)); // cell manipulation (create, write and modify cells) d.def_stack_word("is_empty(); - stack.o << (next_empty ? "WHILEEND:<{" : "WHILE:<{"); + stack.o << "WHILE:<{"; stack.o.indent(); stack.forget_const(); block0->generate_code_all(stack); @@ -638,7 +638,7 @@ bool Op::generate_code_step(Stack& stack) { stack.modified(); stack.o.undent(); Stack stack_copy{stack}; - stack.o << (next_empty ? "}>" : "}>DO<{"); + stack.o << (next_empty ? "}>DO:" : "}>DO<{"); if (!next_empty) { stack.o.indent(); } diff --git a/submodules/ton/tonlib-src/crypto/parser/srcread.cpp b/submodules/ton/tonlib-src/crypto/parser/srcread.cpp index ac031e1e14..3b363242ba 100644 --- a/submodules/ton/tonlib-src/crypto/parser/srcread.cpp +++ b/submodules/ton/tonlib-src/crypto/parser/srcread.cpp @@ -169,6 +169,11 @@ bool SourceReader::load_line() { error("line too long"); return false; } + if (len && cur_line.back() == '\r') { + // CP/M line breaks support + cur_line.pop_back(); + --len; + } loc.text = cur_line; cur_line_len = (int)len; loc.line_pos = 0; diff --git a/submodules/ton/tonlib-src/crypto/smartcont/gen-zerostate-test.fif b/submodules/ton/tonlib-src/crypto/smartcont/gen-zerostate-test.fif index 58161a2318..2e6d87a75e 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/gen-zerostate-test.fif +++ b/submodules/ton/tonlib-src/crypto/smartcont/gen-zerostate-test.fif @@ -15,10 +15,10 @@ cr ."initial basechain state is:" cr dup B dup Bx. cr dup "basestate0" +suffix +".boc" tuck B>file ."(Initial basechain state saved to file " type .")" cr -Bhash dup =: basestate0_fhash +Bhashu dup =: basestate0_fhash ."file hash=" dup x. space 256 u>B dup B>base64url type cr "basestate0" +suffix +".fhash" B>file -hash dup =: basestate0_rhash +hashu dup =: basestate0_rhash ."root hash=" dup x. space 256 u>B dup B>base64url type cr "basestate0" +suffix +".rhash" B>file @@ -227,10 +227,10 @@ cr cr ."new state is:" cr dup B dup Bx. cr dup "zerostate" +suffix +".boc" tuck B>file ."(Initial masterchain state saved to file " type .")" cr -Bhash dup =: zerostate_fhash +Bhashu dup =: zerostate_fhash ."file hash=" dup x. space 256 u>B dup B>base64url type cr "zerostate" +suffix +".fhash" B>file -hash dup =: zerostate_rhash ."root hash=" dup x. space 256 u>B dup B>base64url type cr +hashu dup =: zerostate_rhash ."root hash=" dup x. space 256 u>B dup B>base64url type cr "zerostate" +suffix +".rhash" B>file basestate0_rhash ."Basestate0 root hash=" dup x. space 256 u>B B>base64url type cr basestate0_fhash ."Basestate0 file hash=" dup x. space 256 u>B B>base64url type cr diff --git a/submodules/ton/tonlib-src/crypto/smartcont/gen-zerostate.fif b/submodules/ton/tonlib-src/crypto/smartcont/gen-zerostate.fif index f5f9aac39e..43ba07b156 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/gen-zerostate.fif +++ b/submodules/ton/tonlib-src/crypto/smartcont/gen-zerostate.fif @@ -15,10 +15,10 @@ cr ."initial basechain state is:" cr dup B dup Bx. cr dup "basestate0" +suffix +".boc" tuck B>file ."(Initial basechain state saved to file " type .")" cr -Bhash dup =: basestate0_fhash +Bhashu dup =: basestate0_fhash ."file hash=" dup x. space 256 u>B dup B>base64url type cr "basestate0" +suffix +".fhash" B>file -hash dup =: basestate0_rhash +hashu dup =: basestate0_rhash ."root hash=" dup x. space 256 u>B dup B>base64url type cr "basestate0" +suffix +".rhash" B>file @@ -231,10 +231,10 @@ cr cr ."new state is:" cr dup B dup Bx. cr dup "zerostate" +suffix +".boc" tuck B>file ."(Initial masterchain state saved to file " type .")" cr -Bhash dup =: zerostate_fhash +Bhashu dup =: zerostate_fhash ."file hash= " dup X. space 256 u>B dup B>base64url type cr "zerostate" +suffix +".fhash" B>file -hash dup =: zerostate_rhash ."root hash= " dup X. space 256 u>B dup B>base64url type cr +hashu dup =: zerostate_rhash ."root hash= " dup X. space 256 u>B dup B>base64url type cr "zerostate" +suffix +".rhash" B>file basestate0_rhash ."Basestate0 root hash= " dup X. space 256 u>B B>base64url type cr basestate0_fhash ."Basestate0 file hash= " dup X. space 256 u>B B>base64url type cr diff --git a/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-code.fc b/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-code.fc new file mode 100644 index 0000000000..70abb48e23 --- /dev/null +++ b/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-code.fc @@ -0,0 +1,41 @@ +;; Heavy-duty wallet for mass transfers (e.g., for cryptocurrency exchanges) +;; accepts orders for up to 254 internal messages (transfers) in one external message + +() recv_internal(slice in_msg) impure { + ;; do nothing for internal messages +} + +() recv_external(slice in_msg) impure { + var signature = in_msg~load_bits(512); + var cs = in_msg; + var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32)); + throw_if(35, valid_until <= now()); + var ds = get_data().begin_parse(); + var (stored_seqno, stored_subwallet, public_key) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256)); + ds.end_parse(); + throw_unless(33, msg_seqno == stored_seqno); + throw_unless(34, subwallet_id == stored_subwallet); + throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key)); + var dict = cs~load_dict(); + cs.end_parse(); + accept_message(); + int i = -1; + do { + (i, var cs, var f) = dict.idict_get_next?(16, i); + if (f) { + var mode = cs~load_uint(8); + send_raw_message(cs~load_ref(), mode); + } + } until (~ f); + set_data(begin_cell() + .store_uint(stored_seqno + 1, 32) + .store_uint(stored_subwallet, 32) + .store_uint(public_key, 256) + .end_cell()); +} + +;; Get methods + +int seqno() method_id { + return get_data().begin_parse().preload_uint(32); +} diff --git a/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-code.fif b/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-code.fif new file mode 100644 index 0000000000..d2122a96fb --- /dev/null +++ b/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-code.fif @@ -0,0 +1,79 @@ +// automatically generated from `smartcont/stdlib.fc` `smartcont/highload-wallet-code.fc` +PROGRAM{ + DECLPROC recv_internal + DECLPROC recv_external + 85143 DECLMETHOD seqno + recv_internal PROC:<{ + // in_msg + DROP // + }> + recv_external PROC:<{ + // in_msg + 9 PUSHPOW2 // in_msg _3=512 + LDSLICEX // signature in_msg + DUP // signature in_msg cs + 32 LDU // signature in_msg _9 cs + 32 LDU // signature in_msg _9 _12 cs + 32 LDU // signature in_msg subwallet_id valid_until msg_seqno cs + NOW // signature in_msg subwallet_id valid_until msg_seqno cs _19 + s1 s3 XCHG // signature in_msg subwallet_id cs msg_seqno valid_until _19 + LEQ // signature in_msg subwallet_id cs msg_seqno _20 + 35 THROWIF + c4 PUSH // signature in_msg subwallet_id cs msg_seqno _23 + CTOS // signature in_msg subwallet_id cs msg_seqno ds + 32 LDU // signature in_msg subwallet_id cs msg_seqno _28 ds + 32 LDU // signature in_msg subwallet_id cs msg_seqno _28 _31 ds + 256 LDU // signature in_msg subwallet_id cs msg_seqno stored_seqno stored_subwallet public_key ds + ENDS + s3 s2 XCPU // signature in_msg subwallet_id cs public_key stored_seqno stored_subwallet msg_seqno stored_seqno + EQUAL // signature in_msg subwallet_id cs public_key stored_seqno stored_subwallet _39 + 33 THROWIFNOT + s4 s4 XCPU // signature in_msg stored_subwallet cs public_key stored_seqno subwallet_id stored_subwallet + EQUAL // signature in_msg stored_subwallet cs public_key stored_seqno _42 + 34 THROWIFNOT + s0 s4 XCHG // signature stored_seqno stored_subwallet cs public_key in_msg + HASHSU // signature stored_seqno stored_subwallet cs public_key _45 + s0 s5 s5 XC2PU // public_key stored_seqno stored_subwallet cs _45 signature public_key + CHKSIGNU // public_key stored_seqno stored_subwallet cs _46 + 35 THROWIFNOT + LDDICT // public_key stored_seqno stored_subwallet dict cs + ENDS + ACCEPT + -1 PUSHINT // public_key stored_seqno stored_subwallet dict i=-1 + UNTIL:<{ + OVER + 16 PUSHINT // public_key stored_seqno stored_subwallet dict i dict _57=16 + DICTIGETNEXT + NULLSWAPIFNOT + NULLSWAPIFNOT // public_key stored_seqno stored_subwallet dict cs i f + DUP // public_key stored_seqno stored_subwallet dict cs i f f + IF:<{ // public_key stored_seqno stored_subwallet dict cs i f + s0 s2 XCHG // public_key stored_seqno stored_subwallet dict f i cs + 8 LDU // public_key stored_seqno stored_subwallet dict f i mode cs + LDREF // public_key stored_seqno stored_subwallet dict f i mode _100 _99 + DROP // public_key stored_seqno stored_subwallet dict f i mode _63 + SWAP // public_key stored_seqno stored_subwallet dict f i _63 mode + SENDRAWMSG + }>ELSE<{ + s2 POP // public_key stored_seqno stored_subwallet dict f i + }> + SWAP // public_key stored_seqno stored_subwallet dict i f + NOT // public_key stored_seqno stored_subwallet dict i _66 + }> // public_key stored_seqno stored_subwallet dict i + 2DROP // public_key stored_seqno stored_subwallet + SWAP // public_key stored_subwallet stored_seqno + INC // public_key stored_subwallet _68 + NEWC // public_key stored_subwallet _68 _69 + 32 STU // public_key stored_subwallet _71 + 32 STU // public_key _73 + 256 STU // _75 + ENDC // _76 + c4 POP + }> + seqno PROC:<{ + // + c4 PUSH // _0 + CTOS // _1 + 32 PLDU // _3 + }> +}END>c diff --git a/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-v2-code.fc b/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-v2-code.fc new file mode 100644 index 0000000000..88d7885563 --- /dev/null +++ b/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-v2-code.fc @@ -0,0 +1,65 @@ +;; Heavy-duty wallet for mass transfers (e.g., for cryptocurrency exchanges) +;; accepts orders for up to 254 internal messages (transfers) in one external message +;; this version does not use seqno for replay protection; instead, it remembers all recent query_ids +;; in this way several external messages with different query_id can be sent in parallel + +() recv_internal(slice in_msg) impure { + ;; do nothing for internal messages +} + +() recv_external(slice in_msg) impure { + var signature = in_msg~load_bits(512); + var cs = in_msg; + var (subwallet_id, query_id) = (cs~load_uint(32), cs~load_uint(64)); + var bound = (now() << 32); + throw_if(35, query_id < bound); + var ds = get_data().begin_parse(); + var (stored_subwallet, last_cleaned, public_key, old_queries) = (ds~load_uint(32), ds~load_uint(64), ds~load_uint(256), ds~load_dict()); + ds.end_parse(); + (_, var found?) = old_queries.udict_get?(64, query_id); + throw_if(32, found?); + throw_unless(34, subwallet_id == stored_subwallet); + throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key)); + var dict = cs~load_dict(); + cs.end_parse(); + accept_message(); + int i = -1; + do { + (i, var cs, var f) = dict.idict_get_next?(16, i); + if (f) { + var mode = cs~load_uint(8); + send_raw_message(cs~load_ref(), mode); + } + } until (~ f); + bound -= (64 << 32); ;; clean up records expired more than 64 seconds ago + old_queries~udict_set_builder(64, query_id, begin_cell()); + var queries = old_queries; + do { + var (old_queries', i, _, f) = old_queries.udict_delete_get_min(64); + f~touch(); + if (f) { + f = (i < bound); + } + if (f) { + old_queries = old_queries'; + last_cleaned = i; + } + } until (~ f); + set_data(begin_cell() + .store_uint(stored_subwallet, 32) + .store_uint(last_cleaned, 64) + .store_uint(public_key, 256) + .store_dict(old_queries) + .end_cell()); +} + +;; Get methods + +;; returns -1 for processed queries, 0 for unprocessed, 1 for unknown (forgotten) +int processed?(int query_id) method_id { + var ds = get_data().begin_parse(); + var (_, last_cleaned, _, old_queries) = (ds~load_uint(32), ds~load_uint(64), ds~load_uint(256), ds~load_dict()); + ds.end_parse(); + (_, var found) = old_queries.udict_get?(64, query_id); + return found ? true : - (query_id <= last_cleaned); +} diff --git a/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-v2-code.fif b/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-v2-code.fif new file mode 100644 index 0000000000..9d5e467de5 --- /dev/null +++ b/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-v2-code.fif @@ -0,0 +1,134 @@ +// automatically generated from `smartcont/stdlib.fc` `smartcont/highload-wallet-v2-code.fc` +PROGRAM{ + DECLPROC recv_internal + DECLPROC recv_external + 117746 DECLMETHOD processed? + recv_internal PROC:<{ + // in_msg + DROP // + }> + recv_external PROC:<{ + // in_msg + 9 PUSHPOW2 // in_msg _3=512 + LDSLICEX // signature in_msg + DUP // signature in_msg cs + 32 LDU // signature in_msg _8 cs + 64 LDU // signature in_msg subwallet_id query_id cs + NOW // signature in_msg subwallet_id query_id cs _15 + 32 LSHIFT# // signature in_msg subwallet_id query_id cs bound + s2 s0 PUSH2 // signature in_msg subwallet_id query_id cs bound query_id bound + LESS // signature in_msg subwallet_id query_id cs bound _19 + 35 THROWIF + c4 PUSH // signature in_msg subwallet_id query_id cs bound _22 + CTOS // signature in_msg subwallet_id query_id cs bound ds + 32 LDU // signature in_msg subwallet_id query_id cs bound _28 ds + 64 LDU // signature in_msg subwallet_id query_id cs bound _28 _31 ds + 256 LDU // signature in_msg subwallet_id query_id cs bound _28 _31 _34 ds + LDDICT // signature in_msg subwallet_id query_id cs bound stored_subwallet last_cleaned public_key old_queries ds + ENDS + s6 s0 PUSH2 + 64 PUSHINT // signature in_msg subwallet_id query_id cs bound stored_subwallet last_cleaned public_key old_queries query_id old_queries _42=64 + DICTUGET + NULLSWAPIFNOT // signature in_msg subwallet_id query_id cs bound stored_subwallet last_cleaned public_key old_queries _115 _116 + NIP // signature in_msg subwallet_id query_id cs bound stored_subwallet last_cleaned public_key old_queries found? + 32 THROWIF + s7 s3 XCPU // signature in_msg old_queries query_id cs bound stored_subwallet last_cleaned public_key subwallet_id stored_subwallet + EQUAL // signature in_msg old_queries query_id cs bound stored_subwallet last_cleaned public_key _47 + 34 THROWIFNOT + s0 s7 XCHG // signature public_key old_queries query_id cs bound stored_subwallet last_cleaned in_msg + HASHSU // signature public_key old_queries query_id cs bound stored_subwallet last_cleaned _50 + s0 s8 s7 XC2PU // last_cleaned public_key old_queries query_id cs bound stored_subwallet _50 signature public_key + CHKSIGNU // last_cleaned public_key old_queries query_id cs bound stored_subwallet _51 + 35 THROWIFNOT + s0 s2 XCHG // last_cleaned public_key old_queries query_id stored_subwallet bound cs + LDDICT // last_cleaned public_key old_queries query_id stored_subwallet bound dict cs + ENDS + ACCEPT + -1 PUSHINT // last_cleaned public_key old_queries query_id stored_subwallet bound dict i=-1 + UNTIL:<{ + OVER + 16 PUSHINT // last_cleaned public_key old_queries query_id stored_subwallet bound dict i dict _62=16 + DICTIGETNEXT + NULLSWAPIFNOT + NULLSWAPIFNOT // last_cleaned public_key old_queries query_id stored_subwallet bound dict cs i f + DUP // last_cleaned public_key old_queries query_id stored_subwallet bound dict cs i f f + IF:<{ // last_cleaned public_key old_queries query_id stored_subwallet bound dict cs i f + s0 s2 XCHG // last_cleaned public_key old_queries query_id stored_subwallet bound dict f i cs + 8 LDU // last_cleaned public_key old_queries query_id stored_subwallet bound dict f i mode cs + LDREF // last_cleaned public_key old_queries query_id stored_subwallet bound dict f i mode _125 _124 + DROP // last_cleaned public_key old_queries query_id stored_subwallet bound dict f i mode _68 + SWAP // last_cleaned public_key old_queries query_id stored_subwallet bound dict f i _68 mode + SENDRAWMSG + }>ELSE<{ + s2 POP // last_cleaned public_key old_queries query_id stored_subwallet bound dict f i + }> + SWAP // last_cleaned public_key old_queries query_id stored_subwallet bound dict i f + NOT // last_cleaned public_key old_queries query_id stored_subwallet bound dict i _71 + }> // last_cleaned public_key old_queries query_id stored_subwallet bound dict i + 2DROP // last_cleaned public_key old_queries query_id stored_subwallet bound + 38 PUSHPOW2 // last_cleaned public_key old_queries query_id stored_subwallet bound _74 + SUB // last_cleaned public_key old_queries query_id stored_subwallet bound + NEWC // last_cleaned public_key old_queries query_id stored_subwallet bound _77 + s0 s3 s4 XCHG3 + 64 PUSHINT // last_cleaned public_key stored_subwallet bound _77 query_id old_queries _78=64 + DICTUSETB // last_cleaned public_key stored_subwallet bound old_queries + UNTIL:<{ + DUP + 64 PUSHINT // last_cleaned public_key stored_subwallet bound old_queries old_queries _85=64 + DICTUREMMIN + NULLSWAPIFNOT + NULLSWAPIFNOT // last_cleaned public_key stored_subwallet bound old_queries _126 _128 _127 _129 + s2 POP // last_cleaned public_key stored_subwallet bound old_queries old_queries' f i + s1 s0 XCPU // last_cleaned public_key stored_subwallet bound old_queries old_queries' i f f + IF:<{ // last_cleaned public_key stored_subwallet bound old_queries old_queries' i f + DROP // last_cleaned public_key stored_subwallet bound old_queries old_queries' i + s0 s3 PUSH2 // last_cleaned public_key stored_subwallet bound old_queries old_queries' i i bound + LESS // last_cleaned public_key stored_subwallet bound old_queries old_queries' i f + }> // last_cleaned public_key stored_subwallet bound old_queries old_queries' i f + DUP // last_cleaned public_key stored_subwallet bound old_queries old_queries' i f f + IF:<{ // last_cleaned public_key stored_subwallet bound old_queries old_queries' i f + s3 POP + s6 POP // last_cleaned public_key stored_subwallet bound f old_queries + }>ELSE<{ + s3 s1 s3 XCHG3 + 2DROP // last_cleaned public_key stored_subwallet bound f old_queries + }> + SWAP // last_cleaned public_key stored_subwallet bound old_queries f + NOT // last_cleaned public_key stored_subwallet bound old_queries _90 + }> // last_cleaned public_key stored_subwallet bound old_queries + NIP // last_cleaned public_key stored_subwallet old_queries + NEWC // last_cleaned public_key stored_subwallet old_queries _91 + s1 s2 XCHG // last_cleaned public_key old_queries stored_subwallet _91 + 32 STU // last_cleaned public_key old_queries _93 + s1 s3 XCHG // old_queries public_key last_cleaned _93 + 64 STU // old_queries public_key _95 + 256 STU // old_queries _97 + STDICT // _98 + ENDC // _99 + c4 POP + }> + processed? PROC:<{ + // query_id + c4 PUSH // query_id _2 + CTOS // query_id ds + 32 LDU // query_id _29 _28 + NIP // query_id ds + 64 LDU // query_id _11 ds + 256 LDU // query_id _11 _33 _32 + NIP // query_id _11 ds + LDDICT // query_id last_cleaned old_queries ds + ENDS + s2 s(-1) PUXC + 64 PUSHINT // query_id last_cleaned query_id old_queries _22=64 + DICTUGET + NULLSWAPIFNOT // query_id last_cleaned _36 _37 + NIP // query_id last_cleaned found + IF:<{ // query_id last_cleaned + 2DROP // + TRUE // _24 + }>ELSE<{ // query_id last_cleaned + LEQ // _26 + NEGATE // _24 + }> + }> +}END>c diff --git a/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-v2.fif b/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-v2.fif new file mode 100644 index 0000000000..76f06ed590 --- /dev/null +++ b/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet-v2.fif @@ -0,0 +1,69 @@ +#!/usr/bin/env fift -s +"TonUtil.fif" include + +{ ."usage: " @' $0 type ." []" cr + ."Creates a request with up to 254 orders loaded from to high-load v2 (sub)wallet created by new-highload-v2-wallet.fif, with private key loaded from file .pk " + ."and address from .addr, and saves it into .boc ('wallet-query.boc' by default)" cr + ." is a text file with lines `SEND `" cr 1 halt +} : usage +$# dup 3 < swap 4 > or ' usage if + +$1 =: file-base +$2 parse-int dup 32 fits ' usage ifnot =: subwallet-id // parse subwallet-id +{ subwallet-id (.) $+ } : +subwallet +$3 =: order-file +def? $4 { @' $4 } { "wallet-query" } cond constant savefile +3 constant send-mode // mode for SENDRAWMSG: +1 - sender pays fees, +2 - ignore errors +60 constant timeout // external message expires in 60 seconds + +file-base +subwallet +".addr" load-address +2dup 2constant wallet_addr +."Source wallet address = " 2dup .addr cr 6 .Addr cr +file-base +".pk" load-keypair nip constant wallet_pk + +variable orders dictnew orders ! +variable order# order# 0! +// c -- +{ = abort"more than 254 orders" + orders @ 16 udict!+ not abort"cannot add order to dictionary" + orders ! order# 1+! +} : add-order +// b body -- b' +{ tuck +} : create-int-msg +// ng wc addr bnc -- +{ ."Transferring " 3 roll .GR ."to account " + -rot 2dup 4 pick 7 + .Addr ." = " .addr ." bounce=" . cr +} : .transfer +// addr$ ng -- c +{ swap parse-smc-addr // ng wc addr bnc + 2over 2over .transfer + create-int-msg +} : create-simple-transfer +// c m -- c' +{ } : create-order + +// addr$ ng -- +{ create-simple-transfer send-mode create-order add-order } : send +{ bl word bl word $>GR send } : SEND + +// parse order file +order-file include + +// create external message +now timeout + 32 << hashu 32 1<<1- and + =: query_id + +dup ."signing message: " +dup ."resulting external message: " B dup Bx. cr +."Query_id is " query_id dup . ."= 0x" X. cr +savefile +".boc" tuck B>file +."(Saved to file " type .")" cr diff --git a/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet.fif b/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet.fif new file mode 100644 index 0000000000..ab69fdf368 --- /dev/null +++ b/submodules/ton/tonlib-src/crypto/smartcont/highload-wallet.fif @@ -0,0 +1,68 @@ +#!/usr/bin/env fift -s +"TonUtil.fif" include + +{ ."usage: " @' $0 type ." []" cr + ."Creates a request with up to 254 orders loaded from to high-load (sub)wallet created by new-highload-wallet.fif, with private key loaded from file .pk " + ."and address from .addr, and saves it into .boc ('wallet-query.boc' by default)" cr + ." is a text file with lines `SEND `" cr 1 halt +} : usage +$# dup 4 < swap 5 > or ' usage if + +$1 =: file-base +$2 parse-int dup 32 fits ' usage ifnot =: subwallet-id // parse subwallet-id +{ subwallet-id (.) $+ } : +subwallet +$3 parse-int =: seqno +$4 =: order-file +def? $5 { @' $5 } { "wallet-query" } cond constant savefile +3 constant send-mode // mode for SENDRAWMSG: +1 - sender pays fees, +2 - ignore errors +60 constant timeout // external message expires in 60 seconds + +file-base +subwallet +".addr" load-address +2dup 2constant wallet_addr +."Source wallet address = " 2dup .addr cr 6 .Addr cr +file-base +".pk" load-keypair nip constant wallet_pk + +variable orders dictnew orders ! +variable order# order# 0! +// c -- +{ = abort"more than 254 orders" + orders @ 16 udict!+ not abort"cannot add order to dictionary" + orders ! order# 1+! +} : add-order +// b body -- b' +{ tuck +} : create-int-msg +// ng wc addr bnc -- +{ ."Transferring " 3 roll .GR ."to account " + -rot 2dup 4 pick 7 + .Addr ." = " .addr ." bounce=" . cr +} : .transfer +// addr$ ng -- c +{ swap parse-smc-addr // ng wc addr bnc + 2over 2over .transfer + create-int-msg +} : create-simple-transfer +// c m -- c' +{ } : create-order + +// addr$ ng -- +{ create-simple-transfer send-mode create-order add-order } : send +{ bl word bl word $>GR send } : SEND + +// parse order file +order-file include + +// create external message + +dup ."signing message: " +dup ."resulting external message: " B dup Bx. cr +savefile +".boc" tuck B>file +."(Saved to file " type .")" cr diff --git a/submodules/ton/tonlib-src/crypto/smartcont/new-highload-wallet-v2.fif b/submodules/ton/tonlib-src/crypto/smartcont/new-highload-wallet-v2.fif new file mode 100644 index 0000000000..df386cc72a --- /dev/null +++ b/submodules/ton/tonlib-src/crypto/smartcont/new-highload-wallet-v2.fif @@ -0,0 +1,47 @@ +#!/usr/bin/env fift -s +"TonUtil.fif" include +"Asm.fif" include + +{ ."usage: " @' $0 type ." []" cr + ."Creates a new v2 high-load wallet in the specified workchain, with the controlling private key saved to or loaded from .pk " + ."('new-wallet.pk' by default)" cr + ." is the 32-bit identifier of this subwallet among all controlled by the same private key" cr 1 halt +} : usage +$# 2- -2 and ' usage if + +$1 parse-workchain-id =: wc // set workchain id from command line argument +$2 parse-int dup =: subwallet-id // parse subwallet-id +32 fits ' usage ifnot +{ subwallet-id (.) $+ } : +subwallet +def? $3 { @' $3 } { "new-wallet" } cond constant file-base +65536 constant timeout // init query times out in 65536 seconds + +."Creating new v2 high-load wallet in workchain " wc . +."with subwallet id " subwallet-id . cr + +// Create new high-load wallet; source code included from `highload-wallet-v2-code.fif` +"highload-wallet-v2-code.fif" include +// code + // data +null // no libraries + // create StateInit +dup ."StateInit: " +dup ."signing message: " +dup ."External message for initialization is " B dup Bx. cr +file-base +subwallet +"-query.boc" tuck B>file +."(Saved wallet creating query to file " type .")" cr diff --git a/submodules/ton/tonlib-src/crypto/smartcont/new-highload-wallet.fif b/submodules/ton/tonlib-src/crypto/smartcont/new-highload-wallet.fif new file mode 100644 index 0000000000..57be6a2311 --- /dev/null +++ b/submodules/ton/tonlib-src/crypto/smartcont/new-highload-wallet.fif @@ -0,0 +1,44 @@ +#!/usr/bin/env fift -s +"TonUtil.fif" include +"Asm.fif" include + +{ ."usage: " @' $0 type ." []" cr + ."Creates a new high-load wallet in the specified workchain, with the controlling private key saved to or loaded from .pk " + ."('new-wallet.pk' by default)" cr + ." is the 32-bit identifier of this subwallet among all controlled by the same private key" cr 1 halt +} : usage +$# 2- -2 and ' usage if + +$1 parse-workchain-id =: wc // set workchain id from command line argument +$2 parse-int dup =: subwallet-id // parse subwallet-id +32 fits ' usage ifnot +{ subwallet-id (.) $+ } : +subwallet +def? $3 { @' $3 } { "new-wallet" } cond constant file-base + +."Creating new high-load wallet in workchain " wc . +."with subwallet id " subwallet-id . cr + +// Create new high-load wallet; source code included from `highload-wallet-code.fif` +"highload-wallet-code.fif" include +// code + // data +null // no libraries + // create StateInit +dup ."StateInit: " +dup ."signing message: " +dup ."External message for initialization is " B dup Bx. cr +file-base +subwallet +"-query.boc" tuck B>file +."(Saved wallet creating query to file " type .")" cr diff --git a/submodules/ton/tonlib-src/crypto/smartcont/new-pinger.fif b/submodules/ton/tonlib-src/crypto/smartcont/new-pinger.fif index b833268889..646bfdf68c 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/new-pinger.fif +++ b/submodules/ton/tonlib-src/crypto/smartcont/new-pinger.fif @@ -41,7 +41,7 @@ def? $3 { @' $3 } { "new-pinger" } cond constant file-base // no libraries // create StateInit dup ."StateInit: " // create StateInit dup ."StateInit: " // data null // no libraries // create StateInit dup ."StateInit: " dup ."signing message: " dup ."External message for initialization is " B dup Bx. cr diff --git a/submodules/ton/tonlib-src/crypto/smartcont/new-wallet.fif b/submodules/ton/tonlib-src/crypto/smartcont/new-wallet.fif index c1ad403ca5..9bdb0bdb38 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/new-wallet.fif +++ b/submodules/ton/tonlib-src/crypto/smartcont/new-wallet.fif @@ -47,14 +47,14 @@ null // no libraries // Libs{ x{ABACABADABACABA} drop x{AAAA} s>c public_lib x{1234} x{5678} |_ s>c public_lib }Libs // create StateInit dup ."StateInit: " dup ."signing message: " dup ."External message for initialization is " B dup Bx. cr diff --git a/submodules/ton/tonlib-src/crypto/smartcont/stdlib.fc b/submodules/ton/tonlib-src/crypto/smartcont/stdlib.fc index 4fb30bdd10..fb9b49f56a 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/stdlib.fc +++ b/submodules/ton/tonlib-src/crypto/smartcont/stdlib.fc @@ -86,6 +86,8 @@ cell dict_set_builder(cell dict, int key_len, slice index, builder value) asm(va (cell, (slice, slice, int)) ~dict::delete_get_min(cell dict, int key_len) asm(-> 0 2 1 3) "DICTREMMIN" "NULLSWAPIFNOT" "NULLSWAPIFNOT"; (int, slice, int) udict_get_next?(cell dict, int key_len, int pivot) asm(pivot dict key_len -> 1 0 2) "DICTUGETNEXT" "NULLSWAPIFNOT" "NULLSWAPIFNOT"; (int, slice, int) udict_get_prev?(cell dict, int key_len, int pivot) asm(pivot dict key_len -> 1 0 2) "DICTUGETPREV" "NULLSWAPIFNOT" "NULLSWAPIFNOT"; +(int, slice, int) idict_get_next?(cell dict, int key_len, int pivot) asm(pivot dict key_len -> 1 0 2) "DICTIGETNEXT" "NULLSWAPIFNOT" "NULLSWAPIFNOT"; +(int, slice, int) idict_get_prev?(cell dict, int key_len, int pivot) asm(pivot dict key_len -> 1 0 2) "DICTIGETPREV" "NULLSWAPIFNOT" "NULLSWAPIFNOT"; cell new_dict() asm "NEWDICT"; int dict_empty?(cell c) asm "DICTEMPTY"; diff --git a/submodules/ton/tonlib-src/crypto/smartcont/update-config-smc.fif b/submodules/ton/tonlib-src/crypto/smartcont/update-config-smc.fif index 3840e128f8..22f01f0456 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/update-config-smc.fif +++ b/submodules/ton/tonlib-src/crypto/smartcont/update-config-smc.fif @@ -6,7 +6,7 @@ ."with private key loaded from file .pk, " ."and saves it into .boc ('config-query.boc' by default)" cr 1 halt } : usage -def? $# { @' $# dup 2 < swap 3 > or ' usage if } if +$# dup 2 < swap 3 > or ' usage if "config-master" constant file-base 0 constant seqno @@ -15,18 +15,16 @@ true constant bounce "config-code.fif" constant config-source 100 constant interval // valid for 100 seconds -def? $2 { - @' $1 =: file-base - @' $2 parse-int =: seqno -} if -def? $5 { @' $5 } { "config-query" } cond constant savefile +$1 =: file-base +$2 parse-int =: seqno +def? $3 { @' $3 } { "config-query" } cond constant savefile file-base +".addr" load-address 2dup 2constant config_addr ."Configuration smart contract address = " 2dup .addr cr 6 .Addr cr file-base +".pk" load-keypair nip constant config_pk -."Loading new configuration smart contract code from file file " config-source type cr +."Loading new configuration smart contract code from file " config-source type cr "Asm.fif" include config-source include dup dup ."signing message: " dup ."resulting external message: " .pk, " ."and saves it into .boc ('config-query.boc' by default)" cr 1 halt } : usage -def? $# { @' $# dup 4 < swap 5 > or ' usage if } if +$# dup 4 < swap 5 > or ' usage if "config-master" constant file-base 0 constant seqno @@ -15,12 +15,10 @@ true constant bounce "new-value.boc" constant boc-filename 100 constant interval // valid for 100 seconds -def? $4 { - @' $1 =: file-base - @' $2 parse-int =: seqno - @' $3 parse-int =: idx - @' $4 =: boc-filename -} if +$1 =: file-base +$2 parse-int =: seqno +$3 parse-int =: idx +$4 =: boc-filename def? $5 { @' $5 } { "config-query" } cond constant savefile file-base +".addr" load-address @@ -39,7 +37,7 @@ dup idx is-valid-config? not abort"not a valid value for chosen configuration pa // create a message dup ."signing message: " dup ."resulting external message: " .pk, " ."and saves it into .boc ('config-query.boc' by default)" cr 1 halt } : usage -def? $# { @' $# dup 2 < swap 3 > or ' usage if } if +$# dup 2 < swap 3 > or ' usage if "config-master" constant file-base 0 constant seqno @@ -15,18 +15,16 @@ true constant bounce "elector-code.fif" constant elector-source 100 constant interval // valid for 100 seconds -def? $2 { - @' $1 =: file-base - @' $2 parse-int =: seqno -} if -def? $5 { @' $5 } { "config-query" } cond constant savefile +$1 =: file-base +$2 parse-int =: seqno +def? $3 { @' $3 } { "config-query" } cond constant savefile file-base +".addr" load-address 2dup 2constant config_addr ."Configuration smart contract address = " 2dup .addr cr 6 .Addr cr file-base +".pk" load-keypair nip constant config_pk -."Loading new elector smart contract code from file file " elector-source type cr +."Loading new elector smart contract code from file " elector-source type cr "Asm.fif" include elector-source include dup dup ."signing message: " dup ."resulting external message: " dup ."resulting external message: " dup ."resulting external message: " CellSlice::fetch_ref() { } } +bool CellSlice::prefetch_maybe_ref(Ref& res) const { + auto z = prefetch_ulong(1); + if (!z) { + res.clear(); + return true; + } else { + return z == 1 && prefetch_ref_to(res); + } +} + +bool CellSlice::fetch_maybe_ref(Ref& res) { + auto z = prefetch_ulong(1); + if (!z) { + res.clear(); + return advance(1); + } else { + return z == 1 && prefetch_ref_to(res) && advance_ext(1, 1); + } +} + bool CellSlice::begins_with(unsigned bits, unsigned long long value) const { return have(bits) && !((prefetch_ulong(bits) ^ value) & ((1ULL << bits) - 1)); } diff --git a/submodules/ton/tonlib-src/crypto/vm/cells/CellSlice.h b/submodules/ton/tonlib-src/crypto/vm/cells/CellSlice.h index 5d7f906bc4..433344f982 100644 --- a/submodules/ton/tonlib-src/crypto/vm/cells/CellSlice.h +++ b/submodules/ton/tonlib-src/crypto/vm/cells/CellSlice.h @@ -185,6 +185,8 @@ class CellSlice : public td::CntObject { bool prefetch_ref_to(Ref& ref, unsigned offset = 0) const { return (ref = prefetch_ref(offset)).not_null(); } + bool fetch_maybe_ref(Ref& ref); + bool prefetch_maybe_ref(Ref& ref) const; td::BitSlice fetch_bits(unsigned bits); td::BitSlice prefetch_bits(unsigned bits) const; td::Ref fetch_subslice(unsigned bits, unsigned refs = 0); diff --git a/submodules/ton/tonlib-src/crypto/vm/cells/MerkleProof.cpp b/submodules/ton/tonlib-src/crypto/vm/cells/MerkleProof.cpp index 084a973ed8..a373e80468 100644 --- a/submodules/ton/tonlib-src/crypto/vm/cells/MerkleProof.cpp +++ b/submodules/ton/tonlib-src/crypto/vm/cells/MerkleProof.cpp @@ -267,16 +267,18 @@ MerkleProofBuilder::MerkleProofBuilder(Ref root) usage_root = UsageCell::create(orig_root, usage_tree->root_ptr()); } -void MerkleProofBuilder::reset(Ref root) { +Ref MerkleProofBuilder::init(Ref root) { usage_tree = std::make_shared(); orig_root = std::move(root); usage_root = UsageCell::create(orig_root, usage_tree->root_ptr()); + return usage_root; } -void MerkleProofBuilder::clear() { +bool MerkleProofBuilder::clear() { usage_tree.reset(); orig_root.clear(); usage_root.clear(); + return true; } Ref MerkleProofBuilder::extract_proof() const { diff --git a/submodules/ton/tonlib-src/crypto/vm/cells/MerkleProof.h b/submodules/ton/tonlib-src/crypto/vm/cells/MerkleProof.h index 8dfb43a65c..5b3b8ebcef 100644 --- a/submodules/ton/tonlib-src/crypto/vm/cells/MerkleProof.h +++ b/submodules/ton/tonlib-src/crypto/vm/cells/MerkleProof.h @@ -51,9 +51,10 @@ class MerkleProofBuilder { Ref orig_root, usage_root; public: + MerkleProofBuilder() = default; MerkleProofBuilder(Ref root); - void reset(Ref root); - void clear(); + Ref init(Ref root); + bool clear(); Ref root() const { return usage_root; } diff --git a/submodules/ton/tonlib-src/lite-client/lite-client.cpp b/submodules/ton/tonlib-src/lite-client/lite-client.cpp index 0d446e6ec7..3817e987f8 100644 --- a/submodules/ton/tonlib-src/lite-client/lite-client.cpp +++ b/submodules/ton/tonlib-src/lite-client/lite-client.cpp @@ -914,8 +914,10 @@ bool TestNode::do_parse_line() { return parse_block_id_ext(blkid) && parse_account_addr(workchain, addr) && parse_lt(lt) && seekeoln() && get_one_transaction(blkid, workchain, addr, lt, true); } else if (word == "lasttrans" || word == "lasttransdump") { - return parse_account_addr(workchain, addr) && parse_lt(lt) && parse_hash(hash) && seekeoln() && - get_last_transactions(workchain, addr, lt, hash, 10, word == "lasttransdump"); + count = 10; + return parse_account_addr(workchain, addr) && parse_lt(lt) && parse_hash(hash) && + (seekeoln() || parse_uint32(count)) && seekeoln() && + get_last_transactions(workchain, addr, lt, hash, count, word == "lasttransdump"); } else if (word == "listblocktrans" || word == "listblocktransrev") { lt = 0; int mode = (word == "listblocktrans" ? 7 : 0x47); diff --git a/submodules/ton/tonlib-src/tdactor/td/actor/common.h b/submodules/ton/tonlib-src/tdactor/td/actor/common.h index 039f25b2c9..3a29b4736a 100644 --- a/submodules/ton/tonlib-src/tdactor/td/actor/common.h +++ b/submodules/ton/tonlib-src/tdactor/td/actor/common.h @@ -364,7 +364,7 @@ inline void register_actor_info_ptr(core::ActorInfoPtr actor_info_ptr) { } template -core::ActorInfoPtr create_actor(core::ActorOptions &options, ArgsT &&... args) { +core::ActorInfoPtr create_actor(core::ActorOptions &options, ArgsT &&... args) noexcept { auto *scheduler_context = core::SchedulerContext::get(); if (!options.has_scheduler()) { options.on_scheduler(scheduler_context->get_scheduler_id()); diff --git a/submodules/ton/tonlib-src/tdactor/td/actor/core/ActorExecutor.cpp b/submodules/ton/tonlib-src/tdactor/td/actor/core/ActorExecutor.cpp index fcca341fd7..7554a05d10 100644 --- a/submodules/ton/tonlib-src/tdactor/td/actor/core/ActorExecutor.cpp +++ b/submodules/ton/tonlib-src/tdactor/td/actor/core/ActorExecutor.cpp @@ -75,7 +75,7 @@ void ActorExecutor::send(ActorSignals signals) { pending_signals_.add_signals(signals); } -void ActorExecutor::start() { +void ActorExecutor::start() noexcept { //LOG(ERROR) << "START " << actor_info_.get_name() << " " << tag("from_queue", options.from_queue); if (is_closed()) { return; @@ -126,7 +126,7 @@ void ActorExecutor::start() { } } -void ActorExecutor::finish() { +void ActorExecutor::finish() noexcept { //LOG(ERROR) << "FINISH " << actor_info_.get_name() << " " << tag("own_lock", actor_locker_.own_lock()); if (!actor_locker_.own_lock()) { if (!pending_signals_.empty() && actor_locker_.add_signals(pending_signals_)) { diff --git a/submodules/ton/tonlib-src/tdactor/td/actor/core/ActorExecutor.h b/submodules/ton/tonlib-src/tdactor/td/actor/core/ActorExecutor.h index d11c77b2c2..53fc1e11ac 100644 --- a/submodules/ton/tonlib-src/tdactor/td/actor/core/ActorExecutor.h +++ b/submodules/ton/tonlib-src/tdactor/td/actor/core/ActorExecutor.h @@ -106,8 +106,8 @@ class ActorExecutor { return flags_; } - void start(); - void finish(); + void start() noexcept; + void finish() noexcept; bool flush_one(ActorSignals &signals); bool flush_one_signal(ActorSignals &signals); diff --git a/submodules/ton/tonlib-src/tdutils/td/utils/Status.h b/submodules/ton/tonlib-src/tdutils/td/utils/Status.h index f96ca82776..1759c0abef 100644 --- a/submodules/ton/tonlib-src/tdutils/td/utils/Status.h +++ b/submodules/ton/tonlib-src/tdutils/td/utils/Status.h @@ -50,6 +50,9 @@ #define TRY_RESULT(name, result) TRY_RESULT_IMPL(TD_CONCAT(TD_CONCAT(r_, name), __LINE__), auto name, result) +#define TRY_RESULT_PROMISE(promise_name, name, result) \ + TRY_RESULT_PROMISE_IMPL(promise_name, TD_CONCAT(TD_CONCAT(r_, name), __LINE__), auto name, result) + #define TRY_RESULT_ASSIGN(name, result) TRY_RESULT_IMPL(TD_CONCAT(TD_CONCAT(r_, name), __LINE__), name, result) #define TRY_RESULT_PREFIX(name, result, prefix) \ @@ -78,10 +81,18 @@ } \ name = r_name.move_as_ok(); +#define TRY_RESULT_PROMISE_IMPL(promise_name, r_name, name, result) \ + auto r_name = (result); \ + if (r_name.is_error()) { \ + promise_name.set_error(r_name.move_as_error()); \ + return; \ + } \ + name = r_name.move_as_ok(); + #define TRY_RESULT_PROMISE_PREFIX_IMPL(promise_name, r_name, name, result, prefix) \ auto r_name = (result); \ if (r_name.is_error()) { \ - promise.set_error(r_name.move_as_error()); \ + promise_name.set_error(r_name.move_as_error_prefix(prefix)); \ return; \ } \ name = r_name.move_as_ok(); @@ -298,14 +309,31 @@ class Status { return std::move(*this); } - Status move_as_error_prefix(Slice prefix) TD_WARN_UNUSED_RESULT { + Status move_as_error_prefix(const Status &status) const TD_WARN_UNUSED_RESULT { + return status.move_as_error_suffix(message()); + } + + Status move_as_error_prefix(Slice prefix) const TD_WARN_UNUSED_RESULT { CHECK(is_error()); Info info = get_info(); switch (info.error_type) { case ErrorType::general: - return Error(code(), PSLICE() << prefix << message()); + return Error(code(), PSLICE() << prefix << " " << message()); case ErrorType::os: - return Status(false, ErrorType::os, code(), PSLICE() << prefix << message()); + return Status(false, ErrorType::os, code(), PSLICE() << prefix << " " << message()); + default: + UNREACHABLE(); + return {}; + } + } + Status move_as_error_suffix(Slice suffix) const TD_WARN_UNUSED_RESULT { + CHECK(is_error()); + Info info = get_info(); + switch (info.error_type) { + case ErrorType::general: + return Error(code(), PSLICE() << message() << " " << suffix); + case ErrorType::os: + return Status(false, ErrorType::os, code(), PSLICE() << message() << " " << suffix); default: UNREACHABLE(); return {}; @@ -488,6 +516,18 @@ class Result { }; return status_.move_as_error_prefix(prefix); } + Status move_as_error_prefix(const Status &prefix) TD_WARN_UNUSED_RESULT { + SCOPE_EXIT { + status_ = Status::Error<-5>(); + }; + return status_.move_as_error_prefix(prefix); + } + Status move_as_error_suffix(Slice suffix) TD_WARN_UNUSED_RESULT { + SCOPE_EXIT { + status_ = Status::Error<-5>(); + }; + return status_.move_as_error_suffix(suffix); + } const T &ok() const { LOG_CHECK(status_.is_ok()) << status_; return value_; diff --git a/submodules/ton/tonlib-src/tdutils/td/utils/tl_helpers.h b/submodules/ton/tonlib-src/tdutils/td/utils/tl_helpers.h index 30cf09556a..df89ed1a71 100644 --- a/submodules/ton/tonlib-src/tdutils/td/utils/tl_helpers.h +++ b/submodules/ton/tonlib-src/tdutils/td/utils/tl_helpers.h @@ -32,10 +32,10 @@ #include #include -#define BEGIN_STORE_FLAGS() \ - do { \ - uint32 flags_store = 0; \ - uint32 bit_offset_store = 0 +#define BEGIN_STORE_FLAGS() \ + do { \ + td::uint32 flags_store = 0; \ + td::uint32 bit_offset_store = 0 #define STORE_FLAG(flag) \ flags_store |= (flag) << bit_offset_store; \ @@ -47,10 +47,10 @@ } \ while (false) -#define BEGIN_PARSE_FLAGS() \ - do { \ - uint32 flags_parse; \ - uint32 bit_offset_parse = 0; \ +#define BEGIN_PARSE_FLAGS() \ + do { \ + td::uint32 flags_parse; \ + td::uint32 bit_offset_parse = 0; \ td::parse(flags_parse, parser) #define PARSE_FLAG(flag) \ diff --git a/submodules/ton/tonlib-src/tdutils/td/utils/tl_parsers.h b/submodules/ton/tonlib-src/tdutils/td/utils/tl_parsers.h index 734afdb713..e0fc419447 100644 --- a/submodules/ton/tonlib-src/tdutils/td/utils/tl_parsers.h +++ b/submodules/ton/tonlib-src/tdutils/td/utils/tl_parsers.h @@ -99,6 +99,16 @@ class TlParser { } } + bool can_prefetch_int() const { + return get_left_len() >= sizeof(int32); + } + + int32 prefetch_int_unsafe() const { + int32 result; + std::memcpy(&result, data, sizeof(int32)); + return result; + } + int32 fetch_int_unsafe() { int32 result; std::memcpy(&result, data, sizeof(int32)); diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.cpp b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.cpp index c6c6f32804..810c29527e 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.cpp +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.cpp @@ -244,6 +244,8 @@ object_ptr Object::fetch(td::TlParser &p) { return db_state_destroyedSessions::fetch(p); case db_state_gcBlockId::ID: return db_state_gcBlockId::fetch(p); + case db_state_hardforks::ID: + return db_state_hardforks::fetch(p); case db_state_initBlockId::ID: return db_state_initBlockId::fetch(p); case db_state_key_destroyedSessions::ID: @@ -256,6 +258,8 @@ object_ptr Object::fetch(td::TlParser &p) { return db_state_key_shardClient::fetch(p); case db_state_key_asyncSerializer::ID: return db_state_key_asyncSerializer::fetch(p); + case db_state_key_hardforks::ID: + return db_state_key_hardforks::fetch(p); case db_state_shardClient::ID: return db_state_shardClient::fetch(p); case dht_key::ID: @@ -498,6 +502,8 @@ object_ptr Object::fetch(td::TlParser &p) { return tonNode_zeroStateIdExt::fetch(p); case validator_group::ID: return validator_group::fetch(p); + case validator_groupEx::ID: + return validator_groupEx::fetch(p); case validator_config_global::ID: return validator_config_global::fetch(p); case validator_config_local::ID: @@ -5905,6 +5911,44 @@ void db_state_gcBlockId::store(td::TlStorerToString &s, const char *field_name) } } +db_state_hardforks::db_state_hardforks() + : blocks_() +{} + +db_state_hardforks::db_state_hardforks(std::vector> &&blocks_) + : blocks_(std::move(blocks_)) +{} + +const std::int32_t db_state_hardforks::ID; + +object_ptr db_state_hardforks::fetch(td::TlParser &p) { + return make_object(p); +} + +db_state_hardforks::db_state_hardforks(td::TlParser &p) +#define FAIL(error) p.set_error(error) + : blocks_(TlFetchVector>::parse(p)) +#undef FAIL +{} + +void db_state_hardforks::store(td::TlStorerCalcLength &s) const { + (void)sizeof(s); + TlStoreVector::store(blocks_, s); +} + +void db_state_hardforks::store(td::TlStorerUnsafe &s) const { + (void)sizeof(s); + TlStoreVector::store(blocks_, s); +} + +void db_state_hardforks::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "db_state_hardforks"); + { const std::vector> &v = blocks_; const std::uint32_t multiplicity = static_cast(v.size()); const auto vector_name = "vector[" + td::to_string(multiplicity)+ "]"; s.store_class_begin("blocks", vector_name.c_str()); for (std::uint32_t i = 0; i < multiplicity; i++) { if (v[i] == nullptr) { s.store_field("", "null"); } else { v[i]->store(s, ""); } } s.store_class_end(); } + s.store_class_end(); + } +} + db_state_initBlockId::db_state_initBlockId() : block_() {} @@ -5957,6 +6001,8 @@ object_ptr db_state_Key::fetch(td::TlParser &p) { return db_state_key_shardClient::fetch(p); case db_state_key_asyncSerializer::ID: return db_state_key_asyncSerializer::fetch(p); + case db_state_key_hardforks::ID: + return db_state_key_hardforks::fetch(p); default: FAIL(PSTRING() << "Unknown constructor found " << td::format::as_hex(constructor)); } @@ -6118,6 +6164,37 @@ void db_state_key_asyncSerializer::store(td::TlStorerToString &s, const char *fi } } +db_state_key_hardforks::db_state_key_hardforks() { +} + +const std::int32_t db_state_key_hardforks::ID; + +object_ptr db_state_key_hardforks::fetch(td::TlParser &p) { + return make_object(p); +} + +db_state_key_hardforks::db_state_key_hardforks(td::TlParser &p) +#define FAIL(error) p.set_error(error) +#undef FAIL +{ + (void)p; +} + +void db_state_key_hardforks::store(td::TlStorerCalcLength &s) const { + (void)sizeof(s); +} + +void db_state_key_hardforks::store(td::TlStorerUnsafe &s) const { + (void)sizeof(s); +} + +void db_state_key_hardforks::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "db_state_key_hardforks"); + s.store_class_end(); + } +} + db_state_shardClient::db_state_shardClient() : block_() {} @@ -11755,6 +11832,20 @@ void tonNode_zeroStateIdExt::store(td::TlStorerToString &s, const char *field_na } } +object_ptr validator_Group::fetch(td::TlParser &p) { +#define FAIL(error) p.set_error(error); return nullptr; + int constructor = p.fetch_int(); + switch (constructor) { + case validator_group::ID: + return validator_group::fetch(p); + case validator_groupEx::ID: + return validator_groupEx::fetch(p); + default: + FAIL(PSTRING() << "Unknown constructor found " << td::format::as_hex(constructor)); + } +#undef FAIL +} + validator_group::validator_group() : workchain_() , shard_() @@ -11773,7 +11864,7 @@ validator_group::validator_group(std::int32_t workchain_, std::int64_t shard_, s const std::int32_t validator_group::ID; -object_ptr validator_group::fetch(td::TlParser &p) { +object_ptr validator_group::fetch(td::TlParser &p) { return make_object(p); } @@ -11817,6 +11908,74 @@ void validator_group::store(td::TlStorerToString &s, const char *field_name) con } } +validator_groupEx::validator_groupEx() + : workchain_() + , shard_() + , vertical_seqno_() + , catchain_seqno_() + , config_hash_() + , members_() +{} + +validator_groupEx::validator_groupEx(std::int32_t workchain_, std::int64_t shard_, std::int32_t vertical_seqno_, std::int32_t catchain_seqno_, td::Bits256 const &config_hash_, std::vector> &&members_) + : workchain_(workchain_) + , shard_(shard_) + , vertical_seqno_(vertical_seqno_) + , catchain_seqno_(catchain_seqno_) + , config_hash_(config_hash_) + , members_(std::move(members_)) +{} + +const std::int32_t validator_groupEx::ID; + +object_ptr validator_groupEx::fetch(td::TlParser &p) { + return make_object(p); +} + +validator_groupEx::validator_groupEx(td::TlParser &p) +#define FAIL(error) p.set_error(error) + : workchain_(TlFetchInt::parse(p)) + , shard_(TlFetchLong::parse(p)) + , vertical_seqno_(TlFetchInt::parse(p)) + , catchain_seqno_(TlFetchInt::parse(p)) + , config_hash_(TlFetchInt256::parse(p)) + , members_(TlFetchVector>::parse(p)) +#undef FAIL +{} + +void validator_groupEx::store(td::TlStorerCalcLength &s) const { + (void)sizeof(s); + TlStoreBinary::store(workchain_, s); + TlStoreBinary::store(shard_, s); + TlStoreBinary::store(vertical_seqno_, s); + TlStoreBinary::store(catchain_seqno_, s); + TlStoreBinary::store(config_hash_, s); + TlStoreVector::store(members_, s); +} + +void validator_groupEx::store(td::TlStorerUnsafe &s) const { + (void)sizeof(s); + TlStoreBinary::store(workchain_, s); + TlStoreBinary::store(shard_, s); + TlStoreBinary::store(vertical_seqno_, s); + TlStoreBinary::store(catchain_seqno_, s); + TlStoreBinary::store(config_hash_, s); + TlStoreVector::store(members_, s); +} + +void validator_groupEx::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "validator_groupEx"); + s.store_field("workchain", workchain_); + s.store_field("shard", shard_); + s.store_field("vertical_seqno", vertical_seqno_); + s.store_field("catchain_seqno", catchain_seqno_); + s.store_field("config_hash", config_hash_); + { const std::vector> &v = members_; const std::uint32_t multiplicity = static_cast(v.size()); const auto vector_name = "vector[" + td::to_string(multiplicity)+ "]"; s.store_class_begin("members", vector_name.c_str()); for (std::uint32_t i = 0; i < multiplicity; i++) { if (v[i] == nullptr) { s.store_field("", "null"); } else { v[i]->store(s, ""); } } s.store_class_end(); } + s.store_class_end(); + } +} + validator_config_global::validator_config_global() : zero_state_() , init_block_() diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.h b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.h index 537ece403d..3f3f8e8ad8 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.h +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.h @@ -162,6 +162,8 @@ class db_state_destroyedSessions; class db_state_gcBlockId; +class db_state_hardforks; + class db_state_initBlockId; class db_state_Key; @@ -344,7 +346,7 @@ class tonNode_success; class tonNode_zeroStateIdExt; -class validator_group; +class validator_Group; class validator_config_global; @@ -3215,6 +3217,30 @@ class db_state_gcBlockId final : public Object { void store(td::TlStorerToString &s, const char *field_name) const final; }; +class db_state_hardforks final : public Object { + public: + std::vector> blocks_; + + db_state_hardforks(); + + explicit db_state_hardforks(std::vector> &&blocks_); + + static const std::int32_t ID = -2047668988; + std::int32_t get_id() const final { + return ID; + } + + static object_ptr fetch(td::TlParser &p); + + explicit db_state_hardforks(td::TlParser &p); + + void store(td::TlStorerCalcLength &s) const final; + + void store(td::TlStorerUnsafe &s) const final; + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + class db_state_initBlockId final : public Object { public: object_ptr block_; @@ -3350,6 +3376,27 @@ class db_state_key_asyncSerializer final : public db_state_Key { void store(td::TlStorerToString &s, const char *field_name) const final; }; +class db_state_key_hardforks final : public db_state_Key { + public: + + db_state_key_hardforks(); + + static const std::int32_t ID = -420206662; + std::int32_t get_id() const final { + return ID; + } + + static object_ptr fetch(td::TlParser &p); + + explicit db_state_key_hardforks(td::TlParser &p); + + void store(td::TlStorerCalcLength &s) const final; + + void store(td::TlStorerUnsafe &s) const final; + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + class db_state_shardClient final : public Object { public: object_ptr block_; @@ -6440,7 +6487,13 @@ class tonNode_zeroStateIdExt final : public Object { void store(td::TlStorerToString &s, const char *field_name) const final; }; -class validator_group final : public Object { +class validator_Group: public Object { + public: + + static object_ptr fetch(td::TlParser &p); +}; + +class validator_group final : public validator_Group { public: std::int32_t workchain_; std::int64_t shard_; @@ -6457,7 +6510,7 @@ class validator_group final : public Object { return ID; } - static object_ptr fetch(td::TlParser &p); + static object_ptr fetch(td::TlParser &p); explicit validator_group(td::TlParser &p); @@ -6468,6 +6521,35 @@ class validator_group final : public Object { void store(td::TlStorerToString &s, const char *field_name) const final; }; +class validator_groupEx final : public validator_Group { + public: + std::int32_t workchain_; + std::int64_t shard_; + std::int32_t vertical_seqno_; + std::int32_t catchain_seqno_; + td::Bits256 config_hash_; + std::vector> members_; + + validator_groupEx(); + + validator_groupEx(std::int32_t workchain_, std::int64_t shard_, std::int32_t vertical_seqno_, std::int32_t catchain_seqno_, td::Bits256 const &config_hash_, std::vector> &&members_); + + static const std::int32_t ID = 479350270; + std::int32_t get_id() const final { + return ID; + } + + static object_ptr fetch(td::TlParser &p); + + explicit validator_groupEx(td::TlParser &p); + + void store(td::TlStorerCalcLength &s) const final; + + void store(td::TlStorerUnsafe &s) const final; + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + class validator_config_global final : public Object { public: object_ptr zero_state_; diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.hpp b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.hpp index 1f033147db..29f45bb527 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.hpp +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.hpp @@ -344,6 +344,9 @@ bool downcast_call(Object &obj, const T &func) { case db_state_gcBlockId::ID: func(static_cast(obj)); return true; + case db_state_hardforks::ID: + func(static_cast(obj)); + return true; case db_state_initBlockId::ID: func(static_cast(obj)); return true; @@ -362,6 +365,9 @@ bool downcast_call(Object &obj, const T &func) { case db_state_key_asyncSerializer::ID: func(static_cast(obj)); return true; + case db_state_key_hardforks::ID: + func(static_cast(obj)); + return true; case db_state_shardClient::ID: func(static_cast(obj)); return true; @@ -725,6 +731,9 @@ bool downcast_call(Object &obj, const T &func) { case validator_group::ID: func(static_cast(obj)); return true; + case validator_groupEx::ID: + func(static_cast(obj)); + return true; case validator_config_global::ID: func(static_cast(obj)); return true; @@ -1470,6 +1479,9 @@ bool downcast_call(db_state_Key &obj, const T &func) { case db_state_key_asyncSerializer::ID: func(static_cast(obj)); return true; + case db_state_key_hardforks::ID: + func(static_cast(obj)); + return true; default: return false; } @@ -1874,6 +1886,26 @@ bool downcast_call(tonNode_PreparedState &obj, const T &func) { } } +/** + * Calls specified function object with the specified object downcasted to the most-derived type. + * \param[in] obj Object to pass as an argument to the function object. + * \param[in] func Function object to which the object will be passed. + * \returns whether function object call has happened. Should always return true for correct parameters. + */ +template +bool downcast_call(validator_Group &obj, const T &func) { + switch (obj.get_id()) { + case validator_group::ID: + func(static_cast(obj)); + return true; + case validator_groupEx::ID: + func(static_cast(obj)); + return true; + default: + return false; + } +} + /** * Calls specified function object with the specified object downcasted to the most-derived type. * \param[in] obj Object to pass as an argument to the function object. diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.cpp b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.cpp index 66c7c9df17..df0f134a1d 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.cpp +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.cpp @@ -226,7 +226,8 @@ Result tl_constructor_from_string(ton_api::db_state_Key *object, const st {"db.state.key.initBlockId", 1971484899}, {"db.state.key.gcBlockId", -1015417890}, {"db.state.key.shardClient", -912576121}, - {"db.state.key.asyncSerializer", 699304479} + {"db.state.key.asyncSerializer", 699304479}, + {"db.state.key.hardforks", -420206662} }; auto it = m.find(str); if (it == m.end()) { @@ -445,6 +446,17 @@ Result tl_constructor_from_string(ton_api::tonNode_PreparedState *object, } return it->second; } +Result tl_constructor_from_string(ton_api::validator_Group *object, const std::string &str) { + static const std::unordered_map m = { + {"validator.group", -120029535}, + {"validator.groupEx", 479350270} + }; + auto it = m.find(str); + if (it == m.end()) { + return Status::Error(str + "Unknown class"); + } + return it->second; +} Result tl_constructor_from_string(ton_api::validator_config_Local *object, const std::string &str) { static const std::unordered_map m = { {"validator.config.local", 1716256616}, @@ -596,12 +608,14 @@ Result tl_constructor_from_string(ton_api::Object *object, const std::str {"db.state.asyncSerializer", -751883871}, {"db.state.destroyedSessions", -1381443196}, {"db.state.gcBlockId", -550453937}, + {"db.state.hardforks", -2047668988}, {"db.state.initBlockId", 1932303605}, {"db.state.key.destroyedSessions", -386404007}, {"db.state.key.initBlockId", 1971484899}, {"db.state.key.gcBlockId", -1015417890}, {"db.state.key.shardClient", -912576121}, {"db.state.key.asyncSerializer", 699304479}, + {"db.state.key.hardforks", -420206662}, {"db.state.shardClient", 186033821}, {"dht.key", -160964977}, {"dht.keyDescription", 673009157}, @@ -723,6 +737,7 @@ Result tl_constructor_from_string(ton_api::Object *object, const std::str {"tonNode.success", -1063902129}, {"tonNode.zeroStateIdExt", 494024110}, {"validator.group", -120029535}, + {"validator.groupEx", 479350270}, {"validator.config.global", -2038562966}, {"validator.config.local", 1716256616}, {"validator.config.random.local", 1501795426}, @@ -2554,6 +2569,15 @@ Status from_json(ton_api::db_state_gcBlockId &to, JsonObject &from) { } return Status::OK(); } +Status from_json(ton_api::db_state_hardforks &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "blocks", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.blocks_, value)); + } + } + return Status::OK(); +} Status from_json(ton_api::db_state_initBlockId &to, JsonObject &from) { { TRY_RESULT(value, get_json_object_field(from, "block", JsonValue::Type::Null, true)); @@ -2578,6 +2602,9 @@ Status from_json(ton_api::db_state_key_shardClient &to, JsonObject &from) { Status from_json(ton_api::db_state_key_asyncSerializer &to, JsonObject &from) { return Status::OK(); } +Status from_json(ton_api::db_state_key_hardforks &to, JsonObject &from) { + return Status::OK(); +} Status from_json(ton_api::db_state_shardClient &to, JsonObject &from) { { TRY_RESULT(value, get_json_object_field(from, "block", JsonValue::Type::Null, true)); @@ -4507,6 +4534,45 @@ Status from_json(ton_api::validator_group &to, JsonObject &from) { } return Status::OK(); } +Status from_json(ton_api::validator_groupEx &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "workchain", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.workchain_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "shard", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.shard_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "vertical_seqno", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.vertical_seqno_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "catchain_seqno", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.catchain_seqno_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "config_hash", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.config_hash_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "members", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.members_, value)); + } + } + return Status::OK(); +} Status from_json(ton_api::validator_config_global &to, JsonObject &from) { { TRY_RESULT(value, get_json_object_field(from, "zero_state", JsonValue::Type::Null, true)); @@ -6631,6 +6697,11 @@ void to_json(JsonValueScope &jv, const ton_api::db_state_gcBlockId &object) { jo << ctie("block", ToJson(object.block_)); } } +void to_json(JsonValueScope &jv, const ton_api::db_state_hardforks &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "db.state.hardforks"); + jo << ctie("blocks", ToJson(object.blocks_)); +} void to_json(JsonValueScope &jv, const ton_api::db_state_initBlockId &object) { auto jo = jv.enter_object(); jo << ctie("@type", "db.state.initBlockId"); @@ -6661,6 +6732,10 @@ void to_json(JsonValueScope &jv, const ton_api::db_state_key_asyncSerializer &ob auto jo = jv.enter_object(); jo << ctie("@type", "db.state.key.asyncSerializer"); } +void to_json(JsonValueScope &jv, const ton_api::db_state_key_hardforks &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "db.state.key.hardforks"); +} void to_json(JsonValueScope &jv, const ton_api::db_state_shardClient &object) { auto jo = jv.enter_object(); jo << ctie("@type", "db.state.shardClient"); @@ -7535,6 +7610,9 @@ void to_json(JsonValueScope &jv, const ton_api::tonNode_zeroStateIdExt &object) jo << ctie("root_hash", ToJson(object.root_hash_)); jo << ctie("file_hash", ToJson(object.file_hash_)); } +void to_json(JsonValueScope &jv, const ton_api::validator_Group &object) { + ton_api::downcast_call(const_cast(object), [&jv](const auto &object) { to_json(jv, object); }); +} void to_json(JsonValueScope &jv, const ton_api::validator_group &object) { auto jo = jv.enter_object(); jo << ctie("@type", "validator.group"); @@ -7544,6 +7622,16 @@ void to_json(JsonValueScope &jv, const ton_api::validator_group &object) { jo << ctie("config_hash", ToJson(object.config_hash_)); jo << ctie("members", ToJson(object.members_)); } +void to_json(JsonValueScope &jv, const ton_api::validator_groupEx &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "validator.groupEx"); + jo << ctie("workchain", ToJson(object.workchain_)); + jo << ctie("shard", ToJson(JsonInt64{object.shard_})); + jo << ctie("vertical_seqno", ToJson(object.vertical_seqno_)); + jo << ctie("catchain_seqno", ToJson(object.catchain_seqno_)); + jo << ctie("config_hash", ToJson(object.config_hash_)); + jo << ctie("members", ToJson(object.members_)); +} void to_json(JsonValueScope &jv, const ton_api::validator_config_global &object) { auto jo = jv.enter_object(); jo << ctie("@type", "validator.config.global"); diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.h b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.h index cfa271e76f..da8fa1524d 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.h +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.h @@ -45,6 +45,7 @@ Result tl_constructor_from_string(ton_api::tonNode_DataFull *object, cons Result tl_constructor_from_string(ton_api::tonNode_Prepared *object, const std::string &str); Result tl_constructor_from_string(ton_api::tonNode_PreparedProof *object, const std::string &str); Result tl_constructor_from_string(ton_api::tonNode_PreparedState *object, const std::string &str); +Result tl_constructor_from_string(ton_api::validator_Group *object, const std::string &str); Result tl_constructor_from_string(ton_api::validator_config_Local *object, const std::string &str); Result tl_constructor_from_string(ton_api::validatorSession_Message *object, const std::string &str); Result tl_constructor_from_string(ton_api::validatorSession_round_Message *object, const std::string &str); @@ -160,12 +161,14 @@ Status from_json(ton_api::db_root_key_config &to, JsonObject &from); Status from_json(ton_api::db_state_asyncSerializer &to, JsonObject &from); Status from_json(ton_api::db_state_destroyedSessions &to, JsonObject &from); Status from_json(ton_api::db_state_gcBlockId &to, JsonObject &from); +Status from_json(ton_api::db_state_hardforks &to, JsonObject &from); Status from_json(ton_api::db_state_initBlockId &to, JsonObject &from); Status from_json(ton_api::db_state_key_destroyedSessions &to, JsonObject &from); Status from_json(ton_api::db_state_key_initBlockId &to, JsonObject &from); Status from_json(ton_api::db_state_key_gcBlockId &to, JsonObject &from); Status from_json(ton_api::db_state_key_shardClient &to, JsonObject &from); Status from_json(ton_api::db_state_key_asyncSerializer &to, JsonObject &from); +Status from_json(ton_api::db_state_key_hardforks &to, JsonObject &from); Status from_json(ton_api::db_state_shardClient &to, JsonObject &from); Status from_json(ton_api::dht_key &to, JsonObject &from); Status from_json(ton_api::dht_keyDescription &to, JsonObject &from); @@ -287,6 +290,7 @@ Status from_json(ton_api::tonNode_shardPublicOverlayId &to, JsonObject &from); Status from_json(ton_api::tonNode_success &to, JsonObject &from); Status from_json(ton_api::tonNode_zeroStateIdExt &to, JsonObject &from); Status from_json(ton_api::validator_group &to, JsonObject &from); +Status from_json(ton_api::validator_groupEx &to, JsonObject &from); Status from_json(ton_api::validator_config_global &to, JsonObject &from); Status from_json(ton_api::validator_config_local &to, JsonObject &from); Status from_json(ton_api::validator_config_random_local &to, JsonObject &from); @@ -505,6 +509,7 @@ void to_json(JsonValueScope &jv, const ton_api::db_root_key_config &object); void to_json(JsonValueScope &jv, const ton_api::db_state_asyncSerializer &object); void to_json(JsonValueScope &jv, const ton_api::db_state_destroyedSessions &object); void to_json(JsonValueScope &jv, const ton_api::db_state_gcBlockId &object); +void to_json(JsonValueScope &jv, const ton_api::db_state_hardforks &object); void to_json(JsonValueScope &jv, const ton_api::db_state_initBlockId &object); void to_json(JsonValueScope &jv, const ton_api::db_state_Key &object); void to_json(JsonValueScope &jv, const ton_api::db_state_key_destroyedSessions &object); @@ -512,6 +517,7 @@ void to_json(JsonValueScope &jv, const ton_api::db_state_key_initBlockId &object void to_json(JsonValueScope &jv, const ton_api::db_state_key_gcBlockId &object); void to_json(JsonValueScope &jv, const ton_api::db_state_key_shardClient &object); void to_json(JsonValueScope &jv, const ton_api::db_state_key_asyncSerializer &object); +void to_json(JsonValueScope &jv, const ton_api::db_state_key_hardforks &object); void to_json(JsonValueScope &jv, const ton_api::db_state_shardClient &object); void to_json(JsonValueScope &jv, const ton_api::dht_key &object); void to_json(JsonValueScope &jv, const ton_api::dht_keyDescription &object); @@ -650,7 +656,9 @@ void to_json(JsonValueScope &jv, const ton_api::tonNode_sessionId &object); void to_json(JsonValueScope &jv, const ton_api::tonNode_shardPublicOverlayId &object); void to_json(JsonValueScope &jv, const ton_api::tonNode_success &object); void to_json(JsonValueScope &jv, const ton_api::tonNode_zeroStateIdExt &object); +void to_json(JsonValueScope &jv, const ton_api::validator_Group &object); void to_json(JsonValueScope &jv, const ton_api::validator_group &object); +void to_json(JsonValueScope &jv, const ton_api::validator_groupEx &object); void to_json(JsonValueScope &jv, const ton_api::validator_config_global &object); void to_json(JsonValueScope &jv, const ton_api::validator_config_Local &object); void to_json(JsonValueScope &jv, const ton_api::validator_config_local &object); diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.cpp b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.cpp index 3a3e034c82..16050639bc 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.cpp +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.cpp @@ -199,6 +199,36 @@ void key::store(td::TlStorerToString &s, const char *field_name) const { } } +keyStoreTypeDirectory::keyStoreTypeDirectory() + : directory_() +{} + +keyStoreTypeDirectory::keyStoreTypeDirectory(std::string const &directory_) + : directory_(std::move(directory_)) +{} + +const std::int32_t keyStoreTypeDirectory::ID; + +void keyStoreTypeDirectory::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "keyStoreTypeDirectory"); + s.store_field("directory", directory_); + s.store_class_end(); + } +} + +keyStoreTypeInMemory::keyStoreTypeInMemory() { +} + +const std::int32_t keyStoreTypeInMemory::ID; + +void keyStoreTypeInMemory::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "keyStoreTypeInMemory"); + s.store_class_end(); + } +} + logStreamDefault::logStreamDefault() { } @@ -294,12 +324,12 @@ void ok::store(td::TlStorerToString &s, const char *field_name) const { options::options() : config_() - , keystore_directory_() + , keystore_type_() {} -options::options(object_ptr &&config_, std::string const &keystore_directory_) +options::options(object_ptr &&config_, object_ptr &&keystore_type_) : config_(std::move(config_)) - , keystore_directory_(std::move(keystore_directory_)) + , keystore_type_(std::move(keystore_type_)) {} const std::int32_t options::ID; @@ -308,17 +338,19 @@ void options::store(td::TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { s.store_class_begin(field_name, "options"); if (config_ == nullptr) { s.store_field("config", "null"); } else { config_->store(s, "config"); } - s.store_field("keystore_directory", keystore_directory_); + if (keystore_type_ == nullptr) { s.store_field("keystore_type", "null"); } else { keystore_type_->store(s, "keystore_type"); } s.store_class_end(); } } sendGramsResult::sendGramsResult() : sent_until_() + , body_hash_() {} -sendGramsResult::sendGramsResult(std::int64_t sent_until_) +sendGramsResult::sendGramsResult(std::int64_t sent_until_, std::string const &body_hash_) : sent_until_(sent_until_) + , body_hash_(std::move(body_hash_)) {} const std::int32_t sendGramsResult::ID; @@ -327,6 +359,7 @@ void sendGramsResult::store(td::TlStorerToString &s, const char *field_name) con if (!LOG_IS_STRIPPED(ERROR)) { s.store_class_begin(field_name, "sendGramsResult"); s.store_field("sent_until", sent_until_); + s.store_bytes_field("body_hash", body_hash_); s.store_class_end(); } } @@ -545,13 +578,21 @@ raw_message::raw_message() : source_() , destination_() , value_() + , fwd_fee_() + , ihr_fee_() + , created_lt_() + , body_hash_() , message_() {} -raw_message::raw_message(std::string const &source_, std::string const &destination_, std::int64_t value_, std::string const &message_) +raw_message::raw_message(std::string const &source_, std::string const &destination_, std::int64_t value_, std::int64_t fwd_fee_, std::int64_t ihr_fee_, std::int64_t created_lt_, std::string const &body_hash_, std::string const &message_) : source_(std::move(source_)) , destination_(std::move(destination_)) , value_(value_) + , fwd_fee_(fwd_fee_) + , ihr_fee_(ihr_fee_) + , created_lt_(created_lt_) + , body_hash_(std::move(body_hash_)) , message_(std::move(message_)) {} @@ -563,6 +604,10 @@ void raw_message::store(td::TlStorerToString &s, const char *field_name) const { s.store_field("source", source_); s.store_field("destination", destination_); s.store_field("value", value_); + s.store_field("fwd_fee", fwd_fee_); + s.store_field("ihr_fee", ihr_fee_); + s.store_field("created_lt", created_lt_); + s.store_bytes_field("body_hash", body_hash_); s.store_bytes_field("message", message_); s.store_class_end(); } @@ -573,15 +618,19 @@ raw_transaction::raw_transaction() , data_() , transaction_id_() , fee_() + , storage_fee_() + , other_fee_() , in_msg_() , out_msgs_() {} -raw_transaction::raw_transaction(std::int64_t utime_, std::string const &data_, object_ptr &&transaction_id_, std::int64_t fee_, object_ptr &&in_msg_, std::vector> &&out_msgs_) +raw_transaction::raw_transaction(std::int64_t utime_, std::string const &data_, object_ptr &&transaction_id_, std::int64_t fee_, std::int64_t storage_fee_, std::int64_t other_fee_, object_ptr &&in_msg_, std::vector> &&out_msgs_) : utime_(utime_) , data_(std::move(data_)) , transaction_id_(std::move(transaction_id_)) , fee_(fee_) + , storage_fee_(storage_fee_) + , other_fee_(other_fee_) , in_msg_(std::move(in_msg_)) , out_msgs_(std::move(out_msgs_)) {} @@ -595,6 +644,8 @@ void raw_transaction::store(td::TlStorerToString &s, const char *field_name) con s.store_bytes_field("data", data_); if (transaction_id_ == nullptr) { s.store_field("transaction_id", "null"); } else { transaction_id_->store(s, "transaction_id"); } s.store_field("fee", fee_); + s.store_field("storage_fee", storage_fee_); + s.store_field("other_fee", other_fee_); if (in_msg_ == nullptr) { s.store_field("in_msg", "null"); } else { in_msg_->store(s, "in_msg"); } { const std::vector> &v = out_msgs_; const std::uint32_t multiplicity = static_cast(v.size()); const auto vector_name = "vector[" + td::to_string(multiplicity)+ "]"; s.store_class_begin("out_msgs", vector_name.c_str()); for (std::uint32_t i = 0; i < multiplicity; i++) { if (v[i] == nullptr) { s.store_field("", "null"); } else { v[i]->store(s, ""); } } s.store_class_end(); } s.store_class_end(); @@ -841,6 +892,18 @@ void createNewKey::store(td::TlStorerToString &s, const char *field_name) const } } +deleteAllKeys::deleteAllKeys() { +} + +const std::int32_t deleteAllKeys::ID; + +void deleteAllKeys::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deleteAllKeys"); + s.store_class_end(); + } +} + deleteKey::deleteKey() : key_() {} diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.h b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.h index c4a9fa6d15..8d8275b55e 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.h +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.h @@ -62,6 +62,8 @@ class inputKey; class key; +class KeyStoreType; + class LogStream; class logTags; @@ -264,6 +266,39 @@ class key final : public Object { void store(td::TlStorerToString &s, const char *field_name) const final; }; +class KeyStoreType: public Object { + public: +}; + +class keyStoreTypeDirectory final : public KeyStoreType { + public: + std::string directory_; + + keyStoreTypeDirectory(); + + explicit keyStoreTypeDirectory(std::string const &directory_); + + static const std::int32_t ID = -378990038; + std::int32_t get_id() const final { + return ID; + } + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + +class keyStoreTypeInMemory final : public KeyStoreType { + public: + + keyStoreTypeInMemory(); + + static const std::int32_t ID = -2106848825; + std::int32_t get_id() const final { + return ID; + } + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + class LogStream: public Object { public: }; @@ -359,13 +394,13 @@ class ok final : public Object { class options final : public Object { public: object_ptr config_; - std::string keystore_directory_; + object_ptr keystore_type_; options(); - options(object_ptr &&config_, std::string const &keystore_directory_); + options(object_ptr &&config_, object_ptr &&keystore_type_); - static const std::int32_t ID = 789823302; + static const std::int32_t ID = -1924388359; std::int32_t get_id() const final { return ID; } @@ -376,12 +411,13 @@ class options final : public Object { class sendGramsResult final : public Object { public: std::int64_t sent_until_; + std::string body_hash_; sendGramsResult(); - explicit sendGramsResult(std::int64_t sent_until_); + sendGramsResult(std::int64_t sent_until_, std::string const &body_hash_); - static const std::int32_t ID = -858318471; + static const std::int32_t ID = 426872238; std::int32_t get_id() const final { return ID; } @@ -568,13 +604,17 @@ class raw_message final : public Object { std::string source_; std::string destination_; std::int64_t value_; + std::int64_t fwd_fee_; + std::int64_t ihr_fee_; + std::int64_t created_lt_; + std::string body_hash_; std::string message_; raw_message(); - raw_message(std::string const &source_, std::string const &destination_, std::int64_t value_, std::string const &message_); + raw_message(std::string const &source_, std::string const &destination_, std::int64_t value_, std::int64_t fwd_fee_, std::int64_t ihr_fee_, std::int64_t created_lt_, std::string const &body_hash_, std::string const &message_); - static const std::int32_t ID = -259956097; + static const std::int32_t ID = -906281442; std::int32_t get_id() const final { return ID; } @@ -588,14 +628,16 @@ class raw_transaction final : public Object { std::string data_; object_ptr transaction_id_; std::int64_t fee_; + std::int64_t storage_fee_; + std::int64_t other_fee_; object_ptr in_msg_; std::vector> out_msgs_; raw_transaction(); - raw_transaction(std::int64_t utime_, std::string const &data_, object_ptr &&transaction_id_, std::int64_t fee_, object_ptr &&in_msg_, std::vector> &&out_msgs_); + raw_transaction(std::int64_t utime_, std::string const &data_, object_ptr &&transaction_id_, std::int64_t fee_, std::int64_t storage_fee_, std::int64_t other_fee_, object_ptr &&in_msg_, std::vector> &&out_msgs_); - static const std::int32_t ID = -1159530820; + static const std::int32_t ID = 1887601793; std::int32_t get_id() const final { return ID; } @@ -612,7 +654,7 @@ class raw_transactions final : public Object { raw_transactions(std::vector> &&transactions_, object_ptr &&previous_transaction_id_); - static const std::int32_t ID = 240548986; + static const std::int32_t ID = -2063931155; std::int32_t get_id() const final { return ID; } @@ -800,6 +842,21 @@ class createNewKey final : public Function { void store(td::TlStorerToString &s, const char *field_name) const final; }; +class deleteAllKeys final : public Function { + public: + + deleteAllKeys(); + + static const std::int32_t ID = 1608776483; + std::int32_t get_id() const final { + return ID; + } + + using ReturnType = object_ptr; + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + class deleteKey final : public Function { public: object_ptr key_; diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.hpp b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.hpp index 920df0e9eb..b5d3bd076c 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.hpp +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api.hpp @@ -41,6 +41,12 @@ bool downcast_call(Object &obj, const T &func) { case key::ID: func(static_cast(obj)); return true; + case keyStoreTypeDirectory::ID: + func(static_cast(obj)); + return true; + case keyStoreTypeInMemory::ID: + func(static_cast(obj)); + return true; case logStreamDefault::ID: func(static_cast(obj)); return true; @@ -148,6 +154,9 @@ bool downcast_call(Function &obj, const T &func) { case createNewKey::ID: func(static_cast(obj)); return true; + case deleteAllKeys::ID: + func(static_cast(obj)); + return true; case deleteKey::ID: func(static_cast(obj)); return true; @@ -270,6 +279,26 @@ bool downcast_call(Function &obj, const T &func) { } } +/** + * Calls specified function object with the specified object downcasted to the most-derived type. + * \param[in] obj Object to pass as an argument to the function object. + * \param[in] func Function object to which the object will be passed. + * \returns whether function object call has happened. Should always return true for correct parameters. + */ +template +bool downcast_call(KeyStoreType &obj, const T &func) { + switch (obj.get_id()) { + case keyStoreTypeDirectory::ID: + func(static_cast(obj)); + return true; + case keyStoreTypeInMemory::ID: + func(static_cast(obj)); + return true; + default: + return false; + } +} + /** * Calls specified function object with the specified object downcasted to the most-derived type. * \param[in] obj Object to pass as an argument to the function object. diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.cpp b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.cpp index 29ee340f62..c0b6ec7cea 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.cpp +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.cpp @@ -14,6 +14,17 @@ namespace ton { namespace tonlib_api{ using namespace td; +Result tl_constructor_from_string(tonlib_api::KeyStoreType *object, const std::string &str) { + static const std::unordered_map m = { + {"keyStoreTypeDirectory", -378990038}, + {"keyStoreTypeInMemory", -2106848825} + }; + auto it = m.find(str); + if (it == m.end()) { + return Status::Error(str + "Unknown class"); + } + return it->second; +} Result tl_constructor_from_string(tonlib_api::LogStream *object, const std::string &str) { static const std::unordered_map m = { {"logStreamDefault", 1390581436}, @@ -51,14 +62,16 @@ Result tl_constructor_from_string(tonlib_api::Object *object, const std:: {"exportedPemKey", 1425473725}, {"inputKey", 869287093}, {"key", -1978362923}, + {"keyStoreTypeDirectory", -378990038}, + {"keyStoreTypeInMemory", -2106848825}, {"logStreamDefault", 1390581436}, {"logStreamFile", -1880085930}, {"logStreamEmpty", -499912244}, {"logTags", -1604930601}, {"logVerbosityLevel", 1734624234}, {"ok", -722616727}, - {"options", 789823302}, - {"sendGramsResult", -858318471}, + {"options", -1924388359}, + {"sendGramsResult", 426872238}, {"unpackedAccountAddress", 1892946998}, {"updateSendLiteServerQuery", -1555130916}, {"generic.accountStateRaw", -1387096685}, @@ -69,9 +82,9 @@ Result tl_constructor_from_string(tonlib_api::Object *object, const std:: {"internal.transactionId", -989527262}, {"raw.accountState", 461615898}, {"raw.initialAccountState", 777456197}, - {"raw.message", -259956097}, - {"raw.transaction", -1159530820}, - {"raw.transactions", 240548986}, + {"raw.message", -906281442}, + {"raw.transaction", 1887601793}, + {"raw.transactions", -2063931155}, {"testGiver.accountState", 860930426}, {"testWallet.accountState", 305698744}, {"testWallet.initialAccountState", -1231516227}, @@ -91,6 +104,7 @@ Result tl_constructor_from_string(tonlib_api::Function *object, const std {"changeLocalPassword", -1685491421}, {"close", -1187782273}, {"createNewKey", -1861385712}, + {"deleteAllKeys", 1608776483}, {"deleteKey", -1579595571}, {"exportEncryptedKey", 155352861}, {"exportKey", 399723440}, @@ -254,6 +268,18 @@ Status from_json(tonlib_api::key &to, JsonObject &from) { } return Status::OK(); } +Status from_json(tonlib_api::keyStoreTypeDirectory &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "directory", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.directory_, value)); + } + } + return Status::OK(); +} +Status from_json(tonlib_api::keyStoreTypeInMemory &to, JsonObject &from) { + return Status::OK(); +} Status from_json(tonlib_api::logStreamDefault &to, JsonObject &from) { return Status::OK(); } @@ -304,9 +330,9 @@ Status from_json(tonlib_api::options &to, JsonObject &from) { } } { - TRY_RESULT(value, get_json_object_field(from, "keystore_directory", JsonValue::Type::Null, true)); + TRY_RESULT(value, get_json_object_field(from, "keystore_type", JsonValue::Type::Null, true)); if (value.type() != JsonValue::Type::Null) { - TRY_STATUS(from_json(to.keystore_directory_, value)); + TRY_STATUS(from_json(to.keystore_type_, value)); } } return Status::OK(); @@ -318,6 +344,12 @@ Status from_json(tonlib_api::sendGramsResult &to, JsonObject &from) { TRY_STATUS(from_json(to.sent_until_, value)); } } + { + TRY_RESULT(value, get_json_object_field(from, "body_hash", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json_bytes(to.body_hash_, value)); + } + } return Status::OK(); } Status from_json(tonlib_api::unpackedAccountAddress &to, JsonObject &from) { @@ -489,6 +521,30 @@ Status from_json(tonlib_api::raw_message &to, JsonObject &from) { TRY_STATUS(from_json(to.value_, value)); } } + { + TRY_RESULT(value, get_json_object_field(from, "fwd_fee", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.fwd_fee_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "ihr_fee", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.ihr_fee_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "created_lt", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.created_lt_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "body_hash", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json_bytes(to.body_hash_, value)); + } + } { TRY_RESULT(value, get_json_object_field(from, "message", JsonValue::Type::Null, true)); if (value.type() != JsonValue::Type::Null) { @@ -522,6 +578,18 @@ Status from_json(tonlib_api::raw_transaction &to, JsonObject &from) { TRY_STATUS(from_json(to.fee_, value)); } } + { + TRY_RESULT(value, get_json_object_field(from, "storage_fee", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.storage_fee_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "other_fee", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.other_fee_, value)); + } + } { TRY_RESULT(value, get_json_object_field(from, "in_msg", JsonValue::Type::Null, true)); if (value.type() != JsonValue::Type::Null) { @@ -725,6 +793,9 @@ Status from_json(tonlib_api::createNewKey &to, JsonObject &from) { } return Status::OK(); } +Status from_json(tonlib_api::deleteAllKeys &to, JsonObject &from) { + return Status::OK(); +} Status from_json(tonlib_api::deleteKey &to, JsonObject &from) { { TRY_RESULT(value, get_json_object_field(from, "key", JsonValue::Type::Null, true)); @@ -1291,6 +1362,18 @@ void to_json(JsonValueScope &jv, const tonlib_api::key &object) { jo << ctie("public_key", ToJson(object.public_key_)); jo << ctie("secret", ToJson(JsonBytes{object.secret_})); } +void to_json(JsonValueScope &jv, const tonlib_api::KeyStoreType &object) { + tonlib_api::downcast_call(const_cast(object), [&jv](const auto &object) { to_json(jv, object); }); +} +void to_json(JsonValueScope &jv, const tonlib_api::keyStoreTypeDirectory &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "keyStoreTypeDirectory"); + jo << ctie("directory", ToJson(object.directory_)); +} +void to_json(JsonValueScope &jv, const tonlib_api::keyStoreTypeInMemory &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "keyStoreTypeInMemory"); +} void to_json(JsonValueScope &jv, const tonlib_api::LogStream &object) { tonlib_api::downcast_call(const_cast(object), [&jv](const auto &object) { to_json(jv, object); }); } @@ -1328,12 +1411,15 @@ void to_json(JsonValueScope &jv, const tonlib_api::options &object) { if (object.config_) { jo << ctie("config", ToJson(object.config_)); } - jo << ctie("keystore_directory", ToJson(object.keystore_directory_)); + if (object.keystore_type_) { + jo << ctie("keystore_type", ToJson(object.keystore_type_)); + } } void to_json(JsonValueScope &jv, const tonlib_api::sendGramsResult &object) { auto jo = jv.enter_object(); jo << ctie("@type", "sendGramsResult"); jo << ctie("sent_until", ToJson(object.sent_until_)); + jo << ctie("body_hash", ToJson(JsonBytes{object.body_hash_})); } void to_json(JsonValueScope &jv, const tonlib_api::unpackedAccountAddress &object) { auto jo = jv.enter_object(); @@ -1416,6 +1502,10 @@ void to_json(JsonValueScope &jv, const tonlib_api::raw_message &object) { jo << ctie("source", ToJson(object.source_)); jo << ctie("destination", ToJson(object.destination_)); jo << ctie("value", ToJson(JsonInt64{object.value_})); + jo << ctie("fwd_fee", ToJson(JsonInt64{object.fwd_fee_})); + jo << ctie("ihr_fee", ToJson(JsonInt64{object.ihr_fee_})); + jo << ctie("created_lt", ToJson(JsonInt64{object.created_lt_})); + jo << ctie("body_hash", ToJson(JsonBytes{object.body_hash_})); jo << ctie("message", ToJson(JsonBytes{object.message_})); } void to_json(JsonValueScope &jv, const tonlib_api::raw_transaction &object) { @@ -1427,6 +1517,8 @@ void to_json(JsonValueScope &jv, const tonlib_api::raw_transaction &object) { jo << ctie("transaction_id", ToJson(object.transaction_id_)); } jo << ctie("fee", ToJson(JsonInt64{object.fee_})); + jo << ctie("storage_fee", ToJson(JsonInt64{object.storage_fee_})); + jo << ctie("other_fee", ToJson(JsonInt64{object.other_fee_})); if (object.in_msg_) { jo << ctie("in_msg", ToJson(object.in_msg_)); } @@ -1514,6 +1606,10 @@ void to_json(JsonValueScope &jv, const tonlib_api::createNewKey &object) { jo << ctie("mnemonic_password", ToJson(JsonBytes{object.mnemonic_password_})); jo << ctie("random_extra_seed", ToJson(JsonBytes{object.random_extra_seed_})); } +void to_json(JsonValueScope &jv, const tonlib_api::deleteAllKeys &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "deleteAllKeys"); +} void to_json(JsonValueScope &jv, const tonlib_api::deleteKey &object) { auto jo = jv.enter_object(); jo << ctie("@type", "deleteKey"); diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.h b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.h index ebe3a9cfd7..a53d9030aa 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.h +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/tonlib_api_json.h @@ -11,6 +11,7 @@ namespace ton { namespace tonlib_api{ using namespace td; +Result tl_constructor_from_string(tonlib_api::KeyStoreType *object, const std::string &str); Result tl_constructor_from_string(tonlib_api::LogStream *object, const std::string &str); Result tl_constructor_from_string(tonlib_api::generic_AccountState *object, const std::string &str); Result tl_constructor_from_string(tonlib_api::Object *object, const std::string &str); @@ -24,6 +25,8 @@ Status from_json(tonlib_api::exportedKey &to, JsonObject &from); Status from_json(tonlib_api::exportedPemKey &to, JsonObject &from); Status from_json(tonlib_api::inputKey &to, JsonObject &from); Status from_json(tonlib_api::key &to, JsonObject &from); +Status from_json(tonlib_api::keyStoreTypeDirectory &to, JsonObject &from); +Status from_json(tonlib_api::keyStoreTypeInMemory &to, JsonObject &from); Status from_json(tonlib_api::logStreamDefault &to, JsonObject &from); Status from_json(tonlib_api::logStreamFile &to, JsonObject &from); Status from_json(tonlib_api::logStreamEmpty &to, JsonObject &from); @@ -55,6 +58,7 @@ Status from_json(tonlib_api::addLogMessage &to, JsonObject &from); Status from_json(tonlib_api::changeLocalPassword &to, JsonObject &from); Status from_json(tonlib_api::close &to, JsonObject &from); Status from_json(tonlib_api::createNewKey &to, JsonObject &from); +Status from_json(tonlib_api::deleteAllKeys &to, JsonObject &from); Status from_json(tonlib_api::deleteKey &to, JsonObject &from); Status from_json(tonlib_api::exportEncryptedKey &to, JsonObject &from); Status from_json(tonlib_api::exportKey &to, JsonObject &from); @@ -103,6 +107,9 @@ void to_json(JsonValueScope &jv, const tonlib_api::exportedKey &object); void to_json(JsonValueScope &jv, const tonlib_api::exportedPemKey &object); void to_json(JsonValueScope &jv, const tonlib_api::inputKey &object); void to_json(JsonValueScope &jv, const tonlib_api::key &object); +void to_json(JsonValueScope &jv, const tonlib_api::KeyStoreType &object); +void to_json(JsonValueScope &jv, const tonlib_api::keyStoreTypeDirectory &object); +void to_json(JsonValueScope &jv, const tonlib_api::keyStoreTypeInMemory &object); void to_json(JsonValueScope &jv, const tonlib_api::LogStream &object); void to_json(JsonValueScope &jv, const tonlib_api::logStreamDefault &object); void to_json(JsonValueScope &jv, const tonlib_api::logStreamFile &object); @@ -136,6 +143,7 @@ void to_json(JsonValueScope &jv, const tonlib_api::addLogMessage &object); void to_json(JsonValueScope &jv, const tonlib_api::changeLocalPassword &object); void to_json(JsonValueScope &jv, const tonlib_api::close &object); void to_json(JsonValueScope &jv, const tonlib_api::createNewKey &object); +void to_json(JsonValueScope &jv, const tonlib_api::deleteAllKeys &object); void to_json(JsonValueScope &jv, const tonlib_api::deleteKey &object); void to_json(JsonValueScope &jv, const tonlib_api::exportEncryptedKey &object); void to_json(JsonValueScope &jv, const tonlib_api::exportKey &object); diff --git a/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tl b/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tl index 89827f7f5c..942ec47ef9 100644 --- a/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tl +++ b/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tl @@ -444,12 +444,14 @@ db.state.initBlockId block:tonNode.blockIdExt = db.state.InitBlockId; db.state.gcBlockId block:tonNode.blockIdExt = db.state.GcBlockId; db.state.shardClient block:tonNode.blockIdExt = db.state.ShardClient; db.state.asyncSerializer block:tonNode.blockIdExt last:tonNode.blockIdExt last_ts:int = db.state.AsyncSerializer; +db.state.hardforks blocks:(vector tonNode.blockIdExt) = db.state.Hardforks; db.state.key.destroyedSessions = db.state.Key; db.state.key.initBlockId = db.state.Key; db.state.key.gcBlockId = db.state.Key; db.state.key.shardClient = db.state.Key; db.state.key.asyncSerializer = db.state.Key; +db.state.key.hardforks = db.state.Key; db.lt.el.key workchain:int shard:long idx:int = db.lt.Key; db.lt.desc.key workchain:int shard:long = db.lt.Key; @@ -466,6 +468,7 @@ db.lt.status.value total_shards:int = db.lt.status.Value; validator.groupMember public_key_hash:int256 adnl:int256 weight:long = engine.validator.GroupMember; validator.group workchain:int shard:long catchain_seqno:int config_hash:int256 members:(vector validator.groupMember) = validator.Group; +validator.groupEx workchain:int shard:long vertical_seqno:int catchain_seqno:int config_hash:int256 members:(vector validator.groupMember) = validator.Group; ---functions--- diff --git a/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tlo b/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tlo index 6959d9a3c9..6727841e90 100644 Binary files a/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tlo and b/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tlo differ diff --git a/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tl b/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tl index 07a2f32c14..deae3fa970 100644 --- a/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tl +++ b/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tl @@ -16,8 +16,12 @@ vector {t:Type} # [ t ] = Vector t; error code:int32 message:string = Error; ok = Ok; +keyStoreTypeDirectory directory:string = KeyStoreType; +keyStoreTypeInMemory = KeyStoreType; + config config:string blockchain_name:string use_callbacks_for_network:Bool ignore_cache:Bool = Config; -options config:config keystore_directory:string = Options; + +options config:config keystore_type:KeyStoreType = Options; key public_key:string secret:secureBytes = Key; inputKey key:key local_password:secureBytes = InputKey; @@ -35,9 +39,9 @@ internal.transactionId lt:int64 hash:bytes = internal.TransactionId; raw.initialAccountState code:bytes data:bytes = raw.InitialAccountState; raw.accountState balance:int64 code:bytes data:bytes last_transaction_id:internal.transactionId sync_utime:int53 = raw.AccountState; -raw.message source:string destination:string value:int64 message:bytes = raw.Message; -raw.transaction utime:int53 data:bytes transaction_id:internal.transactionId fee:int64 in_msg:raw.message out_msgs:vector = raw.Transaction; -raw.transactions transactions:vector previous_transaction_id:internal.transactionId = raw.Transactions; +raw.message source:string destination:string value:int64 fwd_fee:int64 ihr_fee:int64 created_lt:int64 body_hash:bytes message:bytes = raw.Message; +raw.transaction utime:int53 data:bytes transaction_id:internal.transactionId fee:int64 storage_fee:int64 other_fee:int64 in_msg:raw.message out_msgs:vector = raw.Transaction; +raw.transactions transactions:vector previous_transaction_id:internal.transactionId = raw.Transactions; testWallet.initialAccountState public_key:string = testWallet.InitialAccountState; testWallet.accountState balance:int64 seqno:int32 last_transaction_id:internal.transactionId sync_utime:int53 = testWallet.AccountState; @@ -59,7 +63,7 @@ generic.accountStateWallet account_state:wallet.accountState = generic.AccountSt generic.accountStateTestGiver account_state:testGiver.accountState = generic.AccountState; generic.accountStateUninited account_state:uninited.accountState = generic.AccountState; -sendGramsResult sent_until:int53 = SendGramsResult; +sendGramsResult sent_until:int53 body_hash:bytes = SendGramsResult; updateSendLiteServerQuery id:int64 data:bytes = Update; @@ -90,6 +94,7 @@ options.setConfig config:config = Ok; createNewKey local_password:secureBytes mnemonic_password:secureBytes random_extra_seed:secureBytes = Key; deleteKey key:key = Ok; +deleteAllKeys = Ok; exportKey input_key:inputKey = ExportedKey; exportPemKey input_key:inputKey key_password:secureBytes = ExportedPemKey; exportEncryptedKey input_key:inputKey key_password:secureBytes = ExportedEncryptedKey; diff --git a/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tlo b/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tlo index b77565e03e..180f352172 100644 Binary files a/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tlo and b/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tlo differ diff --git a/submodules/ton/tonlib-src/tonlib/CMakeLists.txt b/submodules/ton/tonlib-src/tonlib/CMakeLists.txt index 3867779643..a46f3d3c7b 100644 --- a/submodules/ton/tonlib-src/tonlib/CMakeLists.txt +++ b/submodules/ton/tonlib-src/tonlib/CMakeLists.txt @@ -5,6 +5,7 @@ if (NOT OPENSSL_FOUND) endif() set(TONLIB_SOURCE + tonlib/CellString.cpp tonlib/Client.cpp tonlib/Config.cpp tonlib/ExtClient.cpp @@ -12,6 +13,7 @@ set(TONLIB_SOURCE tonlib/ExtClientOutbound.cpp tonlib/GenericAccount.cpp tonlib/KeyStorage.cpp + tonlib/KeyValue.cpp tonlib/LastBlock.cpp tonlib/LastBlockStorage.cpp tonlib/Logging.cpp @@ -21,6 +23,7 @@ set(TONLIB_SOURCE tonlib/utils.cpp tonlib/Wallet.cpp + tonlib/CellString.h tonlib/Client.h tonlib/Config.h tonlib/ExtClient.h @@ -28,6 +31,7 @@ set(TONLIB_SOURCE tonlib/ExtClientOutbound.h tonlib/GenericAccount.h tonlib/KeyStorage.h + tonlib/KeyValue.h tonlib/LastBlock.h tonlib/LastBlockStorage.h tonlib/Logging.h diff --git a/submodules/ton/tonlib-src/tonlib/test/offline.cpp b/submodules/ton/tonlib-src/tonlib/test/offline.cpp index 63a52fae39..d6f6d92ce1 100644 --- a/submodules/ton/tonlib-src/tonlib/test/offline.cpp +++ b/submodules/ton/tonlib-src/tonlib/test/offline.cpp @@ -28,6 +28,7 @@ #include "vm/boc.h" #include "vm/cells/MerkleProof.h" +#include "tonlib/CellString.h" #include "tonlib/utils.h" #include "tonlib/TestGiver.h" #include "tonlib/TestWallet.h" @@ -53,6 +54,20 @@ #include "tonlib/keys/Mnemonic.h" #include "tonlib/keys/SimpleEncryption.h" +TEST(Tonlib, CellString) { + for (unsigned size : + {0, 1, 7, 8, 35, 127, 128, 255, 256, (int)vm::CellString::max_bytes - 1, (int)vm::CellString::max_bytes}) { + auto str = td::rand_string('a', 'z', size); + for (unsigned head : {0, 1, 7, 8, 127, 35 * 8, 127 * 8, 1023, 1024}) { + vm::CellBuilder cb; + vm::CellString::store(cb, str, head).ensure(); + auto cs = vm::load_cell_slice(cb.finalize()); + auto got_str = vm::CellString::load(cs, head).move_as_ok(); + ASSERT_EQ(str, got_str); + } + } +}; + using namespace tonlib; std::string current_dir() { @@ -268,20 +283,23 @@ static auto sync_send = [](auto &client, auto query) { TEST(Tonlib, InitClose) { using tonlib_api::make_object; auto cfg = [](auto str) { return make_object(str, "", false, false); }; + auto dir = [](auto str) { return make_object(str); }; { Client client; sync_send(client, make_object()).ensure(); - sync_send(client, make_object(make_object(nullptr, "."))).ensure_error(); + sync_send(client, make_object(make_object(nullptr, dir(".")))) + .ensure_error(); } { Client client; sync_send(client, make_object(nullptr)).ensure_error(); - sync_send(client, make_object(make_object(cfg("fdajkfldsjkafld"), "."))) + sync_send(client, make_object(make_object(cfg("fdajkfldsjkafld"), dir(".")))) .ensure_error(); - sync_send(client, make_object(make_object(nullptr, "fdhskfds"))) + sync_send(client, make_object(make_object(nullptr, dir("fdhskfds")))) + .ensure_error(); + sync_send(client, make_object(make_object(nullptr, dir(".")))).ensure(); + sync_send(client, make_object(make_object(nullptr, dir(".")))) .ensure_error(); - sync_send(client, make_object(make_object(nullptr, "."))).ensure(); - sync_send(client, make_object(make_object(nullptr, "."))).ensure_error(); td::Slice bad_config = R"abc( { @@ -294,7 +312,8 @@ TEST(Tonlib, InitClose) { sync_send(client, make_object()).ensure_error(); sync_send(client, make_object()).ensure(); sync_send(client, make_object()).ensure_error(); - sync_send(client, make_object(make_object(nullptr, "."))).ensure_error(); + sync_send(client, make_object(make_object(nullptr, dir(".")))) + .ensure_error(); } } @@ -389,7 +408,9 @@ TEST(Tonlib, ParseAddres) { Client client; // init - sync_send(client, make_object(make_object(nullptr, "."))).ensure(); + sync_send(client, make_object( + make_object(nullptr, make_object(".")))) + .ensure(); sync_send(client, make_object("hello")).ensure_error(); auto addr = @@ -409,7 +430,9 @@ TEST(Tonlib, KeysApi) { Client client; // init - sync_send(client, make_object(make_object(nullptr, "."))).ensure(); + sync_send(client, make_object( + make_object(nullptr, make_object(".")))) + .ensure(); auto local_password = td::SecureString("local password"); auto mnemonic_password = td::SecureString("mnemonic password"); { diff --git a/submodules/ton/tonlib-src/tonlib/test/online.cpp b/submodules/ton/tonlib-src/tonlib/test/online.cpp index 0425f53757..6ac47921df 100644 --- a/submodules/ton/tonlib-src/tonlib/test/online.cpp +++ b/submodules/ton/tonlib-src/tonlib/test/online.cpp @@ -197,7 +197,8 @@ int main(int argc, char* argv[]) { Client client; { sync_send(client, make_object(make_object( - make_object(global_config_str, "", false, false), "."))) + make_object(global_config_str, "", false, false), + make_object(".")))) .ensure(); } //dump_transaction_history(client, get_test_giver_address(client)); @@ -211,7 +212,8 @@ int main(int argc, char* argv[]) { { // init sync_send(client, make_object(make_object( - make_object(global_config_str, "", false, false), "."))) + make_object(global_config_str, "", false, false), + make_object(".")))) .ensure(); auto key = sync_send(client, make_object( diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/.TonlibClient.cpp.swp b/submodules/ton/tonlib-src/tonlib/tonlib/.TonlibClient.cpp.swp deleted file mode 100644 index a3dd3f30b9..0000000000 Binary files a/submodules/ton/tonlib-src/tonlib/tonlib/.TonlibClient.cpp.swp and /dev/null differ diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/.TonlibError.h.swp b/submodules/ton/tonlib-src/tonlib/tonlib/.TonlibError.h.swp new file mode 100644 index 0000000000..0c158e3988 Binary files /dev/null and b/submodules/ton/tonlib-src/tonlib/tonlib/.TonlibError.h.swp differ diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/.Wallet.cpp.swp b/submodules/ton/tonlib-src/tonlib/tonlib/.Wallet.cpp.swp index 61ab3cfd77..e45873644b 100644 Binary files a/submodules/ton/tonlib-src/tonlib/tonlib/.Wallet.cpp.swp and b/submodules/ton/tonlib-src/tonlib/tonlib/.Wallet.cpp.swp differ diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/CellString.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/CellString.cpp new file mode 100644 index 0000000000..ad2cbf5f8f --- /dev/null +++ b/submodules/ton/tonlib-src/tonlib/tonlib/CellString.cpp @@ -0,0 +1,64 @@ +#include "CellString.h" +#include "td/utils/misc.h" + +#include "vm/cells/CellSlice.h" + +namespace vm { +td::Status CellString::store(CellBuilder &cb, td::Slice slice, unsigned int top_bits) { + td::uint32 size = td::narrow_cast(slice.size() * 8); + return store(cb, td::BitSlice(slice.ubegin(), size), top_bits); +} + +td::Status CellString::store(CellBuilder &cb, td::BitSlice slice, unsigned int top_bits) { + if (slice.size() > max_bytes * 8) { + return td::Status::Error("String is too long (1)"); + } + unsigned int head = td::min(slice.size(), td::min(cb.remaining_bits(), top_bits)) / 8 * 8; + auto max_bits = vm::Cell::max_bits / 8 * 8; + auto depth = 1 + (slice.size() - head + max_bits - 1) / max_bits; + if (depth > max_chain_length) { + return td::Status::Error("String is too long (2)"); + } + cb.append_bitslice(slice.subslice(0, head)); + slice.advance(head); + if (slice.size() == 0) { + return td::Status::OK(); + } + CellBuilder child_cb; + store(child_cb, std::move(slice)); + cb.store_ref(child_cb.finalize()); + return td::Status::OK(); +} + +template +void CellString::for_each(F &&f, CellSlice &cs, unsigned int top_bits) { + unsigned int head = td::min(cs.size(), top_bits); + f(cs.prefetch_bits(head)); + if (!cs.have_refs()) { + return; + } + auto ref = cs.prefetch_ref(); + while (true) { + auto cs = vm::load_cell_slice(ref); + f(cs.prefetch_bits(cs.size())); + if (!cs.have_refs()) { + return; + } + ref = cs.prefetch_ref(); + } +} + +td::Result CellString::load(CellSlice &cs, unsigned int top_bits) { + unsigned int size = 0; + for_each([&](auto slice) { size += slice.size(); }, cs, top_bits); + if (size % 8 != 0) { + return td::Status::Error("Size is not divisible by 8"); + } + std::string res(size / 8, 0); + + td::BitPtr to(td::MutableSlice(res).ubegin()); + for_each([&](auto slice) { to.concat(slice); }, cs, top_bits); + CHECK(to.offs == (int)size); + return res; +} +} // namespace vm diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/CellString.h b/submodules/ton/tonlib-src/tonlib/tonlib/CellString.h new file mode 100644 index 0000000000..89c933d876 --- /dev/null +++ b/submodules/ton/tonlib-src/tonlib/tonlib/CellString.h @@ -0,0 +1,22 @@ +#pragma once + +#include "td/utils/Status.h" + +#include "vm/cells/CellBuilder.h" + +namespace vm { +class CellString { + public: + static constexpr unsigned int max_bytes = 1024; + static constexpr unsigned int max_chain_length = 16; + + static td::Status store(CellBuilder &cb, td::Slice slice, unsigned int top_bits = Cell::max_bits); + static td::Status store(CellBuilder &cb, td::BitSlice slice, unsigned int top_bits = Cell::max_bits); + static td::Result load(CellSlice &cs, unsigned int top_bits = Cell::max_bits); + + private: + template + static void for_each(F &&f, CellSlice &cs, unsigned int top_bits = Cell::max_bits); +}; + +} // namespace vm diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/ExtClient.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/ExtClient.cpp index 0ec942ed90..442d65033a 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/ExtClient.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/ExtClient.cpp @@ -30,7 +30,7 @@ void ExtClient::with_last_block(td::Promise promise) { }); }; if (client_.last_block_actor_.empty()) { - return P.set_error(td::Status::Error(500, "No lite clients")); + return P.set_error(TonlibError::NoLiteServers()); } td::actor::send_closure(client_.last_block_actor_, &LastBlock::get_last_block, std::move(P)); } @@ -44,7 +44,7 @@ void ExtClient::send_raw_query(td::BufferSlice query, td::Promise void send_query(QueryT query, td::Promise promise) { auto raw_query = ton::serialize_tl_object(&query, true); - LOG(ERROR) << "send query to liteserver: " << to_string(query); + td::uint32 tag = td::Random::fast_uint32(); + VLOG(lite_server) << "send query to liteserver: " << tag << " " << to_string(query); td::BufferSlice liteserver_query = ton::serialize_tl_object(ton::create_tl_object(std::move(raw_query)), true); - send_raw_query(std::move(liteserver_query), [promise = std::move(promise)](td::Result R) mutable { - promise.set_result([&]() -> td::Result { - TRY_RESULT(data, std::move(R)); - auto r_error = ton::fetch_tl_object(data.clone(), true); - if (r_error.is_ok()) { - auto f = r_error.move_as_ok(); - return td::Status::Error(f->code_, f->message_); - } - return ton::fetch_result(std::move(data)); - }()); - }); + send_raw_query( + std::move(liteserver_query), [promise = std::move(promise), tag](td::Result R) mutable { + auto res = [&]() -> td::Result { + TRY_RESULT_PREFIX(data, std::move(R), TonlibError::LiteServerNetwork()); + auto r_error = ton::fetch_tl_object(data.clone(), true); + if (r_error.is_ok()) { + auto f = r_error.move_as_ok(); + return TonlibError::LiteServer(f->code_, f->message_); + } + return ton::fetch_result(std::move(data)); + } + (); + VLOG_IF(lite_server, res.is_ok()) + << "got result from liteserver: " << tag << " " << td::Slice(to_string(res.ok())).truncate(1 << 12); + VLOG_IF(lite_server, res.is_error()) << "got error from liteserver: " << tag << " " << res.error(); + promise.set_result(std::move(res)); + }); } private: diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/ExtClientOutbound.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/ExtClientOutbound.cpp index a20a8c59f2..f1746af5d6 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/ExtClientOutbound.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/ExtClientOutbound.cpp @@ -18,6 +18,7 @@ Copyright 2017-2019 Telegram Systems LLP */ #include "ExtClientOutbound.h" +#include "TonlibError.h" #include namespace tonlib { @@ -40,7 +41,7 @@ class ExtClientOutboundImp : public ExtClientOutbound { void on_query_result(td::int64 id, td::Result r_data, td::Promise promise) override { auto it = queries_.find(id); if (it == queries_.end()) { - promise.set_error(td::Status::Error(400, "Unknown query id")); + promise.set_error(TonlibError::Internal("Unknown query id")); } it->second.set_result(std::move(r_data)); queries_.erase(it); @@ -54,7 +55,7 @@ class ExtClientOutboundImp : public ExtClientOutbound { void tear_down() override { for (auto &it : queries_) { - it.second.set_error(td::Status::Error(400, "Query cancelled")); + it.second.set_error(TonlibError::Cancelled()); } queries_.clear(); } diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/GenericAccount.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/GenericAccount.cpp index 08ea33bdc9..9f44ede274 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/GenericAccount.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/GenericAccount.cpp @@ -20,18 +20,19 @@ #include "tonlib/utils.h" #include "block/block-auto.h" namespace tonlib { -td::Ref GenericAccount::get_init_state(td::Ref code, td::Ref data) { +td::Ref GenericAccount::get_init_state(td::Ref code, td::Ref data) noexcept { return vm::CellBuilder() .append_cellslice(binary_bitstring_to_cellslice("b{00110}").move_as_ok()) .store_ref(std::move(code)) .store_ref(std::move(data)) .finalize(); } -block::StdAddress GenericAccount::get_address(ton::WorkchainId workchain_id, const td::Ref& init_state) { +block::StdAddress GenericAccount::get_address(ton::WorkchainId workchain_id, + const td::Ref& init_state) noexcept { return block::StdAddress(workchain_id, init_state->get_hash().bits(), true /*bounce*/); } td::Ref GenericAccount::create_ext_message(const block::StdAddress& address, td::Ref new_state, - td::Ref body) { + td::Ref body) noexcept { block::gen::Message::Record message; /*info*/ { block::gen::CommonMsgInfo::Record_ext_in_msg_info info; diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/GenericAccount.h b/submodules/ton/tonlib-src/tonlib/tonlib/GenericAccount.h index 253274f05e..4a36d78a53 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/GenericAccount.h +++ b/submodules/ton/tonlib-src/tonlib/tonlib/GenericAccount.h @@ -22,9 +22,9 @@ namespace tonlib { class GenericAccount { public: - static td::Ref get_init_state(td::Ref code, td::Ref data); - static block::StdAddress get_address(ton::WorkchainId workchain_id, const td::Ref& init_state); + static td::Ref get_init_state(td::Ref code, td::Ref data) noexcept; + static block::StdAddress get_address(ton::WorkchainId workchain_id, const td::Ref& init_state) noexcept; static td::Ref create_ext_message(const block::StdAddress& address, td::Ref new_state, - td::Ref body); + td::Ref body) noexcept; }; } // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/KeyStorage.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/KeyStorage.cpp index 6137c0e347..85aec05263 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/KeyStorage.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/KeyStorage.cpp @@ -22,34 +22,26 @@ #include "tonlib/keys/DecryptedKey.h" #include "tonlib/keys/EncryptedKey.h" +#include "tonlib/TonlibError.h" + #include "td/utils/filesystem.h" #include "td/utils/port/path.h" #include "td/utils/crypto.h" +#include "td/utils/PathView.h" namespace tonlib { +namespace { std::string to_file_name_old(const KeyStorage::Key &key) { return td::buffer_to_hex(key.public_key); } -std::string KeyStorage::to_file_path_old(const Key &key) { - return directory_ + TD_DIR_SLASH + to_file_name_old(key); -} - std::string to_file_name(const KeyStorage::Key &key) { return td::buffer_to_hex(td::sha512(key.secret.as_slice()).substr(0, 32)); } +} // namespace -std::string KeyStorage::to_file_path(const Key &key) { - return directory_ + TD_DIR_SLASH + to_file_name(key); -} -td::Status KeyStorage::set_directory(std::string directory) { - TRY_RESULT(path, td::realpath(directory)); - TRY_RESULT(stat, td::stat(path)); - if (!stat.is_dir_) { - return td::Status::Error("not a directory"); - } - directory_ = std::move(path); - return td::Status::OK(); +void KeyStorage::set_key_value(std::shared_ptr kv) { + kv_ = std::move(kv); } td::Result KeyStorage::save_key(const DecryptedKey &decrypted_key, td::Slice local_password) { @@ -58,17 +50,7 @@ td::Result KeyStorage::save_key(const DecryptedKey &decrypted_k Key res; res.public_key = encrypted_key.public_key.as_octet_string(); res.secret = std::move(encrypted_key.secret); - - auto size = encrypted_key.encrypted_data.size(); - - LOG(ERROR) << "SAVE " << to_file_name(res); - TRY_RESULT(to_file, td::FileFd::open(to_file_path(res), td::FileFd::CreateNew | td::FileFd::Write)); - TRY_RESULT(written, to_file.write(encrypted_key.encrypted_data)); - if (written != static_cast(size)) { - return td::Status::Error(PSLICE() << "Failed to write file: written " << written << " bytes instead of " << size); - } - to_file.close(); - + TRY_STATUS_PREFIX(kv_->set(to_file_name(res), encrypted_key.encrypted_data), TonlibError::Internal()); return std::move(res); } @@ -83,19 +65,22 @@ td::Result KeyStorage::create_new_key(td::Slice local_password, } td::Result KeyStorage::export_decrypted_key(InputKey input_key) { - auto r_encrypted_data = td::read_file_secure(to_file_path(input_key.key)); + auto r_encrypted_data = kv_->get(to_file_name(input_key.key)); if (r_encrypted_data.is_error()) { - r_encrypted_data = td::read_file_secure(to_file_path_old(input_key.key)); + r_encrypted_data = kv_->get(to_file_name_old(input_key.key)); if (r_encrypted_data.is_ok()) { - LOG(WARNING) << "Restore private from deprecated location " << to_file_path_old(input_key.key) << " --> " - << to_file_path(input_key.key); - td::rename(to_file_path_old(input_key.key), to_file_path(input_key.key)).ignore(); + LOG(WARNING) << "Restore private from deprecated location " << to_file_name_old(input_key.key) << " --> " + << to_file_name(input_key.key); + TRY_STATUS_PREFIX(kv_->set(to_file_name(input_key.key), r_encrypted_data.ok()), TonlibError::Internal()); + kv_->erase(to_file_name_old(input_key.key)).ignore(); } } - TRY_RESULT(encrypted_data, std::move(r_encrypted_data)); + TRY_RESULT_PREFIX(encrypted_data, std::move(r_encrypted_data), TonlibError::KeyUnknown()); EncryptedKey encrypted_key{std::move(encrypted_data), td::Ed25519::PublicKey(std::move(input_key.key.public_key)), std::move(input_key.key.secret)}; - return encrypted_key.decrypt(std::move(input_key.local_password)); + TRY_RESULT_PREFIX(decrypted_key, encrypted_key.decrypt(std::move(input_key.local_password)), + TonlibError::KeyDecrypt()); + return decrypted_key; } td::Result KeyStorage::export_key(InputKey input_key) { @@ -113,7 +98,26 @@ td::Result KeyStorage::load_private_key(InputKey input_k } td::Status KeyStorage::delete_key(const Key &key) { - return td::unlink(to_file_path(key)); + LOG(WARNING) << "Delete private key stored at " << to_file_name(key); + return kv_->erase(to_file_name(key)); +} + +td::Status KeyStorage::delete_all_keys() { + std::vector keys; + kv_->foreach_key([&](td::Slice key) { + if (td::PathView(key).extension().empty()) { + keys.push_back(key.str()); + } + }); + td::Status status; + for (auto key : keys) { + LOG(WARNING) << "Delete private key stored at " << key; + auto err = kv_->erase(key); + if (err.is_error() && status.is_ok()) { + status = std::move(err); + } + } + return status; } td::Result KeyStorage::import_key(td::Slice local_password, td::Slice mnemonic_password, @@ -121,16 +125,16 @@ td::Result KeyStorage::import_key(td::Slice local_password, td: TRY_RESULT(mnemonic, Mnemonic::create(std::move(exported_key.mnemonic_words), td::SecureString(mnemonic_password))); if (!mnemonic.is_basic_seed()) { if (mnemonic_password.empty() && mnemonic.is_password_seed()) { - return td::Status::Error("Mnemonic password is expected"); + return TonlibError::NeedMnemonicPassword(); } - return td::Status::Error("Invalid mnemonic words or password (invalid checksum)"); + return TonlibError::InvalidMnemonic(); } return save_key(DecryptedKey(std::move(mnemonic)), local_password); } td::Result KeyStorage::export_pem_key(InputKey input_key, td::Slice key_password) { TRY_RESULT(decrypted_key, export_decrypted_key(std::move(input_key))); - TRY_RESULT(pem, decrypted_key.private_key.as_pem(key_password)); + TRY_RESULT_PREFIX(pem, decrypted_key.private_key.as_pem(key_password), TonlibError::Internal()); return ExportedPemKey{std::move(pem)}; } @@ -140,13 +144,15 @@ td::Result KeyStorage::change_local_password(InputKey input_key Key res; res.public_key = std::move(input_key.key.public_key); res.secret = std::move(new_secret); - TRY_STATUS(td::copy_file(to_file_path(input_key.key), to_file_path(res))); + TRY_RESULT_PREFIX(value, kv_->get(to_file_name(input_key.key)), TonlibError::KeyUnknown()); + TRY_STATUS_PREFIX(kv_->add(to_file_name(res), value), TonlibError::Internal()); return std::move(res); } td::Result KeyStorage::import_pem_key(td::Slice local_password, td::Slice key_password, ExportedPemKey exported_key) { - TRY_RESULT(key, td::Ed25519::PrivateKey::from_pem(exported_key.pem, key_password)); + TRY_RESULT_PREFIX(key, td::Ed25519::PrivateKey::from_pem(exported_key.pem, key_password), + TonlibError::InvalidPemKey()); return save_key(DecryptedKey({}, std::move(key)), local_password); } @@ -162,7 +168,7 @@ td::Result KeyStorage::import_encrypted_key(td::Slice local_pas ExportedEncryptedKey exported_key) { EncryptedKey encrypted_key{std::move(exported_key.data), td::Ed25519::PublicKey(td::SecureString()), td::SecureString(dummy_secret)}; - TRY_RESULT(decrypted_key, encrypted_key.decrypt(key_password, false)); + TRY_RESULT_PREFIX(decrypted_key, encrypted_key.decrypt(key_password, false), TonlibError::KeyDecrypt()); return save_key(std::move(decrypted_key), local_password); } diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/KeyStorage.h b/submodules/ton/tonlib-src/tonlib/tonlib/KeyStorage.h index f7982805ef..1e37082885 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/KeyStorage.h +++ b/submodules/ton/tonlib-src/tonlib/tonlib/KeyStorage.h @@ -21,6 +21,8 @@ #include "td/utils/Status.h" #include "td/utils/SharedSlice.h" +#include "KeyValue.h" + #include namespace tonlib { @@ -48,7 +50,7 @@ class KeyStorage { td::SecureString private_key; }; - td::Status set_directory(std::string directory); + void set_key_value(std::shared_ptr kv); td::Result create_new_key(td::Slice local_password, td::Slice key_password, td::Slice entropy); @@ -58,6 +60,7 @@ class KeyStorage { td::Result change_local_password(InputKey input_key, td::Slice new_local_password); td::Status delete_key(const Key& key); + td::Status delete_all_keys(); td::Result import_key(td::Slice local_password, td::Slice mnemonic_password, ExportedKey exported_key); td::Result import_pem_key(td::Slice local_password, td::Slice key_password, ExportedPemKey exported_key); @@ -67,12 +70,9 @@ class KeyStorage { td::Result load_private_key(InputKey input_key); private: - std::string directory_; + std::shared_ptr kv_; td::Result save_key(const DecryptedKey& mnemonic, td::Slice local_password); td::Result export_decrypted_key(InputKey input_key); - - std::string to_file_path(const Key& key); - std::string to_file_path_old(const Key& key); }; } // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/KeyValue.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/KeyValue.cpp new file mode 100644 index 0000000000..d71744f04d --- /dev/null +++ b/submodules/ton/tonlib-src/tonlib/tonlib/KeyValue.cpp @@ -0,0 +1,124 @@ +#include "KeyValue.h" + +#include "td/utils/filesystem.h" +#include "td/utils/port/path.h" + +#include +#include + +namespace tonlib { +namespace detail { +class KeyValueDir : public KeyValue { + public: + static td::Result> create(td::CSlice directory) { + TRY_RESULT(path, td::realpath(directory)); + TRY_RESULT(stat, td::stat(path)); + if (!stat.is_dir_) { + return td::Status::Error("not a directory"); + } + return td::make_unique(path); + } + + KeyValueDir(std::string directory) : directory_(std::move(directory)) { + } + + td::Status add(td::Slice key, td::Slice value) override { + auto path = to_file_path(key.str()); + if (td::stat(path).is_ok()) { + return td::Status::Error(PSLICE() << "File " << path << "already exists"); + } + return td::atomic_write_file(path, value); + } + + td::Status set(td::Slice key, td::Slice value) override { + return td::atomic_write_file(to_file_path(key.str()), value); + } + + td::Result get(td::Slice key) override { + return td::read_file_secure(to_file_path(key.str())); + } + + td::Status erase(td::Slice key) override { + return td::unlink(key.str()); + } + + void foreach_key(std::function f) override { + int cnt = 0; + td::WalkPath::run(directory_, [&](td::Slice path, td::WalkPath::Type type) { + cnt++; + if (type == td::WalkPath::Type::EnterDir) { + if (cnt != 1) { + return td::WalkPath::Action::SkipDir; + } + } else if (type == td::WalkPath::Type::NotDir) { + f(path); + } + + return td::WalkPath::Action::Continue; + }).ignore(); + } + + private: + std::string directory_; + + std::string to_file_path(std::string key) { + return directory_ + TD_DIR_SLASH + key; + } +}; + +class KeyValueInmemory : public KeyValue { + public: + td::Status add(td::Slice key, td::Slice value) override { + auto res = map_.insert(std::make_pair(key.str(), td::SecureString(value))); + if (!res.second) { + return td::Status::Error(PSLICE() << "Add failed: value with key=`" << key << "` already exists"); + } + return td::Status::OK(); + } + + td::Status set(td::Slice key, td::Slice value) override { + map_[key.str()] = td::SecureString(value); + return td::Status::OK(); + } + td::Result get(td::Slice key) override { + auto it = map_.find(key); + if (it == map_.end()) { + return td::Status::Error("Unknown key"); + } + return it->second.copy(); + } + static td::Result> create() { + return td::make_unique(); + } + td::Status erase(td::Slice key) override { + auto it = map_.find(key); + if (it == map_.end()) { + return td::Status::Error("Unknown key"); + } + map_.erase(it); + return td::Status::OK(); + } + void foreach_key(std::function f) override { + for (auto &it : map_) { + f(it.first); + } + } + + private: + class Cmp : public std::less<> { + public: + using is_transparent = void; + }; + std::map map_; +}; +} // namespace detail + +td::Result> KeyValue::create_dir(td::CSlice dir) { + TRY_RESULT(res, detail::KeyValueDir::create(dir.str())); + return std::move(res); +} +td::Result> KeyValue::create_inmemory() { + TRY_RESULT(res, detail::KeyValueInmemory::create()); + return std::move(res); +} +} // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/KeyValue.h b/submodules/ton/tonlib-src/tonlib/tonlib/KeyValue.h new file mode 100644 index 0000000000..75b3df9c79 --- /dev/null +++ b/submodules/ton/tonlib-src/tonlib/tonlib/KeyValue.h @@ -0,0 +1,19 @@ +#pragma once +#include "td/utils/SharedSlice.h" +#include "td/utils/Slice.h" +#include "td/utils/Status.h" + +namespace tonlib { +class KeyValue { + public: + virtual ~KeyValue() = default; + virtual td::Status add(td::Slice key, td::Slice value) = 0; + virtual td::Status set(td::Slice key, td::Slice value) = 0; + virtual td::Status erase(td::Slice key) = 0; + virtual td::Result get(td::Slice key) = 0; + virtual void foreach_key(std::function f) = 0; + + static td::Result> create_dir(td::CSlice dir); + static td::Result> create_inmemory(); +}; +} // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/LastBlock.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/LastBlock.cpp index 7c4cda5dd3..05f078e086 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/LastBlock.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/LastBlock.cpp @@ -18,12 +18,18 @@ */ #include "tonlib/LastBlock.h" +#include "tonlib/utils.h" + #include "ton/lite-tl.hpp" #include "lite-client/lite-client-common.h" namespace tonlib { +// init_state <-> last_key_block +// state.valitated_init_state +// last_key_block -> +// td::StringBuilder& operator<<(td::StringBuilder& sb, const LastBlockState& state) { return sb << td::tag("last_block", state.last_block_id.to_str()) << td::tag("last_key_block", state.last_key_block_id.to_str()) << td::tag("utime", state.utime); @@ -32,9 +38,10 @@ td::StringBuilder& operator<<(td::StringBuilder& sb, const LastBlockState& state LastBlock::LastBlock(ExtClientRef client, LastBlockState state, Config config, td::unique_ptr callback) : state_(std::move(state)), config_(std::move(config)), callback_(std::move(callback)) { client_.set_client(client); - if (!config_.init_block_id.is_valid()) { - check_init_block_state_ = QueryState::Done; - } + state_.last_block_id = state_.last_key_block_id; + + VLOG(last_block) << "check_init_block: skip - FIXME before release"; + check_init_block_state_ = QueryState::Done; } void LastBlock::get_last_block(td::Promise promise) { @@ -42,9 +49,13 @@ void LastBlock::get_last_block(td::Promise promise) { promise.set_error(fatal_error_.clone()); return; } + if (promises_.empty() && get_last_block_state_ == QueryState::Done) { + VLOG(last_block) << "sync: start"; + VLOG(last_block) << "get_last_block: reset"; get_last_block_state_ = QueryState::Empty; } + promises_.push_back(std::move(promise)); sync_loop(); } @@ -54,36 +65,43 @@ void LastBlock::sync_loop() { return; } - update_zero_state(state_.zero_state_id); + update_zero_state(state_.zero_state_id, "cache"); update_zero_state(ton::ZeroStateIdExt(config_.zero_state_id.id.workchain, config_.zero_state_id.root_hash, - config_.zero_state_id.file_hash)); + config_.zero_state_id.file_hash), + "config"); if (get_mc_info_state_ == QueryState::Empty) { + VLOG(last_block) << "get_masterchain_info: start"; get_mc_info_state_ = QueryState::Active; client_.send_query(ton::lite_api::liteServer_getMasterchainInfo(), [this](auto r_info) { this->on_masterchain_info(std::move(r_info)); }); } - if (get_last_block_state_ == QueryState::Empty) { - get_last_block_state_ = QueryState::Active; - total_sync_ = td::Timer(); - validate_ = td::Timer(true); - queries_ = 0; - LOG(INFO) << "Begin last block synchronization " << state_; - do_get_last_block(); + if (check_init_block_state_ == QueryState::Empty) { + if (!config_.init_block_id.is_valid()) { + check_init_block_state_ = QueryState::Done; + VLOG(last_block) << "check_init_block: skip - no init_block in config"; + } else if (config_.init_block_id == state_.init_block_id) { + check_init_block_state_ = QueryState::Done; + VLOG(last_block) << "check_init_block: skip - was checked before"; + } else { + check_init_block_state_ = QueryState::Active; + check_init_block_stats_.start(); + if (state_.last_block_id.id.seqno >= config_.init_block_id.id.seqno) { + VLOG(last_block) << "check_init_block: start - init_block -> last_block"; + do_check_init_block(config_.init_block_id, state_.last_key_block_id); + } else { + VLOG(last_block) << "check_init_block: start - last_block -> init_block"; + do_check_init_block(state_.last_key_block_id, config_.init_block_id); + } + } } - if (check_init_block_state_ == QueryState::Empty) { - if (state_.last_block_id.id.seqno >= config_.init_block_id.id.seqno) { - check_init_block_state_ = QueryState::Active; - // validate - //total_sync_ = td::Timer(); - //validate_ = td::Timer(true); - //queries_ = 0; - LOG(INFO) << "Begin last block synchronization (check init_block)" << state_; - do_check_init_block(state_.last_key_block_id); - } else { - } + if (get_last_block_state_ == QueryState::Empty && check_init_block_state_ == QueryState::Done) { + VLOG(last_block) << "get_last_block: start"; + get_last_block_stats_.start(); + get_last_block_state_ = QueryState::Active; + do_get_last_block(); } if (get_mc_info_state_ == QueryState::Done && get_last_block_state_ == QueryState::Done && @@ -94,7 +112,8 @@ void LastBlock::sync_loop() { void LastBlock::do_get_last_block() { //liteServer.getBlockProof mode:# known_block:tonNode.blockIdExt target_block:mode.0?tonNode.blockIdExt = liteServer.PartialBlockProof; - queries_++; + VLOG(last_block) << "get_last_block: continue " << state_.last_key_block_id.to_str() << " -> ?"; + get_last_block_stats_.queries_++; client_.send_query( ton::lite_api::liteServer_getBlockProof(0, create_tl_lite_block_id(state_.last_key_block_id), nullptr), [this, from = state_.last_key_block_id](auto r_block_proof) { @@ -102,64 +121,69 @@ void LastBlock::do_get_last_block() { }); } -void LastBlock::do_check_init_block(ton::BlockIdExt from) { +void LastBlock::do_check_init_block(ton::BlockIdExt from, ton::BlockIdExt to) { + VLOG(last_block) << "check_init_block: continue " << from.to_str() << " -> " << to.to_str(); //liteServer.getBlockProof mode:# known_block:tonNode.blockIdExt target_block:mode.0?tonNode.blockIdExt = liteServer.PartialBlockProof; - //queries_++; - client_.send_query(ton::lite_api::liteServer_getBlockProof(1, create_tl_lite_block_id(from), - create_tl_lite_block_id(config_.init_block_id)), - [this, from = state_.last_key_block_id](auto r_block_proof) { - this->on_init_block_proof(from, std::move(r_block_proof)); - }); + check_init_block_stats_.queries_++; + client_.send_query( + ton::lite_api::liteServer_getBlockProof(1, create_tl_lite_block_id(from), create_tl_lite_block_id(to)), + [this, from, to](auto r_block_proof) { this->on_init_block_proof(from, to, std::move(r_block_proof)); }); } td::Result> LastBlock::process_block_proof( ton::BlockIdExt from, td::Result> r_block_proof) { - TRY_RESULT(block_proof, std::move(r_block_proof)); - LOG(DEBUG) << "Got proof FROM\n" << to_string(block_proof->from_) << "TO\n" << to_string(block_proof->to_); + TRY_RESULT(block_proof, std::move(r_block_proof)); //TODO: it is fatal? + TRY_RESULT_PREFIX(chain, TRY_VM(process_block_proof(from, std::move(block_proof))), + TonlibError::ValidateBlockProof()); + return chain; +} + +td::Result> LastBlock::process_block_proof( + ton::BlockIdExt from, ton::ton_api::object_ptr block_proof) { + VLOG(last_block) << "Got proof FROM\n" << to_string(block_proof->from_) << "TO\n" << to_string(block_proof->to_); TRY_RESULT(chain, liteclient::deserialize_proof_chain(std::move(block_proof))); if (chain->from != from) { return td::Status::Error(PSLICE() << "block proof chain starts from block " << chain->from.to_str() << ", not from requested block " << from.to_str()); } TRY_STATUS(chain->validate()); + return chain; +} + +void LastBlock::update_state(block::BlockProofChain& chain) { + // Update state_ bool is_changed = false; - is_changed |= update_mc_last_block(chain->to); - if (chain->has_key_block) { - is_changed |= update_mc_last_key_block(chain->key_blkid); + is_changed |= update_mc_last_block(chain.to); + if (chain.has_key_block) { + is_changed |= update_mc_last_key_block(chain.key_blkid); } - if (chain->has_utime) { - update_utime(chain->last_utime); + if (chain.has_utime) { + update_utime(chain.last_utime); } if (is_changed) { callback_->on_state_changed(state_); } - return std::move(chain); } void LastBlock::on_block_proof( ton::BlockIdExt from, td::Result> r_block_proof) { - validate_.resume(); + get_last_block_stats_.validate_.resume(); auto r_chain = process_block_proof(from, std::move(r_block_proof)); - validate_.pause(); - bool is_ready; + get_last_block_stats_.validate_.pause(); if (r_chain.is_error()) { - LOG(WARNING) << "Error during last block synchronization " << r_chain.error(); - if (config_.init_block_id.is_valid()) { - if (state_.last_key_block_id.id.seqno < config_.init_block_id.id.seqno) { - on_sync_error(td::Status::Error(PSLICE() << "Sync failed and we can't validate config.init_block: " - << r_chain.move_as_error())); - } - } - is_ready = true; - } else { - is_ready = r_chain.ok()->complete; + get_last_block_state_ = QueryState::Empty; + VLOG(last_block) << "get_last_block: error " << r_chain.error(); + on_sync_error(r_chain.move_as_error_suffix("(during last block synchronization)")); + return; } - if (is_ready) { - LOG(INFO) << "End last block synchronization " << state_ << "\n" - << " net queries: " << queries_ << "\n" - << " total: " << total_sync_ << " validation: " << validate_; + + auto chain = r_chain.move_as_ok(); + CHECK(chain); + update_state(*chain); + if (chain->complete) { + VLOG(last_block) << "get_last_block: done\n" << get_last_block_stats_; get_last_block_state_ = QueryState::Done; sync_loop(); } else { @@ -168,26 +192,26 @@ void LastBlock::on_block_proof( } void LastBlock::on_init_block_proof( - ton::BlockIdExt from, + ton::BlockIdExt from, ton::BlockIdExt to, td::Result> r_block_proof) { - validate_.resume(); + check_init_block_stats_.validate_.resume(); auto r_chain = process_block_proof(from, std::move(r_block_proof)); - validate_.pause(); + check_init_block_stats_.validate_.pause(); if (r_chain.is_error()) { check_init_block_state_ = QueryState::Empty; - on_sync_error( - td::Status::Error(PSLICE() << "Error during last block synchronization (check init_block)" << r_chain.error())); + VLOG(last_block) << "check_init_block: error " << r_chain.error(); + on_sync_error(r_chain.move_as_error_suffix("(during check init block)")); return; } auto chain = r_chain.move_as_ok(); + CHECK(chain); + update_state(*chain); if (chain->complete) { - LOG(INFO) << "End last block synchronization " << state_ << "\n" - << " net queries: " << queries_ << "\n" - << " total: " << total_sync_ << " validation: " << validate_; - get_last_block_state_ = QueryState::Done; + VLOG(last_block) << "check_init_block: done\n" << check_init_block_stats_; + check_init_block_state_ = QueryState::Done; sync_loop(); } else { - do_check_init_block(chain->to); + do_check_init_block(chain->to, to); } } @@ -195,28 +219,30 @@ void LastBlock::on_masterchain_info( td::Result> r_info) { if (r_info.is_ok()) { auto info = r_info.move_as_ok(); - update_zero_state(create_zero_state_id(info->init_)); - update_mc_last_block(create_block_id(info->last_)); + update_zero_state(create_zero_state_id(info->init_), "masterchain info"); + // last block is not validated! Do not update it get_mc_info_state_ = QueryState::Done; + VLOG(last_block) << "get_masterchain_info: done"; } else { get_mc_info_state_ = QueryState::Empty; + VLOG(last_block) << "get_masterchain_info: error " << r_info.error(); LOG(WARNING) << "Failed liteServer_getMasterchainInfo " << r_info.error(); on_sync_error(r_info.move_as_error()); } sync_loop(); } -void LastBlock::update_zero_state(ton::ZeroStateIdExt zero_state_id) { +void LastBlock::update_zero_state(ton::ZeroStateIdExt zero_state_id, td::Slice source) { if (has_fatal_error()) { return; } if (!zero_state_id.is_valid()) { - LOG(ERROR) << "Ignore invalid zero state update"; + LOG(ERROR) << "Ignore invalid zero state update from " << source; return; } if (!state_.zero_state_id.is_valid()) { - LOG(INFO) << "Init zerostate: " << zero_state_id.to_str(); + LOG(INFO) << "Init zerostate from " << source << ": " << zero_state_id.to_str(); state_.zero_state_id = std::move(zero_state_id); return; } @@ -225,8 +251,9 @@ void LastBlock::update_zero_state(ton::ZeroStateIdExt zero_state_id) { return; } - on_fatal_error(td::Status::Error(PSLICE() << "Masterchain zerostate mismatch: expected: " - << state_.zero_state_id.to_str() << ", found " << zero_state_id.to_str())); + on_fatal_error(TonlibError::ValidateZeroState(PSLICE() << "Masterchain zerostate mismatch: expected: " + << state_.zero_state_id.to_str() << ", found " + << zero_state_id.to_str() << " from " << source)); } bool LastBlock::update_mc_last_block(ton::BlockIdExt mc_block_id) { @@ -256,6 +283,9 @@ bool LastBlock::update_mc_last_key_block(ton::BlockIdExt mc_key_block_id) { if (!state_.last_key_block_id.is_valid() || state_.last_key_block_id.id.seqno < mc_key_block_id.id.seqno) { state_.last_key_block_id = mc_key_block_id; LOG(INFO) << "Update masterchain key block id: " << state_.last_key_block_id.to_str(); + //LOG(ERROR) << td::int64(state_.last_key_block_id.id.shard) << " " + //<< td::base64_encode(state_.last_key_block_id.file_hash.as_slice()) << " " + //<< td::base64_encode(state_.last_key_block_id.root_hash.as_slice()); return true; } return false; @@ -268,6 +298,7 @@ void LastBlock::update_utime(td::int64 utime) { } void LastBlock::on_sync_ok() { + VLOG(last_block) << "sync: ok " << state_; for (auto& promise : promises_) { auto state = state_; promise.set_value(std::move(state)); @@ -275,12 +306,14 @@ void LastBlock::on_sync_ok() { promises_.clear(); } void LastBlock::on_sync_error(td::Status status) { + VLOG(last_block) << "sync: error " << status; for (auto& promise : promises_) { promise.set_error(status.clone()); } promises_.clear(); } void LastBlock::on_fatal_error(td::Status status) { + VLOG(last_block) << "sync: fatal error " << status; fatal_error_ = std::move(status); on_sync_error(fatal_error_.clone()); } diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/LastBlock.h b/submodules/ton/tonlib-src/tonlib/tonlib/LastBlock.h index 2add3bcfb9..bb2a62ed4e 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/LastBlock.h +++ b/submodules/ton/tonlib-src/tonlib/tonlib/LastBlock.h @@ -22,6 +22,8 @@ #include "tonlib/Config.h" #include "tonlib/ExtClient.h" +#include "td/utils/tl_helpers.h" + namespace block { struct BlockProofChain; } @@ -89,25 +91,44 @@ struct LastBlockState { ton::BlockIdExt last_key_block_id; ton::BlockIdExt last_block_id; td::int64 utime{0}; + ton::BlockIdExt init_block_id; + + static constexpr td::int32 magic = 0xa7f171a4; + enum Version { None = 0, Magic, InitBlock, Next }; + static constexpr td::int32 version = Version::Next - 1; template void store(StorerT &storer) const { using td::store; using tonlib::store; + store(magic, storer); + store(version, storer); + store(zero_state_id, storer); store(last_key_block_id, storer); store(last_block_id, storer); store(utime, storer); + store(init_block_id, storer); } template void parse(ParserT &parser) { using td::parse; using tonlib::parse; + td::int32 version = 0; + if (parser.can_prefetch_int() && parser.prefetch_int_unsafe() == magic) { + td::int32 magic; + parse(magic, parser); + parse(version, parser); + } + parse(zero_state_id, parser); parse(last_key_block_id, parser); parse(last_block_id, parser); parse(utime, parser); + if (version >= InitBlock) { + parse(init_block_id, parser); + } } }; @@ -132,20 +153,36 @@ class LastBlock : public td::actor::Actor { td::Status fatal_error_; enum class QueryState { Empty, Active, Done }; - QueryState get_mc_info_state_{QueryState::Empty}; - QueryState get_last_block_state_{QueryState::Empty}; - QueryState check_init_block_state_{QueryState::Empty}; + QueryState get_mc_info_state_{QueryState::Empty}; // just to check zero state + QueryState check_init_block_state_{QueryState::Empty}; // init_block <---> last_key_block (from older to newer) + QueryState get_last_block_state_{QueryState::Empty}; // last_key_block_id --> ? // stats - td::Timer total_sync_; - td::Timer validate_; - td::uint32 queries_; + struct Stats { + td::Timer total_sync_; + td::Timer validate_; + td::uint32 queries_; + + void start() { + total_sync_ = td::Timer(); + validate_ = td::Timer(true); + queries_ = 0; + } + + friend td::StringBuilder &operator<<(td::StringBuilder &sb, const Stats &stats) { + return sb << " net queries: " << stats.queries_ << "\n" + << " total: " << stats.total_sync_ << " validation: " << stats.validate_; + } + }; + + Stats check_init_block_stats_; + Stats get_last_block_stats_; std::vector> promises_; - void do_check_init_block(ton::BlockIdExt from); + void do_check_init_block(ton::BlockIdExt from, ton::BlockIdExt to); void on_init_block_proof( - ton::BlockIdExt from, + ton::BlockIdExt from, ton::BlockIdExt to, td::Result> r_block_proof); void on_masterchain_info(td::Result> r_info); void do_get_last_block(); @@ -155,7 +192,11 @@ class LastBlock : public td::actor::Actor { ton::BlockIdExt from, td::Result> r_block_proof); - void update_zero_state(ton::ZeroStateIdExt zero_state_id); + td::Result> process_block_proof( + ton::BlockIdExt from, ton::ton_api::object_ptr block_proof); + + void update_state(block::BlockProofChain &chain); + void update_zero_state(ton::ZeroStateIdExt zero_state_id, td::Slice source); bool update_mc_last_block(ton::BlockIdExt mc_block_id); bool update_mc_last_key_block(ton::BlockIdExt mc_key_block_id); diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/LastBlockStorage.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/LastBlockStorage.cpp index 684b2c056c..dff4265d62 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/LastBlockStorage.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/LastBlockStorage.cpp @@ -18,6 +18,8 @@ */ #include "LastBlockStorage.h" +#include "tonlib/utils.h" + #include "td/utils/as.h" #include "td/utils/filesystem.h" #include "td/utils/port/path.h" @@ -25,22 +27,18 @@ namespace tonlib { -td::Status LastBlockStorage::set_directory(std::string directory) { - TRY_RESULT(path, td::realpath(directory)); - TRY_RESULT(stat, td::stat(path)); - if (!stat.is_dir_) { - return td::Status::Error("not a directory"); - } - directory_ = std::move(path); - return td::Status::OK(); +void LastBlockStorage::set_key_value(std::shared_ptr kv) { + kv_ = std::move(kv); } -std::string LastBlockStorage::get_file_name(td::Slice name) { - return directory_ + TD_DIR_SLASH + td::buffer_to_hex(name) + ".blkstate"; +namespace { +std::string get_file_name(td::Slice name) { + return td::buffer_to_hex(name) + ".blkstate"; } +} // namespace td::Result LastBlockStorage::get_state(td::Slice name) { - TRY_RESULT(data, td::read_file(get_file_name(name))); + TRY_RESULT(data, kv_->get(get_file_name(name))); if (data.size() < 8) { return td::Status::Error("too short"); } @@ -53,10 +51,11 @@ td::Result LastBlockStorage::get_state(td::Slice name) { } void LastBlockStorage::save_state(td::Slice name, LastBlockState state) { + VLOG(last_block) << "Save to cache: " << state; auto x = td::serialize(state); std::string y(x.size() + 8, 0); td::MutableSlice(y).substr(8).copy_from(x); td::as(td::MutableSlice(y).data()) = td::crc64(x); - td::atomic_write_file(get_file_name(name), y); + kv_->set(get_file_name(name), y); } } // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/LastBlockStorage.h b/submodules/ton/tonlib-src/tonlib/tonlib/LastBlockStorage.h index d8cbd3fcd1..df5dd12c9e 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/LastBlockStorage.h +++ b/submodules/ton/tonlib-src/tonlib/tonlib/LastBlockStorage.h @@ -20,15 +20,16 @@ #include "tonlib/LastBlock.h" +#include "tonlib/KeyValue.h" + namespace tonlib { class LastBlockStorage { public: - td::Status set_directory(std::string directory); + void set_key_value(std::shared_ptr kv); td::Result get_state(td::Slice name); void save_state(td::Slice name, LastBlockState state); private: - std::string directory_; - std::string get_file_name(td::Slice name); + std::shared_ptr kv_; }; } // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/Logging.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/Logging.cpp index 043fe0190d..31dc275c00 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/Logging.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/Logging.cpp @@ -17,6 +17,7 @@ Copyright 2017-2019 Telegram Systems LLP */ #include "Logging.h" +#include "utils.h" #include "auto/tl/tonlib_api.h" @@ -36,11 +37,9 @@ static td::FileLog file_log; static td::TsLog ts_log(&file_log); static td::NullLog null_log; -td::int32 VERBOSITY_NAME(abc) = VERBOSITY_NAME(DEBUG); -td::int32 VERBOSITY_NAME(bcd) = VERBOSITY_NAME(DEBUG); #define ADD_TAG(tag) \ { #tag, &VERBOSITY_NAME(tag) } -static const std::map log_tags{ADD_TAG(abc), ADD_TAG(bcd)}; +static const std::map log_tags{ADD_TAG(tonlib_query), ADD_TAG(last_block)}; #undef ADD_TAG td::Status Logging::set_current_stream(tonlib_api::object_ptr stream) { diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/TestGiver.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/TestGiver.cpp index 50c68571ce..b906193d9e 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/TestGiver.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/TestGiver.cpp @@ -22,19 +22,18 @@ #include "td/utils/base64.h" namespace tonlib { -const block::StdAddress& TestGiver::address() { +const block::StdAddress& TestGiver::address() noexcept { static block::StdAddress res = block::StdAddress::parse("kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny").move_as_ok(); return res; } -vm::CellHash TestGiver::get_init_code_hash() { +vm::CellHash TestGiver::get_init_code_hash() noexcept { return vm::CellHash::from_slice(td::base64_decode("wDkZp0yR4xo+9+BnuAPfGVjBzK6FPzqdv2DwRq3z3KE=").move_as_ok()); } td::Ref TestGiver::make_a_gift_message(td::uint32 seqno, td::uint64 gramms, td::Slice message, - const block::StdAddress& dest_address) { - CHECK(message.size() <= 124); + const block::StdAddress& dest_address) noexcept { td::BigInt256 dest_addr; dest_addr.import_bits(dest_address.addr.as_bitslice()); vm::CellBuilder cb; @@ -45,7 +44,9 @@ td::Ref TestGiver::make_a_gift_message(td::uint32 seqno, td::uint64 gr .store_int256(dest_addr, 256); block::tlb::t_Grams.store_integer_value(cb, td::BigInt256(gramms)); - auto message_inner = cb.store_zeroes(9 + 64 + 32 + 1 + 1).store_bytes("\0\0\0\0", 4).store_bytes(message).finalize(); + cb.store_zeroes(9 + 64 + 32 + 1 + 1).store_bytes("\0\0\0\0", 4); + vm::CellString::store(cb, message, 35 * 8).ensure(); + auto message_inner = cb.finalize(); return vm::CellBuilder().store_long(seqno, 32).store_long(1, 8).store_ref(message_inner).finalize(); } } // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/TestGiver.h b/submodules/ton/tonlib-src/tonlib/tonlib/TestGiver.h index 6859be8ff0..f8b62599fe 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/TestGiver.h +++ b/submodules/ton/tonlib-src/tonlib/tonlib/TestGiver.h @@ -18,12 +18,14 @@ */ #pragma once #include "block/block.h" +#include "CellString.h" namespace tonlib { class TestGiver { public: - static const block::StdAddress& address(); - static vm::CellHash get_init_code_hash(); + static constexpr unsigned max_message_size = vm::CellString::max_bytes; + static const block::StdAddress& address() noexcept; + static vm::CellHash get_init_code_hash() noexcept; static td::Ref make_a_gift_message(td::uint32 seqno, td::uint64 gramms, td::Slice message, - const block::StdAddress& dest_address); + const block::StdAddress& dest_address) noexcept; }; } // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/TestWallet.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/TestWallet.cpp index 022eaca9db..7c3b6f952f 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/TestWallet.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/TestWallet.cpp @@ -24,13 +24,13 @@ #include "td/utils/base64.h" namespace tonlib { -td::Ref TestWallet::get_init_state(const td::Ed25519::PublicKey& public_key) { +td::Ref TestWallet::get_init_state(const td::Ed25519::PublicKey& public_key) noexcept { auto code = get_init_code(); auto data = get_init_data(public_key); return GenericAccount::get_init_state(std::move(code), std::move(data)); } -td::Ref TestWallet::get_init_message(const td::Ed25519::PrivateKey& private_key) { +td::Ref TestWallet::get_init_message(const td::Ed25519::PrivateKey& private_key) noexcept { std::string seq_no(4, 0); auto signature = private_key.sign(vm::CellBuilder().store_bytes(seq_no).finalize()->get_hash().as_slice()).move_as_ok(); @@ -39,8 +39,7 @@ td::Ref TestWallet::get_init_message(const td::Ed25519::PrivateKey& pr td::Ref TestWallet::make_a_gift_message(const td::Ed25519::PrivateKey& private_key, td::uint32 seqno, td::int64 gramms, td::Slice message, - const block::StdAddress& dest_address) { - CHECK(message.size() <= 124); + const block::StdAddress& dest_address) noexcept { td::BigInt256 dest_addr; dest_addr.import_bits(dest_address.addr.as_bitslice()); vm::CellBuilder cb; @@ -49,16 +48,22 @@ td::Ref TestWallet::make_a_gift_message(const td::Ed25519::PrivateKey& .append_cellslice(binary_bitstring_to_cellslice("b{000100}").move_as_ok()) .store_long(dest_address.workchain, 8) .store_int256(dest_addr, 256); - block::tlb::t_Grams.store_integer_value(cb, td::BigInt256(gramms)); - auto message_inner = cb.store_zeroes(9 + 64 + 32 + 1 + 1).store_bytes("\0\0\0\0", 4).store_bytes(message).finalize(); td::int8 send_mode = 3; + if (gramms == -1) { + gramms = 0; + send_mode += 128; + } + block::tlb::t_Grams.store_integer_value(cb, td::BigInt256(gramms)); + cb.store_zeroes(9 + 64 + 32 + 1 + 1).store_bytes("\0\0\0\0", 4); + vm::CellString::store(cb, message, 35 * 8).ensure(); + auto message_inner = cb.finalize(); auto message_outer = vm::CellBuilder().store_long(seqno, 32).store_long(send_mode, 8).store_ref(message_inner).finalize(); auto signature = private_key.sign(message_outer->get_hash().as_slice()).move_as_ok(); return vm::CellBuilder().store_bytes(signature).append_cellslice(vm::load_cell_slice(message_outer)).finalize(); } -td::Ref TestWallet::get_init_code() { +td::Ref TestWallet::get_init_code() noexcept { static auto res = [] { auto serialized_code = td::base64_decode( "te6ccgEEAQEAAAAAUwAAov8AIN0gggFMl7qXMO1E0NcLH+Ck8mCBAgDXGCDXCx/tRNDTH9P/" @@ -69,11 +74,11 @@ td::Ref TestWallet::get_init_code() { return res; } -vm::CellHash TestWallet::get_init_code_hash() { +vm::CellHash TestWallet::get_init_code_hash() noexcept { return get_init_code()->get_hash(); } -td::Ref TestWallet::get_init_data(const td::Ed25519::PublicKey& public_key) { +td::Ref TestWallet::get_init_data(const td::Ed25519::PublicKey& public_key) noexcept { return vm::CellBuilder().store_long(0, 32).store_bytes(public_key.as_octet_string()).finalize(); } } // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/TestWallet.h b/submodules/ton/tonlib-src/tonlib/tonlib/TestWallet.h index 921e3b3afe..ef726b552d 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/TestWallet.h +++ b/submodules/ton/tonlib-src/tonlib/tonlib/TestWallet.h @@ -21,18 +21,20 @@ #include "vm/cells.h" #include "Ed25519.h" #include "block/block.h" +#include "CellString.h" namespace tonlib { class TestWallet { public: - static td::Ref get_init_state(const td::Ed25519::PublicKey& public_key); - static td::Ref get_init_message(const td::Ed25519::PrivateKey& private_key); + static constexpr unsigned max_message_size = vm::CellString::max_bytes; + static td::Ref get_init_state(const td::Ed25519::PublicKey& public_key) noexcept; + static td::Ref get_init_message(const td::Ed25519::PrivateKey& private_key) noexcept; static td::Ref make_a_gift_message(const td::Ed25519::PrivateKey& private_key, td::uint32 seqno, td::int64 gramms, td::Slice message, - const block::StdAddress& dest_address); + const block::StdAddress& dest_address) noexcept; - static td::Ref get_init_code(); - static vm::CellHash get_init_code_hash(); - static td::Ref get_init_data(const td::Ed25519::PublicKey& public_key); + static td::Ref get_init_code() noexcept; + static vm::CellHash get_init_code_hash() noexcept; + static td::Ref get_init_data(const td::Ed25519::PublicKey& public_key) noexcept; }; } // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.cpp index d0a9cba7d9..fb046d26df 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.cpp @@ -29,6 +29,8 @@ #include "tonlib/utils.h" #include "tonlib/keys/Mnemonic.h" +#include "tonlib/TonlibError.h" + #include "auto/tl/tonlib_api.hpp" #include "block/block-auto.h" #include "block/check-proof.h" @@ -45,17 +47,6 @@ namespace tonlib { -template -auto try_f(F&& f) noexcept -> decltype(f()) { - try { - return f(); - } catch (vm::VmError error) { - return td::Status::Error(PSLICE() << "Got a vm exception: " << error.get_msg()); - } -} - -#define TRY_VM(f) try_f([&] { return f; }) - tonlib_api::object_ptr status_to_tonlib_api(const td::Status& status) { return tonlib_api::make_object(status.code(), status.message().str()); } @@ -73,6 +64,7 @@ struct RawAccountState { td::int64 balance = -1; td::Ref code; td::Ref data; + std::string frozen_hash; block::AccountState::Info info; }; @@ -96,8 +88,12 @@ td::Result to_balance(td::Ref balance_ref) { class GetTransactionHistory : public td::actor::Actor { public: GetTransactionHistory(ExtClientRef ext_client_ref, block::StdAddress address, ton::LogicalTime lt, ton::Bits256 hash, - td::Promise promise) - : address_(std::move(address)), lt_(std::move(lt)), hash_(std::move(hash)), promise_(std::move(promise)) { + td::actor::ActorShared<> parent, td::Promise promise) + : address_(std::move(address)) + , lt_(std::move(lt)) + , hash_(std::move(hash)) + , parent_(std::move(parent)) + , promise_(std::move(promise)) { client_.set_client(ext_client_ref); } @@ -107,6 +103,7 @@ class GetTransactionHistory : public td::actor::Actor { ton::Bits256 hash_; ExtClient client_; td::int32 count_{10}; + td::actor::ActorShared<> parent_; td::Promise promise_; void check(td::Status status) { @@ -117,7 +114,31 @@ class GetTransactionHistory : public td::actor::Actor { } } - td::Status do_with_transactions(std::vector blkids, td::BufferSlice transactions) { + void with_transactions( + td::Result> r_transactions) { + check(do_with_transactions(std::move(r_transactions))); + stop(); + } + + td::Status do_with_transactions( + td::Result> r_transactions) { + TRY_RESULT(transactions, std::move(r_transactions)); + TRY_RESULT_PREFIX(info, TRY_VM(do_with_transactions(std::move(transactions))), TonlibError::ValidateTransactions()); + promise_.set_value(std::move(info)); + return td::Status::OK(); + } + + td::Result do_with_transactions( + ton::lite_api::object_ptr transactions) { + std::vector blkids; + for (auto& id : transactions->ids_) { + blkids.push_back(ton::create_block_id(std::move(id))); + } + return do_with_transactions(std::move(blkids), std::move(transactions->transactions_)); + } + + td::Result do_with_transactions(std::vector blkids, + td::BufferSlice transactions) { LOG(INFO) << "got up to " << count_ << " transactions for " << address_ << " from last transaction " << lt_ << ":" << hash_.to_hex(); block::TransactionList list; @@ -130,24 +151,7 @@ class GetTransactionHistory : public td::actor::Actor { LOG(WARNING) << "obtained " << info.transactions.size() << " transaction, but only " << count_ << " have been requested"; } - promise_.set_value(std::move(info)); - return td::Status::OK(); - } - - td::Status do_with_transactions( - td::Result> r_transactions) { - TRY_RESULT(transactions, std::move(r_transactions)); - std::vector blkids; - for (auto& id : transactions->ids_) { - blkids.push_back(ton::create_block_id(std::move(id))); - } - return do_with_transactions(std::move(blkids), std::move(transactions->transactions_)); - } - - void with_transactions( - td::Result> r_transactions) { - check(TRY_VM(do_with_transactions(std::move(r_transactions)))); - stop(); + return info; } void start_up() override { @@ -166,25 +170,35 @@ class GetTransactionHistory : public td::actor::Actor { class GetRawAccountState : public td::actor::Actor { public: - GetRawAccountState(ExtClientRef ext_client_ref, block::StdAddress address, td::Promise&& promise) - : address_(std::move(address)), promise_(std::move(promise)) { + GetRawAccountState(ExtClientRef ext_client_ref, block::StdAddress address, td::actor::ActorShared<> parent, + td::Promise&& promise) + : address_(std::move(address)), promise_(std::move(promise)), parent_(std::move(parent)) { client_.set_client(ext_client_ref); } private: block::StdAddress address_; td::Promise promise_; + td::actor::ActorShared<> parent_; ExtClient client_; LastBlockState last_block_; void with_account_state(td::Result> r_account_state) { - promise_.set_result(TRY_VM(do_with_account_state(std::move(r_account_state)))); + check(do_with_account_state(std::move(r_account_state))); + } + + td::Status do_with_account_state( + td::Result> r_raw_account_state) { + TRY_RESULT(raw_account_state, std::move(r_raw_account_state)); + TRY_RESULT_PREFIX(state, TRY_VM(do_with_account_state(std::move(raw_account_state))), + TonlibError::ValidateAccountState()); + promise_.set_value(std::move(state)); stop(); + return td::Status::OK(); } td::Result do_with_account_state( - td::Result> r_account_state) { - TRY_RESULT(raw_account_state, std::move(r_account_state)); + ton::tl_object_ptr raw_account_state) { auto account_state = create_account_state(std::move(raw_account_state)); TRY_RESULT(info, account_state.validate(last_block_.last_block_id, address_)); auto serialized_state = account_state.state.clone(); @@ -192,10 +206,12 @@ class GetRawAccountState : public td::actor::Actor { res.info = std::move(info); LOG_IF(ERROR, res.info.gen_utime > last_block_.utime) << res.info.gen_utime << " " << last_block_.utime; auto cell = res.info.root; + std::ostringstream outp; + block::gen::t_Account.print_ref(outp, cell); + LOG(ERROR) << outp.str(); if (cell.is_null()) { return res; } - //block::gen::t_Account.print_ref(std::cerr, cell); block::gen::Account::Record_account account; if (!tlb::unpack_cell(cell, account)) { return td::Status::Error("Failed to unpack Account"); @@ -210,7 +226,14 @@ class GetRawAccountState : public td::actor::Actor { if (state_tag < 0) { return td::Status::Error("Failed to parse AccountState tag"); } - // TODO: handle frozen account + if (state_tag == block::gen::AccountState::account_frozen) { + block::gen::AccountState::Record_account_frozen state; + if (!tlb::csr_unpack(storage.state, state)) { + return td::Status::Error("Failed to parse AccountState"); + } + res.frozen_hash = state.state_hash.as_slice().str(); + return res; + } if (state_tag != block::gen::AccountState::account_active) { return res; } @@ -228,19 +251,23 @@ class GetRawAccountState : public td::actor::Actor { return res; } - void start_up() override { - client_.with_last_block([self = this](td::Result r_last_block) { - if (r_last_block.is_error()) { - return self->check(r_last_block.move_as_error()); - } - self->last_block_ = r_last_block.move_as_ok(); + void with_last_block(td::Result r_last_block) { + check(do_with_last_block(std::move(r_last_block))); + } - self->client_.send_query( - ton::lite_api::liteServer_getAccountState(ton::create_tl_lite_block_id(self->last_block_.last_block_id), - ton::create_tl_object( - self->address_.workchain, self->address_.addr)), - [self](auto r_state) { self->with_account_state(std::move(r_state)); }); - }); + td::Status do_with_last_block(td::Result r_last_block) { + TRY_RESULT_ASSIGN(last_block_, std::move(r_last_block)); + client_.send_query( + ton::lite_api::liteServer_getAccountState( + ton::create_tl_lite_block_id(last_block_.last_block_id), + ton::create_tl_object(address_.workchain, address_.addr)), + [self = this](auto r_state) { self->with_account_state(std::move(r_state)); }); + return td::Status::OK(); + } + + void start_up() override { + client_.with_last_block( + [self = this](td::Result r_last_block) { self->with_last_block(std::move(r_last_block)); }); } void check(td::Status status) { @@ -354,18 +381,19 @@ void TonlibClient::init_last_block() { raw_last_block_ = td::actor::create_actor("LastBlock", get_client_ref(), std::move(state), config_, td::make_unique(td::actor::actor_shared(this), config_generation_)); - client_.set_client(get_client_ref()); } void TonlibClient::on_result(td::uint64 id, tonlib_api::object_ptr response) { + VLOG(tonlib_query) << "Tonlib answer query " << td::tag("id", id) << " " << to_string(response); if (response->get_id() == tonlib_api::error::ID) { callback_->on_error(id, tonlib_api::move_object_as(response)); return; } callback_->on_result(id, std::move(response)); } + void TonlibClient::request(td::uint64 id, tonlib_api::object_ptr function) { - LOG(ERROR) << to_string(function); + VLOG(tonlib_query) << "Tonlib got query " << td::tag("id", id) << " " << to_string(function); if (function == nullptr) { LOG(ERROR) << "Receive empty static request"; return on_result(id, tonlib_api::make_object(400, "Request is empty")); @@ -408,6 +436,7 @@ void TonlibClient::close() { } tonlib_api::object_ptr TonlibClient::static_request( tonlib_api::object_ptr function) { + VLOG(tonlib_query) << "Tonlib got static query " << to_string(function); if (function == nullptr) { LOG(ERROR) << "Receive empty static request"; return tonlib_api::make_object(400, "Request is empty"); @@ -415,6 +444,7 @@ tonlib_api::object_ptr TonlibClient::static_request( tonlib_api::object_ptr response; downcast_call(*function, [&response](auto& request) { response = TonlibClient::do_static_request(request); }); + VLOG(tonlib_query) << " answer static query " << to_string(function); return response; } @@ -459,24 +489,35 @@ tonlib_api::object_ptr TonlibClient::do_static_request(const runner.run_all(); return tonlib_api::make_object(); } + +td::Result get_public_key(td::Slice public_key) { + TRY_RESULT_PREFIX(address, block::PublicKey::parse(public_key), TonlibError::InvalidPublicKey()); + return address; +} + td::Result get_account_address(const tonlib_api::raw_initialAccountState& raw_state) { - TRY_RESULT(code, vm::std_boc_deserialize(raw_state.code_)); - TRY_RESULT(data, vm::std_boc_deserialize(raw_state.data_)); + TRY_RESULT_PREFIX(code, vm::std_boc_deserialize(raw_state.code_), TonlibError::InvalidBagOfCells("raw_state.code")); + TRY_RESULT_PREFIX(data, vm::std_boc_deserialize(raw_state.data_), TonlibError::InvalidBagOfCells("raw_state.data")); return GenericAccount::get_address(0 /*zerochain*/, GenericAccount::get_init_state(std::move(code), std::move(data))); } td::Result get_account_address(const tonlib_api::testWallet_initialAccountState& test_wallet_state) { - TRY_RESULT(key_bytes, block::PublicKey::parse(test_wallet_state.public_key_)); + TRY_RESULT(key_bytes, get_public_key(test_wallet_state.public_key_)); auto key = td::Ed25519::PublicKey(td::SecureString(key_bytes.key)); return GenericAccount::get_address(0 /*zerochain*/, TestWallet::get_init_state(key)); } td::Result get_account_address(const tonlib_api::wallet_initialAccountState& test_wallet_state) { - TRY_RESULT(key_bytes, block::PublicKey::parse(test_wallet_state.public_key_)); + TRY_RESULT(key_bytes, get_public_key(test_wallet_state.public_key_)); auto key = td::Ed25519::PublicKey(td::SecureString(key_bytes.key)); return GenericAccount::get_address(0 /*zerochain*/, Wallet::get_init_state(key)); } +td::Result get_account_address(td::Slice account_address) { + TRY_RESULT_PREFIX(address, block::StdAddress::parse(account_address), TonlibError::InvalidAccountAddress()); + return address; +} + tonlib_api::object_ptr TonlibClient::do_static_request( const tonlib_api::raw_getAccountAddress& request) { auto r_account_address = get_account_address(*request.initital_account_state_); @@ -485,6 +526,7 @@ tonlib_api::object_ptr TonlibClient::do_static_request( } return tonlib_api::make_object(r_account_address.ok().rserialize(true)); } + tonlib_api::object_ptr TonlibClient::do_static_request( const tonlib_api::testWallet_getAccountAddress& request) { auto r_account_address = get_account_address(*request.initital_account_state_); @@ -493,6 +535,7 @@ tonlib_api::object_ptr TonlibClient::do_static_request( } return tonlib_api::make_object(r_account_address.ok().rserialize(true)); } + tonlib_api::object_ptr TonlibClient::do_static_request( const tonlib_api::wallet_getAccountAddress& request) { auto r_account_address = get_account_address(*request.initital_account_state_); @@ -501,6 +544,7 @@ tonlib_api::object_ptr TonlibClient::do_static_request( } return tonlib_api::make_object(r_account_address.ok().rserialize(true)); } + tonlib_api::object_ptr TonlibClient::do_static_request( const tonlib_api::testGiver_getAccountAddress& request) { return tonlib_api::make_object(TestGiver::address().rserialize(true)); @@ -508,7 +552,7 @@ tonlib_api::object_ptr TonlibClient::do_static_request( tonlib_api::object_ptr TonlibClient::do_static_request( const tonlib_api::unpackAccountAddress& request) { - auto r_account_address = block::StdAddress::parse(request.account_address_); + auto r_account_address = get_account_address(request.account_address_); if (r_account_address.is_error()) { return status_to_tonlib_api(r_account_address.move_as_error()); } @@ -521,10 +565,10 @@ tonlib_api::object_ptr TonlibClient::do_static_request( tonlib_api::object_ptr TonlibClient::do_static_request( const tonlib_api::packAccountAddress& request) { if (!request.account_address_) { - return status_to_tonlib_api(td::Status::Error(400, "Field account_address must not be empty")); + return status_to_tonlib_api(TonlibError::EmptyField("account_address")); } if (request.account_address_->addr_.size() != 32) { - return status_to_tonlib_api(td::Status::Error(400, "Field account_address.addr must not be exactly 32 bytes")); + return status_to_tonlib_api(TonlibError::InvalidField("account_address.addr", "must be 32 bytes long")); } block::StdAddress addr; addr.workchain = request.account_address_->workchain_id_; @@ -545,10 +589,23 @@ td::Status TonlibClient::do_request(const tonlib_api::init& request, return td::Status::Error(400, "Tonlib is already inited"); } if (!request.options_) { - return td::Status::Error(400, "Field options must not be empty"); + return TonlibError::EmptyField("options"); } - TRY_STATUS(key_storage_.set_directory(request.options_->keystore_directory_)); - TRY_STATUS(last_block_storage_.set_directory(request.options_->keystore_directory_)); + if (!request.options_->keystore_type_) { + return TonlibError::EmptyField("options.keystore_type"); + } + + td::Result> r_kv; + downcast_call( + *request.options_->keystore_type_, + td::overloaded( + [&](tonlib_api::keyStoreTypeDirectory& directory) { r_kv = KeyValue::create_dir(directory.directory_); }, + [&](tonlib_api::keyStoreTypeInMemory& inmemory) { r_kv = KeyValue::create_inmemory(); })); + TRY_RESULT(kv, std::move(r_kv)); + kv_ = std::shared_ptr(kv.release()); + + key_storage_.set_key_value(kv_); + last_block_storage_.set_key_value(kv_); if (request.options_->config_) { TRY_STATUS(set_config(std::move(request.options_->config_))); } @@ -558,15 +615,14 @@ td::Status TonlibClient::do_request(const tonlib_api::init& request, } td::Status TonlibClient::set_config(object_ptr config) { - if (!config) { - return td::Status::Error(400, "config is empty"); - } + CHECK(config); if (config->config_.empty()) { - return td::Status::Error(400, "config is empty"); + return TonlibError::InvalidConfig("config is empty"); } - TRY_RESULT(new_config, Config::parse(std::move(config->config_))); + TRY_RESULT_PREFIX(new_config, Config::parse(std::move(config->config_)), + TonlibError::InvalidConfig("can't parse config")); if (new_config.lite_clients.empty() && !config->use_callbacks_for_network_) { - return td::Status::Error("No lite clients in config"); + return TonlibError::InvalidConfig("no lite clients"); } config_ = std::move(new_config); config_generation_++; @@ -579,6 +635,7 @@ td::Status TonlibClient::set_config(object_ptr config) { ignore_cache_ = config->ignore_cache_; init_ext_client(); init_last_block(); + client_.set_client(get_client_ref()); return td::Status::OK(); } @@ -592,6 +649,9 @@ td::Status TonlibClient::do_request(const tonlib_api::close& request, td::Status TonlibClient::do_request(tonlib_api::options_setConfig& request, td::Promise>&& promise) { + if (!request.config_) { + return TonlibError::EmptyField("config"); + } TRY_STATUS(set_config(std::move(request.config_))); promise.set_value(tonlib_api::make_object()); return td::Status::OK(); @@ -664,6 +724,9 @@ td::Result> to_raw_message_or_th TRY_RESULT(balance, to_balance(msg_info.value)); TRY_RESULT(src, to_std_address(msg_info.src)); TRY_RESULT(dest, to_std_address(msg_info.dest)); + TRY_RESULT(fwd_fee, to_balance(msg_info.fwd_fee)); + TRY_RESULT(ihr_fee, to_balance(msg_info.ihr_fee)); + auto created_lt = static_cast(msg_info.created_lt); td::Ref body; if (message.body->prefetch_long(1) == 0) { body = std::move(message.body); @@ -671,17 +734,18 @@ td::Result> to_raw_message_or_th } else { body = vm::load_cell_slice_ref(message.body->prefetch_ref()); } + auto body_hash = vm::CellBuilder().append_cellslice(*body).finalize()->get_hash().as_slice().str(); std::string body_message; - if (body->size() % 8 == 0) { - body_message = std::string(body->size() / 8, 0); - body->prefetch_bytes(td::MutableSlice(body_message).ubegin(), body->size() / 8); - if (body_message.size() >= 4 && body_message[0] == 0 && body_message[1] == 0 && body_message[2] == 0 && - body_message[3] == 0) { - body_message = body_message.substr(4); + if (body->size() >= 32 && body->prefetch_long(32) == 0) { + body.write().fetch_long(32); + auto r_body_message = vm::CellString::load(body.write()); + if (r_body_message.is_ok()) { + body_message = r_body_message.move_as_ok(); } } - return tonlib_api::make_object(std::move(src), std::move(dest), balance, + return tonlib_api::make_object(std::move(src), std::move(dest), balance, fwd_fee, + ihr_fee, created_lt, std::move(body_hash), std::move(body_message)); } case block::gen::CommonMsgInfo::ext_in_msg_info: { @@ -690,7 +754,16 @@ td::Result> to_raw_message_or_th return td::Status::Error("Failed to unpack CommonMsgInfo::ext_in_msg_info"); } TRY_RESULT(dest, to_std_address(msg_info.dest)); - return tonlib_api::make_object("", std::move(dest), 0, ""); + td::Ref body; + if (message.body->prefetch_long(1) == 0) { + body = std::move(message.body); + body.write().advance(1); + } else { + body = vm::load_cell_slice_ref(message.body->prefetch_ref()); + } + auto body_hash = vm::CellBuilder().append_cellslice(*body).finalize()->get_hash().as_slice().str(); + return tonlib_api::make_object("", std::move(dest), 0, 0, 0, 0, std::move(body_hash), + ""); } case block::gen::CommonMsgInfo::ext_out_msg_info: { block::gen::CommonMsgInfo::Record_ext_out_msg_info msg_info; @@ -698,7 +771,7 @@ td::Result> to_raw_message_or_th return td::Status::Error("Failed to unpack CommonMsgInfo::ext_out_msg_info"); } TRY_RESULT(src, to_std_address(msg_info.src)); - return tonlib_api::make_object(std::move(src), "", 0, ""); + return tonlib_api::make_object(std::move(src), "", 0, 0, 0, 0, "", ""); } } @@ -716,6 +789,7 @@ td::Result> to_raw_transacti tonlib_api::object_ptr in_msg; std::vector> out_msgs; td::int64 fees = 0; + td::int64 storage_fee = 0; if (info.transaction.not_null()) { TRY_RESULT(copy_data, vm::std_boc_serialize(info.transaction)); data = copy_data.as_slice().str(); @@ -724,8 +798,7 @@ td::Result> to_raw_transacti return td::Status::Error("Failed to unpack Transaction"); } - TRY_RESULT(copy_fees, to_balance(trans.total_fees)); - fees = copy_fees; + TRY_RESULT_ASSIGN(fees, to_balance(trans.total_fees)); std::ostringstream outp; block::gen::t_Transaction.print_ref(outp, info.transaction); @@ -745,15 +818,22 @@ td::Result> to_raw_transacti vm::Dictionary dict{trans.r1.out_msgs, 15}; for (int x = 0; x < trans.outmsg_cnt && x < 100; x++) { TRY_RESULT(out_msg, to_raw_message(dict.lookup_ref(td::BitArray<15>{x}))); + fees += out_msg->fwd_fee_; + fees += out_msg->ihr_fee_; out_msgs.push_back(std::move(out_msg)); } } + td::RefInt256 storage_fees; + if (!block::tlb::t_TransactionDescr.get_storage_fees(trans.description, storage_fees)) { + return td::Status::Error("Failed to fetch storage fee from transaction"); + } + storage_fee = storage_fees->to_long(); } return tonlib_api::make_object( info.now, data, tonlib_api::make_object(info.prev_trans_lt, info.prev_trans_hash.as_slice().str()), - fees, std::move(in_msg), std::move(out_msgs)); + fees, storage_fee, fees - storage_fee, std::move(in_msg), std::move(out_msgs)); } td::Result> to_raw_transaction(block::Transaction::Info&& info) { @@ -779,8 +859,11 @@ td::Result> to_raw_transact td::Result> to_testWallet_accountState( RawAccountState&& raw_state) { - if (raw_state.data.is_null()) { - return td::Status::Error(400, "Not a TestWallet"); + if (raw_state.code.is_null()) { + return TonlibError::AccountNotInited(); + } + if (raw_state.code->prefetch_ref()->get_hash() != TestWallet::get_init_code_hash()) { + return TonlibError::AccountTypeUnexpected("TestWallet"); } auto ref = raw_state.data->prefetch_ref(); auto cs = vm::load_cell_slice(std::move(ref)); @@ -794,8 +877,11 @@ td::Result> to_testW td::Result> to_wallet_accountState( RawAccountState&& raw_state) { - if (raw_state.data.is_null()) { - return td::Status::Error(400, "Not a Wallet"); + if (raw_state.code.is_null()) { + return TonlibError::AccountNotInited(); + } + if (raw_state.code->prefetch_ref()->get_hash() != Wallet::get_init_code_hash()) { + return TonlibError::AccountTypeUnexpected("Wallet"); } auto ref = raw_state.data->prefetch_ref(); auto cs = vm::load_cell_slice(std::move(ref)); @@ -809,8 +895,11 @@ td::Result> to_wallet_ac td::Result> to_testGiver_accountState( RawAccountState&& raw_state) { - if (raw_state.data.is_null()) { - return td::Status::Error(400, "Not a TestGiver"); + if (raw_state.code.is_null()) { + return TonlibError::AccountNotInited(); + } + if (raw_state.code->prefetch_ref()->get_hash() != TestGiver::get_init_code_hash()) { + return TonlibError::AccountTypeUnexpected("TestGiver"); } auto ref = raw_state.data->prefetch_ref(); auto cs = vm::load_cell_slice(std::move(ref)); @@ -853,21 +942,18 @@ td::Status TonlibClient::do_request(const tonlib_api::raw_sendMessage& request, td::Promise>&& promise) { td::Ref init_state; if (!request.initial_account_state_.empty()) { - TRY_RESULT(new_init_state, vm::std_boc_deserialize(request.initial_account_state_)); + TRY_RESULT_PREFIX(new_init_state, vm::std_boc_deserialize(request.initial_account_state_), + TonlibError::InvalidBagOfCells("initial_account_state")); init_state = std::move(new_init_state); } - TRY_RESULT(data, vm::std_boc_deserialize(request.data_)); - TRY_RESULT(account_address, block::StdAddress::parse(request.destination_->account_address_)); + TRY_RESULT_PREFIX(data, vm::std_boc_deserialize(request.data_), TonlibError::InvalidBagOfCells("data")); + TRY_RESULT(account_address, get_account_address(request.destination_->account_address_)); auto message = GenericAccount::create_ext_message(account_address, std::move(init_state), std::move(data)); client_.send_query(ton::lite_api::liteServer_sendMessage(vm::std_boc_serialize(message).move_as_ok()), [promise = std::move(promise)](auto r_info) mutable { - if (r_info.is_error()) { - promise.set_error(r_info.move_as_error()); - } else { - auto info = r_info.move_as_ok(); - LOG(ERROR) << "info: " << to_string(info); - promise.set_value(tonlib_api::make_object()); - } + TRY_RESULT_PROMISE(promise, info, std::move(r_info)); + LOG(ERROR) << "info: " << to_string(info); + promise.set_value(tonlib_api::make_object()); }); return td::Status::OK(); } @@ -875,30 +961,28 @@ td::Status TonlibClient::do_request(const tonlib_api::raw_sendMessage& request, td::Status TonlibClient::do_request(tonlib_api::raw_getAccountState& request, td::Promise>&& promise) { if (!request.account_address_) { - return td::Status::Error(400, "Field account_address must not be empty"); + return TonlibError::EmptyField("account_address"); } - TRY_RESULT(account_address, block::StdAddress::parse(request.account_address_->account_address_)); - td::actor::create_actor( - "GetAccountState", client_.get_client(), std::move(account_address), + TRY_RESULT(account_address, get_account_address(request.account_address_->account_address_)); + auto actor_id = actor_id_++; + actors_[actor_id] = td::actor::create_actor( + "GetAccountState", client_.get_client(), std::move(account_address), actor_shared(this, actor_id), [promise = std::move(promise)](td::Result r_state) mutable { - if (r_state.is_error()) { - return promise.set_error(r_state.move_as_error()); - } - promise.set_result(to_raw_accountState(r_state.move_as_ok())); - }) - .release(); + TRY_RESULT_PROMISE(promise, state, std::move(r_state)); + promise.set_result(to_raw_accountState(std::move(state))); + }); return td::Status::OK(); } td::Status TonlibClient::do_request(tonlib_api::raw_getTransactions& request, td::Promise>&& promise) { if (!request.account_address_) { - return td::Status::Error(400, "Field account_address must not be empty"); + return TonlibError::EmptyField("account_address"); } if (!request.from_transaction_id_) { - return td::Status::Error(400, "Field from_transaction_id must not be empty"); + return TonlibError::EmptyField("from_transaction_id"); } - TRY_RESULT(account_address, block::StdAddress::parse(request.account_address_->account_address_)); + TRY_RESULT(account_address, get_account_address(request.account_address_->account_address_)); auto lt = request.from_transaction_id_->lt_; auto hash_str = request.from_transaction_id_->hash_; if (hash_str.size() != 32) { @@ -907,24 +991,22 @@ td::Status TonlibClient::do_request(tonlib_api::raw_getTransactions& request, td::Bits256 hash; hash.as_slice().copy_from(hash_str); - td::actor::create_actor( - "GetTransactionHistory", client_.get_client(), account_address, lt, hash, + auto actor_id = actor_id_++; + actors_[actor_id] = td::actor::create_actor( + "GetTransactionHistory", client_.get_client(), account_address, lt, hash, actor_shared(this, actor_id), [promise = std::move(promise)](td::Result r_info) mutable { - if (r_info.is_error()) { - return promise.set_error(r_info.move_as_error()); - } - promise.set_result(to_raw_transactions(r_info.move_as_ok())); - }) - .release(); + TRY_RESULT_PROMISE(promise, info, std::move(r_info)); + promise.set_result(to_raw_transactions(std::move(info))); + }); return td::Status::OK(); } td::Result from_tonlib(tonlib_api::inputKey& input_key) { if (!input_key.key_) { - return td::Status::Error(400, "Field key must not be empty"); + return TonlibError::EmptyField("key"); } - TRY_RESULT(key_bytes, block::PublicKey::parse(input_key.key_->public_key_)); + TRY_RESULT(key_bytes, get_public_key(input_key.key_->public_key_)); return KeyStorage::InputKey{{td::SecureString(key_bytes.key), std::move(input_key.key_->secret_)}, std::move(input_key.local_password_)}; } @@ -950,15 +1032,15 @@ td::Status TonlibClient::do_request(const tonlib_api::testWallet_init& request, td::Status TonlibClient::do_request(const tonlib_api::testWallet_sendGrams& request, td::Promise>&& promise) { if (!request.destination_) { - return td::Status::Error(400, "Field destination must not be empty"); + return TonlibError::EmptyField("destination"); } if (!request.private_key_) { - return td::Status::Error(400, "Field private_key must not be empty"); + return TonlibError::EmptyField("private_key"); } - if (request.message_.size() > 70) { - return td::Status::Error(400, "Message is too long"); + if (request.message_.size() > TestWallet::max_message_size) { + return TonlibError::MessageTooLong(); } - TRY_RESULT(account_address, block::StdAddress::parse(request.destination_->account_address_)); + TRY_RESULT(account_address, get_account_address(request.destination_->account_address_)); account_address.bounceable = false; TRY_RESULT(input_key, from_tonlib(*request.private_key_)); auto address = GenericAccount::get_address( @@ -967,43 +1049,37 @@ td::Status TonlibClient::do_request(const tonlib_api::testWallet_sendGrams& requ auto private_key = td::Ed25519::PrivateKey(std::move(private_key_str.private_key)); std::string init_state; if (request.seqno_ == 0) { - TRY_RESULT(public_key, private_key.get_public_key()); + TRY_RESULT_PREFIX(public_key, private_key.get_public_key(), TonlibError::Internal()); init_state = vm::std_boc_serialize(TestWallet::get_init_state(public_key)).move_as_ok().as_slice().str(); } + auto message = + TestWallet::make_a_gift_message(private_key, request.seqno_, request.amount_, request.message_, account_address); + auto message_hash = message->get_hash().as_slice().str(); td::Promise> new_promise = - [promise = std::move(promise)](td::Result> res) mutable { - if (res.is_error()) { - promise.set_error(res.move_as_error()); - } else { - promise.set_value(tonlib_api::make_object(0)); - } + [promise = std::move(promise), + message_hash = std::move(message_hash)](td::Result> res) mutable { + TRY_RESULT_PROMISE(promise, ok, std::move(res)); + promise.set_value(tonlib_api::make_object(0, std::move(message_hash))); }; - return do_request( - tonlib_api::raw_sendMessage( - tonlib_api::make_object(address.rserialize(true)), std::move(init_state), - vm::std_boc_serialize(TestWallet::make_a_gift_message(private_key, request.seqno_, request.amount_, - request.message_, account_address)) - .move_as_ok() - .as_slice() - .str()), - std::move(new_promise)); + return do_request(tonlib_api::raw_sendMessage( + tonlib_api::make_object(address.rserialize(true)), + std::move(init_state), vm::std_boc_serialize(std::move(message)).move_as_ok().as_slice().str()), + std::move(new_promise)); } td::Status TonlibClient::do_request(tonlib_api::testWallet_getAccountState& request, td::Promise>&& promise) { if (!request.account_address_) { - return td::Status::Error(400, "Field account_address must not be empty"); + return TonlibError::EmptyField("account_address"); } - TRY_RESULT(account_address, block::StdAddress::parse(request.account_address_->account_address_)); - td::actor::create_actor( - "GetAccountState", client_.get_client(), std::move(account_address), + TRY_RESULT(account_address, get_account_address(request.account_address_->account_address_)); + auto actor_id = actor_id_++; + actors_[actor_id] = td::actor::create_actor( + "GetAccountState", client_.get_client(), std::move(account_address), actor_shared(this, actor_id), [promise = std::move(promise)](td::Result r_state) mutable { - if (r_state.is_error()) { - return promise.set_error(r_state.move_as_error()); - } - promise.set_result(to_testWallet_accountState(r_state.move_as_ok())); - }) - .release(); + TRY_RESULT_PROMISE(promise, state, std::move(r_state)); + promise.set_result(to_testWallet_accountState(std::move(state))); + }); return td::Status::OK(); } @@ -1011,7 +1087,7 @@ td::Status TonlibClient::do_request(tonlib_api::testWallet_getAccountState& requ td::Status TonlibClient::do_request(const tonlib_api::wallet_init& request, td::Promise>&& promise) { if (!request.private_key_) { - return td::Status::Error(400, "Field private_key must not be empty"); + return TonlibError::EmptyField("private_key"); } TRY_RESULT(input_key, from_tonlib(*request.private_key_)); auto init_state = Wallet::get_init_state(td::Ed25519::PublicKey(input_key.key.public_key.copy())); @@ -1028,16 +1104,17 @@ td::Status TonlibClient::do_request(const tonlib_api::wallet_init& request, td::Status TonlibClient::do_request(const tonlib_api::wallet_sendGrams& request, td::Promise>&& promise) { if (!request.destination_) { - return td::Status::Error(400, "Field destination must not be empty"); + return TonlibError::EmptyField("destination"); } if (!request.private_key_) { - return td::Status::Error(400, "Field private_key must not be empty"); + return TonlibError::EmptyField("private_key"); } - if (request.message_.size() > 70) { - return td::Status::Error(400, "Message is too long"); + if (request.message_.size() > Wallet::max_message_size) { + return TonlibError::MessageTooLong(); } - TRY_RESULT(valid_until, td::narrow_cast_safe(request.valid_until_)); - TRY_RESULT(account_address, block::StdAddress::parse(request.destination_->account_address_)); + TRY_RESULT_PREFIX(valid_until, td::narrow_cast_safe(request.valid_until_), + TonlibError::InvalidField("valid_until", "overflow")); + TRY_RESULT(account_address, get_account_address(request.destination_->account_address_)); account_address.bounceable = false; TRY_RESULT(input_key, from_tonlib(*request.private_key_)); auto address = GenericAccount::get_address( @@ -1046,43 +1123,37 @@ td::Status TonlibClient::do_request(const tonlib_api::wallet_sendGrams& request, auto private_key = td::Ed25519::PrivateKey(std::move(private_key_str.private_key)); std::string init_state; if (request.seqno_ == 0) { - TRY_RESULT(public_key, private_key.get_public_key()); + TRY_RESULT_PREFIX(public_key, private_key.get_public_key(), TonlibError::Internal()); init_state = vm::std_boc_serialize(Wallet::get_init_state(public_key)).move_as_ok().as_slice().str(); } + auto message = Wallet::make_a_gift_message(private_key, request.seqno_, valid_until, request.amount_, + request.message_, account_address); + auto message_hash = message->get_hash().as_slice().str(); td::Promise> new_promise = - [promise = std::move(promise), valid_until](td::Result> res) mutable { - if (res.is_error()) { - promise.set_error(res.move_as_error()); - } else { - promise.set_value(tonlib_api::make_object(valid_until)); - } + [promise = std::move(promise), valid_until, + message_hash = std::move(message_hash)](td::Result> res) mutable { + TRY_RESULT_PROMISE(promise, ok, std::move(res)); + promise.set_value(tonlib_api::make_object(valid_until, std::move(message_hash))); }; - return do_request( - tonlib_api::raw_sendMessage( - tonlib_api::make_object(address.rserialize(true)), std::move(init_state), - vm::std_boc_serialize(Wallet::make_a_gift_message(private_key, request.seqno_, valid_until, request.amount_, - request.message_, account_address)) - .move_as_ok() - .as_slice() - .str()), - std::move(new_promise)); + return do_request(tonlib_api::raw_sendMessage( + tonlib_api::make_object(address.rserialize(true)), + std::move(init_state), vm::std_boc_serialize(std::move(message)).move_as_ok().as_slice().str()), + std::move(new_promise)); } td::Status TonlibClient::do_request(tonlib_api::wallet_getAccountState& request, td::Promise>&& promise) { if (!request.account_address_) { - return td::Status::Error(400, "Field account_address must not be empty"); + return TonlibError::EmptyField("account_address"); } - TRY_RESULT(account_address, block::StdAddress::parse(request.account_address_->account_address_)); - td::actor::create_actor( - "GetAccountState", client_.get_client(), std::move(account_address), + TRY_RESULT(account_address, get_account_address(request.account_address_->account_address_)); + auto actor_id = actor_id_++; + actors_[actor_id] = td::actor::create_actor( + "GetAccountState", client_.get_client(), std::move(account_address), actor_shared(this, actor_id), [promise = std::move(promise)](td::Result r_state) mutable { - if (r_state.is_error()) { - return promise.set_error(r_state.move_as_error()); - } - promise.set_result(to_wallet_accountState(r_state.move_as_ok())); - }) - .release(); + TRY_RESULT_PROMISE(promise, state, std::move(r_state)); + promise.set_result(to_wallet_accountState(std::move(state))); + }); return td::Status::OK(); } @@ -1090,60 +1161,52 @@ td::Status TonlibClient::do_request(tonlib_api::wallet_getAccountState& request, td::Status TonlibClient::do_request(const tonlib_api::testGiver_sendGrams& request, td::Promise>&& promise) { if (!request.destination_) { - return td::Status::Error(400, "Field destination must not be empty"); + return TonlibError::EmptyField("destination"); } - if (request.message_.size() > 70) { - return td::Status::Error(400, "Message is too long"); + if (request.message_.size() > TestGiver::max_message_size) { + return TonlibError::MessageTooLong(); } - TRY_RESULT(account_address, block::StdAddress::parse(request.destination_->account_address_)); + TRY_RESULT(account_address, get_account_address(request.destination_->account_address_)); account_address.bounceable = false; + auto message = TestGiver::make_a_gift_message(request.seqno_, request.amount_, request.message_, account_address); + auto message_hash = message->get_hash().as_slice().str(); td::Promise> new_promise = - [promise = std::move(promise)](td::Result> res) mutable { - if (res.is_error()) { - promise.set_error(res.move_as_error()); - } else { - promise.set_value(tonlib_api::make_object(0)); - } + [promise = std::move(promise), + message_hash = std::move(message_hash)](td::Result> res) mutable { + TRY_RESULT_PROMISE(promise, ok, std::move(res)); + promise.set_value(tonlib_api::make_object(0, std::move(message_hash))); }; return do_request(tonlib_api::raw_sendMessage( tonlib_api::make_object(TestGiver::address().rserialize(true)), "", - vm::std_boc_serialize(TestGiver::make_a_gift_message(request.seqno_, request.amount_, - request.message_, account_address)) - .move_as_ok() - .as_slice() - .str()), + vm::std_boc_serialize(std::move(message)).move_as_ok().as_slice().str()), std::move(new_promise)); } td::Status TonlibClient::do_request(const tonlib_api::testGiver_getAccountState& request, td::Promise>&& promise) { - td::actor::create_actor( - "GetAccountState", client_.get_client(), TestGiver::address(), + auto actor_id = actor_id_++; + actors_[actor_id] = td::actor::create_actor( + "GetAccountState", client_.get_client(), TestGiver::address(), actor_shared(this, actor_id), [promise = std::move(promise)](td::Result r_state) mutable { - if (r_state.is_error()) { - return promise.set_error(r_state.move_as_error()); - } - promise.set_result(to_testGiver_accountState(r_state.move_as_ok())); - }) - .release(); + TRY_RESULT_PROMISE(promise, state, std::move(r_state)); + promise.set_result(to_testGiver_accountState(std::move(state))); + }); return td::Status::OK(); } td::Status TonlibClient::do_request(const tonlib_api::generic_getAccountState& request, td::Promise>&& promise) { if (!request.account_address_) { - return td::Status::Error(400, "Field account_address must not be empty"); + return TonlibError::EmptyField("account_address"); } - TRY_RESULT(account_address, block::StdAddress::parse(request.account_address_->account_address_)); - td::actor::create_actor( - "GetAccountState", client_.get_client(), std::move(account_address), + TRY_RESULT(account_address, get_account_address(request.account_address_->account_address_)); + auto actor_id = actor_id_++; + actors_[actor_id] = td::actor::create_actor( + "GetAccountState", client_.get_client(), std::move(account_address), actor_shared(this, actor_id), [promise = std::move(promise)](td::Result r_state) mutable { - if (r_state.is_error()) { - return promise.set_error(r_state.move_as_error()); - } - promise.set_result(to_generic_accountState(r_state.move_as_ok())); - }) - .release(); + TRY_RESULT_PROMISE(promise, state, std::move(r_state)); + promise.set_result(to_generic_accountState(std::move(state))); + }); return td::Status::OK(); } @@ -1185,7 +1248,6 @@ class GenericSendGrams : public TonlibQueryActor { void check(td::Status status) { if (status.is_error()) { - LOG(ERROR) << status; promise_.set_error(std::move(status)); return stop(); } @@ -1196,17 +1258,16 @@ class GenericSendGrams : public TonlibQueryActor { } td::Status do_start_up() { - alarm_timestamp() = td::Timestamp::in(15); if (!send_grams_.destination_) { - return td::Status::Error(400, "Field destination must not be empty"); + return TonlibError::EmptyField("destination"); } - TRY_RESULT(destination_address, block::StdAddress::parse(send_grams_.destination_->account_address_)); + TRY_RESULT(destination_address, get_account_address(send_grams_.destination_->account_address_)); is_destination_bounce_ = destination_address.bounceable; if (!send_grams_.source_) { - return td::Status::Error(400, "Field source must not be empty"); + return TonlibError::EmptyField("destination"); } - TRY_RESULT(source_address, block::StdAddress::parse(send_grams_.source_->account_address_)); + TRY_RESULT(source_address, get_account_address(send_grams_.source_->account_address_)); source_address_ = std::move(source_address); send_query(tonlib_api::generic_getAccountState( @@ -1245,19 +1306,19 @@ class GenericSendGrams : public TonlibQueryActor { source_state_ = std::move(state); if (source_state_->get_id() == tonlib_api::generic_accountStateUninited::ID && send_grams_.private_key_ && send_grams_.private_key_->key_) { - TRY_RESULT(key_bytes, block::PublicKey::parse(send_grams_.private_key_->key_->public_key_)); + TRY_RESULT(key_bytes, get_public_key(send_grams_.private_key_->key_->public_key_)); auto key = td::Ed25519::PublicKey(td::SecureString(key_bytes.key)); if (GenericAccount::get_address(0 /*zerochain*/, TestWallet::get_init_state(key)).addr == source_address_.addr) { auto state = ton::move_tl_object_as(source_state_); source_state_ = tonlib_api::make_object( - tonlib_api::make_object(-1, 0, nullptr, + tonlib_api::make_object(state->account_state_->balance_, 0, nullptr, state->account_state_->sync_utime_)); } else if (GenericAccount::get_address(0 /*zerochain*/, Wallet::get_init_state(key)).addr == source_address_.addr) { auto state = ton::move_tl_object_as(source_state_); source_state_ = tonlib_api::make_object( - tonlib_api::make_object(-1, 0, nullptr, + tonlib_api::make_object(state->account_state_->balance_, 0, nullptr, state->account_state_->sync_utime_)); } } @@ -1273,54 +1334,68 @@ class GenericSendGrams : public TonlibQueryActor { destination_state_ = std::move(state); if (destination_state_->get_id() == tonlib_api::generic_accountStateUninited::ID && is_destination_bounce_ && !send_grams_.allow_send_to_uninited_) { - return td::Status::Error(400, "DANGEROUS_TRANSACTION: Transfer to uninited wallet"); + return TonlibError::DangerousTransaction("Transfer to uninited wallet"); } return do_loop(); } - void alarm() override { - check(td::Status::Error("Timeout")); - } td::Status do_loop() { if (!source_state_ || !destination_state_) { return td::Status::OK(); } - downcast_call(*source_state_, - td::overloaded( - [&](tonlib_api::generic_accountStateTestGiver& test_giver_state) { - send_query(tonlib_api::testGiver_sendGrams( - std::move(send_grams_.destination_), test_giver_state.account_state_->seqno_, - send_grams_.amount_, std::move(send_grams_.message_)), - std::move(promise_)); - stop(); - }, - [&](tonlib_api::generic_accountStateTestWallet& test_wallet_state) { - send_query(tonlib_api::testWallet_sendGrams( - std::move(send_grams_.private_key_), std::move(send_grams_.destination_), - test_wallet_state.account_state_->seqno_, send_grams_.amount_, - std::move(send_grams_.message_)), - std::move(promise_)); - stop(); - }, - [&](tonlib_api::generic_accountStateWallet& test_wallet_state) { - send_query(tonlib_api::wallet_sendGrams( - std::move(send_grams_.private_key_), std::move(send_grams_.destination_), - test_wallet_state.account_state_->seqno_, - send_grams_.timeout_ == 0 - ? 60 + test_wallet_state.account_state_->sync_utime_ - : send_grams_.timeout_ + test_wallet_state.account_state_->sync_utime_, - send_grams_.amount_, std::move(send_grams_.message_)), - std::move(promise_)); - stop(); - }, - [&](tonlib_api::generic_accountStateUninited&) { - promise_.set_error(td::Status::Error(400, "Account is not inited")); - stop(); - }, - [&](tonlib_api::generic_accountStateRaw&) { - promise_.set_error(td::Status::Error(400, "Unknown account type")); - stop(); - })); + downcast_call( + *source_state_, + td::overloaded( + [&](tonlib_api::generic_accountStateTestGiver& test_giver_state) { + auto amount = send_grams_.amount_; + send_query(tonlib_api::testGiver_sendGrams(std::move(send_grams_.destination_), + test_giver_state.account_state_->seqno_, amount, + std::move(send_grams_.message_)), + std::move(promise_)); + stop(); + }, + [&](tonlib_api::generic_accountStateTestWallet& test_wallet_state) { + auto amount = send_grams_.amount_; + auto balance = test_wallet_state.account_state_->balance_; + if (false && amount == balance) { + amount = -1; + } else if (amount >= balance) { + promise_.set_error(TonlibError::NotEnoughFunds()); + return stop(); + } + send_query(tonlib_api::testWallet_sendGrams( + std::move(send_grams_.private_key_), std::move(send_grams_.destination_), + test_wallet_state.account_state_->seqno_, amount, std::move(send_grams_.message_)), + std::move(promise_)); + stop(); + }, + [&](tonlib_api::generic_accountStateWallet& wallet_state) { + auto amount = send_grams_.amount_; + auto balance = wallet_state.account_state_->balance_; + if (false && amount == balance) { + amount = -1; + } else if (amount >= balance) { + promise_.set_error(TonlibError::NotEnoughFunds()); + return stop(); + } + send_query( + tonlib_api::wallet_sendGrams(std::move(send_grams_.private_key_), std::move(send_grams_.destination_), + wallet_state.account_state_->seqno_, + send_grams_.timeout_ == 0 + ? 60 + wallet_state.account_state_->sync_utime_ + : send_grams_.timeout_ + wallet_state.account_state_->sync_utime_, + amount, std::move(send_grams_.message_)), + std::move(promise_)); + stop(); + }, + [&](tonlib_api::generic_accountStateUninited&) { + promise_.set_error(TonlibError::AccountNotInited()); + stop(); + }, + [&](tonlib_api::generic_accountStateRaw&) { + promise_.set_error(TonlibError::AccountTypeUnknown()); + stop(); + })); return td::Status::OK(); } }; @@ -1328,7 +1403,7 @@ class GenericSendGrams : public TonlibQueryActor { td::Status TonlibClient::do_request(tonlib_api::generic_sendGrams& request, td::Promise>&& promise) { if (request.timeout_ < 0 || request.timeout_ > 300) { - return td::Status::Error(400, "Invalid timeout: must be between 0 and 300"); + return TonlibError::InvalidField("timeout", "must be between 0 and 300"); } auto id = actor_id_++; actors_[id] = td::actor::create_actor("GenericSendGrams", actor_shared(this, id), @@ -1336,11 +1411,19 @@ td::Status TonlibClient::do_request(tonlib_api::generic_sendGrams& request, return td::Status::OK(); } +td::Result public_key_from_bytes(td::Slice bytes) { + TRY_RESULT_PREFIX(key_bytes, block::PublicKey::from_bytes(bytes), TonlibError::Internal()); + return key_bytes; +} + td::Status TonlibClient::do_request(const tonlib_api::createNewKey& request, td::Promise>&& promise) { - TRY_RESULT(key, key_storage_.create_new_key(std::move(request.local_password_), std::move(request.mnemonic_password_), - std::move(request.random_extra_seed_))); - TRY_RESULT(key_bytes, block::PublicKey::from_bytes(key.public_key.as_slice())); + TRY_RESULT_PREFIX( + key, + key_storage_.create_new_key(std::move(request.local_password_), std::move(request.mnemonic_password_), + std::move(request.random_extra_seed_)), + TonlibError::Internal()); + TRY_RESULT(key_bytes, public_key_from_bytes(key.public_key.as_slice())); promise.set_value(tonlib_api::make_object(key_bytes.serialize(true), std::move(key.secret))); return td::Status::OK(); } @@ -1348,7 +1431,7 @@ td::Status TonlibClient::do_request(const tonlib_api::createNewKey& request, td::Status TonlibClient::do_request(const tonlib_api::exportKey& request, td::Promise>&& promise) { if (!request.input_key_) { - return td::Status::Error(400, "Field input_key must not be empty"); + return TonlibError::EmptyField("input_key"); } TRY_RESULT(input_key, from_tonlib(*request.input_key_)); TRY_RESULT(exported_key, key_storage_.export_key(std::move(input_key))); @@ -1359,13 +1442,20 @@ td::Status TonlibClient::do_request(const tonlib_api::exportKey& request, td::Status TonlibClient::do_request(const tonlib_api::deleteKey& request, td::Promise>&& promise) { if (!request.key_) { - return td::Status::Error(400, "Field key must not be empty"); + return TonlibError::EmptyField("key"); } - TRY_RESULT(key_bytes, block::PublicKey::parse(request.key_->public_key_)); + TRY_RESULT(key_bytes, get_public_key(request.key_->public_key_)); KeyStorage::Key key; key.public_key = td::SecureString(key_bytes.key); key.secret = std::move(request.key_->secret_); - TRY_STATUS(key_storage_.delete_key(key)); + TRY_STATUS_PREFIX(key_storage_.delete_key(key), TonlibError::KeyUnknown()); + promise.set_value(tonlib_api::make_object()); + return td::Status::OK(); +} + +td::Status TonlibClient::do_request(const tonlib_api::deleteAllKeys& request, + td::Promise>&& promise) { + TRY_STATUS_PREFIX(key_storage_.delete_all_keys(), TonlibError::Internal()); promise.set_value(tonlib_api::make_object()); return td::Status::OK(); } @@ -1373,11 +1463,11 @@ td::Status TonlibClient::do_request(const tonlib_api::deleteKey& request, td::Status TonlibClient::do_request(const tonlib_api::importKey& request, td::Promise>&& promise) { if (!request.exported_key_) { - return td::Status::Error(400, "Field exported_key must not be empty"); + return TonlibError::EmptyField("exported_key"); } TRY_RESULT(key, key_storage_.import_key(std::move(request.local_password_), std::move(request.mnemonic_password_), KeyStorage::ExportedKey{std::move(request.exported_key_->word_list_)})); - TRY_RESULT(key_bytes, block::PublicKey::from_bytes(key.public_key.as_slice())); + TRY_RESULT(key_bytes, public_key_from_bytes(key.public_key.as_slice())); promise.set_value(tonlib_api::make_object(key_bytes.serialize(true), std::move(key.secret))); return td::Status::OK(); } @@ -1385,13 +1475,13 @@ td::Status TonlibClient::do_request(const tonlib_api::importKey& request, td::Status TonlibClient::do_request(const tonlib_api::exportPemKey& request, td::Promise>&& promise) { if (!request.input_key_) { - return td::Status::Error(400, "Field input_key must not be empty"); + return TonlibError::EmptyField("input_key"); } if (!request.input_key_->key_) { - return td::Status::Error(400, "Field key must not be empty"); + return TonlibError::EmptyField("key"); } - TRY_RESULT(key_bytes, block::PublicKey::parse(request.input_key_->key_->public_key_)); + TRY_RESULT(key_bytes, get_public_key(request.input_key_->key_->public_key_)); KeyStorage::InputKey input_key{{td::SecureString(key_bytes.key), std::move(request.input_key_->key_->secret_)}, std::move(request.input_key_->local_password_)}; TRY_RESULT(exported_pem_key, key_storage_.export_pem_key(std::move(input_key), std::move(request.key_password_))); @@ -1402,11 +1492,11 @@ td::Status TonlibClient::do_request(const tonlib_api::exportPemKey& request, td::Status TonlibClient::do_request(const tonlib_api::importPemKey& request, td::Promise>&& promise) { if (!request.exported_key_) { - return td::Status::Error(400, "Field exported_key must not be empty"); + return TonlibError::EmptyField("exported_key"); } TRY_RESULT(key, key_storage_.import_pem_key(std::move(request.local_password_), std::move(request.key_password_), KeyStorage::ExportedPemKey{std::move(request.exported_key_->pem_)})); - TRY_RESULT(key_bytes, block::PublicKey::from_bytes(key.public_key.as_slice())); + TRY_RESULT(key_bytes, public_key_from_bytes(key.public_key.as_slice())); promise.set_value(tonlib_api::make_object(key_bytes.serialize(true), std::move(key.secret))); return td::Status::OK(); } @@ -1414,7 +1504,7 @@ td::Status TonlibClient::do_request(const tonlib_api::importPemKey& request, td::Status TonlibClient::do_request(const tonlib_api::exportEncryptedKey& request, td::Promise>&& promise) { if (!request.input_key_) { - return td::Status::Error(400, "Field input_key must not be empty"); + return TonlibError::EmptyField("input_key"); } TRY_RESULT(input_key, from_tonlib(*request.input_key_)); TRY_RESULT(exported_key, key_storage_.export_encrypted_key(std::move(input_key), request.key_password_)); @@ -1425,12 +1515,12 @@ td::Status TonlibClient::do_request(const tonlib_api::exportEncryptedKey& reques td::Status TonlibClient::do_request(const tonlib_api::importEncryptedKey& request, td::Promise>&& promise) { if (!request.exported_encrypted_key_) { - return td::Status::Error(400, "Field exported_encrypted_key must not be empty"); + return TonlibError::EmptyField("exported_encrypted_key"); } TRY_RESULT(key, key_storage_.import_encrypted_key( std::move(request.local_password_), std::move(request.key_password_), KeyStorage::ExportedEncryptedKey{std::move(request.exported_encrypted_key_->data_)})); - TRY_RESULT(key_bytes, block::PublicKey::from_bytes(key.public_key.as_slice())); + TRY_RESULT(key_bytes, public_key_from_bytes(key.public_key.as_slice())); promise.set_value(tonlib_api::make_object(key_bytes.serialize(true), std::move(key.secret))); return td::Status::OK(); } @@ -1438,10 +1528,10 @@ td::Status TonlibClient::do_request(const tonlib_api::importEncryptedKey& reques td::Status TonlibClient::do_request(const tonlib_api::changeLocalPassword& request, td::Promise>&& promise) { if (!request.input_key_) { - return td::Status::Error(400, "Field input_key must not be empty"); + return TonlibError::EmptyField("input_key"); } if (!request.input_key_->key_) { - return td::Status::Error(400, "Field key must not be empty"); + return TonlibError::EmptyField("key"); } TRY_RESULT(input_key, from_tonlib(*request.input_key_)); TRY_RESULT(key, key_storage_.change_local_password(std::move(input_key), std::move(request.new_local_password_))); @@ -1465,7 +1555,8 @@ td::Status TonlibClient::do_request(const tonlib_api::onLiteServerQueryResult& r td::Status TonlibClient::do_request(const tonlib_api::onLiteServerQueryError& request, td::Promise>&& promise) { send_closure(ext_client_outbound_, &ExtClientOutbound::on_query_result, request.id_, - td::Status::Error(request.error_->code_, request.error_->message_), + td::Status::Error(request.error_->code_, request.error_->message_) + .move_as_error_prefix(TonlibError::LiteServerNetwork()), [promise = std::move(promise)](td::Result res) mutable { if (res.is_ok()) { promise.set_value(tonlib_api::make_object()); diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.h b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.h index 9e7ecdafea..649df52d74 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.h +++ b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.h @@ -24,6 +24,7 @@ #include "tonlib/ExtClient.h" #include "tonlib/ExtClientOutbound.h" #include "tonlib/KeyStorage.h" +#include "tonlib/KeyValue.h" #include "tonlib/LastBlockStorage.h" #include "td/actor/actor.h" @@ -46,20 +47,22 @@ class TonlibClient : public td::actor::Actor { private: enum class State { Uninited, Running, Closed } state_ = State::Uninited; td::unique_ptr callback_; + + // Config Config config_; td::uint32 config_generation_{0}; std::string blockchain_name_; bool ignore_cache_{false}; - bool use_callbacks_for_network_{false}; - td::actor::ActorId ext_client_outbound_; // KeyStorage + std::shared_ptr kv_; KeyStorage key_storage_; LastBlockStorage last_block_storage_; // network td::actor::ActorOwn raw_client_; + td::actor::ActorId ext_client_outbound_; td::actor::ActorOwn raw_last_block_; ExtClient client_; @@ -156,6 +159,7 @@ class TonlibClient : public td::actor::Actor { td::Status do_request(const tonlib_api::exportKey& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::deleteKey& request, td::Promise>&& promise); + td::Status do_request(const tonlib_api::deleteAllKeys& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::importKey& request, td::Promise>&& promise); td::Status do_request(const tonlib_api::exportPemKey& request, diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/TonlibError.h b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibError.h new file mode 100644 index 0000000000..e0b4d0b189 --- /dev/null +++ b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibError.h @@ -0,0 +1,157 @@ +/* + This file is part of TON Blockchain Library. + + TON Blockchain Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + TON Blockchain Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with TON Blockchain Library. If not, see . + + Copyright 2017-2019 Telegram Systems LLP +*/ + +#pragma once + +#include "td/utils/Status.h" +#include "common/errorcode.h" +// NEED_MNEMONIC_PASSWORD +// KEY_UNKNOWN +// KEY_DECRYPT +// INVALID_MNEMONIC +// INVALID_BAG_OF_CELLS +// INVALID_PUBLIC_KEY +// INVALID_ACCOUNT_ADDRESS +// INVALID_CONFIG +// INVALID_PEM_KEY +// MESSAGE_TOO_LONG +// EMPTY_FIELD +// INVALID_FIELD +// DANGEROUS_TRANSACTION +// ACCOUNT_NOT_INITED +// ACCOUNT_TYPE_UNKNOWN +// ACCOUNT_TYPE_UNEXPECTED +// VALIDATE_ACCOUNT_STATE +// VALIDATE_TRANSACTION +// VALIDATE_ZERO_STATE +// VALIDATE_BLOCK_PROOF +// NO_LITE_SERVERS +// LITE_SERVER_NETWORK +// CANCELLED +// NOT_ENOUGH_FUNDS +// LITE_SERVER +// INTERNAL + +namespace tonlib { +struct TonlibError { + static td::Status NeedMnemonicPassword() { + return td::Status::Error(400, "NEED_MNEMONIC_PASSWORD"); + } + static td::Status InvalidMnemonic() { + return td::Status::Error(400, "INVALID_MNEMONIC: Invalid mnemonic words or password (invalid checksum)"); + } + static td::Status InvalidBagOfCells(td::Slice comment) { + return td::Status::Error(400, PSLICE() << "INVALID_BAG_OF_CELLS: " << comment); + } + static td::Status InvalidPublicKey() { + return td::Status::Error(400, "INVALID_PUBLIC_KEY"); + } + static td::Status InvalidAccountAddress() { + return td::Status::Error(400, "INVALID_ACCOUNT_ADDRESS"); + } + static td::Status InvalidConfig(td::Slice reason) { + return td::Status::Error(400, PSLICE() << "INVALID_CONFIG: " << reason); + } + static td::Status InvalidPemKey() { + return td::Status::Error(400, "INVALID_PEM_KEY"); + } + static td::Status MessageTooLong() { + return td::Status::Error(400, "MESSAGE_TOO_LONG"); + } + static td::Status EmptyField(td::Slice field_name) { + return td::Status::Error(400, PSLICE() << "EMPTY_FIELD: Field " << field_name << " must not be emtpy"); + } + static td::Status InvalidField(td::Slice field_name, td::Slice reason) { + return td::Status::Error(400, PSLICE() << "INVALID_FIELD: Field " << field_name << " has invalid value " << reason); + } + static td::Status DangerousTransaction(td::Slice reason) { + return td::Status::Error(400, PSLICE() << "DANGEROUS_TRANSACTION: " << reason); + } + static td::Status AccountNotInited() { + return td::Status::Error(400, "ACCOUNT_NOT_INITED"); + } + static td::Status AccountTypeUnknown() { + return td::Status::Error(400, "ACCOUNT_TYPE_UNKNOWN"); + } + static td::Status AccountTypeUnexpected(td::Slice expected) { + return td::Status::Error(400, PSLICE() << "ACCOUNT_TYPE_UNEXPECTED: not a " << expected); + } + static td::Status Internal() { + return td::Status::Error(500, "INTERNAL"); + } + static td::Status Internal(td::Slice message) { + return td::Status::Error(500, PSLICE() << "INTERNAL: " << message); + } + static td::Status KeyUnknown() { + return td::Status::Error(500, "KEY_UNKNOWN"); + } + static td::Status KeyDecrypt() { + return td::Status::Error(500, "KEY_DECRYPT"); + } + static td::Status ValidateAccountState() { + return td::Status::Error(500, "VALIDATE_ACCOUNT_STATE"); + } + static td::Status ValidateTransactions() { + return td::Status::Error(500, "VALIDATE_TRANSACTION"); + } + static td::Status ValidateZeroState(td::Slice message) { + return td::Status::Error(500, PSLICE() << "VALIDATE_ZERO_STATE: " << message); + } + static td::Status ValidateBlockProof() { + return td::Status::Error(500, "VALIDATE_BLOCK_PROOF"); + } + static td::Status NoLiteServers() { + return td::Status::Error(500, "NO_LITE_SERVERS"); + } + static td::Status LiteServerNetwork() { + return td::Status::Error(500, "LITE_SERVER_NETWORK"); + } + static td::Status Cancelled() { + return td::Status::Error(500, "CANCELLED"); + } + static td::Status NotEnoughFunds() { + return td::Status::Error(500, "NOT_ENOUGH_FUNDS"); + } + + static td::Status LiteServer(td::int32 code, td::Slice message) { + auto f = [&](td::Slice code_description) { return LiteServer(code, code_description, message); }; + switch (ton::ErrorCode(code)) { + case ton::ErrorCode::cancelled: + return f("CANCELLED"); + case ton::ErrorCode::failure: + return f("FAILURE"); + case ton::ErrorCode::error: + return f("ERROR"); + case ton::ErrorCode::warning: + return f("WARNING"); + case ton::ErrorCode::protoviolation: + return f("PROTOVIOLATION"); + case ton::ErrorCode::timeout: + return f("TIMEOUT"); + case ton::ErrorCode::notready: + return f("NOTREADY"); + } + return f("UNKNOWN"); + } + + static td::Status LiteServer(td::int32 code, td::Slice code_description, td::Slice message) { + return td::Status::Error(500, PSLICE() << "LITE_SERVER_" << code_description << ": " << message); + } +}; +} // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/Wallet.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/Wallet.cpp index 7546e8fd22..e35acfd3bc 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/Wallet.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/Wallet.cpp @@ -17,6 +17,7 @@ Copyright 2017-2019 Telegram Systems LLP */ #include "tonlib/Wallet.h" +#include "tonlib/CellString.h" #include "tonlib/GenericAccount.h" #include "tonlib/utils.h" @@ -26,13 +27,13 @@ #include namespace tonlib { -td::Ref Wallet::get_init_state(const td::Ed25519::PublicKey& public_key) { +td::Ref Wallet::get_init_state(const td::Ed25519::PublicKey& public_key) noexcept { auto code = get_init_code(); auto data = get_init_data(public_key); return GenericAccount::get_init_state(std::move(code), std::move(data)); } -td::Ref Wallet::get_init_message(const td::Ed25519::PrivateKey& private_key) { +td::Ref Wallet::get_init_message(const td::Ed25519::PrivateKey& private_key) noexcept { td::uint32 seqno = 0; td::uint32 valid_until = std::numeric_limits::max(); auto signature = @@ -44,8 +45,7 @@ td::Ref Wallet::get_init_message(const td::Ed25519::PrivateKey& privat td::Ref Wallet::make_a_gift_message(const td::Ed25519::PrivateKey& private_key, td::uint32 seqno, td::uint32 valid_until, td::int64 gramms, td::Slice message, - const block::StdAddress& dest_address) { - CHECK(message.size() <= 124); + const block::StdAddress& dest_address) noexcept { td::BigInt256 dest_addr; dest_addr.import_bits(dest_address.addr.as_bitslice()); vm::CellBuilder cb; @@ -54,9 +54,15 @@ td::Ref Wallet::make_a_gift_message(const td::Ed25519::PrivateKey& pri .append_cellslice(binary_bitstring_to_cellslice("b{000100}").move_as_ok()) .store_long(dest_address.workchain, 8) .store_int256(dest_addr, 256); - block::tlb::t_Grams.store_integer_value(cb, td::BigInt256(gramms)); - auto message_inner = cb.store_zeroes(9 + 64 + 32 + 1 + 1).store_bytes("\0\0\0\0", 4).store_bytes(message).finalize(); td::int8 send_mode = 3; + if (gramms == -1) { + gramms = 0; + send_mode += 128; + } + block::tlb::t_Grams.store_integer_value(cb, td::BigInt256(gramms)); + cb.store_zeroes(9 + 64 + 32 + 1 + 1).store_bytes("\0\0\0\0", 4); + vm::CellString::store(cb, message, 35 * 8).ensure(); + auto message_inner = cb.finalize(); auto message_outer = vm::CellBuilder() .store_long(seqno, 32) .store_long(valid_until, 32) @@ -68,7 +74,7 @@ td::Ref Wallet::make_a_gift_message(const td::Ed25519::PrivateKey& pri return vm::CellBuilder().store_bytes(signature).append_cellslice(vm::load_cell_slice(message_outer)).finalize(); } -td::Ref Wallet::get_init_code() { +td::Ref Wallet::get_init_code() noexcept { static auto res = [] { auto serialized_code = td::base64_decode( "te6ccgEEAQEAAAAAVwAAqv8AIN0gggFMl7qXMO1E0NcLH+Ck8mCDCNcYINMf0x8B+CO78mPtRNDTH9P/" @@ -79,11 +85,11 @@ td::Ref Wallet::get_init_code() { return res; } -vm::CellHash Wallet::get_init_code_hash() { +vm::CellHash Wallet::get_init_code_hash() noexcept { return get_init_code()->get_hash(); } -td::Ref Wallet::get_init_data(const td::Ed25519::PublicKey& public_key) { +td::Ref Wallet::get_init_data(const td::Ed25519::PublicKey& public_key) noexcept { return vm::CellBuilder().store_long(0, 32).store_bytes(public_key.as_octet_string()).finalize(); } } // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/Wallet.h b/submodules/ton/tonlib-src/tonlib/tonlib/Wallet.h index 2f2d8a8de1..dd114cce77 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/Wallet.h +++ b/submodules/ton/tonlib-src/tonlib/tonlib/Wallet.h @@ -21,18 +21,20 @@ #include "vm/cells.h" #include "Ed25519.h" #include "block/block.h" +#include "CellString.h" namespace tonlib { class Wallet { public: - static td::Ref get_init_state(const td::Ed25519::PublicKey& public_key); - static td::Ref get_init_message(const td::Ed25519::PrivateKey& private_key); + static constexpr unsigned max_message_size = vm::CellString::max_bytes; + static td::Ref get_init_state(const td::Ed25519::PublicKey& public_key) noexcept; + static td::Ref get_init_message(const td::Ed25519::PrivateKey& private_key) noexcept; static td::Ref make_a_gift_message(const td::Ed25519::PrivateKey& private_key, td::uint32 seqno, td::uint32 valid_until, td::int64 gramms, td::Slice message, - const block::StdAddress& dest_address); + const block::StdAddress& dest_address) noexcept; - static td::Ref get_init_code(); - static vm::CellHash get_init_code_hash(); - static td::Ref get_init_data(const td::Ed25519::PublicKey& public_key); + static td::Ref get_init_code() noexcept; + static vm::CellHash get_init_code_hash() noexcept; + static td::Ref get_init_data(const td::Ed25519::PublicKey& public_key) noexcept; }; } // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/keys/DecryptedKey.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/keys/DecryptedKey.cpp index 3161d904c7..746ca188c0 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/keys/DecryptedKey.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/keys/DecryptedKey.cpp @@ -67,7 +67,8 @@ EncryptedKey DecryptedKey::encrypt(td::Slice local_password, td::Slice old_secre } td::SecureString encryption_secret(64); - pbkdf2_sha512(as_slice(decrypted_secret), "TON local key", PBKDF_ITERATIONS, encryption_secret.as_mutable_slice()); + pbkdf2_sha512(as_slice(decrypted_secret), "TON local key", EncryptedKey::PBKDF_ITERATIONS, + encryption_secret.as_mutable_slice()); std::vector mnemonic_words_copy; for (auto &w : mnemonic_words) { diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/keys/EncryptedKey.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/keys/EncryptedKey.cpp index 075e89f479..143677914f 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/keys/EncryptedKey.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/keys/EncryptedKey.cpp @@ -25,7 +25,6 @@ namespace tonlib { td::Result EncryptedKey::decrypt(td::Slice local_password, bool check_public_key) { - LOG(ERROR) << "decrypt"; if (secret.size() != 32) { return td::Status::Error("Failed to decrypt key: invalid secret size"); } diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/keys/EncryptedKey.h b/submodules/ton/tonlib-src/tonlib/tonlib/keys/EncryptedKey.h index 5a32c9f89f..56aa661531 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/keys/EncryptedKey.h +++ b/submodules/ton/tonlib-src/tonlib/tonlib/keys/EncryptedKey.h @@ -25,9 +25,9 @@ #include namespace tonlib { -constexpr int PBKDF_ITERATIONS = 100000; struct DecryptedKey; struct EncryptedKey { + static constexpr int PBKDF_ITERATIONS = 100000; td::SecureString encrypted_data; td::Ed25519::PublicKey public_key; td::SecureString secret; diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/keys/SimpleEncryption.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/keys/SimpleEncryption.cpp index 760dda36b9..026a34292e 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/keys/SimpleEncryption.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/keys/SimpleEncryption.cpp @@ -77,7 +77,7 @@ td::Result SimpleEncryption::decrypt_data(td::Slice encrypted_ return td::Status::Error("Failed to decrypt: data is too small"); } if (encrypted_data.size() % 16 != 0) { - return td::Status::Error("Failed to decrypt: data size is not divisible by 32"); + return td::Status::Error("Failed to decrypt: data size is not divisible by 16"); } auto data_hash = encrypted_data.substr(0, 32); encrypted_data = encrypted_data.substr(32); diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/tonlib-cli.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/tonlib-cli.cpp index ce8d5f481f..a783d2aa37 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/tonlib-cli.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/tonlib-cli.cpp @@ -27,6 +27,7 @@ class TonlibCli : public td::actor::Actor { std::string config; std::string name; std::string key_dir{"."}; + bool in_memory{false}; bool use_callbacks_for_network{false}; bool use_simple_wallet{false}; bool ignore_cache{false}; @@ -120,7 +121,14 @@ class TonlibCli : public td::actor::Actor { ? make_object(options_.config, options_.name, options_.use_callbacks_for_network, options_.ignore_cache) : nullptr; - send_query(make_object(make_object(std::move(config), options_.key_dir)), + + tonlib_api::object_ptr ks_type; + if (options_.in_memory) { + ks_type = make_object(); + } else { + ks_type = make_object(options_.key_dir); + } + send_query(make_object(make_object(std::move(config), std::move(ks_type))), [](auto r_ok) { LOG_IF(ERROR, r_ok.is_error()) << r_ok.error(); td::TerminalIO::out() << "Tonlib is inited\n"; @@ -184,6 +192,7 @@ class TonlibCli : public td::actor::Actor { td::TerminalIO::out() << "keys - show all stored keys\n"; td::TerminalIO::out() << "unpackaddress
- validate and parse address\n"; td::TerminalIO::out() << "importkey - import key\n"; + td::TerminalIO::out() << "deletekeys - delete ALL PRIVATE KEYS\n"; td::TerminalIO::out() << "exportkey [] - export key\n"; td::TerminalIO::out() << "setconfig [] [] [] - set lite server config\n"; td::TerminalIO::out() << "getstate - get state of simple wallet with requested key\n"; @@ -205,6 +214,8 @@ class TonlibCli : public td::actor::Actor { try_stop(); } else if (cmd == "keys") { dump_keys(); + } else if (cmd == "deletekeys") { + delete_all_keys(); } else if (cmd == "exportkey") { export_key(parser.read_word()); } else if (cmd == "importkey") { @@ -407,6 +418,27 @@ class TonlibCli : public td::actor::Actor { dump_key(i); } } + void delete_all_keys() { + static td::Slice password = td::Slice("I have written down mnemonic words"); + td::TerminalIO::out() << "You are going to delete ALL PRIVATE KEYS. To confirm enter `" << password << "`\n"; + cont_ = [this](td::Slice entered) { + if (password == entered) { + this->do_delete_all_keys(); + } else { + td::TerminalIO::out() << "Your keys left intact\n"; + } + }; + } + + void do_delete_all_keys() { + send_query(tonlib_api::make_object(), [](auto r_res) { + if (r_res.is_error()) { + td::TerminalIO::out() << "Something went wrong: " << r_res.error() << "\n"; + return; + } + td::TerminalIO::out() << "All your keys have been deleted\n"; + }); + } std::string key_db_path() { return options_.key_dir + TD_DIR_SLASH + "key_db"; @@ -824,6 +856,10 @@ int main(int argc, char* argv[]) { options.key_dir = arg.str(); return td::Status::OK(); }); + p.add_option('M', "in-memory", "store keys only in-memory", [&]() { + options.in_memory = true; + return td::Status::OK(); + }); p.add_option('E', "execute", "execute one command", [&](td::Slice arg) { options.one_shot = true; options.cmd = arg.str(); diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/utils.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/utils.cpp index b577faf3f0..5cef21f56d 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/utils.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/utils.cpp @@ -20,6 +20,10 @@ #include "td/utils/misc.h" #include "vm/cellslice.h" namespace tonlib { +int VERBOSITY_NAME(tonlib_query) = VERBOSITY_NAME(INFO); +int VERBOSITY_NAME(last_block) = VERBOSITY_NAME(INFO); +int VERBOSITY_NAME(lite_server) = VERBOSITY_NAME(INFO); + td::Result> binary_bitstring_to_cellslice(td::Slice literal) { unsigned char buff[128]; if (!begins_with(literal, "b{") || !ends_with(literal, "}")) { diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/utils.h b/submodules/ton/tonlib-src/tonlib/tonlib/utils.h index 924e86d695..840bc10d20 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/utils.h +++ b/submodules/ton/tonlib-src/tonlib/tonlib/utils.h @@ -21,6 +21,21 @@ #include "ton/ton-types.h" #include "block/block.h" #include "block/block-parse.h" + namespace tonlib { +template +auto try_f(F&& f) noexcept -> decltype(f()) { + try { + return f(); + } catch (vm::VmError error) { + return td::Status::Error(PSLICE() << "Got a vm exception: " << error.get_msg()); + } +} + +#define TRY_VM(f) try_f([&] { return f; }) + +extern int VERBOSITY_NAME(tonlib_query); +extern int VERBOSITY_NAME(last_block); +extern int VERBOSITY_NAME(lite_server); td::Result> binary_bitstring_to_cellslice(td::Slice literal); } // namespace tonlib