1{"version":3,"sources":["webpack:///./src/components.ts","webpack:///./src/components/toggle_button.ts","webpack:///./src/config.ts","webpack:///./src/helpers.ts","webpack:///./src/controllers/dialog.ts","webpack:///./src/helpers/clipboard.ts","webpack:///./src/controllers/troubleshooting.ts","webpack:///./src/controllers/footer.ts","webpack:///./src/controllers/header.ts","webpack:///./src/typeguards.ts","webpack:///./src/helpers/confidential.ts","webpack:///./src/helpers/data_channel.ts","webpack:///./src/services/peerconnection.ts","webpack:///./src/exceptions.ts","webpack:///./src/helpers/crypto.ts","webpack:///./src/services/push.ts","webpack:///./src/helpers/emoji.ts","webpack:///./src/partials/messenger.ts","webpack:///./src/protocol/cache.ts","webpack:///./src/protocol/sequence_number.ts","webpack:///./src/services/webclient.ts","webpack:///./src/controllers/status.ts","webpack:///./src/controllers/theme.ts","webpack:///./src/controllers.ts","webpack:///./src/directives/avatar.ts","webpack:///./src/receiver_helpers.ts","webpack:///./src/directives/avatar_area.ts","webpack:///./src/directives/avatar_editor.ts","webpack:///./src/directives/click_action.ts","webpack:///./src/directives/compose_area.ts","webpack:///./src/directives/contact_badge.ts","webpack:///./src/directives/drag_file.ts","webpack:///./src/directives/group_badge.ts","webpack:///./src/helpers/messages.ts","webpack:///./src/directives/latest_message.ts","webpack:///./src/directives/mediabox.ts","webpack:///./src/directives/member_list_editor.ts","webpack:///./src/directives/message.ts","webpack:///./src/directives/message_icon.ts","webpack:///./src/directives/message_media.ts","webpack:///./src/directives/message_meta.ts","webpack:///./src/directives/message_text.ts","webpack:///./src/directives/verification_level.ts","webpack:///./src/directives.ts","webpack:///./src/directives/autofocus.ts","webpack:///./src/directives/battery.ts","webpack:///./src/directives/distribution_list_badge.ts","webpack:///./src/directives/message_contact.ts","webpack:///./src/directives/message_date.ts","webpack:///./src/directives/message_quote.ts","webpack:///./src/directives/message_state.ts","webpack:///./src/directives/message_voip_status.ts","webpack:///./src/directives/include_replace.ts","webpack:///./src/directives/location.ts","webpack:///./src/directives/searchbox.ts","webpack:///./src/directives/status_bar.ts","webpack:///./src/markup_parser.ts","webpack:///./src/filters.ts","webpack:///./src/partials/welcome.ts","webpack:///./src/helpers/password_strength.ts","webpack:///./src/services/battery.ts","webpack:///./src/helpers/browser_info.ts","webpack:///./src/services/browser.ts","webpack:///./src/services/contact.ts","webpack:///./src/controller_model/avatar.ts","webpack:///./src/controller_model/contact.ts","webpack:///./src/controller_model/distributionList.ts","webpack:///./src/controller_model/group.ts","webpack:///./src/controller_model/me.ts","webpack:///./src/services/controller_model.ts","webpack:///./src/services/keystore.ts","webpack:///./src/helpers/logger.ts","webpack:///./src/services/log.ts","webpack:///./src/services/message.ts","webpack:///./src/services/mime.ts","webpack:///./src/services/notification.ts","webpack:///./src/services/qrcode.ts","webpack:///./src/services/settings.ts","webpack:///./src/services/state.ts","webpack:///./src/services/theme.ts","webpack:///./src/services/timeout.ts","webpack:///./src/services/title.ts","webpack:///./src/services/version.ts","webpack:///./src/message_helpers.ts","webpack:///./src/threema/container.ts","webpack:///./src/services.ts","webpack:///./src/services/fingerprint.ts","webpack:///./src/services/receiver.ts","webpack:///./src/services/controller.ts","webpack:///./src/services/mediabox.ts","webpack:///./src/services/uri.ts","webpack:///./src/app.ts","webpack:///./src/services/string.ts"],"names":["angular","module","component","bindings","flag","onEnable","onDisable","labelEnabled","labelDisabled","iconEnabled","iconDisabled","controller","this","getLabel","getIcon","action","template","VERSION","SELF_HOSTED","VERSION_MOUNTAIN","VERSION_MOUNTAIN_URL","VERSION_MOUNTAIN_IMAGE_URL","VERSION_MOUNTAIN_IMAGE_COPYRIGHT","VERSION_MOUNTAIN_HEIGHT","PREV_PROTOCOL_LAST_VERSION","GIT_BRANCH","SALTYRTC_HOST","SALTYRTC_PORT","SALTYRTC_SERVER_KEY","ICE_SERVERS","urls","username","credential","PUSH_URL","FONT_CSS_URL","LOG_TAG_PADDING","CONSOLE_LOG_LEVEL","REPORT_LOG_LEVEL","REPORT_LOG_LIMIT","COMPOSE_AREA_LOG_LEVEL","SALTYRTC_LOG_LEVEL","TIMER_LOG_LEVEL","ARP_LOG_LEVEL","ARP_LOG_TRACE","MSGPACK_LOG_TRACE","TRANSPORT_LOG_LEVEL","VISUALIZE_STATE","u8aToHex","array","results","forEach","arrayByte","push","toString","replace","join","hexToU8a","hexstring","i","k","ref","j","length","Uint8Array","parseInt","substr","u8aToBase64","btoa","Array","from","byte","String","fromCharCode","randomString","chars","str","charAt","Math","floor","random","stringToUtf8a","out","p","c","charCodeAt","filter","obj","callback","key","Object","keys","value","msgpackVisualizer","encodeURIComponent","hasFeature","contactReceiver","feature","log","undefined","featureMask","warn","id","bufferToUrl","buffer","mimeType","fallbackMimeType","hasValue","val","sleep","ms","Promise","resolve","setTimeout","arraysAreEqual","a1","a2","isActionTrigger","ev","copyShallow","object","assign","DialogController","constructor","$scope","$mdDialog","themeService","activeElement","document","theme","evtThemeChange","attach","newTheme","$apply","cancel","restoreFocus","hide","data","focus","copyString","text","useSelectionRange","textArea","createElement","style","position","left","top","body","appendChild","contentEditable","readOnly","range","createRange","selection","self","getSelection","removeAllRanges","addRange","setSelectionRange","select","execCommand","Error","removeChild","$inject","TroubleshootingController","$mdToast","$translate","config","logService","browserService","webClientService","super","sanitize","isSending","sendingFailed","description","getLogger","readyToSubmit","isConnected","TextEncoder","encode","getLog","fail","show","simple","textContent","instant","support","type","contacts","has","addContact","error","get","browser","getBrowser","message","name","fileType","size","byteLength","byteOffset","slice","caption","sendAsFile","sendMessage","waitUntilAcknowledged","copyToClipboard","toastString","clipboard","isSafari","map","server","container","memory","getRecords","replacer","getReplacer","JSON","stringify","VersionDialogController","version","fullVersion","FooterController","CONFIG","showVersionInfo","controllerAs","templateUrl","parent","element","clickOutsideToClose","fullscreen","showTroubleshooting","HeaderController","useThreemaFont","fontUrl","isContactReceiver","receiver","isValidReceiverType","receiverType","isEmojiInfo","emojiString","imgPath","codepoint","isKeyboardEvent","censor","BaseConfidential","censored","item","ArrayBuffer","Blob","v","entries","ConfidentialArray","uncensored","ConfidentialObjectValues","ConfidentialWireMessage","args","ConfidentialIceCandidate","candidateSdp","candidate","SDPUtils","address","ip","censorIp","relatedAddress","includes","ipv4","split","ipv6","head","shift","UnboundedFlowControlledDataChannel","dc","logLevel","lowWaterMark","highWaterMark","_ready","Future","bufferedAmountLowThreshold","onbufferedamountlow","done","debug","label","bufferedAmount","write","send","arguments","queue","ready","then","writeWhenReady","PeerConnectionHelper","$q","$rootScope","timeoutService","webrtcTask","iceServers","connectionFailedTimer","sdc","closed","connectionState","onConnectionStateChange","info","concat","pc","RTCPeerConnection","onnegotiationneeded","initiatorFlow","onconnectionstatechange","onsignalingstatechange","signalingState","setupIceCandidateHandling","ondatachannel","e","channel","onicecandidate","sendCandidate","sdpMid","sdpMLineIndex","onicecandidateerror","errorText","url","hostCandidate","errorCode","oniceconnectionstatechange","iceConnectionState","setConnectionState","register","close","CONNECTION_FAILED_TIMEOUT_MS","onicegatheringstatechange","iceGatheringState","on","candidateInit","addIceCandidate","catch","offer","createOffer","setLocalDescription","sendOffer","answer","once","receiveAnswer","setRemoteDescription","handover","link","getTransportLink","createDataChannel","negotiated","ordered","protocol","binaryType","handler","sctp","maxMessageSize","onopen","onclose","onerror","event","onmessage","receive","state","off","TimeoutError","PushError","msg","statusCode","async","sha256","bytes","window","crypto","subtle","buf","digest","PushSession","service","session","doneFuture","affiliation","running","tries","defaultConfig","retryTimeoutMs","retryTimeoutInitMs","timeToLiveRange","triesMax","retryTimeoutMaxMs","Number","POSITIVE_INFINITY","sumMs","min","start","run","reject","sessionHash","URLSearchParams","set","PushService","ARG_TYPE","pushType","ARG_SESSION","ARG_VERSION","ARG_AFFILIATION","parts","pushToken","ARG_TOKEN","ARG_ENDPOINT","ARG_BUNDLE_ID","timeToLive","delete","ARG_COLLAPSE_KEY","ARG_TIME_TO_LIVE","response","fetch","method","headers","ok","status","PROTOCOL_VERSION","_pushToken","_pushType","init","pushTokenType","reset","isAvailable","createSession","SHORTNAMES","TEXT_WHEN_UNQUALIFIED","emojify","tokens","parseEmoji","output","token","regex","RegExp","EMOJI_REGEX","result","match","startIndex","endIndex","exec","emoji","prevEndIndex","lastIndex","substring","forceText","twemoji","convert","toCodePoint","strippedCodepoint","x","pattern","SendFileController","preview","previewDataUrl","keypress","$event","hasPreview","DeviceUnreachableController","$window","stateService","retrying","progress","canRetry","salty","attempt","expectedPeriodMaxMs","pushSessionPromise","sendPush","interval","setInterval","clearInterval","reload","location","closeWithWarning","alert","title","PushRejectedDialogController","trustedKeyStore","forget","clearTrustedKey","SettingsController","settingsService","notificationService","desktopNotifications","getWantsNotifications","notificationApiAvailable","isNotificationApiAvailable","notificationPermission","getNotificationPermission","notificationPreview","getWantsPreview","notificationSound","getWantsSound","setWantsNotifications","setWantsPreview","setWantsSound","ConversationController","$stateParams","$filter","$state","$transitions","receiverService","mimeService","versionService","controllerModelService","showScrollJump","initialized","allMentions","currentMentions","currentMentionFilterWord","selectedMention","lastReadMsg","msgReadReportPending","hasMore","latestRefMsgId","initialData","draft","initialText","locked","isTyping","uploading","enabled","value1","value2","submit","contents","showError","success","nextCallback","index","showSendAsFileCheckbox","captionSupported","isImage","isAudio","clientInfo","os","isVideo","senderName","displayName","placeholder","confirmSendAsFile","locals","options","noop","quote","getQuote","setQuote","onTyping","setDraft","getSelectedMention","showMentionSelector","onComposeKeyDown","onUploading","inProgress","percentCurrent","percentFull","startTyping","sendMeIsTyping","stopTyping","maxTextLength","getMaxTextLength","allText","onStart","trans","injector","checkForUpdate","go","domChatElement","querySelector","addEventListener","updateScrollJump","opts","defineProperty","supportsPassive","passive","receivers","getData","_conversation","conversations","find","mode","controllerModel","me","contact","group","distributionList","canChat","setActive","latestHeight","messages","allMessages","wasInitialized","updateFirstUnreadMessage","scrollTop","scrollHeight","cm","identity","query","toLowerCase","isAll","getMembers","getDraft","initParams","getList","requestMessages","$watch","isEnabled","disabled","isQuoting","cancelQuoting","errorMessage","hideDelayMs","hideDelay","showMessage","msgTranslation","onMentionSelected","$broadcast","mention","toUpperCase","topOfChat","refMsgId","showReceiver","hasMoreMessages","msgRead","sortKey","isOutbox","unread","conversation","unreadCount","copy","requestRead","goBack","scrollDown","chat","offsetHeight","pinConversation","modifyConversation","unpinConversation","AboutDialogController","NavigationController","trustedKeyStoreService","activeTab","searchVisible","searchText","searchConversation","matches","latestMessage","searchContact","indexOf","values","hidden","haystack","needle","trim","isVisible","visible","isActive","isConversationActive","startupDone","hideInactiveContacts","appConfig","showInactiveIDs","showDialog","targetEvent","about","troubleshooting","settings","showProfile","isPersistent","hasTrustedKey","closeSession","confirm","stop","reason","connectionBuildupState","deleteSession","createGroup","createDistributionList","toggleSearch","getMe","showCreateDistributionListButton","appCapabilities","distributionLists","dndModeSimplified","getDndModeSimplified","MessengerController","controllerService","setControllerName","alerts","setReceiverListener","onConversationRemoved","current","params","showDetail","is","QrDialogController","profile","qrCode","errorCorrectionLevel","publicKey","ReceiverDetailController","fingerPrintService","contactService","fingerPrint","showGroups","showDistributionLists","inGroups","inDistributionLists","hasSystemEmails","hasSystemPhones","isWorkReceiver","showBlocked","requiredDetails","systemContact","emails","phoneNumbers","identityType","generate","setFingerPrint","bind","groups","groupReceiver","members","distributionListReceiver","isBlocked","meReceiver","setOnRemoved","receiverId","$digest","edit","canEdit","showQr","history","back","ReceiverEditController","$timeout","isValid","save","future","withMinDuration","showEditError","isSaving","subject","ReceiverCreateController","showAddError","create","$stateProvider","abstract","views","navigation","content","ChunkCache","sequenceNumber","_byteLength","cache","_sequenceNumber","chunk","transfer","count","append","increment","prune","theirSequenceNumber","validate","beginOffset","chunkCountBefore","reduce","sum","acknowledged","SequenceNumber","initialValue","minValue","maxValue","other","by","fakeConnectionId","WebClientService","messageService","pushService","titleService","qrCodeService","batteryStatusService","startupPromise","handoverDone","pendingInitializationStepRoutines","Set","saltyRtcHost","connectionInfoFuture","relayedDataTask","secureDataChannel","secureDataChannelCrypto","secureDataChannelChunkLength","secureDataChannelMessageId","chosenTask","previousConnectionId","currentConnectionId","previousIncomingChunkSequenceNumber","previousChunkCache","currentChunkCache","handshakeCompleted","ackTimer","pendingAckRequest","unchunker","pushSession","pushPromise","deviceUnreachableDialog","pushTimer","schedulePushAfterCooldown","batteryStatusTimeout","pcHelper","blobCache","Map","loadingMessages","receiverListener","msgpackEncoderOptions","codec","msgpack","binarraybuffer","msgpackDecoderOptions","wireMessageFutures","arpLog","arpLogV","msgpackLog","pushSessionConfig","MAX_CONNECT_ATTEMPTS","pushSessionExpectedPeriodMaxMs","drafts","createDrafts","_resetFields","evtConnectionBuildupStateChange","stateChange","notify","evtGlobalConnectionStateChange","handleGlobalConnectionStateChange","typingInstance","buildQrCodePayload","persistent","permanentKeyBytes","authTokenBytes","flags","keyStore","resumeSession","resume","peerTrustedKey","clearCache","clear","cancelAll","discardSession","resetMessageSequenceNumber","currentIncomingChunkSequenceNumber","SEQUENCE_NUMBER_MIN","SEQUENCE_NUMBER_MAX","outgoingChunkSequenceNumber","tasks","supportsWebrtcTask","saltyrtcTaskWebrtc","WebRTCTaskBuilder","withLoggingLevel","withVersion","withHandover","build","withMaxChunkLength","isFirefox","saltyrtcTaskRelayedData","RelayedDataTask","saltyrtcClient","KeyStore","publicKeyHex","builder","SaltyRTCBuilder","connectTo","withServerKey","withKeyStore","usingTasks","withPingInterval","withTrustedPeerKey","asInitiator","permanentKeyHex","authTokenHex","updateConnectionBuildupState","onTaskEstablished","updateSignalingConnectionState","onPeerDisconnected","onHandover","offeredWebrtc","offered","t","endsWith","failSession","showWebrtcAndroidWarning","onReady","htmlContent","firefoxLink","chromeLink","operaLink","edgeLink","showAlert","alertMessage","$$phase","failSessionOnReject","subType","logOnReject","maybeResumeSession","remoteInfo","remoteCurrentConnectionId","remotePreviousConnectionId","chunks","transferred","sendChunk","outgoingMessageSequenceNumber","chunkedDc","UnreliableUnorderedUnchunker","onMessage","handleIncomingMessageBytes","scheduleConnectionAck","timeout","_sendConnectionAck","schedulePush","timeoutMs","_requestConnectionAck","cancelPush","cooldownMs","clearTimeout","resetPushSession","task","getTask","getName","prefix","nacl","isArray","updateTaskConnectionState","incomingSequenceNumber","_sendConnectionInfo","sessionWasResumed","outgoingSequenceNumber","remoteResume","requiredInitializationSteps","_requestInitialData","runAfterInitializationSteps","_resetInitializationSteps","connectionIdBox","encryptForPeer","CONNECTION_ID_NONCE","DC_LABEL","createCryptoContext","DATA_CHANNEL_MAX_CHUNK_SIZE","onConnectionEstablished","add","box","Box","fromUint8Array","DataChannelCryptoContext","NONCE_LENGTH","decrypt","receiveChunk","peerId","taskConnectionState","showDeviceUnreachableDialog","showPushRejectedDialog","hideDeviceUnreachableDialog","escapeToClose","finally","skipPush","defer","connect","promise","remove","sendUpdateWireMessage","SUB_TYPE_CONNECTION_DISCONNECT","resetUnreadCount","disconnect","registerInitializationStep","routine","requiredSteps","every","requiredStep","apply","listener","connectionId","resumeId","SUB_TYPE_CONNECTION_INFO","sendRequestWireMessage","SUB_TYPE_CONNECTION_ACK","requestClientInfo","ARGUMENT_USER_AGENT","navigator","userAgent","ARGUMENT_BROWSER_NAME","ARGUMENT_BROWSER_VERSION","SUB_TYPE_CLIENT_INFO","requiresTemporaryIdBackwardsCompatibility","TYPE_REQUEST","requestReceivers","SUB_TYPE_RECEIVERS","requestConversations","SUB_TYPE_CONVERSATIONS","ARGUMENT_MAX_SIZE","AVATAR_LOW_MAX_SIZE","requestBatteryStatus","SUB_TYPE_BATTERY_STATUS","requestProfile","SUB_TYPE_PROFILE","isRequested","getReferenceMsgId","setRequested","ARGUMENT_RECEIVER_TYPE","ARGUMENT_RECEIVER_ID","msgId","ARGUMENT_REFERENCE_MSG_ID","SUB_TYPE_MESSAGES","requestAvatar","highResolution","resolution","receiverInfo","avatar","ARGUMENT_AVATAR_HIGH_RESOLUTION","SUB_TYPE_AVATAR","requestThumbnail","thumbnail","img","ARGUMENT_MESSAGE_ID","SUB_TYPE_THUMBNAIL","requestBlob","cached","SUB_TYPE_BLOB","newestMessage","SUB_TYPE_READ","requestContactDetail","ARGUMENT_IDENTITY","SUB_TYPE_CONTACT_DETAIL","baseReceiver","sendType","reflectedType","SUB_TYPE_TEXT_MESSAGE","fileData","MAX_FILE_SIZE_WEBRTC_TASK_V0","capabilities","maxFileSize","maxmb","requiredFeature","invalidFeatureMessage","SUB_TYPE_FILE_MESSAGE","unsupportedMembers","receiverName","createRandomWireMessageId","temporaryMessage","createTemporary","addNewer","sendPromise","sendCreateWireMessage","removeTemporary","temporaryId","source","ackMessage","ARGUMENT_MESSAGE_ACKNOWLEDGED","SUB_TYPE_ACK","deleteMessage","SUB_TYPE_MESSAGE","sendDeleteWireMessage","TYPE_DELETE","ARGUMENT_IS_TYPING","SUB_TYPE_TYPING","sendKeyPersisted","SUB_TYPE_KEY_PERSISTED","threemaId","SUB_TYPE_CONTACT","modifyContact","firstName","lastName","ARGUMENT_FIRST_NAME","ARGUMENT_LAST_NAME","ARGUMENT_AVATAR","isPinned","SUB_TYPE_CONVERSATION","ARGUMENT_MEMBERS","ARGUMENT_NAME","SUB_TYPE_GROUP","modifyGroup","leaveGroup","access","canLeave","ARGUMENT_DELETE_TYPE","DELETE_GROUP_TYPE_LEAVE","deleteGroup","canDelete","DELETE_GROUP_TYPE_DELETE","syncGroup","canSync","SUB_TYPE_GROUP_SYNC","SUB_TYPE_DISTRIBUTION_LIST","modifyDistributionList","deleteDistributionList","cleanReceiverConversation","SUB_TYPE_CLEAN_RECEIVER_CONVERSATION","modifyProfile","nickname","ARGUMENT_NICKNAME","typing","removeQuote","quoteText","getQuoteText","partnerId","removeText","setText","getText","createReceivers","createConversations","createMessages","createTyping","setConverter","Converter","addReceiverToConversation","setFilter","Filters","hasData","_receiveResponseConfirmAction","popWireMessageFuture","ack","_receiveResponseReceivers","sortContacts","_receiveResponseContactDetail","SUB_TYPE_RECEIVER","ARGUMENT_SYSTEM_CONTACT","_receiveUpdateAlert","_receiveRequestConnectionAck","_receiveUpdateConnectionAck","_receiveUpdateConnectionDisconnect","isWelcome","_receiveConnectionInfo","_receiveReplyReceiver","extendContact","isGroupReceiver","isDistributionListReceiver","extendDistributionList","extendGroup","_receiveCreateContact","_receiveCreateGroup","_receiveCreateDistributionList","_receiveCreateMessage","wireMessage","messageId","bindTemporaryToMessageId","isSentOrSendingFailed","sentId","_receiveResponseConversations","low","updateUnreadCount","_receiveResponseMessages","more","ARGUMENT_HAS_MORE","logChatMessages","addOlder","clearRequested","setMore","_receiveResponseAvatar","field","receiverData","_receiveResponseThumbnail","setThumbnail","_receiveResponseBlob","blobInfo","DATA_FIELD_BLOB_BLOB","mimetype","DATA_FIELD_BLOB_TYPE","filename","DATA_FIELD_BLOB_NAME","_receiveUpdateConfirm","_receiveUpdateMessages","ARGUMENT_MODE","sentFuture","ARGUMENT_MODE_NEW","update","unsetTyping","ARGUMENT_MODE_MODIFIED","addStatusMessage","ARGUMENT_MODE_REMOVED","_receiveUpdateReceiver","updatedReceiver","extend","clearReceiverMessages","_receiveUpdateReceivers","setContacts","setGroups","setDistributionLists","_receiveUpdateTyping","setTyping","_receiveUpdateConversation","oldConversation","updateOrAdd","onNewMessage","unreadCountIncreased","unreadCountDecreased","hideNotification","_receiveUpdateAvatar","high","_receiveUpdateBatteryStatus","setStatus","_receiveUpdateContact","_receiveUpdateGroup","_receiveUpdateDistributionList","_receiveUpdateProfile","publicNickname","_receiveResponseClientInfo","getOrDefault","defaultVal","device","osVersion","isWork","configuration","voipEnabled","voipForceTurn","largeSingleEmoji","maxGroupSize","maxMessageBodySize","imageFormat","mdm","changeTheme","_receiveResponseProfile","setMe","verificationLevel","canChangeAvatar","canChangeFirstName","canChangeLastName","color","setPassword","password","_maybeTrustKeys","getMaxGroupMemberSize","shouldNotify","dnd","mentionOnly","textToSearch","quotedMe","forMe","forAll","sender","hasFocus","compare","getActive","simplifiedNotification","getAppNotificationSettings","partner","partnerName","messageCount","titlePrefix","messageType","captionString","messageTypeString","file","translationKey","voip","tag","showNotification","sound","muted","storeTrustedKey","publicKeyBytes","secretKeyBytes","peerPermanentKeyBytes","updatePushToken","tokenType","retransmit","sendWireMessage","TYPE_UPDATE","TYPE_CREATE","ARGUMENT_TEMPORARY_ID","optional","ARGUMENT_SUCCESS","ARGUMENT_ERROR","validateWireMessageAcknowledgement","_receiveRequest","_receiveResponse","SUB_TYPE_CONFIRM_ACTION","_receiveUpdate","SUB_TYPE_CONFIRM","SUB_TYPE_ALERT","_receiveCreate","msgpackEncode","msgpackDecode","encrypt","chunker","UnreliableUnorderedChunker","toUint8Array","canQueue","messageSequenceNumber","RELAYED_DATA_CHUNK_SIZE","CHUNK_CACHE_SIZE_MAX","shouldQueue","chunkCache","handleIncomingMessage","copyDeepOrReference","messageHandler","TYPE_RESPONSE","console","trace","totalUnreadCount","a","b","getSortableName","startsWith","supportsExtendedLocaleCompare","usage","sensitivity","sort","right","localeCompare","clearIsTypingFlags","clearAll","isOk","wasOk","prevState","dataAvailable","clearStatus","base64String","atob","char","isStatus","date","StatusController","expandStatusBar","expandStatusBarTimer","expandStatusBarTimeout","onStateChange","evtUnreadCountChange","classes","newValue","oldValue","isWebrtc","isRelayedData","collapseStatusBar","scheduleStatusBar","reconnectIos","reconnectAndroid","originalKeyStore","originalPeerPermanentKeyBytes","pause","pendingWireMessages","unacknowledgedWireMessages","reconnectTimeout","wide","getControllerName","ThemeController","restrict","scope","bindToController","elem","attrs","ctrl","newReceiver","oldReceiver","loadingPromise","avatarUri","avatarToUri","res","initial","isLoading","backgroundColor","$onInit","avatarClass","avatarExists","getDefaultAvatarUri","getAvatarUri","inView","loadingTimeout","isWorkApp","showWorkIndicator","showHomeIndicator","isEchoContact","onChange","loadAvatar","enableClear","avatarFormat","setAvatar","avatarBytes","imageChanged","image","modify","changeAvatar","newImage","editorArea","fileTrigger","fileInput","croppieInstance","loading","addClass","removeClass","updateTimeout","uploadFiles","fileList","reader","FileReader","onload","onprogress","lengthComputable","readAsArrayBuffer","imageBase64Url","croppie","croppieTarget","Croppie","viewport","width","height","customClass","showZoomer","circle","format","fileReader","initCroppie","Image","w","naturalWidth","h","naturalHeight","imageSize","points","src","setImage","onDragleave","stopPropagation","preventDefault","dataTransfer","files","click","uriService","validateThreemaId","test","viewReceiver","addAction","composeAction","getThreemaActionHandler","el","childNodes","node","nodeType","Node","ELEMENT_NODE","tagName","innerText","parseQueryParams","mentionCssClass","cls","getAttribute","setAttribute","stringService","onInit","onKeyDown","wrapper","selector","composeDiv","emojiTrigger","emojiKeyboard","sendTrigger","composeArea","ComposeArea","bind_to","chatBlocked","setChatBlocked","blocked","attr","hasClass","hideEmojiPicker","composeAreaIsEmpty","_scope","wasBlocked","stopTypingTimer","get_text","sendText","submitTexts","strings","piece","chunkSize","pieces","byteChunk","max","submitText","updateView","isComposing","compositionHasJustEnded","buffers","fileCounter","next","n","loaded","total","fetchFileListContents","fileMessages","fileMessageData","regularPlaceholder","dragoverPlaceholder","emojiPicker","allEmoji","querySelectorAll","allEmojiTabs","onEmojiChosen","onEmojiTabSelected","onEmojiTrigger","skinSelectors","onSkintoneSelected","insertSingleEmojiString","target","tone","parentElement","previousElementSibling","checked","insertEmoji","insert_image","draggable","ondragstart","onFileTrigger","onSendTrigger","translated","shiftKey","trigger","alreadyProcessed","word","get_word_at_caret","before","after","trimmed","unicodeEmoji","select_word_at_caret","store_selection_range","onEmojiShortcodeKeyPressed","clipboardData","items","fileIdx","textIdx","blob","getAsFile","progressEvent","fileName","insert_text","unsubscribeListeners","$on","u","linked","onRemove","newIdentity","oldIdentity","updateReceiverData","showActions","overlay","dragElement","onDragLeave","showRoleIcon","administrator","roleIcon","roleName","getSenderIdentity","myId","isGroup","isDistributionList","showVoipInfo","getStatusIcon","showStatusIcon","getContact","isHidden","showIcon","showDraft","$document","mediaboxService","imageDataUrl","currentTarget","saveAs","evtMediaChanged","$element","requiredMemberFeatureMask","selectedItemChange","selectedItem","querySearch","lowercaseQuery","allContacts","onRemoveMember","browserInfo","isStatusMessage","isContactMessage","isContact","isBusinessReceiver","isBusinessContact","showName","showAvatar","showText","showMedia","showState","showQuote","getAccess","toast","download","downloading","isDownloading","showHistory","getEvents","events","getMessageId","domElement","newId","oldId","msgType","icon","altText","showDownloading","clearMedia","thumbnailDownloading","downloaded","isGif","hasPreviewThumbnail","getThumbnailPreviewUri","getThumbnailPreviewUriStyle","previewUri","thumbnailStyle","loadingThumbnailTimeout","wasInView","thumbnailInView","openMapLink","open","playAudio","audioSrc","showAudioDialog","setMedia","blobBufferUrl","showThumbnail","contentString","transclude","duration","audio","video","multiLine","linkify","updateText","newCaption","oldCaption","escapeHtml","markify","mentionify","nlToBr","processText","linkifyText","nonLinkified","enlarge","enlargeSingleEmoji","maybeLinkified","level","directive","avatarArea","avatarEditor","available","isLow","isCharging","percent","clickAction","dragFile","contactBadge","groupBadge","colored","messageIcon","messageMedia","messageMeta","messageText","incoming","colorClass","msgString","require","replaceWith","children","mediabox","memberListEditor","currentValue","previousValue","input","triggerHandler","active","logout","markupChars","cssClasses","isBoundary","character","stack","tokensPresent","hasToken","consumeStack","textBuf","kind","splice","popStack","stackTop","pop","pushMarkup","textParts","cssClass","html","markupChar","hasOwnProperty","parse","matchingUrl","pushTextBufToken","currentChar","prevIsBoundary","nextIsBoundary","tokenize","m","autolinker","Autolinker","newWindow","stripPrefix","stripTrailingSlash","truncate","className","email","phone","hashtag","escapeHtmlFilter","possibleMention","mentionName","list","reverse","seconds","lat","lon","pow","toFixed","getIconUrl","ids","names","formatTime","getHours","getMinutes","isSameDay","date1","date2","getFullYear","getMonth","getDate","timestamp","forceFull","Date","now","yesterday","getTime","year","num","formatMonth","$sce","trustAsResourceUrl","strength","WelcomeController","minVersions","passwordStrength","score","formLocked","pleaseUpdateAppMsg","browserWarningShown","wasDetermined","CHROME","showBrowserWarning","FF","OPERA","SAFARI","EDGE","showLocalStorageWarning","initVersion","archiveUrl","showLocalStorageException","unlock","scan","slowConnect","stopArguments","payload","buildQrCode","letterCount","categories","digits","lower","upper","nonWords","trunc","scorePassword","setupBroadcastChannel","unlockConfirm","decrypted","retrieveTrustedKey","showDecryptionFailed","ownSecretKey","BROADCAST_DELAY","reconnect","delayMs","BroadcastChannel","postMessage","peerPublicKey","safariLink","errorMsg","showAlreadyConnected","clearPassword","len","REDIRECT_DELAY","BatteryStatusService","batteryStatus","alertedLow","alertedCritical","PERCENT_CRITICAL","notifyLevel","PERCENT_LOW","BrowserInfo","mobile","separator","requireVersion","BrowserService","chrome","chromeIos","firefox","firefoxIos","ie","edge","opera","safari","uagent","versionString","versionInt","isNaN","supportsExtendedLocaleCompareCache","getSupport","ContactService","AvatarControllerModel","_avatarChanged","onChangeAvatar","getAvatar","ContactControllerModel","getMode","avatarController","firstNameLabel","onRemovedCallback","canClean","clean","reallyClean","canShowQr","avatarChanged","DistributionListControllerModel","addContactPlaceholder","reallyDelete","onChangeMembers","identities","GroupControllerModel","getMaxMemberSize","canChangeName","canChangeMembers","leave","reallyLeave","sync","MeControllerModel","readonlyProfile","ControllerModelService","TrustedKeyStoreService","STORAGE_KEY","storage","localStorage","stringToBytes","arr","pwToKey","keyLength","ownPublicKey","nonce","nonceLength","pushTokenString","encrypted","setItem","getItem","storedValue","tokenBytes","tokenString","pos","c1","c2","c3","utf8aToString","removeItem","LOG_TYPES","ALLOWED_TYPES","Boolean","TeeLogger","loggers","forward","LevelLogger","logger","TagLogger","UnveilLogger","unveil","ConsoleLogger","MemoryLogger","limit","records","allowedType","LogService","root","setupUncaughtExceptionHandling","styledTag","padStart","MessageAccess","dec","MessageService","timeoutDelaySeconds","messageState","getPreviewThumbnail","uri","MAX_THUMBNAIL_SIZE","scale","round","textData","inApp","MimeService","imageMimeTypes","audioMimeTypesAndroid","audioMimeTypesIos","videoMimeTypes","getKey","possibleTypes","NotificationService","notificationAPIAvailable","notificationCache","checkNotificationAPI","fetchSettings","requestNotificationPermission","Notification","requestPermission","storeSetting","SETTINGS_NOTIFICATIONS","permission","notifications","retrieveSetting","SETTINGS_NOTIFICATION_PREVIEW","SETTINGS_NOTIFICATION_SOUND","wantsNotifications","wantsPreview","wantsSound","storeUntrustedKeyValuePair","retrieveUntrustedKeyValuePair","simpleSound","simpleDnd","until","simplified","clickCallback","forceShowBody","overwriteOlder","forceMute","Audio","NOTIFICATION_SOUND","play","notification","onclick","QrCodeService","protocolVersion","initiatorKey","authToken","serverKey","host","port","saltyRtcHostBytes","dataView","DataView","setUint16","setUint8","u8Array","SettingsService","STORAGE_KEY_PREFIX","alwaysCreate","hasUntrustedKeyValuePair","removeUntrustedKeyValuePair","StateService","$interval","AsyncEvent","progressInterval","_unreadCount","_state","post","signalingConnectionState","stage","ThemeService","_theme","TimeoutService","timeouts","fn","delay","invokeApply","cancelled","TitleService","DEFAULT_TITLE","VersionService","$http","dialogShowing","fetchVersion","cacheBust","responseType","transformResponse","headersGetter","successResponse","notifyNewVersion","changelogLink","changelog","isFirstUnreadStatusMessage","statusType","setDefault","defaultValue","sha256PublicKey","activeReceiver","currentController","StringService","objStr","decodeURI","StringHashSet","setObj","contains","Receivers","g","d","extendMe","Conversations","converter","returnOld","previousConversation","tmp","ReceiverMessages","referenceMsgId","requested","Messages","lazyCreate","typeMap","getReceiverMessages","messageMap","cachedMessageCount","typeMessages","receiverMessages","firstId","lastId","findIndex","unshift","thumbnailImage","temporaryMessageId","firstUnreadMessageIndex","Typing","getReceiverUid","Drafts","quotes","texts","draftMessage","factory","setScheduler","constant","$urlRouterProvider","otherwise","$translateProvider","useSanitizeValueStrategy","useMessageFormatInterpolation","useStaticFilesLoader","suffix","uniformLanguageTag","registerAvailableLanguageKeys","determinePreferredLanguage","fallbackLanguage","$mdThemingProvider","definePalette","50","100","200","300","400","500","600","700","800","900","A100","A200","A400","A700","contrastDefaultColor","contrastDarkColors","primaryPalette","default","accentPalette","alwaysWatchTheme","$compileProvider","$httpProvider","interceptors","CACHE_BUST","request","conf","cause","offset","currentChunkSize","chunkIndex","offsetChars","lastSeparator","charString","Buffer","appendNewChunk"],"mappings":"0GAAAA,QAAQC,OAAO,kBAAmB,IAElCD,QAAQC,OAAO,mBAAmBC,UAAU,eCF7B,CACXC,SAAU,CACNC,KAAM,IACNC,SAAU,IACVC,UAAW,IACXC,aAAc,IACdC,cAAe,IACfC,YAAa,IACbC,aAAc,KAElBC,WAAY,WACRC,KAAKC,SAAW,IAAMD,KAAKR,KAAOQ,KAAKL,aAAeK,KAAKJ,cAC3DI,KAAKE,QAAU,IAAMF,KAAKR,KAAOQ,KAAKH,YAAcG,KAAKF,aACzDE,KAAKG,OAAS,IAAMH,KAAKR,KAAOQ,KAAKN,YAAcM,KAAKP,YAE5DW,SAAU,sYCfC,OACXC,QAAS,cACTC,aAAa,EACbC,iBAAkB,SAClBC,qBAAsB,uCACtBC,2BAA4B,4FAC5BC,iCAAkC,sBAClCC,wBAAyB,KACzBC,2BAA4B,QAC5BC,WAAY,SACZC,cAAe,+BACfC,cAAe,IACfC,oBAAqB,mEACrBC,YAAa,CAAC,CACNC,KAAM,CACF,qDACA,qDACA,yCAEJC,SAAU,kBACVC,WAAY,qEAEpBC,SAAU,mCACVC,aAAc,KACdC,gBAAiB,GACjBC,kBAAmB,QACnBC,iBAAkB,QAClBC,iBAAkB,IAClBC,uBAAwB,OACxBC,mBAAoB,OACpBC,gBAAiB,OACjBC,cAAe,QACfC,eAAe,EACfC,mBAAmB,EACnBC,oBAAqB,OACrBC,iBAAiB,GCnCd,SAASC,EAASC,GACrB,MAAMC,EAAU,GAIhB,OAHAD,EAAME,QAASC,IACXF,EAAQG,KAAKD,EAAUE,SAAS,IAAIC,QAAQ,cAAe,UAExDL,EAAQM,KAAK,IAEjB,SAASC,EAASC,GACrB,IAAIT,EACAU,EAEAC,EACAC,EAFAC,EAAI,EAOR,IAJIJ,EAAUK,OAAS,GAAM,IACzBL,EAAY,IAAMA,GAEtBT,EAAQ,IAAIe,WAAWN,EAAUK,OAAS,GACrCJ,EAAIC,EAAI,EAAGC,EAAMH,EAAUK,OAAQH,GAAKC,EAAKF,EAAIC,GAAK,EACvDX,EAAMa,KAAOG,SAASP,EAAUQ,OAAOP,EAAG,GAAI,IAElD,OAAOV,EAEJ,SAASkB,EAAYlB,GACxB,OAAOmB,KAAKC,MAAMC,KAAKrB,EAAQsB,GAASC,OAAOC,aAAaF,IAAOf,KAAK,KAKrE,SAASkB,EAAaX,EAAS,GAAIY,EAAQ,kEAC9C,IAAIC,EAAM,GACV,IAAK,IAAIjB,EAAI,EAAGA,EAAII,EAAQJ,IACxBiB,GAAOD,EAAME,OAAOC,KAAKC,MAAMD,KAAKE,SAAWL,EAAMZ,SAEzD,OAAOa,EAEJ,SAASK,EAAcL,GAE1B,IADA,IAAIM,EAAM,GAAIC,EAAI,EACTxB,EAAI,EAAGA,EAAIiB,EAAIb,OAAQJ,IAAK,CACjC,IAAIyB,EAAIR,EAAIS,WAAW1B,GACnByB,EAAI,IACJF,EAAIC,KAAOC,EAENA,EAAI,MACTF,EAAIC,KAAQC,GAAK,EAAK,IACtBF,EAAIC,KAAY,GAAJC,EAAU,KAEA,QAAX,MAAJA,IAA2BzB,EAAI,EAAKiB,EAAIb,QACV,QAAX,MAAxBa,EAAIS,WAAW1B,EAAI,KACrByB,EAAI,QAAgB,KAAJA,IAAe,KAA6B,KAAtBR,EAAIS,aAAa1B,IACvDuB,EAAIC,KAAQC,GAAK,GAAM,IACvBF,EAAIC,KAASC,GAAK,GAAM,GAAM,IAC9BF,EAAIC,KAASC,GAAK,EAAK,GAAM,IAC7BF,EAAIC,KAAY,GAAJC,EAAU,MAGtBF,EAAIC,KAAQC,GAAK,GAAM,IACvBF,EAAIC,KAASC,GAAK,EAAK,GAAM,IAC7BF,EAAIC,KAAY,GAAJC,EAAU,KAG9B,OAAOpB,WAAWM,KAAKY,GA6BpB,SAASI,EAAOC,EAAKC,GACxB,GAAID,aAAelB,MACf,OAAOkB,EAAID,OAAOE,GAEjB,CACD,MAAMN,EAAM,GACZ,IAAK,MAAMO,KAAOC,OAAOC,KAAKJ,GAAM,CAChC,MAAMK,EAAQL,EAAIE,GACdD,EAASI,KACTV,EAAIO,GAAOG,GAGnB,OAAOV,GAoBR,SAASW,EAAkB5C,GAC9B,MAAO,mCAAqC6C,mBAAmB3B,EAAYlB,IAExE,SAAS8C,EAAWC,EAAiBC,EAASC,GACjD,YAAwBC,IAApBH,EACoC,IAAhCA,EAAgBI,aAChBF,EAAIG,KAAJ,mCAAqCL,EAAgBM,GAArD,wBACO,GAEK,IAAZL,GAG+C,IAA3CD,EAAgBI,YAAcH,IAE1CC,EAAIG,KAAK,8DACF,GAEJ,SAASE,EAAYC,EAAQC,EAAUP,GAC1C,OAAQO,GACJ,IAAK,YACL,IAAK,aACL,IAAK,YACL,IAAK,aACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,aACD,MACJ,QACI,MAAMC,EAAmB,aACzBR,EAAIG,KAAJ,4BAA8BI,EAA9B,+BAA6DC,EAA7D,MACAD,EAAWC,EAGnB,MAAO,QAAUD,EAAW,WAAatC,EAAY,IAAIH,WAAWwC,IAQjE,SAASG,EAASC,GACrB,OAAOA,QAEJ,SAASC,EAAMC,GAClB,OAAO,IAAIC,QAASC,GAAYC,WAAWD,EAASF,IAEjD,SAASI,EAAeC,EAAIC,GAC/B,GAAID,EAAGpD,SAAWqD,EAAGrD,OACjB,OAAO,EAEX,IAAK,IAAIJ,EAAI,EAAGA,EAAIwD,EAAGpD,OAAQJ,IAC3B,GAAIwD,EAAGxD,KAAOyD,EAAGzD,GACb,OAAO,EAGf,OAAO,EAEJ,SAAS0D,EAAgBC,GAC5B,QAAenB,IAAXmB,EAAG7B,IACH,OAAO,EAEX,OAAQ6B,EAAG7B,KACP,IAAK,QACL,IAAK,IACD,OAAO,EACX,QACI,OAAO,GAGZ,SAAS8B,EAAYC,GACxB,OAAO9B,OAAO+B,OAAO,GAAID,GClMtB,MAAME,EACTC,YAAYC,EAAQC,EAAWC,EAAcC,GACzClH,KAAKgH,UAAYA,EACjBhH,KAAKkH,mBAAkC5B,IAAlB4B,EAA8BA,EAAgBC,SAASD,cAC5ElH,KAAKoH,MAAQH,EAAaG,MAC1BH,EAAaI,eAAeC,OAAQC,GAAaR,EAAOS,OAAO,IAAMxH,KAAKoH,MAAQG,IAEtFE,SACIzH,KAAKgH,UAAUS,SACfzH,KAAK0H,eAETC,KAAKC,GACD5H,KAAKgH,UAAUW,KAAKC,GACpB5H,KAAK0H,eAETA,eAC+B,OAAvB1H,KAAKkH,eACLlH,KAAKkH,cAAcW,SCjBxB,SAASC,EAAWC,EAAMC,GAAoB,GACjD,MAAMd,EAAgBC,SAASD,cACzBe,EAAWd,SAASe,cAAc,YACxCD,EAASlD,MAAQgD,EACjBE,EAASE,MAAMC,SAAW,WAC1BH,EAASE,MAAME,KAAO,UACtBJ,EAASE,MAAMG,IAAM,UACrBnB,SAASoB,KAAKC,YAAYP,GAC1B,IACI,GAAID,EAAmB,CACnBC,EAASQ,gBAAkB,OAC3BR,EAASS,UAAW,EACpB,MAAMC,EAAQxB,SAASyB,cACjBC,EAAYC,KAAKC,eACvBF,EAAUG,kBACVH,EAAUI,SAASN,GACnBV,EAASiB,kBAAkB,EAAG,aAG9BjB,EAASJ,QACTI,EAASkB,SAEb,IAAKhC,SAASiC,YAAY,QACtB,MAAM,IAAIC,MAAM,iCAfxB,QAmBIlC,SAASoB,KAAKe,YAAYrB,GACJ,OAAlBf,GACAA,EAAcW,SDR1BhB,EAAiB0C,QAAU,CAAC,SAAU,YAAa,gBElB5C,MAAMC,UAAkC3C,EAC3CC,YAAYC,EAAQC,EAAWyC,EAAUC,EAAYC,EAAQC,EAAYC,EAAgB5C,EAAc6C,GACnGC,MAAMhD,EAAQC,EAAWC,GACzBjH,KAAKgK,UAAW,EAChBhK,KAAKiK,WAAY,EACjBjK,KAAKkK,eAAgB,EACrBlK,KAAKmK,YAAc,GACnBnK,KAAK+G,OAASA,EACd/G,KAAKyJ,SAAWA,EAChBzJ,KAAK0J,WAAaA,EAClB1J,KAAK2J,OAASA,EACd3J,KAAK4J,WAAaA,EAClB5J,KAAK6J,eAAiBA,EACtB7J,KAAK8J,iBAAmBA,EACxB9J,KAAKqF,IAAMuE,EAAWQ,UAAU,qBAEpC,kBACI,OAAOpK,KAAK8J,iBAAiBO,cAEjC,cACI,OAAOrK,KAAKsK,aAAetK,KAAKmK,YAAYjH,OAAS,IAAMlD,KAAKiK,UAEpE,aACIjK,KAAKiK,WAAY,EACjBjK,KAAKkK,eAAgB,EACrB,MAAM7E,GAAM,IAAIkF,aAAcC,OAAOxK,KAAKyK,OAAOzK,KAAKgK,WAChDU,EAAO,KACT1K,KAAK+G,OAAOS,OAAO,KACfxH,KAAKiK,WAAY,EACjBjK,KAAKkK,eAAgB,EACrBlK,KAAKyJ,SAASkB,KAAK3K,KAAKyJ,SAASmB,SAC5BC,YAAY7K,KAAK0J,WAAWoB,QAAQ,8CACpC1C,SAAS,qBAGhB2C,EAAU,CACZtF,GAAI,WACJuF,KAAM,WAEV,IAAKhL,KAAK8J,iBAAiBmB,SAASC,IAAIH,EAAQtF,IAC5C,UACUzF,KAAK8J,iBAAiBqB,WAAWJ,EAAQtF,IAEnD,MAAO2F,GAEH,OADApL,KAAKqF,IAAI+F,MAAM,kCAAmCA,GAC3CV,IAGf,IAAK,IAAI5H,EAAI,EAAGA,EAAI,KAAMA,EAAG,CAEzB,GAAIoC,EADYlF,KAAK8J,iBAAiBmB,SAASI,IAAIN,EAAQtF,IACnC,EAAGzF,KAAKqF,KAC5B,YAEEW,EAAM,KAEhB,MAAMsF,EAAUtL,KAAK6J,eAAe0B,aAC9BC,EAAU,CACZC,KAAM,aAAF,OAAezL,KAAK2J,OAAOtJ,QAA3B,YAAsCiL,EAAQnB,YAAY,KAA1D,QACJuB,SAAU,aACVC,KAAMtG,EAAIuG,WACVhE,MH+FkBxF,EG/FEiD,EHgGH,IAArBjD,EAAMyJ,YAAoBzJ,EAAMwJ,aAAexJ,EAAMuD,OAAOiG,WACrDxJ,EAAMuD,OAEVvD,EAAMuD,OAAOmG,MAAM1J,EAAMyJ,WAAYzJ,EAAMyJ,WAAazJ,EAAMwJ,aGlG7DG,QAAS/L,KAAKmK,YACd6B,YAAY,GH6FjB,IAAuB5J,EG3FtB,UACUpC,KAAK8J,iBAAiBmC,YAAYlB,EAAS,OAAQS,EAAS,CAAEU,uBAAuB,IAE/F,MAAOd,GAEH,OADApL,KAAKqF,IAAI+F,MAAM,yCAA0CA,GAClDV,IAEX1K,KAAKiK,WAAY,EACjBjK,KAAKyJ,SAASkB,KAAK3K,KAAKyJ,SAASmB,SAC5BC,YAAY7K,KAAK0J,WAAWoB,QAAQ,+CACpC1C,SAAS,kBACdpI,KAAK2H,OAETwE,kBACI,MAAM9G,EAAMrF,KAAKyK,OAAOzK,KAAKgK,UAC7B,IAAIoC,EAAc,mBAClB,IACIC,EAAqBhH,EAAKrF,KAAK6J,eAAe0B,aAAae,YAE/D,MAAOlB,GACHpL,KAAKqF,IAAIG,KAAK,oCAAqC4F,GACnDgB,EAAc,uBAElBpM,KAAKyJ,SAASkB,KAAK3K,KAAKyJ,SAASmB,SAC5BC,YAAY7K,KAAK0J,WAAWoB,QAAQsB,IACpChE,SAAS,kBAElBqC,OAAOT,GACH,MAAMsB,EAAUtL,KAAK6J,eAAe0B,aAC9B5B,EAASjD,EAAY1G,KAAK2J,QAC5BK,IACAL,EAAO1I,YAAc0I,EAAO1I,YAAYsL,IAAKC,IACzCA,EAAS9F,EAAY8F,GACrB,IAAK,MAAM5H,IAAO,CAAC,WAAY,aAAc,uBACrBU,IAAhBkH,EAAO5H,KACP4H,EAAO5H,GAAP,WAAkB4H,EAAO5H,GAAKkC,YAAY2E,KAA1C,MAGR,OAAOe,KAGf,MAAMC,EAAY,CACd9C,OAAQA,EACR2B,QAASA,EAAQnB,cACjB9E,IAAKrF,KAAK4J,WAAW8C,OAAOC,cAE1BC,EAAW5M,KAAK4J,WAAW8C,OAAOG,YAAY7C,GACpD,OAAO8C,KAAKC,UAAUN,EAAWG,EAAU,IAGnDpD,EAA0BD,QAAU,CAChC,SAAU,YAAa,WAAY,aACnC,SAAU,aAAc,iBAAkB,eAAgB,oBCpH9D,MAAMyD,UAAgCnG,EAClCC,YAAYC,EAAQC,EAAWC,EAAc0C,GACzCI,MAAMhD,EAAQC,EAAWC,GACzBjH,KAAKiN,QAAUtD,EAAOtJ,QACtBL,KAAKkN,YAAL,UAAsBvD,EAAOtJ,QAA7B,YAAwCsJ,EAAOpJ,kBAC/CP,KAAK2J,OAASA,GAGtBqD,EAAwBzD,QAAU,CAAC,SAAU,YAAa,eAAgB,UACnE,MAAM4D,EACTrG,YAAYsG,EAAQpG,GAChBhH,KAAKgH,UAAYA,EACjBhH,KAAK2J,OAASyD,EAElBC,gBAAgB5G,SACDnB,IAAPmB,GAAqBD,EAAgBC,KAGzCzG,KAAKgH,UAAU2D,KAAK,CAChB5K,WAAYiN,EACZM,aAAc,OACdC,YAAa,+BACbC,OAAQpO,QAAQqO,QAAQtG,SAASoB,MACjCmF,qBAAqB,EACrBC,YAAY,IAGpBC,oBAAoBnH,SACLnB,IAAPmB,GAAqBD,EAAgBC,KAGzCzG,KAAKgH,UAAU2D,KAAK,CAChB5K,WAAYyJ,EACZ8D,aAAc,OACdC,YAAa,uCACbC,OAAQpO,QAAQqO,QAAQtG,SAASoB,MACjCmF,qBAAqB,EACrBC,YAAY,IAGpB,mBACI,MAAO,kDAAoD3N,KAAK2J,OAAO9I,WAAa,iBAG5FsM,EAAiB5D,QAAU,CAAC,SAAU,aC/C/B,MAAMsE,EACT/G,YAAY6C,GACR3J,KAAK2J,OAASA,EAElBmE,iBACI,OAAQ9N,KAAK2J,OAAOrJ,aAA4C,OAA7BN,KAAK2J,OAAOrI,aAEnDyM,UACI,OAAiC,OAA7B/N,KAAK2J,OAAOrI,aACL,mDAGAtB,KAAK2J,OAAOrI,cAI/BuM,EAAiBtE,QAAU,CAAC,U,oBChBrB,SAASyE,EAAkBC,GAC9B,MAAyB,YAAlBA,EAASjD,KAQb,SAASkD,EAAoBC,GAChC,OAAQA,GACJ,IAAK,KACL,IAAK,UACL,IAAK,QACL,IAAK,mBACD,OAAO,EAEf,OAAO,EAkBJ,SAASC,EAAYrI,GACxB,MAAsB,iBAARA,QACaT,IAApBS,EAAIsI,kBACY/I,IAAhBS,EAAIuI,cACchJ,IAAlBS,EAAIwI,UAKR,SAASC,EAAgB/H,GAC5B,MAAmB,YAAZA,EAAGuE,MAAkC,aAAZvE,EAAGuE,MAAmC,UAAZvE,EAAGuE,K,YC5C1D,SAASyD,EAAO1J,GACnB,GAAIA,QACA,OAAOA,EAEX,GAAIA,aAAiB2J,EACjB,OAAO3J,EAAM4J,WAEjB,GAAI5J,EAAM+B,cAAgBnD,OACtB,gCAA0BoB,EAAM7B,OAAhC,KAEJ,GAAI6B,aAAiBvB,MACjB,OAAOuB,EAAMwH,IAAKqC,GAASH,EAAOG,IAEtC,GAAI7J,aAAiB8J,YACjB,qCAA+B9J,EAAM6G,WAArC,KAEJ,GAAI7G,aAAiB5B,WACjB,oCAA8B4B,EAAM6G,WAApC,oBAA0D7G,EAAM8G,WAAhE,KAEJ,GAAI9G,aAAiB+J,KACjB,8BAAwB/J,EAAM4G,KAA9B,kBAA4C5G,EAAMiG,KAAlD,KAEJ,GAAIjG,EAAM+B,cAAgBjC,OAAQ,CAC9B,MAAM8B,EAAS,GACf,IAAK,MAAO5D,EAAGgM,KAAMlK,OAAOmK,QAAQjK,GAChC4B,EAAO5D,GAAK0L,EAAOM,GAEvB,OAAOpI,EAEX,iBAAW5B,EAAM+B,YAAY2E,KAA7B,KAEG,MAAMiD,GAEN,MAAMO,UAA0BP,EACnC5H,YAAY1E,GACR2H,QACA/J,KAAKoC,MAAQA,EAEjB,iBACI,OAAOpC,KAAKoC,MAAMmK,IAAKqC,GAASA,EAAKM,YAEzCP,WACI,OAAO3O,KAAKoC,MAAMmK,IAAKqC,GAASA,EAAKD,aAGtC,MAAMQ,UAAiCT,EAC1C5H,YAAYH,GACRoD,QACA/J,KAAKkP,WAAavI,EAEtBgI,WACI,OAAOF,EAAOzO,KAAKkP,aAGpB,MAAME,UAAgCV,EACzC5H,YAAY0E,GACRzB,QACA/J,KAAKkP,WAAa1D,EAEtBmD,WACI,MAAMnD,EAAU3G,OAAO+B,OAAO,GAAI5G,KAAKkP,YAOvC,YANqB5J,IAAjBkG,EAAQ6D,OACR7D,EAAQ6D,KAAOZ,EAAOjD,EAAQ6D,YAEb/J,IAAjBkG,EAAQ5D,OACR4D,EAAQ5D,KAAO6G,EAAOjD,EAAQ5D,OAE3B4D,GAGR,MAAM8D,UAAiCZ,EAC1C5H,YAAYyI,GACRxF,QACA/J,KAAKkP,WAAaK,EAEtBZ,WACI,IACI,MAAMa,EAAYC,iBAAwBzP,KAAKkP,YAO/C,MANuB,UAAnBM,EAAUxE,OACVwE,EAAUE,QAAUF,EAAUG,GAAKL,EAAyBM,SAASJ,EAAUE,eAElDpK,IAA7BkK,EAAUK,iBACVL,EAAUK,eAAiBP,EAAyBM,SAASJ,EAAUK,iBAEpEJ,iBAAwBD,GAEnC,MAAOpE,GACH,OAAOpL,KAAKkP,YAGpB,gBAAgBS,GACZ,GAAIA,EAAGG,SAAS,KACZ,OAAOH,EAEX,MAAMI,EAAOJ,EAAGK,MAAM,KACtB,GAAID,EAAK7M,OAAS,EACd,gBAAU6M,EAAKjE,MAAM,EAAG,GAAGnJ,KAAK,KAAhC,QAEJ,MAAMsN,EAAON,EAAGK,MAAM,KAChBE,EAAOD,EAAKE,QAClB,gBAAUD,EAAV,YAAkBD,EAAK1D,IAAKqC,GAASA,EAAK1L,OAAS,EAAI,IAAM0L,GAAMjM,KAAK,OCvEzE,MAAMyN,UA9BN,MACHtJ,YAAYuJ,EAAIzG,EAAY0G,EAAUC,EAAe,OAAYC,EAAgB,SAC7ExQ,KAAKqF,IAAM,KACXrF,KAAKyQ,OAAS,IAAIC,OAClB1Q,KAAKqF,IAAMuE,EAAWQ,UAAX,oCAAkDiG,EAAG5K,IAAM,yCAA0C6K,GAChHtQ,KAAKqQ,GAAKA,EACVrQ,KAAKwQ,cAAgBA,EACrBxQ,KAAKyQ,OAAOtK,UACZnG,KAAKqQ,GAAGM,2BAA6BJ,EACrCvQ,KAAKqQ,GAAGO,oBAAsB,KACrB5Q,KAAKyQ,OAAOI,OACb7Q,KAAKqF,IAAIyL,MAAT,UAAkB9Q,KAAKqQ,GAAGU,MAA1B,8BAAqD/Q,KAAKqQ,GAAGW,eAA7D,MACAhR,KAAKyQ,OAAOtK,YAIxB,YACI,OAAOnG,KAAKyQ,OAEhBQ,MAAMzF,GACF,IAAKxL,KAAKyQ,OAAOI,KACb,MAAM,IAAIxH,MAAM,4CAEpBrJ,KAAKqQ,GAAGa,KAAK1F,GACTxL,KAAKqQ,GAAGW,gBAAkBhR,KAAKwQ,gBAC/BxQ,KAAKyQ,OAAS,IAAIC,OAClB1Q,KAAKqF,IAAIyL,MAAT,UAAkB9Q,KAAKqQ,GAAGU,MAA1B,6BAAoD/Q,KAAKqQ,GAAGW,eAA5D,SAKRlK,cACIiD,SAASoH,WACTnR,KAAKoR,MAAQpR,KAAKqR,MAEtBJ,MAAMzF,GACFxL,KAAKoR,MAAQpR,KAAKoR,MAAME,KAAK,IAAMtR,KAAKuR,eAAe/F,IAE3D,qBAAqBA,SACXxL,KAAKqR,MACXtH,MAAMkH,MAAMzF,ICtCb,MAAMgG,EACT1K,YAAY2K,EAAIC,EAAY/H,EAAQC,EAAY+H,EAAgBC,EAAYC,GACxE7R,KAAK8R,sBAAwB,KAC7B9R,KAAK+R,IAAM,KACX/R,KAAKgS,QAAS,EACdhS,KAAKiS,gBAAkB,MACvBjS,KAAKkS,wBAA0B,KAC/BlS,KAAKqF,IAAMuE,EAAWQ,UAAU,iBAAkB,0CAClDpK,KAAKqF,IAAI8M,KAAK,oCACdnS,KAAKqF,IAAIyL,MAAM,oBAAqB,GAAGsB,UAAUP,EAAWtF,IAAKC,GAAWA,EAAOtL,QACnFlB,KAAKyR,GAAKA,EACVzR,KAAK0R,WAAaA,EAClB1R,KAAK2J,OAASA,EACd3J,KAAK4J,WAAaA,EAClB5J,KAAK2R,eAAiBA,EACtB3R,KAAK4R,WAAaA,EAClB5R,KAAKqS,GAAK,IAAIC,kBAAkB,CAAET,WAAYA,IAC9C7R,KAAKqS,GAAGE,oBAAsB,KAC1BvS,KAAKqF,IAAIyL,MAAM,yCACf9Q,KAAKwS,gBACAlB,KAAK,IAAMtR,KAAKqF,IAAIyL,MAAM,yBAEnC9Q,KAAKqS,GAAGI,wBAA0B,KAC9BzS,KAAKqF,IAAIyL,MAAM,2BAA4B9Q,KAAKqS,GAAGJ,kBAEvDjS,KAAKqS,GAAGK,uBAAyB,KAC7B1S,KAAKqF,IAAIyL,MAAM,0BAA2B9Q,KAAKqS,GAAGM,iBAEtD3S,KAAK4S,4BACL5S,KAAKqS,GAAGQ,cAAiBC,IACrB9S,KAAKqF,IAAIyL,MAAM,gCAAiCgC,EAAEC,QAAQhC,QAGlE,qBACI,OAAO/Q,KAAKqS,GAEhBO,4BACI5S,KAAKqF,IAAIyL,MAAM,qCACf9Q,KAAKqS,GAAGW,eAAkBF,IAClBA,EAAEtD,WACFxP,KAAKqF,IAAIyL,MAAM,gCAAiC,IAAIxB,EAAyBwD,EAAEtD,UAAUA,YACzFxP,KAAK4R,WAAWqB,cAAc,CAC1BzD,UAAWsD,EAAEtD,UAAUA,UACvB0D,OAAQJ,EAAEtD,UAAU0D,OACpBC,cAAeL,EAAEtD,UAAU2D,iBAI/BnT,KAAKqF,IAAIyL,MAAM,iCAGvB9Q,KAAKqS,GAAGe,oBAAuBN,IAC3B9S,KAAKqF,IAAIG,KAAK,+BAAwBsN,EAAEO,UAA1B,oBACFP,EAAEQ,IADA,4BACuBR,EAAES,cADzB,kBACgDT,EAAEU,UADlD,OAGlBxT,KAAKqS,GAAGoB,2BAA6B,KACjCzT,KAAKqF,IAAIyL,MAAM,+BAAgC9Q,KAAKqS,GAAGqB,oBACvD1T,KAAK0R,WAAWlK,OAAO,KAKnB,OAJmC,OAA/BxH,KAAK8R,wBACL9R,KAAK2R,eAAelK,OAAOzH,KAAK8R,uBAChC9R,KAAK8R,sBAAwB,MAEzB9R,KAAKqS,GAAGqB,oBACZ,IAAK,MACD1T,KAAK2T,mBAAmB,OACxB,MACJ,IAAK,WACL,IAAK,eACD3T,KAAK2T,mBAAmB,cACxB3T,KAAK8R,sBAAwB9R,KAAK2R,eAAeiC,SAAS,KACtD5T,KAAK8R,sBAAwB,KAC7B9R,KAAKqF,IAAIyL,MAAM,oCACf9Q,KAAKgS,QAAS,EACdhS,KAAK6T,QACL7T,KAAK2T,mBAAmB,iBACzBnC,EAAqBsC,8BAA8B,EAAM,yBAC5D,MACJ,IAAK,YACL,IAAK,YACD9T,KAAK2T,mBAAmB,aACxB,MACJ,IAAK,SACL,IAAK,SACD3T,KAAKgS,QAAS,EACdhS,KAAK2T,mBAAmB,gBACxB,MACJ,QACI3T,KAAKqF,IAAIG,KAAK,yCAA0CxF,KAAKqS,GAAGqB,wBAIhF1T,KAAKqS,GAAG0B,0BAA4B,KAChC/T,KAAKqF,IAAIyL,MAAM,8BAA+B9Q,KAAKqS,GAAG2B,oBAE1DhU,KAAK4R,WAAWqC,GAAG,aAAenB,IAC9B,IAAK,MAAMoB,KAAiBpB,EAAElL,KACtBsM,EACAlU,KAAKqF,IAAIyL,MAAM,+BAAgC,IAAIxB,EAAyB4E,EAAc1E,YAG1FxP,KAAKqF,IAAIyL,MAAM,iCAEnB9Q,KAAKqS,GAAG8B,gBAAgBD,GACnBE,MAAOhJ,GAAUpL,KAAKqF,IAAIG,KAAK,+BAAgC4F,MAIhF,sBACI,MAAMiJ,QAAcrU,KAAKqS,GAAGiC,oBACtBtU,KAAKqS,GAAGkC,oBAAoBF,GAClCrU,KAAKqF,IAAIyL,MAAM,wCACf9Q,KAAK4R,WAAW4C,UAAUH,GAC1B,MAOMI,OAPgB,KACX,IAAIvO,QAASC,IAChBnG,KAAK4R,WAAW8C,KAAK,SAAW5B,IAC5B3M,EAAQ2M,EAAElL,UAID+M,SACf3U,KAAKqS,GAAGuC,qBAAqBH,GACnCzU,KAAKqF,IAAIyL,MAAM,2CAEnB+D,WACI,GAAiB,OAAb7U,KAAK+R,IACL,MAAM,IAAI1I,MAAM,+BAEpB,MAAMyL,EAAO9U,KAAK4R,WAAWmD,mBACvB1E,EAAKrQ,KAAKqS,GAAG2C,kBAAkBF,EAAK/D,MAAO,CAC7CtL,GAAIqP,EAAKrP,GACTwP,YAAY,EACZC,SAAS,EACTC,SAAUL,EAAKK,WAEnB9E,EAAG+E,WAAa,cAChBpV,KAAK+R,IAAM,IAAI3B,EAAmCC,EAAIrQ,KAAK4J,WAAY5J,KAAK2J,OAAO1H,qBACnF,MAAM6G,EAAO9I,KACPqV,EAAU,CACZ,qBACI,OAAOvM,EAAKuJ,GAAGiD,KAAKC,gBAExB1B,QACQ/K,EAAKkJ,OACLlJ,EAAKzD,IAAIyL,MAAM,mEAGfhI,EAAKzD,IAAIyL,MAAT,yCACAT,EAAGwD,UAGX3C,KAAK1F,GACD1C,EAAKzD,IAAIyL,MAAM,0EACDtF,EAAQI,aACtB9C,EAAKiJ,IAAId,MAAMzF,KAGvB6E,EAAGmF,OAAS,KACRxV,KAAKqF,IAAI8M,KAAT,gCACA9B,EAAGoF,QAAU,KACLzV,KAAKgS,OACLhS,KAAKqF,IAAIyL,MAAM,4CAGf9Q,KAAKqF,IAAI8M,KAAT,kCACA2C,EAAK9C,WAGbhS,KAAK4R,WAAWiD,SAASQ,IAE7BhF,EAAGoF,QAAU,KACTzV,KAAKqF,IAAI+F,MAAT,mCAEJiF,EAAGqF,QAAWC,IACV3V,KAAKqF,IAAIG,KAAT,gDAAuDxF,KAAKgS,OAA5D,MAAwE2D,EAAMvK,QAElFiF,EAAGuF,UAAaD,IACZ3V,KAAKqF,IAAIyL,MAAT,6DAAqE6E,EAAM/N,KAAKgE,aAChFkJ,EAAKe,QAAQ,IAAI1S,WAAWwS,EAAM/N,QAG1C+L,mBAAmBmC,GACXA,IAAU9V,KAAKiS,kBACfjS,KAAKiS,gBAAkB6D,EACc,OAAjC9V,KAAKkS,yBACLlS,KAAKkS,wBAAwB4D,IAIzCjC,QACuC,OAA/B7T,KAAK8R,wBACL9R,KAAK2R,eAAelK,OAAOzH,KAAK8R,uBAChC9R,KAAK8R,sBAAwB,MAEjC9R,KAAK4R,WAAWmE,MAChB/V,KAAKqS,GAAGE,oBAAsB,KAC9BvS,KAAKqS,GAAGI,wBAA0B,KAClCzS,KAAKqS,GAAGK,uBAAyB,KACjC1S,KAAKqS,GAAGW,eAAiB,KACzBhT,KAAKqS,GAAGe,oBAAsB,KAC9BpT,KAAKqS,GAAGoB,2BAA6B,KACrCzT,KAAKqS,GAAG0B,0BAA4B,KACpC/T,KAAKqS,GAAGQ,cAAgB,KACxB7S,KAAKqS,GAAGwB,SAGhBrC,EAAqBsC,6BAA+B,KC/M7C,MAAMkC,UAAqB3M,OAE3B,MAAM4M,UAAkB5M,MAC3BvC,YAAYoP,EAAKC,GACbpM,MAAMmM,GACNlW,KAAKmW,WAAaA,GCJnBC,eAAeC,EAAOC,GACzB,QAAsBhR,IAAlBiR,OAAOC,OACP,MAAM,IAAInN,MAAM,mCAEpB,QAA6B/D,IAAzBiR,OAAOC,OAAOC,OACd,MAAM,IAAIpN,MAAM,mCAEpB,MAAMqN,QAAYF,OAAOC,OAAOE,OAAO,UAAWL,GAClD,OAAOnU,EAAS,IAAIgB,WAAWuT,ICN5B,MAAME,EACT9P,YAAY+P,EAASC,EAASnN,GAU1B,GATA3J,KAAK+W,WAAa,IAAIrG,OACtB1Q,KAAKgX,YAAcnT,EAAa,GAChC7D,KAAKiX,SAAU,EACfjX,KAAKkX,MAAQ,EACblX,KAAKqF,IAAMwR,EAAQjN,WAAWQ,UAAnB,eAAqCpK,KAAKgX,aAAe,0CACpEhX,KAAK6W,QAAUA,EACf7W,KAAK8W,QAAUA,EACf9W,KAAK2J,YAAoBrE,IAAXqE,EAAuBA,EAASiN,EAAYO,cAC1DnX,KAAKoX,eAAiBpX,KAAK2J,OAAO0N,mBACS,IAAvCrX,KAAK2J,OAAO2N,gBAAgBpU,OAC5B,MAAM,IAAImG,MAAM,8CAEpB,GAAIrJ,KAAK2J,OAAO4N,SAAW,EACvB,MAAM,IAAIlO,MAAM,yBAGxB,2BACI,MAAO,CACHgO,mBAAoB,IACpBG,kBAAmB,IACnBD,SAAU,EACVD,gBAAiB,CAAC,EAAG,GAAI,KAGjC,2BAA2B3N,GAIvB,QAHerE,IAAXqE,IACAA,EAASiN,EAAYO,eAErBxN,EAAO4N,WAAaE,OAAOC,kBAC3B,OAAOD,OAAOC,kBAElB,IAAIN,EAAiBzN,EAAO0N,mBACxBM,EAAQ,EACZ,IAAK,IAAI7U,EAAI,EAAGA,EAAI6G,EAAO4N,WAAYzU,EACnC6U,GAASP,EACTA,EAAiBnT,KAAK2T,IAAqB,EAAjBR,EAAoBzN,EAAO6N,mBAEzD,OAAOG,EAEXE,QAQI,OAPK7X,KAAKiX,UACNjX,KAAK8X,MAAM1D,MAAOhJ,IACdpL,KAAKqF,IAAI+F,MAAM,sBAAuBA,GACtCpL,KAAK+W,WAAWgB,OAAO3M,KAE3BpL,KAAKiX,SAAU,GAEZjX,KAAK+W,WAEhBlG,OACI7Q,KAAKqF,IAAI8M,KAAK,aACdnS,KAAK+W,WAAW5Q,UAEpB,YACI,MAAM6R,QAAoB3B,EAAOrW,KAAK8W,QAAQnR,QACxCiC,EAAO,IAAIqQ,gBAKjB,GAJArQ,EAAKsQ,IAAIC,EAAYC,SAAUpY,KAAK6W,QAAQwB,UAC5CzQ,EAAKsQ,IAAIC,EAAYG,YAAaN,GAClCpQ,EAAKsQ,IAAIC,EAAYI,YAArB,UAAqCvY,KAAK6W,QAAQ5J,UAClDrF,EAAKsQ,IAAIC,EAAYK,gBAAiBxY,KAAKgX,aACb,SAA1BhX,KAAK6W,QAAQwB,SAAqB,CAClC,MAAMI,EAAQzY,KAAK6W,QAAQ6B,UAAU1I,MAAM,KAC3C,GAAIyI,EAAMvV,OAAS,EACf,MAAM,IAAImG,MAAJ,mCAAsCoP,EAAMvV,OAA5C,wCAEV0E,EAAKsQ,IAAIC,EAAYQ,UAAWF,EAAM,IACtC7Q,EAAKsQ,IAAIC,EAAYS,aAAcH,EAAM,IACzC7Q,EAAKsQ,IAAIC,EAAYU,cAAeJ,EAAM,QAEzC,IAA8B,QAA1BzY,KAAK6W,QAAQwB,SAIlB,MAAM,IAAIhP,MAAJ,6BAAgCrJ,KAAK6W,QAAQwB,WAHnDzQ,EAAKsQ,IAAIC,EAAYQ,UAAW3Y,KAAK6W,QAAQ6B,WAKjD,MAAQ1Y,KAAK+W,WAAWlG,MAAM,CAC1B,IAAIiI,EAAa9Y,KAAK2J,OAAO2N,gBAAgBtX,KAAKkX,YAC/B5R,IAAfwT,IACAA,EAAa9Y,KAAK2J,OAAO2N,gBAAgBtX,KAAK2J,OAAO2N,gBAAgBpU,OAAS,IAE/D,IAAf4V,EACAlR,EAAKmR,OAAOZ,EAAYa,kBAGxBpR,EAAKsQ,IAAIC,EAAYa,iBAAkBhB,EAAYlM,MAAM,EAAG,IAEhElE,EAAKsQ,IAAIC,EAAYc,iBAArB,UAA0CH,MACxC9Y,KAAKkX,MACPlX,KAAKqF,IAAIyL,MAAT,uBAA+B9Q,KAAKkX,MAApC,YAA6ClX,KAAK2J,OAAO4N,SAAzD,iBAA0EuB,EAA1E,MACI9Y,KAAK6W,QAAQlN,OAAO5H,eACpB/B,KAAKqF,IAAIyL,MAAM,aAAf,UAAgClJ,IAEpC,IACI,MAAMsR,QAAiBC,MAAMnZ,KAAK6W,QAAQvD,IAAK,CAC3C8F,OAAQ,OACRC,QAAS,CACL,eAAgB,qCAEpB9Q,KAAMX,IAEV,GAAIsR,EAASI,GACTtZ,KAAKqF,IAAIyL,MAAM,+BAEd,GAAIoI,EAASK,QAAU,KAAOL,EAASK,OAAS,IAAK,CACtD,MAAMnO,EAAQ,yCAAH,OAA4C8N,EAASK,QAChEvZ,KAAKqF,IAAIG,KAAK4F,GACdpL,KAAK+W,WAAWgB,OAAO,IAAI9B,EAAU7K,EAAO8N,EAASK,cAGrDvZ,KAAKqF,IAAIG,KAAT,gDAAuD0T,EAASK,SAGxE,MAAOnO,GACHpL,KAAKqF,IAAIG,KAAK,uBAAwB4F,GAI1C,SAFMpF,EAAMhG,KAAKoX,gBACjBpX,KAAKoX,eAAiBnT,KAAK2T,IAA0B,EAAtB5X,KAAKoX,eAAoBpX,KAAK2J,OAAO6N,oBAC/DxX,KAAK+W,WAAWlG,MAAQ7Q,KAAKkX,QAAUlX,KAAK2J,OAAO4N,SAAU,CAC9D,MAAMnM,EAAQ,8BAAH,OAAiCpL,KAAKkX,MAAtC,UACXlX,KAAKqF,IAAIG,KAAK4F,GACdpL,KAAK+W,WAAWgB,OAAO,IAAI/B,EAAa5K,OAKjD,MAAM+M,EACTrR,YAAYsG,EAAQoM,EAAkB5P,GAClC5J,KAAKiN,QAAU,KACfjN,KAAKyZ,WAAa,KAClBzZ,KAAK0Z,UAAY,MACjB1Z,KAAK2J,OAASyD,EACdpN,KAAKsT,IAAMlG,EAAO/L,SAClBrB,KAAKiN,QAAUuM,EACfxZ,KAAK4J,WAAaA,EAClB5J,KAAKqF,IAAMuE,EAAWQ,UAAX,SAA+B,0CAE9C,gBACI,OAAOpK,KAAKyZ,WAEhB,eACI,OAAOzZ,KAAK0Z,UAEhBC,KAAKjB,EAAWkB,GACZ5Z,KAAKqF,IAAI8M,KAAK,mBAAoByH,EAAe,SACjD5Z,KAAKyZ,WAAaf,EAClB1Y,KAAK0Z,UAAYE,EAErBC,QACI7Z,KAAKyZ,WAAa,KAEtBK,cACI,OAA0B,MAAnB9Z,KAAKyZ,WAEhBM,cAAcjD,EAASnN,GACnB,IAAK3J,KAAK8Z,cACN,MAAM,IAAIzQ,MAAM,4BAEpB,OAAO,IAAIuN,EAAY5W,KAAM8W,EAASnN,IAG9CwO,EAAY5O,QAAU,CAAC,SAAU,mBAAoB,cACrD4O,EAAYC,SAAW,OACvBD,EAAYQ,UAAY,QACxBR,EAAYG,YAAc,UAC1BH,EAAYI,YAAc,UAC1BJ,EAAYK,gBAAkB,cAC9BL,EAAYS,aAAe,WAC3BT,EAAYU,cAAgB,WAC5BV,EAAYc,iBAAmB,MAC/Bd,EAAYa,iBAAmB,e,6BC3K/B,MAAMgB,EAAa,CACf,KAAM,MACN,WAAY,OACZ,WAAY,OACZ,WAAY,OACZ,WAAY,OACZ,WAAY,OACZ,KAAM,MACN,WAAY,OACZ,WAAY,OACZ,WAAY,OACZ,WAAY,OACZ,WAAY,OACZ,IAAO,KACP,KAAQ,KACR,QAAS,KACT,QAAW,MACX,SAAY,KACZ,OAAU,KACV,IAAO,KACP,KAAQ,KACR,iBAAoB,KACpB,UAAa,MACb,MAAS,KACT,YAAe,OACf,YAAe,OACf,YAAe,OACf,YAAe,OACf,YAAe,OACf,eAAkB,KAClB,SAAY,KACZ,kBAAqB,KACrB,mBAAsB,KACtB,YAAe,IACf,QAAW,KACX,MAAS,MACT,cAAiB,KACjB,UAAa,MACb,QAAW,KACX,OAAU,KACV,OAAU,KACV,QAAW,KACX,MAAS,KACT,MAAS,KACT,UAAa,KACb,UAAa,KACb,QAAW,KACX,IAAO,KACP,aAAgB,KAChB,QAAW,KACX,UAAa,KACb,MAAS,KACT,SAAY,KACZ,MAAS,KACT,WAAc,KACd,mBAAsB,KACtB,iBAAoB,KACpB,WAAc,KACd,gBAAmB,KACnB,iBAAoB,KACpB,iBAAoB,KACpB,kBAAqB,KACrB,YAAe,KACf,iBAAoB,KACpB,SAAY,KACZ,cAAiB,KACjB,iBAAoB,KACpB,kBAAqB,KACrB,IAAO,KACP,SAAY,MACZ,WAAc,KACd,cAAiB,KACjB,IAAO,KACP,KAAQ,KACR,cAAiB,KACjB,QAAW,KACX,IAAO,KACP,QAAW,MACX,KAAQ,KACR,WAAc,KACd,iBAAoB,OACpB,iBAAoB,OACpB,iBAAoB,OACpB,iBAAoB,OACpB,iBAAoB,OACpB,YAAe,KACf,WAAc,KACd,YAAe,MACf,WAAc,OACd,WAAc,OACd,WAAc,OACd,WAAc,OACd,WAAc,OACd,KAAQ,KACR,kBAAqB,MACrB,wBAA2B,OAC3B,wBAA2B,OAC3B,wBAA2B,OAC3B,wBAA2B,OAC3B,wBAA2B,OAC3B,SAAY,KACZ,MAAS,KACT,OAAU,KACV,UAAa,KACb,MAAS,KACT,cAAiB,KACjB,SAAY,QACZ,eAAkB,UAClB,eAAkB,UAClB,eAAkB,UAClB,eAAkB,UAClB,eAAkB,UAClB,WAAc,QACd,iBAAoB,UACpB,iBAAoB,UACpB,iBAAoB,UACpB,iBAAoB,UACpB,iBAAoB,UACpB,aAAgB,KAChB,QAAW,KACX,WAAc,MACd,OAAU,KACV,OAAU,KACV,QAAW,KACX,SAAY,KACZ,MAAS,KACT,KAAQ,KACR,UAAa,KACb,OAAU,KACV,SAAY,KACZ,OAAU,KACV,WAAc,KACd,IAAO,KACP,KAAQ,KACR,WAAc,OACd,WAAc,OACd,WAAc,OACd,WAAc,OACd,WAAc,OACd,SAAY,KACZ,QAAW,KACX,QAAW,KACX,MAAS,MACT,eAAkB,KAClB,UAAa,KACb,eAAkB,KAClB,qBAAwB,OACxB,qBAAwB,OACxB,qBAAwB,OACxB,qBAAwB,OACxB,qBAAwB,OACxB,IAAO,MACP,IAAO,KACP,KAAQ,KACR,MAAS,KACT,OAAU,KACV,KAAQ,KACR,QAAW,MACX,MAAS,KACT,aAAgB,KAChB,KAAQ,MACR,OAAU,KACV,WAAc,KACd,UAAa,KACb,KAAQ,MACR,SAAY,KACZ,aAAgB,KAChB,WAAc,KACd,YAAe,KACf,YAAe,KACf,UAAa,KACb,oBAAuB,KACvB,SAAY,KACZ,UAAa,QACb,gBAAmB,UACnB,gBAAmB,UACnB,gBAAmB,UACnB,gBAAmB,UACnB,gBAAmB,UACnB,aAAgB,KAChB,mBAAsB,OACtB,mBAAsB,OACtB,mBAAsB,OACtB,mBAAsB,OACtB,mBAAsB,OACtB,YAAe,QACf,kBAAqB,UACrB,kBAAqB,UACrB,kBAAqB,UACrB,kBAAqB,UACrB,kBAAqB,UACrB,WAAc,KACd,QAAW,KACX,OAAU,KACV,SAAY,KACZ,UAAa,KACb,SAAY,KACZ,YAAe,KACf,WAAc,KACd,YAAe,KACf,MAAS,KACT,KAAQ,KACR,KAAQ,MACR,KAAQ,KACR,KAAQ,KACR,SAAY,KACZ,cAAiB,KACjB,MAAS,MACT,KAAQ,KACR,MAAS,KACT,QAAW,KACX,IAAO,KACP,WAAc,KACd,QAAW,KACX,aAAgB,KAChB,IAAO,KACP,UAAa,OACb,UAAa,OACb,UAAa,OACb,UAAa,OACb,UAAa,OACb,MAAS,KACT,MAAS,KACT,eAAkB,KAClB,qBAAwB,OACxB,qBAAwB,OACxB,qBAAwB,OACxB,qBAAwB,OACxB,qBAAwB,OACxB,MAAS,KACT,WAAc,KACd,iBAAoB,OACpB,iBAAoB,OACpB,iBAAoB,OACpB,iBAAoB,OACpB,iBAAoB,OACpB,gBAAmB,KACnB,UAAa,KACb,OAAU,KACV,OAAU,KACV,SAAY,KACZ,aAAgB,KAChB,MAAS,KACT,aAAgB,KAChB,YAAe,KACf,aAAgB,KAChB,IAAO,KACP,KAAQ,KACR,YAAe,KACf,iBAAoB,KACpB,QAAW,KACX,IAAO,KACP,SAAY,KACZ,gBAAmB,KACnB,iBAAoB,KACpB,OAAU,KACV,UAAa,KACb,OAAU,KACV,KAAQ,KACR,SAAY,KACZ,gBAAmB,MACnB,QAAW,KACX,cAAiB,OACjB,cAAiB,OACjB,cAAiB,OACjB,cAAiB,OACjB,cAAiB,OACjB,MAAS,KACT,OAAU,MACV,aAAgB,KAChB,QAAW,MACX,OAAU,KACV,OAAU,MACV,MAAS,KACT,YAAe,KACf,MAAS,KACT,UAAa,KACb,SAAY,MACZ,WAAc,KACd,eAAkB,KAClB,cAAiB,KACjB,OAAU,KACV,OAAU,KACV,IAAO,MACP,SAAY,KACZ,GAAM,MACN,YAAe,KACf,SAAY,KACZ,OAAU,KACV,MAAS,KACT,UAAa,KACb,gBAAmB,KACnB,WAAc,KACd,SAAY,KACZ,WAAc,KACd,eAAkB,KAClB,eAAkB,KAClB,UAAa,KACb,OAAU,KACV,SAAY,KACZ,eAAkB,KAClB,WAAc,KACd,SAAY,KACZ,QAAW,KACX,MAAS,KACT,YAAe,OACf,YAAe,OACf,YAAe,OACf,YAAe,OACf,YAAe,OACf,kBAAqB,KACrB,SAAY,MACZ,cAAiB,KACjB,WAAc,KACd,eAAkB,KAClB,OAAU,KACV,UAAa,KACb,OAAU,KACV,YAAe,KACf,UAAa,MACb,GAAM,KACN,MAAS,MACT,KAAQ,KACR,WAAc,OACd,WAAc,OACd,WAAc,OACd,WAAc,OACd,WAAc,OACd,QAAW,MACX,mBAAsB,MACtB,UAAa,MACb,MAAS,MACT,OAAU,MACV,QAAW,MACX,UAAa,MACb,QAAW,MACX,UAAa,MACb,QAAW,MACX,UAAa,MACb,SAAY,MACZ,OAAU,MACV,SAAY,MACZ,OAAU,MACV,SAAY,MACZ,OAAU,MACV,SAAY,MACZ,OAAU,MACV,SAAY,MACZ,OAAU,MACV,SAAY,MACZ,OAAU,MACV,SAAY,MACZ,OAAU,MACV,SAAY,MACZ,OAAU,MACV,SAAY,MACZ,UAAa,KACb,YAAe,KACf,gBAAmB,KACnB,MAAS,KACT,OAAU,MACV,MAAS,KACT,MAAS,KACT,WAAc,KACd,KAAQ,KACR,SAAY,MACZ,MAAS,KACT,QAAW,KACX,OAAU,KACV,OAAU,KACV,WAAc,KACd,UAAa,KACb,MAAS,KACT,QAAW,KACX,YAAe,MACf,SAAY,MACZ,eAAkB,MAClB,cAAiB,KACjB,UAAa,KACb,WAAc,KACd,SAAY,KACZ,aAAgB,KAChB,kBAAqB,MACrB,oBAAuB,KACvB,0BAA6B,OAC7B,0BAA6B,OAC7B,0BAA6B,OAC7B,0BAA6B,OAC7B,0BAA6B,OAC7B,SAAY,KACZ,cAAiB,MACjB,kBAAqB,KACrB,OAAU,KACV,QAAW,KACX,KAAQ,KACR,UAAa,KACb,KAAQ,KACR,MAAS,MACT,kBAAqB,KACrB,OAAU,KACV,aAAgB,KAChB,UAAa,WACb,UAAa,WACb,UAAa,WACb,UAAa,WACb,IAAO,KACP,SAAY,KACZ,OAAU,KACV,IAAO,KACP,KAAQ,KACR,OAAU,MACV,MAAS,KACT,YAAe,MACf,cAAiB,KACjB,QAAW,KACX,aAAgB,KAChB,UAAa,KACb,UAAa,KACb,MAAS,KACT,WAAc,IACd,kBAAqB,IACrB,WAAc,KACd,cAAiB,KACjB,eAAkB,KAClB,MAAS,KACT,YAAe,MACf,IAAO,KACP,WAAc,KACd,aAAgB,KAChB,SAAY,KACZ,UAAa,KACb,QAAW,KACX,MAAS,KACT,QAAW,KACX,cAAiB,KACjB,iBAAoB,QACpB,uBAA0B,UAC1B,uBAA0B,UAC1B,uBAA0B,UAC1B,uBAA0B,UAC1B,uBAA0B,UAC1B,mBAAsB,QACtB,yBAA4B,UAC5B,yBAA4B,UAC5B,yBAA4B,UAC5B,yBAA4B,UAC5B,yBAA4B,UAC5B,WAAc,IACd,kBAAqB,KACrB,MAAS,KACT,QAAW,KACX,QAAW,KACX,YAAe,KACf,QAAW,KACX,OAAU,MACV,OAAU,KACV,aAAgB,OAChB,aAAgB,OAChB,aAAgB,OAChB,aAAgB,OAChB,aAAgB,OAChB,MAAS,KACT,KAAQ,KACR,KAAQ,KACR,KAAQ,KACR,eAAkB,KAClB,oBAAuB,KACvB,KAAQ,KACR,iBAAoB,KACpB,OAAU,MACV,QAAW,MACX,UAAa,MACb,gBAAmB,OACnB,gBAAmB,OACnB,gBAAmB,OACnB,gBAAmB,OACnB,gBAAmB,OACnB,YAAe,KACf,SAAY,KACZ,IAAO,KACP,aAAgB,KAChB,UAAa,KACb,KAAQ,MACR,WAAc,KACd,SAAY,MACZ,YAAe,KACf,SAAY,IACZ,UAAa,KACb,MAAS,KACT,WAAc,KACd,IAAO,KACP,cAAiB,KACjB,IAAO,MACP,SAAY,KACZ,OAAU,KACV,YAAe,KACf,MAAS,KACT,QAAW,KACX,KAAQ,KACR,kBAAqB,IACrB,mBAAsB,KACtB,aAAgB,KAChB,SAAY,KACZ,KAAQ,MACR,YAAe,KACf,kBAAqB,KACrB,OAAU,KACV,YAAe,KACf,MAAS,KACT,WAAc,KACd,SAAY,KACZ,QAAW,KACX,KAAQ,KACR,KAAQ,KACR,SAAY,KACZ,KAAQ,KACR,IAAO,KACP,MAAS,KACT,IAAO,MACP,YAAe,KACf,UAAa,OACb,UAAa,OACb,UAAa,OACb,UAAa,OACb,UAAa,OACb,aAAgB,MAChB,eAAkB,MAClB,WAAc,MACd,SAAY,KACZ,IAAO,KACP,SAAY,KACZ,MAAS,MACT,mBAAsB,KACtB,sBAAyB,KACzB,MAAS,KACT,cAAiB,KACjB,SAAY,KACZ,IAAO,KACP,UAAa,OACb,UAAa,OACb,UAAa,OACb,UAAa,OACb,UAAa,OACb,MAAS,KACT,WAAc,KACd,IAAO,KACP,QAAW,iBACX,QAAW,KACX,YAAe,KACf,SAAY,KACZ,eAAkB,KAClB,KAAQ,KACR,gBAAmB,KACnB,eAAkB,KAClB,YAAe,KACf,qBAAwB,KACxB,UAAa,KACb,eAAkB,KAClB,eAAkB,KAClB,IAAO,MACP,WAAc,UACd,KAAQ,KACR,UAAa,KACb,QAAW,MACX,MAAS,KACT,YAAe,OACf,YAAe,OACf,YAAe,OACf,YAAe,OACf,YAAe,OACf,QAAW,KACX,YAAe,KACf,OAAU,MACV,UAAa,QACb,WAAc,WACd,UAAa,QACb,WAAc,WACd,WAAc,WACd,WAAc,WACd,YAAe,cACf,WAAc,WACd,YAAe,cACf,YAAe,cACf,WAAc,WACd,YAAe,cACf,WAAc,WACd,YAAe,cACf,YAAe,cACf,UAAa,QACb,WAAc,WACd,UAAa,QACb,WAAc,WACd,WAAc,WACd,WAAc,WACd,YAAe,cACf,WAAc,WACd,YAAe,cACf,YAAe,cACf,iBAAoB,IACpB,aAAgB,KAChB,eAAkB,IAClB,IAAO,KACP,QAAW,KACX,KAAQ,KACR,OAAU,KACV,YAAe,KACf,aAAgB,KAChB,MAAS,KACT,aAAgB,KAChB,aAAgB,MAChB,YAAe,KACf,YAAe,MACf,gBAAmB,KACnB,sBAAyB,OACzB,sBAAyB,OACzB,sBAAyB,OACzB,sBAAyB,OACzB,sBAAyB,OACzB,KAAQ,KACR,YAAe,KACf,kBAAqB,KACrB,YAAe,KACf,UAAa,KACb,YAAe,KACf,mBAAsB,KACtB,wBAA2B,KAC3B,KAAQ,MACR,UAAa,KACb,aAAgB,KAChB,KAAQ,IACR,WAAc,MACd,WAAc,MACd,WAAc,MACd,WAAc,MACd,WAAc,MACd,KAAQ,MACR,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,WAAc,iBACd,WAAc,iBACd,WAAc,iBACd,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,QAAW,OACX,SAAY,KACZ,WAAc,KACd,UAAa,KACb,eAAgB,KAChB,OAAU,KACV,YAAe,KACf,aAAgB,KAChB,QAAW,KACX,YAAe,KACf,cAAiB,KACjB,IAAO,MACP,MAAS,KACT,KAAQ,KACR,WAAc,OACd,WAAc,OACd,WAAc,OACd,WAAc,OACd,WAAc,OACd,SAAY,KACZ,WAAc,KACd,iBAAoB,MACpB,eAAkB,KAClB,SAAY,KACZ,aAAgB,MAChB,KAAQ,MACR,iBAAoB,KACpB,SA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IAAK,WACL,IAAK,YACL,IAAK,WACL,IAAK,gBACL,IAAK,gBACL,IAAK,cACL,IAAK,cACL,IAAK,cACL,IAAK,aACL,IAAK,iBACL,IAAK,cACL,IAAK,0BACL,IAAK,gBACL,IAAK,aACL,IAAK,aACL,IAAK,sBACL,IAAK,wBACL,IAAK,uBACL,IAAK,yBACL,IAAK,mBACL,IAAK,yBACL,IAAK,kBACL,IAAK,kBACL,IAAK,2BACD,MAAO,QACX,IAAK,2BACL,IAAK,kBACL,IAAK,kBACL,IAAK,gCACL,IAAK,+BACL,IAAK,qBACL,IAAK,8BACL,IAAK,oBACL,IAAK,oBACL,IAAK,oBACL,IAAK,wBACL,IAAK,oBACL,IAAK,2BACL,IAAK,+BACL,IAAK,mBACL,IAAK,8BACL,IAAK,oBACL,IAAK,+BACD,MAAO,aACX,IAAK,eACL,IAAK,aACD,MAAO,UACX,IAAK,gBACL,IAAK,mBACD,MAAO,QACX,IAAK,qBACL,IAAK,wBACL,IAAK,0BACL,IAAK,yBACD,MAAO,OACX,IAAK,8CACL,IAAK,uDACL,IAAK,2CACL,IAAK,oCACL,IAAK,+BACL,IAAK,wCACL,IAAK,YACL,IAAK,aACL,IAAK,YACL,IAAK,YACD,MAAO,QACX,IAAK,kBACD,MAAO,MACX,IAAK,gCACL,IAAK,kDACL,IAAK,4EACL,IAAK,yEACL,IAAK,wEACL,IAAK,uCACL,IAAK,kCACL,IAAK,2CACL,IAAK,2BACD,MAAO,eACX,IAAK,iDACL,IAAK,0DACL,IAAK,oCACL,IAAK,+BACL,IAAK,wCACL,IAAK,wBACL,IAAK,2BACL,IAAK,oEACL,IAAK,uEACD,MAAO,cACX,IAAK,0CACL,IAAK,iDACL,IAAK,mDACL,IAAK,8CACL,IAAK,sCACL,IAAK,6CACL,IAAK,iCACL,IAAK,wCACL,IAAK,0CACL,IAAK,wBACL,IAAK,sBACD,MAAO,OACX,IAAK,gCACL,IAAK,gCACD,MAAO,QACX,IAAK,qBACL,IAAK,0EACL,IAAK,0EACD,MAAO,OACX,QACI,OAAO,MAGnBilB,GAAGjlB,EAAUoxD,GACT,YAAoB1xD,IAAbM,IACqC,IAArCoxD,EAAcjvC,QAAQniB,IAGrC8wD,GAAYntD,QAAU,CAAC,cC3LhB,MAAM0tD,GACTnwD,YAAYmV,EAASyC,EAAQ9U,EAAY4T,GACrCxd,KAAK8d,uBAAyB,KAC9B9d,KAAK0d,qBAAuB,KAC5B1d,KAAKk3D,yBAA2B,KAChCl3D,KAAKge,oBAAsB,KAC3Bhe,KAAKke,kBAAoB,KACzBle,KAAKm3D,kBAAoB,GACzBn3D,KAAKic,QAAUA,EACfjc,KAAK0e,OAASA,EACd1e,KAAKwd,gBAAkBA,EACvBxd,KAAKqF,IAAMuE,EAAWQ,UAAU,kBAEpCuP,OACI3Z,KAAKo3D,uBACLp3D,KAAKq3D,gBAETC,gCACI,GAAIt3D,KAAKk3D,yBAA0B,CAC/B,MAAMK,EAAev3D,KAAKic,QAAQs7C,aAClCv3D,KAAKqF,IAAIyL,MAAM,yCACfymD,EAAaC,kBAAmB98C,IAC5B,OAAQA,GACJ,IAAK,SACD1a,KAAK8d,wBAAyB,EAC9B,MACJ,IAAK,UACD9d,KAAK8d,wBAAyB,EAC9B9d,KAAK0d,sBAAuB,EAC5B1d,KAAKy3D,aAAaR,GAAoBS,uBAAwB,QAC9D,MACJ,IAAK,UACD13D,KAAK0d,sBAAuB,EAC5B1d,KAAK8d,uBAAyB,KAC9B,MACJ,QACI9d,KAAK8d,wBAAyB,EAGtC9d,KAAKqF,IAAIyL,MAAM,0BAA2B9Q,KAAK8d,2BAI3Ds5C,uBAGI,GAFAp3D,KAAKk3D,yBAA4B,iBAAkBl3D,KAAKic,QACxDjc,KAAKqF,IAAIyL,MAAM,8BAA+B9Q,KAAKk3D,0BAC/Cl3D,KAAKk3D,yBAA0B,CAE/B,OADqBl3D,KAAKic,QAAQs7C,aACbI,YACjB,IAAK,SACD33D,KAAK8d,wBAAyB,EAC9B,MACJ,IAAK,UACD9d,KAAK8d,wBAAyB,EAC9B,MACJ,IAAK,UACD9d,KAAK8d,uBAAyB,KAC9B,MACJ,QACI9d,KAAK8d,wBAAyB,GAI1C9d,KAAKqF,IAAIyL,MAAM,iCAAkC9Q,KAAK8d,wBAE1Du5C,gBACIr3D,KAAKqF,IAAIyL,MAAM,wBACf,MAAM8mD,EAAgB53D,KAAK63D,gBAAgBZ,GAAoBS,wBACzD/7C,EAAU3b,KAAK63D,gBAAgBZ,GAAoBa,+BACnDlqB,EAAQ5tC,KAAK63D,gBAAgBZ,GAAoBc,6BACjC,SAAlBH,GACA53D,KAAKqF,IAAIyL,MAAM,yBAA0B8mD,GACzC53D,KAAK0d,sBAAuB,EAC5B1d,KAAKs3D,iCAEkB,UAAlBM,GACL53D,KAAKqF,IAAIyL,MAAM,yBAA0B8mD,GACzC53D,KAAK0d,sBAAuB,IAG5B1d,KAAKqF,IAAIyL,MAAM,yBAA0B8mD,EAAe,kBACxD53D,KAAKs3D,iCAEO,UAAZ37C,GACA3b,KAAKqF,IAAIyL,MAAM,wBAAyB6K,GACxC3b,KAAKge,qBAAsB,IAG3Bhe,KAAKqF,IAAIyL,MAAM,wBAAyB6K,EAAS,8BACjD3b,KAAKge,qBAAsB,EAC3Bhe,KAAKy3D,aAAaR,GAAoBa,8BAA+B,SAE3D,SAAVlqB,GACA5tC,KAAKqF,IAAIyL,MAAM,sBAAuB88B,GACtC5tC,KAAKke,mBAAoB,IAGzBle,KAAKqF,IAAIyL,MAAM,sBAAuB88B,EAAO,+BAC7C5tC,KAAKke,mBAAoB,EACzBle,KAAKy3D,aAAaR,GAAoBc,4BAA6B,UAG3Eh6C,4BACI,OAAO/d,KAAK8d,uBAEhBH,wBACI,OAAO3d,KAAK0d,qBAEhBO,kBACI,OAAOje,KAAKge,oBAEhBG,gBACI,OAAOne,KAAKke,kBAEhBL,6BACI,OAAO7d,KAAKk3D,yBAEhB94C,sBAAsB45C,GAClBh4D,KAAKqF,IAAIyL,MAAM,+CAAgDknD,GAC3DA,EACAh4D,KAAKs3D,iCAGLt3D,KAAK0d,sBAAuB,EAC5B1d,KAAKy3D,aAAaR,GAAoBS,uBAAwB,UAGtEr5C,gBAAgB45C,GACZj4D,KAAKqF,IAAIyL,MAAM,0CAA2CmnD,GAC1Dj4D,KAAKge,oBAAsBi6C,EAC3Bj4D,KAAKy3D,aAAaR,GAAoBa,8BAA+BG,EAAe,OAAS,SAEjG35C,cAAc45C,GACVl4D,KAAKqF,IAAIyL,MAAM,wCAAyConD,GACxDl4D,KAAKke,kBAAoBg6C,EACzBl4D,KAAKy3D,aAAaR,GAAoBc,4BAA6BG,EAAa,OAAS,SAE7FT,aAAa7yD,EAAKG,GACd/E,KAAKwd,gBAAgB26C,2BAA2BvzD,EAAKG,GAEzD8yD,gBAAgBjzD,GACZ,OAAO5E,KAAKwd,gBAAgB46C,8BAA8BxzD,GAE9DmoC,2BAA2BrmB,GACvB,IAAKA,EAAakxC,cACd,MAAO,CACHhqB,MAAO,CAAEC,OAAO,GAChBzB,IAAK,CAAEpsB,SAAS,EAAOqsB,aAAa,IAG5C,MAAMuB,EAAQlnB,EAAakxC,cAAchqB,MACnCxB,EAAM1lB,EAAakxC,cAAcxrB,IACjCisB,EAAc,CAChBxqB,QAAwB,YAAfD,EAAMjqB,OAEb20C,EAAY,CACdt4C,QAAsB,OAAbosB,EAAIzoB,KACb0oB,iBAAkC/mC,IAApB8mC,EAAIC,aAAiD,OAApBD,EAAIC,aAAgCD,EAAIC,aAE3F,GAAiB,UAAbD,EAAIzoB,KACJ,IAAKyoB,EAAImsB,OAASnsB,EAAImsB,OAAS,EAC3BD,EAAUt4C,SAAU,MAEnB,CACD,MAAMu4C,EAAQ,IAAI1M,KAAKzf,EAAImsB,OACrBzM,EAAM,IAAID,KAChByM,EAAUt4C,QAAUu4C,EAAQzM,EAMpC,OAHKwM,EAAUt4C,UACXs4C,EAAUjsB,aAAc,GAErB,CACHuB,MAAOyqB,EACPjsB,IAAKksB,GAGbnuC,qBAAqBzD,GACjB,MAAM8xC,EAAax4D,KAAK+sC,2BAA2BrmB,GACnD,OAAI8xC,EAAWpsB,IAAIpsB,QACRw4C,EAAWpsB,IAAIC,YAAc,UAAY,KAE7C,MAEXsB,iBAAiBD,EAAKxwB,EAAO3U,EAAMs2B,EAAS,yBAA0B45B,EAAeC,GAAgB,EAAOC,GAAiB,EAAOC,GAAY,GAC5I,GAAI54D,KAAKke,oBAAsB06C,EAAW,CACxB,IAAIC,MAAM5B,GAAoB6B,oBACtCC,OAEV,IAAoC,IAAhC/4D,KAAK8d,yBAAiE,IAA9B9d,KAAK0d,qBAC7C,OAAO,EAEN1d,KAAKge,qBAAwB06C,IAC9BnwD,EAAO,GACHvI,KAAKm3D,kBAAkBzpB,IACvB1tC,KAAKm0B,WAAWuZ,KAGD,IAAnBirB,GACA34D,KAAKm0B,WAAWuZ,GAEhB1tC,KAAKm3D,kBAAkBzpB,KACvBnlC,EAAO,GAAH,OAAMvI,KAAKm3D,kBAAkBzpB,GAAKnlC,KAAlC,aAA2CA,IAEnDvI,KAAKqF,IAAIyL,MAAM,uBAAwB48B,GACvC,MAAMsrB,EAAe,IAAIh5D,KAAKic,QAAQs7C,aAAar6C,EAAO,CACtDmmC,KAAMxkB,EACNt2B,KAAMA,EAAK6f,OACXslB,IAAKA,IAYT,OAVAsrB,EAAaC,QAAU,KACnBj5D,KAAKic,QAAQpU,aACSvC,IAAlBmzD,GACAA,IAEJz4D,KAAKqF,IAAIyL,MAAM,sBAAuB48B,EAAK,YAC3CsrB,EAAanlD,QACb7T,KAAKm0B,WAAWuZ,IAEpB1tC,KAAKm3D,kBAAkBzpB,GAAOsrB,GACvB,EAEXjvB,iBAAiB2D,GACb,MAAMsrB,EAAeh5D,KAAKm3D,kBAAkBzpB,GAC5C,YAAqBpoC,IAAjB0zD,IACAh5D,KAAKqF,IAAIyL,MAAM,sBAAuB48B,GACtCsrB,EAAanlD,QACb7T,KAAKm0B,WAAWuZ,IACT,GAMfvZ,WAAWuZ,UACA1tC,KAAKm3D,kBAAkBzpB,IAGtCupB,GAAoBS,uBAAyB,gBAC7CT,GAAoBa,8BAAgC,sBACpDb,GAAoBc,4BAA8B,oBAClDd,GAAoB6B,mBAAqB,0BACzC7B,GAAoB1tD,QAAU,CAAC,UAAW,SAAU,aAAc,mBCjP3D,MAAM2vD,GACTpyD,YAAYsG,EAAQoM,GAChBxZ,KAAK2J,OAASyD,EACdpN,KAAKm5D,gBAAkB3/C,EAE3Bka,mBAAmB0lC,EAAcC,EAAWC,EAAWC,EAAMC,EAAM7lC,GAC/D,MAAM8lC,EAAoBr1D,EAAcm1D,GAClC7iD,EAAM,IAAI7H,YAAY,IAA2B4qD,EAAkB7tD,YACzE,IAAIyV,EAAU,EACdA,KAAwC,IAA5BrhB,KAAK2J,OAAOrJ,YAAuB,EAAI,IAAM,EACzD+gB,IAAYsS,EAAa,EAAI,IAAM,EACnC,MAAM+lC,EAAW,IAAIC,SAASjjD,GAC9BgjD,EAASE,UAAU,EAAG55D,KAAKm5D,iBAC3BO,EAASG,SAAS,EAAGx4C,GACrB,MAAMy4C,EAAU,IAAI32D,WAAWuT,GAW/B,OAVAojD,EAAQ5hD,IAAIkhD,EAAc,GAC1BU,EAAQ5hD,IAAImhD,EAAW,IACL,OAAdC,EACAQ,EAAQ5hD,IAAI,IAAI/U,WAAW,IAAK,IAGhC22D,EAAQ5hD,IAAIohD,EAAW,IAE3BI,EAASE,UAAU,GAAIJ,GACvBM,EAAQ5hD,IAAIuhD,EAAmB,KACxBn2D,EAAY,IAAIH,WAAWuT,KAG1CwiD,GAAc3vD,QAAU,CAAC,SAAU,oBC7B5B,MAAMwwD,GACTjzD,YAAYmV,EAASrS,GACjB5J,KAAKqF,IAAMuE,EAAWQ,UAAU,cAChCpK,KAAKmzD,QAAUl3C,EAAQm3C,aAE3B+E,2BAA2BvzD,EAAKG,GAC5B/E,KAAKqF,IAAIyL,MAAM,wBAAyBlM,GACxC5E,KAAKmzD,QAAQW,QAAQiG,GAAgBC,mBAAqBp1D,EAAKG,GAEnEqzD,8BAA8BxzD,EAAKq1D,GAAe,GAE9C,OADAj6D,KAAKqF,IAAIyL,MAAM,2BAA4BlM,GACvC5E,KAAKk6D,yBAAyBt1D,GACvB5E,KAAKmzD,QAAQY,QAAQgG,GAAgBC,mBAAqBp1D,IAG7Dq1D,GACAj6D,KAAKm4D,2BAA2BvzD,EAAK,IAElC,IAGfu1D,4BAA4Bv1D,GACxB5E,KAAKqF,IAAIyL,MAAM,yBAA0BlM,GACzC5E,KAAKmzD,QAAQqB,WAAWuF,GAAgBC,mBAAqBp1D,GAEjEs1D,yBAAyBt1D,GAErB,OAAgB,OADH5E,KAAKmzD,QAAQY,QAAQgG,GAAgBC,mBAAqBp1D,IAI/Em1D,GAAgBC,mBAAqB,YACrCD,GAAgBxwD,QAAU,CAAC,UAAW,cC9B/B,MAAM6wD,GACTtzD,YAAYuzD,EAAWzwD,GACnB5J,KAAKozB,gCAAkC,IAAIknC,aAC3Ct6D,KAAKuzB,+BAAiC,IAAI+mC,aAC1Ct6D,KAAKkyC,qBAAuB,IAAIooB,aAChCt6D,KAAKoc,SAAW,EAChBpc,KAAKu6D,iBAAmB,KACxBv6D,KAAK2tD,aAAc,EACnB3tD,KAAKuc,QAAU,EACfvc,KAAKw6D,aAAe,EACpBx6D,KAAKq6D,UAAYA,EACjBr6D,KAAKqF,IAAMuE,EAAWQ,UAAU,UAAW,0CAC3CpK,KAAK6Z,QAET,YACI,OAAO7Z,KAAKy6D,OAEhB,UAAU3kD,GACN,MAAMu7B,EAAYrxC,KAAKy6D,OACnBppB,IAAcv7B,IAGlB9V,KAAKy6D,OAAS3kD,EACd9V,KAAKuzB,+BAA+BmnC,KAAK,CAAE5kD,MAAOA,EAAOu7B,UAAWA,KAExE7a,+BAA+B1gB,EAAOkb,EAAYV,GAC9C,MAAM+gB,EAAYrxC,KAAK26D,yBAEvB,GADA36D,KAAK26D,yBAA2B7kD,EAC3Bwa,EA2BDtwB,KAAKqF,IAAIyL,MAAM,0CAA4CgF,EAAQ,UAzBnE,OADA9V,KAAKqF,IAAIyL,MAAM,8BAA+BugC,EAAW,KAAMv7B,GACvDA,GACJ,IAAK,MACL,IAAK,gBACL,IAAK,mBACL,IAAK,iBACD9V,KAAK8V,MAAQ,UACb,MACJ,IAAK,OACD9V,KAAK46D,MAAQ,EACM,iBAAf5pC,EACAhxB,KAAKy5B,0BAA0B,aAG/Bz5B,KAAK8V,MAAQ,UAEjB,MACJ,IAAK,UACL,IAAK,SACD9V,KAAK8V,MAAQ,QACb,MACJ,QACI9V,KAAKqF,IAAIG,KAAT,8CAAqDsQ,KAOrE2jB,0BAA0B3jB,GACtB,MAAMu7B,EAAYrxC,KAAKm7B,oBAEvB,GADAn7B,KAAKm7B,oBAAsBrlB,EACR,IAAf9V,KAAK46D,MAEL,OADA56D,KAAKqF,IAAIyL,MAAM,yBAA0BugC,EAAW,KAAMv7B,GAClDA,GACJ,IAAK,MACL,IAAK,aACL,IAAK,eACD9V,KAAK8V,MAAQ,UACb,MACJ,IAAK,YACD9V,KAAK8V,MAAQ,KACb9V,KAAKuc,QAAU,EACf,MACJ,IAAK,eACDvc,KAAK8V,MAAQ,QACb,MACJ,QACI9V,KAAKqF,IAAIG,KAAK,4CAA8CsQ,EAAQ,UAI5E9V,KAAKqF,IAAIyL,MAAM,4CAA8CgF,EAAQ,KAG7EwgB,6BAA6BxgB,GACzB,GAAI9V,KAAKypB,yBAA2B3T,EAChC,OAEJ,MAAMu7B,EAAYrxC,KAAKypB,uBASvB,OARAzpB,KAAKqF,IAAIyL,MAAM,4BAA6BugC,EAAW,KAAMv7B,GAC7D9V,KAAKypB,uBAAyB3T,EAC9B9V,KAAKozB,gCAAgCsnC,KAAK,CAAE5kD,MAAOA,EAAOu7B,UAAWA,IACvC,OAA1BrxC,KAAKu6D,mBACLv6D,KAAKq6D,UAAU5yD,OAAOzH,KAAKu6D,kBAC3Bv6D,KAAKu6D,iBAAmB,MAE5Bv6D,KAAK2tD,aAAc,EACX73C,GACJ,IAAK,MACD9V,KAAKoc,SAAW,EAChB,MACJ,IAAK,OACDpc,KAAKoc,SAAW,EAChBpc,KAAKu6D,iBAAmBv6D,KAAKq6D,UAAU,KAC/Br6D,KAAKoc,SAAW,GAChBpc,KAAKoc,UAAY,EAGjBpc,KAAK2tD,aAAc,GAExB,KACH,MACJ,IAAK,eACD3tD,KAAKoc,SAAW,EAChB,MACJ,IAAK,aACDpc,KAAKoc,SAAW,GAChB,MACJ,IAAK,UACDpc,KAAKoc,SAAW,GAChB,MACJ,IAAK,iBACDpc,KAAKoc,SAAW,GAChBpc,KAAKu6D,iBAAmBv6D,KAAKq6D,UAAU,KAC/Br6D,KAAKoc,SAAW,GAChBpc,KAAKoc,UAAY,EAEZpc,KAAKoc,SAAW,GACrBpc,KAAKoc,UAAY,EAEZpc,KAAKoc,SAAW,GACrBpc,KAAKoc,UAAY,EAGjBpc,KAAK2tD,aAAc,GAExB,KACH,MACJ,IAAK,UACD3tD,KAAKoc,SAAW,GAChBpc,KAAKu6D,iBAAmBv6D,KAAKq6D,UAAU,KAC/Br6D,KAAKoc,SAAW,GAChBpc,KAAKoc,UAAY,EAEZpc,KAAKoc,SAAW,GACrBpc,KAAKoc,UAAY,EAEZpc,KAAKoc,SAAW,GACrBpc,KAAKoc,UAAY,EAGjBpc,KAAK2tD,aAAc,GAExB,KACH,MACJ,IAAK,OACD3tD,KAAKoc,SAAW,IAChB,MACJ,QACIpc,KAAKoc,SAAW,GAI5B/R,cAAc2mB,EAAYvI,GACtB,OAAQuI,GACJ,IAAK,eACD,OAAO,EACX,IAAK,SACL,QACI,MAAsB,OAAfhxB,KAAK8V,OAAkB2S,GAG1C,kBACI,OAAOzoB,KAAKw6D,aAEhB,gBAAgB3rC,GACR7uB,KAAKw6D,eAAiB3rC,IAG1B7uB,KAAKw6D,aAAe3rC,EACpB7uB,KAAKkyC,qBAAqBwoB,KAAK7rC,IAEnChV,MAAM4P,EAAyB,OAC3BzpB,KAAKqF,IAAIyL,MAAM,gBACf9Q,KAAK26D,yBAA2B,MAChC36D,KAAKm7B,oBAAsB,MAC3Bn7B,KAAK46D,MAAQ,EACb56D,KAAK8V,MAAQ,QACb9V,KAAKypB,uBAAyBA,EAC9BzpB,KAAKoc,SAAW,EAChBpc,KAAK2mB,YAAc,GAG3ByzC,GAAa7wD,QAAU,CAAC,YAAa,c,aCjM9B,MAAMsxD,GACT/zD,YAAYuzD,EAAWzwD,GACnB5J,KAAKqH,eAAiB,IAAIizD,aAC1Bt6D,KAAK86D,OAAS,UACd96D,KAAKq6D,UAAYA,EACjBr6D,KAAKqF,IAAMuE,EAAWQ,UAAU,UAAW,0CAC3CpK,KAAKqF,IAAIyL,MAAT,kCAA0C9Q,KAAKoH,QAEnD,YACI,OAAOpH,KAAK86D,OAEhBvvB,YAAYnkC,GACRpH,KAAK86D,OAAS1zD,EACdpH,KAAKqH,eAAeqzD,KAAKtzD,IAGjCyzD,GAAatxD,QAAU,CAAC,YAAa,cCjB9B,MAAMwxD,GACTj0D,YAAY6C,EAAQ2jB,EAAU1jB,GAC1B5J,KAAKg7D,SAAW,IAAIxqC,IACpBxwB,KAAK2J,OAASA,EACd3J,KAAKstB,SAAWA,EAChBttB,KAAKqF,IAAMuE,EAAWQ,UAAU,YAAa,yCAA0CpK,KAAK2J,OAAO9H,iBAEvG+R,SAASqnD,EAAIC,EAAOC,EAAa1vD,GAC7BzL,KAAKqF,IAAIyL,MAAT,kCAA8CxL,IAATmG,EAAqB,GAArB,YAA+BA,EAA/B,OACrC,MAAMitB,EAAU14B,KAAKstB,SAAS2tC,EAAIC,EAAOC,GAUzC,OATAziC,EACKpnB,KAAK,IAAMtR,KAAKg7D,SAASjiD,OAAO2f,IAChCtkB,MAAOoV,IACO,aAAXA,GACAxpB,KAAKqF,IAAI+F,MAAM,uCAAwCoe,KAG/DkP,EAAO,cAAoBjtB,EAC3BzL,KAAKg7D,SAAStgC,IAAIhC,GACXA,EAEXjxB,OAAOixB,GACH,MAAMjtB,EAAOitB,EAAO,cACpB14B,KAAKqF,IAAIyL,MAAT,iCAA6CxL,IAATmG,EAAqB,GAArB,YAA+BA,EAA/B,OACpC,MAAM2vD,EAAYp7D,KAAKstB,SAAS7lB,OAAOixB,GAEvC,OADA14B,KAAKg7D,SAASjiD,OAAO2f,GACd0iC,EAEX/mC,YACIr0B,KAAKqF,IAAIyL,MAAM,cAAgB9Q,KAAKg7D,SAASrvD,KAAO,aACpD,IAAK,MAAM+sB,KAAW14B,KAAKg7D,SACvBh7D,KAAKstB,SAAS7lB,OAAOixB,GAEzB14B,KAAKg7D,SAAS5mC,SAGtB2mC,GAAexxD,QAAU,CAAC,SAAU,WAAY,cCpCzC,MAAM8xD,GACTv0D,YAAYg6C,EAAW5kC,GACnBlc,KAAKs7D,cAAgB,cACrBt7D,KAAK2mB,YAAc,EACnB3mB,KAAK8gD,UAAYA,EACjB9gD,KAAKkc,aAAeA,EACpBlc,KAAKkc,aAAag2B,qBAAqB5qC,OAAQunB,IAC3C7uB,KAAK2mB,YAAckI,EACnB7uB,KAAK0oC,WAET1oC,KAAK0oC,SAETA,SACQ1oC,KAAK2mB,YAAc,EACnB3mB,KAAKkd,MAAL,WAAiBld,KAAK2mB,YAAtB,aAAsC3mB,KAAKs7D,eAG3Ct7D,KAAKkd,MAAQld,KAAKs7D,cAEtBt7D,KAAK8gD,UAAU,GAAG5jC,MAAQld,KAAKkd,OAGvCm+C,GAAa9xD,QAAU,CAAC,YAAa,gBCtB9B,MAAMgyD,GACTz0D,YAAY00D,EAAOx0D,EAAW0C,EAAYuS,EAAS7O,EAAQxD,GACvD5J,KAAKy7D,eAAgB,EACrBz7D,KAAKw7D,MAAQA,EACbx7D,KAAKgH,UAAYA,EACjBhH,KAAK0J,WAAaA,EAClB1J,KAAKic,QAAUA,EACfjc,KAAK2J,OAASyD,EACdpN,KAAKqF,IAAMuE,EAAWQ,UAAU,aAEpCkjD,mBACyBhoD,IAAjBtF,KAAKiN,QAITjN,KAAK07D,eACApqD,KAAMrE,IACPjN,KAAKiN,QAAUA,EACfjN,KAAKqF,IAAI8M,KAAK,4BAA6BnS,KAAKiN,WAE/CmH,MAAOhJ,IACRpL,KAAKqF,IAAI+F,MAAM,+BAAgCA,KAT/CpL,KAAK4iB,iBAYb84C,eACI,OAAO,IAAIx1D,QAAQ,CAACC,EAAS4R,KACzB,MAAM4jD,EAAY13D,KAAKC,MAAsB,IAAhBD,KAAKE,UAClCnE,KAAKw7D,MAAM,CACPpiD,OAAQ,MACR9F,IAAK,eAAiBqoD,EACtBltC,OAAO,EACPmtC,aAAc,OACdC,kBAAmB,CAACj0D,EAAMk0D,EAAe3lD,IAClB,MAAfA,EACO4B,EAAO,QAAU5B,GAErBvO,EAAKwgB,SAEjB9W,KAAMyqD,GACE51D,EAAQ41D,EAAgBn0D,MAC/BwD,GACO2M,EAAO3M,MAI1BwX,iBACI5iB,KAAKqF,IAAIyL,MAAM,uCACMxL,IAAjBtF,KAAKiN,QAITjN,KAAK07D,eACApqD,KAAMrE,IACHA,IAAYjN,KAAKiN,UACjBjN,KAAKqF,IAAIG,KAAK,6CAA8CxF,KAAKiN,QAAS,KAAMA,GAChFjN,KAAKg8D,iBAAiB/uD,MAGzBmH,MAAOhJ,IACRpL,KAAKqF,IAAI+F,MAAM,+BAAgCA,KAX/CpL,KAAKqF,IAAI+F,MAAM,uDAcvB4wD,iBAAiB/uD,GACb,IAA2B,IAAvBjN,KAAKy7D,cACL,OAEJ,MAGMQ,EAAgB,aAHD,kDACfj8D,KAAK2J,OAAO9I,WACZ,iBAC6C,4DAC7CyoB,EAAUtpB,KAAKgH,UAAUiW,QAC1BC,MAAMld,KAAK0J,WAAWoB,QAAQ,wBAC9BosB,YAAYl3B,KAAK0J,WAAWoB,QAAQ,2BAA4B,CACjEmC,QAASA,EACTivD,UAAWD,KAEV3iD,GAAGtZ,KAAK0J,WAAWoB,QAAQ,cAChC9K,KAAKy7D,eAAgB,EACrBz7D,KAAKgH,UAAU2D,KAAK2e,GAAShY,KAAK,KAC9BtR,KAAKic,QAAQc,SAASD,UACvB,KACC9c,KAAKic,QAAQc,SAASD,YCjF3B,SAASq/C,GAA2B3wD,GACvC,MAAwB,WAAjBA,EAAQR,MAA4C,uBAAvBQ,EAAQ4wD,WCEhD,SAASC,GAAW33D,EAAKE,EAAK03D,QACTh3D,IAAbZ,EAAIE,KACJF,EAAIE,GAAO03D,GFgFnBf,GAAehyD,QAAU,CAAC,QAAS,YAAa,aAAc,UAAW,SAAU,cG7DnFnK,QAAQC,OAAO,gBAAiB,IAC3BwX,QAAQ,aAAc4+C,IACtB5+C,QAAQ,uBAAwB44C,IAChC54C,QAAQ,iBAAkBs6C,IAC1Bt6C,QAAQ,yBAA0Bm8C,IAClCn8C,QAAQ,qBC5BN,MACH,eAAeqU,GACX,QAAkB5lB,IAAd4lB,GAAoD,KAAzBA,EAAUtf,WAAmB,CACxD,MAAM2wD,QAAwBlmD,EAAO6U,GACrC,QAAwB5lB,IAApBi3D,EACA,OAAOA,EAAgB13C,cAAcxhB,OAAO,EAAG,IAGvD,MAAO,sBDqBVwT,QAAQ,iBAAkBm/C,IAC1Bn/C,QAAQ,sBAAuBogD,IAC/BpgD,QAAQ,cAAesB,GACvBtB,QAAQ,gBAAiBqiD,IACzBriD,QAAQ,kBEhCN,MACHqN,UAAUs4C,GACNx8D,KAAKw8D,eAAiBA,EAE1B3vB,YACI,OAAO7sC,KAAKw8D,eAEhBh0C,qBAAqB9B,GACjB,QAAK1mB,KAAKw8D,gBAGHx8D,KAAK4sC,QAAQlmB,EAAc1mB,KAAKw8D,gBAE3C5vB,QAAQ2D,EAAGC,GACP,YAAalrC,IAANirC,QACMjrC,IAANkrC,GACAD,EAAEvlC,OAASwlC,EAAExlC,MACbulC,EAAE9qC,KAAO+qC,EAAE/qC,GAEtBw8C,kBAAkBh0C,GACd,OAAOD,EAAkBC,IACW,MAA7BA,EAASxI,GAAGpC,OAAO,EAAG,GAEjCspB,UAAU1e,GACN,QAAKnI,EAASmI,QAGVD,EAAkBC,KAAanI,EAASmI,EAAS0e,aAC1C1e,EAAS0e,cFKvB9V,QAAQ,eAAgBujD,IACxBvjD,QAAQ,eAAgBgkD,IACxBhkD,QAAQ,iBAAkBkkD,IAC1BlkD,QAAQ,eAAgBwkD,IACxBxkD,QAAQ,kBAAmBo8C,IAC3Bp8C,QAAQ,mBAAoBkZ,IAC5BlZ,QAAQ,cAAe6/C,IACvB7/C,QAAQ,iBAAkBu5C,IAC1Bv5C,QAAQ,oBG3CN,MACHyT,kBAAkB7e,GACdzL,KAAKy8D,kBAAoBhxD,EAE7B0nC,oBACI,OAAOnzC,KAAKy8D,qBHuCf5lD,QAAQ,gBAAiB6lD,MACzB7lD,QAAQ,kBAAmBkjD,IAC3BljD,QAAQ,kBI7CN,MACH/P,cACI9G,KAAKmhD,gBAAkB,IAAImZ,aAC3Bt6D,KAAK4H,KAAO,KACZ5H,KAAK+L,QAAU,GACf/L,KAAKmoC,SAAW,GAChBnoC,KAAKioC,SAAW,GAEpBwc,SAAS78C,EAAMugC,EAAUF,EAAUl8B,GAC/B/L,KAAK4H,KAAOA,EACZ5H,KAAKmoC,SAAWA,EAChBnoC,KAAKioC,SAAWA,EAChBjoC,KAAK+L,QAAUA,EACf/L,KAAKmhD,gBAAgBuZ,KAAc,OAAT9yD,GAE9B47C,aACIxjD,KAAK4H,KAAO,KACZ5H,KAAKmoC,SAAW,GAChBnoC,KAAKioC,SAAW,GAChBjoC,KAAK+L,QAAU,GACf/L,KAAKmhD,gBAAgBuZ,MAAK,MJ0B7B7jD,QAAQ,aK/CN,MACHwiC,iBAAiBz0B,GACb,GAAqB,IAAjBA,EAAM1hB,OACN,MAAO,GAEX,MAAMy5D,EAAS,KAAOC,UAAUh4C,GAAOliB,QAAQ,KAAM,OAAOA,QAAQ,KAAM,OAAOA,QAAQ,KAAM,OAAS,KACxG,OAAOoK,KAAKq8C,MAAMwT,ML0CrB9lD,QAAQ,iBAAkB0kD,IDxCxB,MAAMsB,GACT/1D,cACI9G,KAAK88D,OAAS,GACd98D,KAAK+F,IAAM,GAEf20B,IAAI32B,GACA/D,KAAK88D,OAAO/4D,GAAO/D,KAAK+F,IAE5Bg3D,SAASh5D,GACL,OAAO/D,KAAK88D,OAAO/4D,KAAS/D,KAAK+F,IAErC81B,OAAO93B,UACI/D,KAAK88D,OAAO/4D,GAEvBikB,SACI,MAAMA,EAAS,GACf,IAAK,MAAMllB,KAAK9C,KAAK88D,OACb98D,KAAK88D,OAAOh6D,KAAO9C,KAAK+F,KACxBiiB,EAAOxlB,KAAKM,GAGpB,OAAOklB,EAEXkpB,WACI,IAAK,MAAMzjC,KAAWzN,KAAK88D,OACnB98D,KAAK88D,OAAO5T,eAAez7C,IAC3BzN,KAAK67B,OAAOpuB,IAK5B,MAAMuvD,GACFl2D,cACI9G,KAAK6jB,GAAK,KACV7jB,KAAKiL,SAAW,IAAIinB,IACpBlyB,KAAKusB,OAAS,IAAI2F,IAClBlyB,KAAKiqB,kBAAoB,IAAIiI,IAEjC7mB,IAAI8C,GACA,OAAQA,GACJ,IAAK,KACD,OAAOnO,KAAK6jB,GAChB,IAAK,UACD,OAAO7jB,KAAKiL,SAChB,IAAK,QACD,OAAOjL,KAAKusB,OAChB,IAAK,mBACD,OAAOvsB,KAAKiqB,kBAChB,QACI,MAAM,IAAI5gB,MAAM,qCAAuC8E,IAGnEoV,QAAQtV,GACJ,GAAsB,OAAlBA,EAASjD,KACT,OAAOhL,KAAK6jB,GAAGpe,KAAOwI,EAASxI,GAAKzF,KAAK6jB,QAAKve,EAI9C,OADkBtF,KAAKqL,IAAI4C,EAASjD,MACnBK,IAAI4C,EAASxI,IAGtCyS,IAAItQ,GACA5H,KAAKopC,YAAYxhC,EAAI,SACrB5H,KAAKqpC,UAAUzhC,EAAI,OACnB5H,KAAKspC,qBAAqB1hC,EAAI,kBAElC6jC,MAAM7jC,GACFA,EAAKoD,KAAO,KACZhL,KAAK6jB,GAAKjc,EAEdwhC,YAAYxhC,GACR5H,KAAKiL,SAAW,IAAIinB,IAAItqB,EAAK2E,IAAKhI,IAC9BA,EAAEyG,KAAO,UACTqxD,GAAW93D,EAAG,QAAS,WAChB,CAACA,EAAEkB,GAAIlB,WAEFe,IAAZtF,KAAK6jB,IACL7jB,KAAKiL,SAASiN,IAAIlY,KAAK6jB,GAAGpe,GAAIzF,KAAK6jB,IAG3CwlB,UAAUzhC,GACN5H,KAAKusB,OAAS,IAAI2F,IAAItqB,EAAK2E,IAAK0wD,IAC5BA,EAAEjyD,KAAO,QACTqxD,GAAWY,EAAG,YAAY,GAC1BZ,GAAWY,EAAG,UAAU,GACxBZ,GAAWY,EAAG,WAAW,GAClB,CAACA,EAAEx3D,GAAIw3D,MAGtB3zB,qBAAqB1hC,GACjB5H,KAAKiqB,kBAAoB,IAAIiI,IAAItqB,EAAK2E,IAAK2wD,IACvCA,EAAElyD,KAAO,mBACF,CAACkyD,EAAEz3D,GAAIy3D,MAGtBj0B,OAAO96B,EAAcvG,GACjB,OAAQuG,GACJ,IAAK,KACD,OAAOnO,KAAKm9D,SAASv1D,GACzB,IAAK,UACD,OAAO5H,KAAKimC,cAAcr+B,GAC9B,IAAK,QACD,OAAO5H,KAAKqmC,YAAYz+B,GAC5B,IAAK,mBACD,OAAO5H,KAAKomC,uBAAuBx+B,GACvC,QACI,MAAM,IAAIyB,MAAM,qCAAuC8E,IAGnEi4B,uBAAuBx+B,GACnB,IAAI8kB,EAA2B1sB,KAAKiqB,kBAAkB5e,IAAIzD,EAAKnC,IAC/D,YAAiCH,IAA7BonB,GACA9kB,EAAKoD,KAAO,mBACZhL,KAAKiqB,kBAAkB/R,IAAItQ,EAAKnC,GAAImC,GAC7BA,IAEX8kB,EAA2BttB,QAAQ6pC,OAAOvc,EAA0B9kB,GAC7D8kB,GAEX2Z,YAAYz+B,GACRy0D,GAAWz0D,EAAM,YAAY,GAC7By0D,GAAWz0D,EAAM,UAAU,GAC3By0D,GAAWz0D,EAAM,WAAW,GAC5B,IAAI4kB,EAAgBxsB,KAAKusB,OAAOlhB,IAAIzD,EAAKnC,IACzC,YAAsBH,IAAlBknB,GACA5kB,EAAKoD,KAAO,QACZhL,KAAKusB,OAAOrU,IAAItQ,EAAKnC,GAAImC,GAClBA,IAEX4kB,EAAgBptB,QAAQ6pC,OAAOzc,EAAe5kB,GACvC4kB,GAEX2wC,SAASv1D,GACL,YAAgBtC,IAAZtF,KAAK6jB,IACLjc,EAAKoD,KAAO,KACZhL,KAAK6jB,GAAKjc,EACHA,IAEX5H,KAAK6jB,GAAKzkB,QAAQ6pC,OAAOjpC,KAAK6jB,GAAIjc,GAC3B5H,KAAK6jB,IAEhBoiB,cAAcr+B,GACV,IAAIzC,EAAkBnF,KAAKiL,SAASI,IAAIzD,EAAKnC,IAC7C,YAAwBH,IAApBH,GACAyC,EAAKoD,KAAO,UACZqxD,GAAWz0D,EAAM,QAAS,WAC1B5H,KAAKiL,SAASiN,IAAItQ,EAAKnC,GAAImC,GACpBA,IAEXzC,EAAkB/F,QAAQ6pC,OAAO9jC,EAAiByC,GAC3CzC,IAGR,MAAMi4D,GACTt2D,YAAY8X,GACR5e,KAAKyjB,cAAgB,GACrBzjB,KAAKyE,OAAS,KACdzE,KAAKq9D,UAAY,KACjBr9D,KAAK4e,gBAAkBA,EAE3BvT,MACI,IAAIoY,EAAgBzjB,KAAKyjB,cAOzB,OANmB,MAAfzjB,KAAKyE,SACLgf,EAAgBzjB,KAAKyE,OAAOgf,IAEV,MAAlBzjB,KAAKq9D,YACL55C,EAAgBA,EAAclX,IAAIvM,KAAKq9D,YAEpC55C,EAEXvL,IAAItQ,GACA,IAAK,MAAM8e,KAAgB9e,OACOtC,IAA1BohB,EAAate,iBACNse,EAAate,SAExBi0D,GAAW31C,EAAc,aAAa,GAE1C1mB,KAAKyjB,cAAgB7b,EAEzB8b,KAAKjI,GACD,IAAK,MAAMiL,KAAgB1mB,KAAKqL,MAAO,CACnC,MAAMklC,EAAI90B,EACJ+0B,EAAI9pB,EACV,QAAUphB,IAANirC,QAAyBjrC,IAANkrC,GAAmBD,EAAEvlC,OAASwlC,EAAExlC,MAAQulC,EAAE9qC,KAAO+qC,EAAE/qC,GACtE,OAAOihB,EAGf,OAAO,KAEXgU,IAAIhU,GACA1mB,KAAKyjB,cAAcglC,OAAO/hC,EAAate,SAAU,EAAGse,GAExDijB,YAAYjjB,EAAc42C,GAAY,GAClC,IAAK,MAAMx6D,KAAK9C,KAAKyjB,cAAc3e,OAC/B,GAAI9E,KAAK4e,gBAAgBguB,QAAQ5sC,KAAKyjB,cAAc3gB,GAAI4jB,GAAe,CACnE,IAAI62C,EAAuB,KAU3B,GATID,IACAC,EAAuB72D,EAAY1G,KAAKyjB,cAAc3gB,KAE1Du5D,GAAW31C,EAAc,aAAa,GACtC7hB,OAAO+B,OAAO5G,KAAKyjB,cAAc3gB,GAAI4jB,QACFphB,IAA/BohB,EAAamB,oBAC8BviB,IAAxCtF,KAAKyjB,cAAc3gB,GAAG+kB,sBAClB7nB,KAAKyjB,cAAc3gB,GAAG+kB,cAE7B7nB,KAAKyjB,cAAc3gB,GAAGsF,WAAatF,EAAG,CACtC,MAAM06D,EAAMx9D,KAAKyjB,cAAcglC,OAAO3lD,EAAG,GAAG,GAC5C9C,KAAKyjB,cAAcglC,OAAO/hC,EAAate,SAAU,EAAGo1D,GAExD,OAAOD,EAIf,OADAv9D,KAAK06B,IAAIhU,GACF,KAEXmV,OAAOnV,GACH,IAAK,MAAM5jB,KAAK9C,KAAKyjB,cAAc3e,OAC/B,GAAI9E,KAAK4e,gBAAgBguB,QAAQ5sC,KAAKyjB,cAAc3gB,GAAI4jB,GAEpD,YADA1mB,KAAKyjB,cAAcglC,OAAO3lD,EAAG,GAKzCiiC,UAAUtgC,GACNzE,KAAKyE,OAASA,EAElBmgC,aAAay4B,GACTr9D,KAAKq9D,UAAYA,GAGzB,MAAMI,GACF32D,cACI9G,KAAK09D,eAAiB,KACtB19D,KAAK29D,WAAY,EACjB39D,KAAKmnC,MAAO,EACZnnC,KAAKwqD,KAAO,IAGpB,MAAMoT,GACF92D,YAAY8C,GACR5J,KAAKokB,SAAW,IAAI8N,IACpBlyB,KAAKq9D,UAAY,KACjBr9D,KAAKqF,IAAMuE,EAAWQ,UAAU,qBAEpCyzD,WAAW5vD,GACFjO,KAAKokB,SAASlZ,IAAI+C,EAASjD,OAC5BhL,KAAKokB,SAASlM,IAAIjK,EAASjD,KAAM,IAAIknB,KAEzC,MAAM4rC,EAAU99D,KAAKokB,SAAS/Y,IAAI4C,EAASjD,MACtC8yD,EAAQ5yD,IAAI+C,EAASxI,KACtBq4D,EAAQ5lD,IAAIjK,EAASxI,GAAI,IAAIg4D,IAGrCM,oBAAoB9vD,GAEhB,OADAjO,KAAK69D,WAAW5vD,GACTjO,KAAKokB,SAAS/Y,IAAI4C,EAASjD,MAAMK,IAAI4C,EAASxI,IAEzDyf,QAAQjX,GACJ,OAAOjO,KAAK+9D,oBAAoB9vD,GAAUu8C,KAE9Cp2B,MAAMrtB,GACF/G,KAAKokB,SAAS9hB,QAAQ,CAAC07D,EAAY7vD,KAC/B6vD,EAAW17D,QAAQ,CAAC8hB,EAAU3e,KAC1B2e,EAASu5C,WAAY,EACrBv5C,EAASs5C,eAAiB,KAC1Bt5C,EAAS+iB,MAAO,EAChB/iB,EAASomC,KAAO,GAChBxqD,KAAKszB,OAAO,CACR7tB,GAAIA,EACJuF,KAAMmD,GACPpH,OAIfmiC,sBAAsBj7B,GAClB,IAAIgwD,EAAqB,EACzB,GAAIj+D,KAAKokB,SAASlZ,IAAI+C,EAASjD,MAAO,CAClC,MAAMkzD,EAAel+D,KAAKokB,SAAS/Y,IAAI4C,EAASjD,MAC5CkzD,EAAahzD,IAAI+C,EAASxI,MAC1Bw4D,EAAqBC,EAAa7yD,IAAI4C,EAASxI,IAAI+kD,KAAKtnD,OACxDg7D,EAAanlD,OAAO9K,EAASxI,KAGrC,OAAOw4D,EAEXlB,SAAS9uD,GACL,OAAOjO,KAAKokB,SAASlZ,IAAI+C,EAASjD,OAC9BhL,KAAKokB,SAAS/Y,IAAI4C,EAASjD,MAAME,IAAI+C,EAASxI,IAEtD+Z,QAAQvR,GACJ,OAAOjO,KAAK+9D,oBAAoB9vD,GAAUk5B,KAE9CK,QAAQv5B,EAAUk5B,GACdnnC,KAAK+9D,oBAAoB9vD,GAAUk5B,KAAOA,EAE9CjJ,kBAAkBjwB,GACd,OAAOjO,KAAK+9D,oBAAoB9vD,GAAUyvD,eAE9Cz/B,YAAYhwB,GACR,OAAOjO,KAAK+9D,oBAAoB9vD,GAAU0vD,UAE9Cx/B,aAAalwB,GACT,MAAMmW,EAAWpkB,KAAK+9D,oBAAoB9vD,GAC1C,GAAImW,EAASu5C,UACT,MAAM,IAAIt0D,MAAM,gCAAkC4E,EAASxI,GAAK,kBAEpE2e,EAASu5C,WAAY,EAEzBp2B,eAAet5B,GACMjO,KAAK+9D,oBAAoB9vD,GACjC0vD,WAAY,EAEzB78B,SAAS7yB,EAAUmW,GACf,GAAwB,IAApBA,EAASlhB,OACT,OAEJ,MAAMi7D,EAAmBn+D,KAAK+9D,oBAAoB9vD,GACb,IAAjCkwD,EAAiB3T,KAAKtnD,SACtBi7D,EAAiBT,eAAiBt5C,EAAS,GAAG3e,IAElD,IAAK,MAAM+F,KAAW4Y,OACM9e,IAApBkG,EAAQ+a,UACR/a,EAAQ+a,QAAU43C,EAAiB3T,KAAKtnD,OAAS,EAC3Ci7D,EAAiB3T,KAAK2T,EAAiB3T,KAAKtnD,OAAS,GAAGqjB,QACxD,GAEV43C,EAAiB3T,KAAKhoD,KAAKgJ,GAGnC87B,SAASr5B,EAAUmW,GACf,GAAwB,IAApBA,EAASlhB,OACT,OAEJ,MAAMi7D,EAAmBn+D,KAAK+9D,oBAAoB9vD,GAC5CmwD,EAAUh6C,EAAS,GAAG3e,GACtB44D,EAASj6C,EAASA,EAASlhB,OAAS,GAAGuC,IAE8B,IAAvE04D,EAAiB3T,KAAK8T,UADPpoD,GAAQA,EAAIzQ,KAAO24D,GAAWloD,EAAIzQ,KAAO44D,EACbF,EAAiB3T,OAIhE2T,EAAiBT,eAAiBt5C,EAAS,GAAG3e,GAC9C04D,EAAiB3T,KAAK+T,QAAQhiC,MAAM4hC,EAAiB3T,KAAMpmC,IAJvDpkB,KAAKqF,IAAIG,KAAK,6DAA8D,IAAIyJ,EAAkBmV,EAAS7X,IAAKf,GAAY,IAAI2D,EAAyB3D,MAMjKq9B,iBAAiB56B,EAAUlG,GACE/H,KAAK+9D,oBAAoB9vD,GACjCu8C,KAAKhoD,KAAK,CACvBwI,KAAM,SACNvF,GAAI5B,EAAa,GACjB0E,KAAM,GACNwD,QAAShE,EACTwe,aAASjhB,EACT8+B,UAAWn2B,EAASxI,GACpB+gB,UAAU,EACVmrB,UAAU,EACVyqB,WAAY,SAGpB1zB,OAAOz6B,EAAUzC,GACb,MAAMg/C,EAAOxqD,KAAKklB,QAAQjX,GAC1B,IAAK,IAAInL,EAAI,EAAGA,EAAI0nD,EAAKtnD,OAAQJ,IAC7B,GAAI0nD,EAAK1nD,GAAG2C,KAAO+F,EAAQ/F,GAKvB,YAJ0BH,IAAtBkG,EAAQyzB,YACRzzB,EAAQyzB,UAAYurB,EAAK1nD,GAAGm8B,WAEhCurB,EAAK1nD,GAAK0I,GACH,EAGf,OAAO,EAEXq8B,aAAa55B,EAAU04B,EAAW63B,GAC9B,MAAMhU,EAAOxqD,KAAKklB,QAAQjX,GAC1B,IAAK,MAAMzC,KAAWg/C,EAClB,GAAIh/C,EAAQ/F,KAAOkhC,EAOf,YAN0BrhC,IAAtBkG,EAAQyzB,UACRzzB,EAAQyzB,UAAY,CAAEC,IAAKs/B,GAG3BhzD,EAAQyzB,UAAUC,IAAMs/B,GAErB,EAGf,OAAO,EAEX3iC,OAAO5tB,EAAU04B,GACb,MAAM6jB,EAAOxqD,KAAKklB,QAAQjX,GAC1B,IAAK,IAAInL,EAAI,EAAGA,EAAI0nD,EAAKtnD,OAAQJ,IAC7B,GAAI0nD,EAAK1nD,GAAG2C,KAAOkhC,EAEf,OADA6jB,EAAK/B,OAAO3lD,EAAG,IACR,EAGf,OAAO,EAEXm+B,gBAAgBhzB,EAAUwwD,GACtB,MAAMjU,EAAOxqD,KAAKklB,QAAQjX,GAC1B,IAAK,IAAInL,EAAI,EAAGA,EAAI0nD,EAAKtnD,OAAQJ,IAC7B,GAAI0nD,EAAK1nD,GAAGo+B,cAAgBu9B,EAExB,OADAjU,EAAK/B,OAAO3lD,EAAG,IACR,EAGf,OAAO,EAEX8jC,yBAAyB34B,EAAUizB,EAAayF,GAC5C,MAAM6jB,EAAOxqD,KAAKklB,QAAQjX,GAC1B,IAAK,MAAMzC,KAAWg/C,EAClB,GAAIh/C,EAAQ01B,cAAgBA,EACxB,YAAmB57B,IAAfkG,EAAQ/F,GACD+F,GAEXA,EAAQ01B,YAAc,KACtB11B,EAAQ/F,GAAKkhC,EACNn7B,GAGf,OAAO,KAEX8nB,OAAOrlB,EAAUlH,GACbA,EAAOgf,WAAW,oBAAsB9X,EAASjD,KAAO,IAAMiD,EAASxI,GAAK,YAAazF,KAAKklB,QAAQjX,GAAWjO,KAAKwf,QAAQvR,IAElI2F,SAAS3F,EAAUlH,EAAQpC,GAEvB,OADAoC,EAAOq4C,IAAI,oBAAsBnxC,EAASjD,KAAO,IAAMiD,EAASxI,GAAK,YAAad,GAC3E3E,KAAKklB,QAAQjX,GAExBsW,yBAAyBtW,GACrB,MAAMkwD,EAAmBn+D,KAAK+9D,oBAAoB9vD,GAClD,QAAyB3I,IAArB64D,GAAkCA,EAAiB3T,KAAKtnD,OAAS,EAAG,CACpE,IAAIw7D,EACJ,IAAK,IAAI57D,EAAIq7D,EAAiB3T,KAAKtnD,OAAS,EAAGJ,GAAK,EAAGA,IAAK,CACxD,MAAM0I,EAAU2yD,EAAiB3T,KAAK1nD,GAClCq5D,GAA2B3wD,IAC3B2yD,EAAiB3T,KAAK/B,OAAO3lD,EAAG,QACAwC,IAA5Bo5D,IACAA,GAA2B,KAGzBlzD,EAAQgb,UAAYhb,EAAQib,SAClCi4C,EAA0B57D,QAGFwC,IAA5Bo5D,GACAP,EAAiB3T,KAAK/B,OAAOiW,EAAyB,EAAG,CACrD1zD,KAAM,SACN2mC,UAAU,EACVyqB,WAAY,yBAMhC,MAAMv3B,GACF,iCAAiCvhB,GAC7B,OAAQoD,IACJA,EAAazY,SAAWqV,EAAUC,QAAQ,CACtCvY,KAAM0b,EAAa1b,KACnBvF,GAAIihB,EAAajhB,KAEdihB,IAInB,MAAMi4C,GACF73D,cACI9G,KAAKkY,IAAM,IAAI2kD,GAEnB+B,eAAe3wD,GACX,OAAOA,EAASjD,KAAO,IAAMiD,EAASxI,GAE1C+jC,UAAUv7B,GACNjO,KAAKkY,IAAIwiB,IAAI16B,KAAK4+D,eAAe3wD,IAErC06B,YAAY16B,GACRjO,KAAKkY,IAAI2jB,OAAO77B,KAAK4+D,eAAe3wD,IAExCijC,WACIlxC,KAAKkY,IAAIg5B,WAEbpxB,SAAS7R,GACL,OAAOjO,KAAKkY,IAAI6kD,SAAS/8D,KAAK4+D,eAAe3wD,KAGrD,MAAM4wD,GACF/3D,cACI9G,KAAK8+D,OAAS,IAAI5sC,IAClBlyB,KAAK++D,MAAQ,IAAI7sC,IAErB0sC,eAAe3wD,GACX,OAAOA,EAASxI,GAEpBgc,SAASxT,EAAUsT,GACfvhB,KAAK8+D,OAAO5mD,IAAIlY,KAAK4+D,eAAe3wD,GAAWsT,GAEnD0iB,YAAYh2B,GACRjO,KAAK8+D,OAAO/lD,OAAO/Y,KAAK4+D,eAAe3wD,IAE3CuT,SAASvT,GACL,OAAOjO,KAAK8+D,OAAOzzD,IAAIrL,KAAK4+D,eAAe3wD,IAE/Cq2B,QAAQr2B,EAAU+wD,GACdh/D,KAAK++D,MAAM7mD,IAAIlY,KAAK4+D,eAAe3wD,GAAW+wD,GAElD36B,WAAWp2B,GACPjO,KAAK++D,MAAMhmD,OAAO/Y,KAAK4+D,eAAe3wD,IAE1Cs2B,QAAQt2B,GACJ,OAAOjO,KAAK++D,MAAM1zD,IAAIrL,KAAK4+D,eAAe3wD,KAGlD7O,QAAQC,OAAO,iBAAkB,IAC5B4/D,QAAQ,YAAa,CAAC,UAAW,aAAc,kBAChD,SAAUxgD,EAAS7U,EAAYgV,GAY3B,MAAO,CACHimB,UAAWA,GACXG,QAbJ,MACI,eAAe1hB,GACX,OAAQ5e,GAAQ+Z,EAAQ,UAARA,CAAmB/Z,EAAK4e,GAE5C,kBAAkBrY,GACd,OAAQvG,GAAQ+Z,EAAQ,aAARA,CAAsB/Z,EAAKuG,GAE/C,sBAAsBA,GAClB,OAAQvG,GAAQ+Z,EAAQ,iBAARA,CAA0B/Z,EAAKuG,KAMnDu5B,gBAAiB,IAAM,IAAIw4B,GAC3Bv4B,oBAAqB,IAAM,IAAI24B,GAAcx+C,GAC7C8lB,eAAgB,IAAM,IAAIk5B,GAASh0D,GACnC+6B,aAAc,IAAM,IAAIg6B,GACxBzrC,aAAc,IAAM,IAAI2rC,OOjhBpCvE,aAAW4E,cAAa,SAAUv6D,GAC9ByB,WAAWzB,EAAU,MAEzBvF,QAAQC,OAAO,OAAQ,CACnB,YACA,aACA,SACA,YACA,iBACA,oBACA,mBACA,yBACA,aACA,eACA,kBACA,kBACA,iBACA,gBACA,mBACA,eACA,mBAEC0F,MAAM,UAAW4E,EAAOtJ,SACxB0E,MAAM,mBAAoB,GAC1Bo6D,SAAS,SAAUx1D,GACnBw1D,SAAS,aAtBd,YAsBiCx1D,EAAOtJ,UACnC8+D,SAAS,uBAAwB,CAClClS,GAAI,GACJF,OAAQ,GACRG,MAAO,GACPC,OAAQ,GACRC,KAAM,KAELzjD,OAAO,CAAC,qBAAuBy1D,IAC5BA,EAAmBC,UAAU,eAEhC11D,OAAO,CAAC,qBAAuB21D,IAC5BA,EAAmBC,yBAAyB,sBAC5CD,EAAmBE,gCACnBF,EACKG,qBAAqB,CACtBnmC,OAAQ,QACRomC,OAAQ,UAEPC,mBAAmB,QACnBC,8BAA8B,CAAC,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,MAAO,CAC7F,OAAQ,KACR,OAAQ,KACR,OAAQ,KACR,OAAQ,KACR,OAAQ,KACR,OAAQ,KACR,OAAQ,KACR,OAAQ,KACR,OAAQ,KACR,OAAQ,OAEPC,6BACAC,iBAAiB,SAEzBn2D,OAAO,CAAC,qBAAuBo2D,IAC5BA,EAAmBC,cAAc,UAAW,CACxCC,GAAI,SACJC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,KAAM,SACNC,KAAM,SACNC,KAAM,SACNC,KAAM,SACNC,qBAAsB,QACtBC,mBAAoB,CAAC,KAAM,MAAO,MAAO,MAAO,MAAO,MAAO,SAElEjB,EAAmBC,cAAc,cAAe,CAC5CC,GAAI,UACJC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,IAAK,SACLC,KAAM,SACNC,KAAM,SACNC,KAAM,SACNC,KAAM,SACNC,qBAAsB,QACtBC,mBAAoB,CAAC,KAAM,MAAO,MAAO,MAAO,MAAO,MAAO,SAElEjB,EAAmB34D,MAAM,WACpB65D,eAAe,OAAQ,CAAEC,QAAS,QAClCC,cAAc,UAAW,CAAED,QAAS,SACzCnB,EAAmB34D,MAAM,eACpB65D,eAAe,OAAQ,CAAEC,QAAS,QAClCC,cAAc,cAAe,CAAED,QAAS,SAC7CnB,EAAmBqB,kBAAiB,MAEvCz3D,OAAO,CAAC,mBAAqB03D,QAE7B13D,OAAO,CAAC,gBAAkB23D,IACvBA,EAAcC,aAAa/+D,KAAK,CAAC,aAAeg/D,IACjC,CACHC,QAAUC,IACN,IAAuC,IAAnCA,EAAKpuD,IAAIyU,QAAQ,eACoB,IAArC25C,EAAKpuD,IAAIyU,QAAQ,iBACoB,IAArC25C,EAAKpuD,IAAIyU,QAAQ,iBACc,IAA/B25C,EAAKpuD,IAAIyU,QAAQ,SAAiB,CAClC,MAAMmoC,GAAuC,IAA3BwR,EAAKpuD,IAAIyU,QAAQ,KAAc,IAAM,IACvD25C,EAAKpuD,IAAMouD,EAAKpuD,IAAM48C,EAAYsR,EAEtC,OAAOE,UAK1BzC,QAAQ,oBAAqB,CAAC,aAAc,SAAUr1D,GACnD,MAAMorD,EAASprD,EAAWQ,UAAU,qBACpC,OAAO,SAA4B0I,EAAG6uD,GAClC,IAAK77D,EAASgN,GAEV,YADAkiD,EAAO5pD,MAAP,oCAA0C0H,IAG9C,MAAMlL,EAAO,GACbA,EAAKpF,KAAK,6BACNsQ,EAAEtH,SAAWsH,EAAErH,MACf7D,EAAKpF,KAAKsQ,EAAEtH,QAAQsE,SAASgD,EAAErH,MAArB,UAAgCqH,EAAEtH,QAAlC,gBAAmDsH,EAAErH,KAArD,aAA8DqH,EAAEtH,QAAhE,OAEd5D,EAAKpF,KAAKsQ,EAAEq1C,MAAQr1C,EAAEq1C,MAAQr1C,GAC1B6uD,IACA/5D,EAAKpF,KAAK,kBACVoF,EAAKpF,KAAKm/D,EAAMxZ,MAAQwZ,EAAMxZ,MAAQwZ,IAE1C3M,EAAO5pD,SAASxD,Q,oDCvJ5B,8CAAO,MAAM80D,EACTnhB,UAAUx3C,EAAK6H,EAAYg2D,EAAS,MAChC,MAAM99D,EAAQN,MAAMC,KAAKM,GACnBk0B,EAAS,CAAC,IAChB,IAAI4pC,EAAmB,EACnBC,EAAa,EACjB,MAAMC,EAAc,CAAC,IAAK,KAAM,KAAM,KAAM,KAC5C,IAAIC,GAAiB,EA8BrB,OA7BAl+D,EAAMxB,QAAS2/D,IACX,MAAM/+D,EAASg/D,EAAOt2D,WAAWq2D,EAAY,QAM7C,GALe,OAAXL,GACIG,EAAYh6C,QAAQk6C,IAAe,IACnCD,EAAgBH,EAAmB,GAGvCA,EAAmB3+D,EAAS0I,EAAY,CACxC,IAAIu2D,GAAiB,EACjBH,GAAiB,GACbH,EAAmBG,GAAiBJ,GACjC3pC,EAAO/0B,QAAU,IACpB+0B,EAAOz1B,KAAKy1B,EAAO6pC,GAAYz+D,OAAO2+D,GAAe55C,QACrD6P,EAAO6pC,GAAc7pC,EAAO6pC,GAAYz+D,OAAO,EAAG2+D,GAAe55C,OACjE+5C,GAAiB,EACjBN,GAAoBG,EACpBF,IACAE,GAAiB,GAGrBG,IACAL,IACAD,EAAmB,EACnB5pC,EAAOz1B,KAAK,KAGpBy1B,EAAO6pC,GAAe7pC,EAAO6pC,GAAcG,EAC3CJ,GAAoB3+D,IAEjB+0B,M","file":"2.7658f475145d305b88de.bundle.js","sourcesContent":["angular.module('3ema.components', []);\nimport toggleButton from './components/toggle_button';\nangular.module('3ema.components').component('toggleButton', toggleButton);\n","export default {\n    bindings: {\n        flag: '<',\n        onEnable: '&',\n        onDisable: '&',\n        labelEnabled: '@',\n        labelDisabled: '@',\n        iconEnabled: '@',\n        iconDisabled: '@',\n    },\n    controller: function () {\n        this.getLabel = () => this.flag ? this.labelEnabled : this.labelDisabled;\n        this.getIcon = () => this.flag ? this.iconEnabled : this.iconDisabled;\n        this.action = () => this.flag ? this.onDisable() : this.onEnable();\n    },\n    template: `\n        <md-button\n            class=\"md-icon-button\"\n            translate-attr=\"{'aria-label': $ctrl.getLabel(), 'title': $ctrl.getLabel()}\"\n            role=\"button\"\n            tabindex=\"0\"\n            ng-click=\"$ctrl.action()\"\n            aria-pressed=\"{{ $ctrl.flag }}\">\n            <md-icon><img ng-src=\"{{ $ctrl.getIcon() }}\"></md-icon>\n        </md-button>\n    `,\n};\n","export default {\n    VERSION: '[[VERSION]]',\n    SELF_HOSTED: true,\n    VERSION_MOUNTAIN: 'Säntis',\n    VERSION_MOUNTAIN_URL: 'https://en.wikipedia.org/wiki/Säntis',\n    VERSION_MOUNTAIN_IMAGE_URL: 'https://en.wikipedia.org/wiki/S%C3%A4ntis#/media/File:S%C3%A4ntis_mountain_by_sunset..JPG',\n    VERSION_MOUNTAIN_IMAGE_COPYRIGHT: 'CC BY-SA 3.0 B0rder',\n    VERSION_MOUNTAIN_HEIGHT: 2502,\n    PREV_PROTOCOL_LAST_VERSION: '1.8.2',\n    GIT_BRANCH: 'master',\n    SALTYRTC_HOST: 'saltyrtc-{prefix}.threema.ch',\n    SALTYRTC_PORT: 443,\n    SALTYRTC_SERVER_KEY: 'b1337fc8402f7db8ea639e05ed05d65463e24809792f91eca29e88101b4a2171',\n    ICE_SERVERS: [{\n            urls: [\n                'turn:ds-turn-{prefix}.threema.ch:443?transport=udp',\n                'turn:ds-turn-{prefix}.threema.ch:443?transport=tcp',\n                'turns:ds-turn-{prefix}.threema.ch:443',\n            ],\n            username: 'threema-angular',\n            credential: 'Uv0LcCq3kyx6EiRwQW5jVigkhzbp70CjN2CJqzmRxG3UGIdJHSJV6tpo7Gj7YnGB',\n        }],\n    PUSH_URL: 'https://push-web.threema.ch/push',\n    FONT_CSS_URL: null,\n    LOG_TAG_PADDING: 20,\n    CONSOLE_LOG_LEVEL: 'debug',\n    REPORT_LOG_LEVEL: 'debug',\n    REPORT_LOG_LIMIT: 1000,\n    COMPOSE_AREA_LOG_LEVEL: 'warn',\n    SALTYRTC_LOG_LEVEL: 'warn',\n    TIMER_LOG_LEVEL: 'info',\n    ARP_LOG_LEVEL: 'debug',\n    ARP_LOG_TRACE: false,\n    MSGPACK_LOG_TRACE: false,\n    TRANSPORT_LOG_LEVEL: 'warn',\n    VISUALIZE_STATE: true,\n};\n","export function u8aToHex(array) {\n    const results = [];\n    array.forEach((arrayByte) => {\n        results.push(arrayByte.toString(16).replace(/^([\\da-f])$/, '0$1'));\n    });\n    return results.join('');\n}\nexport function hexToU8a(hexstring) {\n    let array;\n    let i;\n    let j = 0;\n    let k;\n    let ref;\n    if (hexstring.length % 2 === 1) {\n        hexstring = '0' + hexstring;\n    }\n    array = new Uint8Array(hexstring.length / 2);\n    for (i = k = 0, ref = hexstring.length; k <= ref; i = k += 2) {\n        array[j++] = parseInt(hexstring.substr(i, 2), 16);\n    }\n    return array;\n}\nexport function u8aToBase64(array) {\n    return btoa(Array.from(array, (byte) => String.fromCharCode(byte)).join(''));\n}\nexport function base64ToU8a(base64String) {\n    return Uint8Array.from(atob(base64String), (char) => char.charCodeAt(0));\n}\nexport function randomString(length = 32, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') {\n    let str = '';\n    for (let i = 0; i < length; i++) {\n        str += chars.charAt(Math.floor(Math.random() * chars.length));\n    }\n    return str;\n}\nexport function stringToUtf8a(str) {\n    var out = [], p = 0;\n    for (var i = 0; i < str.length; i++) {\n        var c = str.charCodeAt(i);\n        if (c < 128) {\n            out[p++] = c;\n        }\n        else if (c < 2048) {\n            out[p++] = (c >> 6) | 192;\n            out[p++] = (c & 63) | 128;\n        }\n        else if (((c & 0xFC00) == 0xD800) && (i + 1) < str.length &&\n            ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {\n            c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);\n            out[p++] = (c >> 18) | 240;\n            out[p++] = ((c >> 12) & 63) | 128;\n            out[p++] = ((c >> 6) & 63) | 128;\n            out[p++] = (c & 63) | 128;\n        }\n        else {\n            out[p++] = (c >> 12) | 224;\n            out[p++] = ((c >> 6) & 63) | 128;\n            out[p++] = (c & 63) | 128;\n        }\n    }\n    return Uint8Array.from(out);\n}\nexport function utf8aToString(bytes) {\n    var out = [], pos = 0, c = 0;\n    while (pos < bytes.length) {\n        var c1 = bytes[pos++];\n        if (c1 < 128) {\n            out[c++] = String.fromCharCode(c1);\n        }\n        else if (c1 > 191 && c1 < 224) {\n            var c2 = bytes[pos++];\n            out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);\n        }\n        else if (c1 > 239 && c1 < 365) {\n            var c2 = bytes[pos++];\n            var c3 = bytes[pos++];\n            var c4 = bytes[pos++];\n            var u = ((c1 & 7) << 18 | (c2 & 63) << 12 | (c3 & 63) << 6 | c4 & 63) - 0x10000;\n            out[c++] = String.fromCharCode(0xD800 + (u >> 10));\n            out[c++] = String.fromCharCode(0xDC00 + (u & 1023));\n        }\n        else {\n            var c2 = bytes[pos++];\n            var c3 = bytes[pos++];\n            out[c++] = String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63);\n        }\n    }\n    return out.join('');\n}\nexport function filter(obj, callback) {\n    if (obj instanceof Array) {\n        return obj.filter(callback);\n    }\n    else {\n        const out = {};\n        for (const key in Object.keys(obj)) {\n            const value = obj[key];\n            if (callback(value)) {\n                out[key] = value;\n            }\n        }\n        return out;\n    }\n}\nexport function isString(val) {\n    return typeof val === 'string' || val instanceof String;\n}\nexport function supportsPassive() {\n    let support = false;\n    try {\n        const opts = Object.defineProperty({}, 'passive', {\n            get: () => support = true,\n        });\n        window.addEventListener('test', null, opts);\n    }\n    catch (e) { }\n    return support;\n}\nexport function escapeRegExp(str) {\n    return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\nexport function msgpackVisualizer(array) {\n    return 'https://msgpack.dbrgn.ch#base64=' + encodeURIComponent(u8aToBase64(array));\n}\nexport function hasFeature(contactReceiver, feature, log) {\n    if (contactReceiver !== undefined) {\n        if (contactReceiver.featureMask === 0) {\n            log.warn(`Contact receiver with id ${contactReceiver.id} has featureMask 0`);\n            return false;\n        }\n        if (feature === 0) {\n            return true;\n        }\n        return (contactReceiver.featureMask & feature) !== 0;\n    }\n    log.warn('Cannot check featureMask of an undefined contact receiver');\n    return false;\n}\nexport function bufferToUrl(buffer, mimeType, log) {\n    switch (mimeType) {\n        case 'image/jpg':\n        case 'image/jpeg':\n        case 'image/png':\n        case 'image/webp':\n        case 'image/gif':\n        case 'audio/mp4':\n        case 'audio/aac':\n        case 'audio/ogg':\n        case 'audio/webm':\n            break;\n        default:\n            const fallbackMimeType = 'image/jpeg';\n            log.warn(`Unknown mimeType \"${mimeType}\", falling back to \"${fallbackMimeType}\"`);\n            mimeType = fallbackMimeType;\n            break;\n    }\n    return 'data:' + mimeType + ';base64,' + u8aToBase64(new Uint8Array(buffer));\n}\nexport function arrayToBuffer(array) {\n    if (array.byteOffset === 0 && array.byteLength === array.buffer.byteLength) {\n        return array.buffer;\n    }\n    return array.buffer.slice(array.byteOffset, array.byteOffset + array.byteLength);\n}\nexport function hasValue(val) {\n    return val !== null && val !== undefined;\n}\nexport function sleep(ms) {\n    return new Promise((resolve) => setTimeout(resolve, ms));\n}\nexport function arraysAreEqual(a1, a2) {\n    if (a1.length !== a2.length) {\n        return false;\n    }\n    for (let i = 0; i < a1.length; i++) {\n        if (a1[i] !== a2[i]) {\n            return false;\n        }\n    }\n    return true;\n}\nexport function isActionTrigger(ev) {\n    if (ev.key === undefined) {\n        return false;\n    }\n    switch (ev.key) {\n        case 'Enter':\n        case ' ':\n            return true;\n        default:\n            return false;\n    }\n}\nexport function copyShallow(object) {\n    return Object.assign({}, object);\n}\nexport function copyDeepOrReference(value) {\n    if (value === null || value === undefined) {\n        return value;\n    }\n    if (value.constructor === Object) {\n        const object = {};\n        for (const [k, v] of Object.entries(value)) {\n            object[k] = copyDeepOrReference(v);\n        }\n        return object;\n    }\n    if (value instanceof Array) {\n        return value.map((item) => copyDeepOrReference(item));\n    }\n    if (value instanceof ArrayBuffer) {\n        return value.slice(0);\n    }\n    if (value instanceof Uint8Array) {\n        const buffer = value.buffer.slice(0);\n        return new Uint8Array(buffer, value.byteOffset, value.byteLength);\n    }\n    return value;\n}\nexport function replaceWhitespace(text) {\n    return text\n        .replace(/ /g, '&nbsp;')\n        .replace(/\\t/, '&nbsp;&nbsp;');\n}\n","export class DialogController {\n    constructor($scope, $mdDialog, themeService, activeElement) {\n        this.$mdDialog = $mdDialog;\n        this.activeElement = activeElement !== undefined ? activeElement : document.activeElement;\n        this.theme = themeService.theme;\n        themeService.evtThemeChange.attach((newTheme) => $scope.$apply(() => this.theme = newTheme));\n    }\n    cancel() {\n        this.$mdDialog.cancel();\n        this.restoreFocus();\n    }\n    hide(data) {\n        this.$mdDialog.hide(data);\n        this.restoreFocus();\n    }\n    restoreFocus() {\n        if (this.activeElement !== null) {\n            this.activeElement.focus();\n        }\n    }\n}\nDialogController.$inject = ['$scope', '$mdDialog', 'ThemeService'];\n","export function copyString(text, useSelectionRange = false) {\n    const activeElement = document.activeElement;\n    const textArea = document.createElement('textarea');\n    textArea.value = text;\n    textArea.style.position = 'absolute';\n    textArea.style.left = '-9999px';\n    textArea.style.top = '-9999px';\n    document.body.appendChild(textArea);\n    try {\n        if (useSelectionRange) {\n            textArea.contentEditable = 'true';\n            textArea.readOnly = false;\n            const range = document.createRange();\n            const selection = self.getSelection();\n            selection.removeAllRanges();\n            selection.addRange(range);\n            textArea.setSelectionRange(0, 999999);\n        }\n        else {\n            textArea.focus();\n            textArea.select();\n        }\n        if (!document.execCommand('copy')) {\n            throw new Error('Unable to copy into clipboard');\n        }\n    }\n    finally {\n        document.body.removeChild(textArea);\n        if (activeElement !== null) {\n            activeElement.focus();\n        }\n    }\n}\n","import { arrayToBuffer, copyShallow, hasFeature, sleep } from '../helpers';\nimport * as clipboard from '../helpers/clipboard';\nimport { DialogController } from './dialog';\nexport class TroubleshootingController extends DialogController {\n    constructor($scope, $mdDialog, $mdToast, $translate, config, logService, browserService, themeService, webClientService) {\n        super($scope, $mdDialog, themeService);\n        this.sanitize = true;\n        this.isSending = false;\n        this.sendingFailed = false;\n        this.description = '';\n        this.$scope = $scope;\n        this.$mdToast = $mdToast;\n        this.$translate = $translate;\n        this.config = config;\n        this.logService = logService;\n        this.browserService = browserService;\n        this.webClientService = webClientService;\n        this.log = logService.getLogger('Troubleshooting-C');\n    }\n    get isConnected() {\n        return this.webClientService.readyToSubmit;\n    }\n    get canSend() {\n        return this.isConnected && this.description.length > 0 && !this.isSending;\n    }\n    async send() {\n        this.isSending = true;\n        this.sendingFailed = false;\n        const log = new TextEncoder().encode(this.getLog(this.sanitize));\n        const fail = () => {\n            this.$scope.$apply(() => {\n                this.isSending = false;\n                this.sendingFailed = true;\n                this.$mdToast.show(this.$mdToast.simple()\n                    .textContent(this.$translate.instant('troubleshooting.REPORT_VIA_THREEMA_FAILED'))\n                    .position('bottom center'));\n            });\n        };\n        const support = {\n            id: '*SUPPORT',\n            type: 'contact',\n        };\n        if (!this.webClientService.contacts.has(support.id)) {\n            try {\n                await this.webClientService.addContact(support.id);\n            }\n            catch (error) {\n                this.log.error('Unable to add contact *SUPPORT:', error);\n                return fail();\n            }\n        }\n        for (let i = 0; i < 50; ++i) {\n            const contact = this.webClientService.contacts.get(support.id);\n            if (hasFeature(contact, 8, this.log)) {\n                break;\n            }\n            await sleep(100);\n        }\n        const browser = this.browserService.getBrowser();\n        const message = {\n            name: `webclient-${this.config.VERSION}-${browser.description('-')}.log`,\n            fileType: 'text/plain',\n            size: log.byteLength,\n            data: arrayToBuffer(log),\n            caption: this.description,\n            sendAsFile: true,\n        };\n        try {\n            await this.webClientService.sendMessage(support, 'file', message, { waitUntilAcknowledged: true });\n        }\n        catch (error) {\n            this.log.error('Unable to send log report to *SUPPORT:', error);\n            return fail();\n        }\n        this.isSending = false;\n        this.$mdToast.show(this.$mdToast.simple()\n            .textContent(this.$translate.instant('troubleshooting.REPORT_VIA_THREEMA_SUCCESS'))\n            .position('bottom center'));\n        this.hide();\n    }\n    copyToClipboard() {\n        const log = this.getLog(this.sanitize);\n        let toastString = 'messenger.COPIED';\n        try {\n            clipboard.copyString(log, this.browserService.getBrowser().isSafari());\n        }\n        catch (error) {\n            this.log.warn('Could not copy text to clipboard:', error);\n            toastString = 'messenger.COPY_ERROR';\n        }\n        this.$mdToast.show(this.$mdToast.simple()\n            .textContent(this.$translate.instant(toastString))\n            .position('bottom center'));\n    }\n    getLog(sanitize) {\n        const browser = this.browserService.getBrowser();\n        const config = copyShallow(this.config);\n        if (sanitize) {\n            config.ICE_SERVERS = config.ICE_SERVERS.map((server) => {\n                server = copyShallow(server);\n                for (const key of ['username', 'credential', 'credentialType']) {\n                    if (server[key] !== undefined) {\n                        server[key] = `[${server[key].constructor.name}]`;\n                    }\n                }\n                return server;\n            });\n        }\n        const container = {\n            config: config,\n            browser: browser.description(),\n            log: this.logService.memory.getRecords(),\n        };\n        const replacer = this.logService.memory.getReplacer(sanitize);\n        return JSON.stringify(container, replacer, 2);\n    }\n}\nTroubleshootingController.$inject = [\n    '$scope', '$mdDialog', '$mdToast', '$translate',\n    'CONFIG', 'LogService', 'BrowserService', 'ThemeService', 'WebClientService',\n];\n","import { isActionTrigger } from '../helpers';\nimport { DialogController } from './dialog';\nimport { TroubleshootingController } from './troubleshooting';\nclass VersionDialogController extends DialogController {\n    constructor($scope, $mdDialog, themeService, config) {\n        super($scope, $mdDialog, themeService);\n        this.version = config.VERSION;\n        this.fullVersion = `${config.VERSION} ${config.VERSION_MOUNTAIN}`;\n        this.config = config;\n    }\n}\nVersionDialogController.$inject = ['$scope', '$mdDialog', 'ThemeService', 'CONFIG'];\nexport class FooterController {\n    constructor(CONFIG, $mdDialog) {\n        this.$mdDialog = $mdDialog;\n        this.config = CONFIG;\n    }\n    showVersionInfo(ev) {\n        if (ev !== undefined && !isActionTrigger(ev)) {\n            return;\n        }\n        this.$mdDialog.show({\n            controller: VersionDialogController,\n            controllerAs: 'ctrl',\n            templateUrl: 'partials/dialog.version.html',\n            parent: angular.element(document.body),\n            clickOutsideToClose: true,\n            fullscreen: true,\n        });\n    }\n    showTroubleshooting(ev) {\n        if (ev !== undefined && !isActionTrigger(ev)) {\n            return;\n        }\n        this.$mdDialog.show({\n            controller: TroubleshootingController,\n            controllerAs: 'ctrl',\n            templateUrl: 'partials/dialog.troubleshooting.html',\n            parent: angular.element(document.body),\n            clickOutsideToClose: true,\n            fullscreen: true,\n        });\n    }\n    get changelogUrl() {\n        return 'https://github.com/threema-ch/threema-web/blob/' + this.config.GIT_BRANCH + '/CHANGELOG.md';\n    }\n}\nFooterController.$inject = ['CONFIG', '$mdDialog'];\n","export class HeaderController {\n    constructor(config) {\n        this.config = config;\n    }\n    useThreemaFont() {\n        return !this.config.SELF_HOSTED || this.config.FONT_CSS_URL !== null;\n    }\n    fontUrl() {\n        if (this.config.FONT_CSS_URL === null) {\n            return 'https://static.threema.ch/fonts/labgrotesque.css';\n        }\n        else {\n            return this.config.FONT_CSS_URL;\n        }\n    }\n}\nHeaderController.$inject = ['CONFIG'];\n","export function isContactReceiver(receiver) {\n    return receiver.type === 'contact';\n}\nexport function isGroupReceiver(receiver) {\n    return receiver.type === 'group';\n}\nexport function isDistributionListReceiver(receiver) {\n    return receiver.type === 'distributionList';\n}\nexport function isValidReceiverType(receiverType) {\n    switch (receiverType) {\n        case 'me':\n        case 'contact':\n        case 'group':\n        case 'distributionList':\n            return true;\n    }\n    return false;\n}\nexport function isValidDisconnectReason(reason) {\n    switch (reason) {\n        case 'stop':\n        case 'delete':\n        case 'disable':\n        case 'replace':\n            return true;\n    }\n    return false;\n}\nexport function isTextNode(node) {\n    return node.nodeType === node.TEXT_NODE;\n}\nexport function isElementNode(node) {\n    return node.nodeType === node.ELEMENT_NODE;\n}\nexport function isEmojiInfo(val) {\n    return typeof val === 'object'\n        && val.emojiString !== undefined\n        && val.imgPath !== undefined\n        && val.codepoint !== undefined;\n}\nexport function controllerModelHasMembers(cm) {\n    return cm.receiverType === 'group' || cm.receiverType === 'distributionList';\n}\nexport function isKeyboardEvent(ev) {\n    return ev.type === 'keydown' || ev.type === 'keypress' || ev.type === 'keyup';\n}\n","import * as SDPUtils from 'sdp';\nexport function censor(value) {\n    if (value === null || value === undefined) {\n        return value;\n    }\n    if (value instanceof BaseConfidential) {\n        return value.censored();\n    }\n    if (value.constructor === String) {\n        return `[String: length=${value.length}]`;\n    }\n    if (value instanceof Array) {\n        return value.map((item) => censor(item));\n    }\n    if (value instanceof ArrayBuffer) {\n        return `[ArrayBuffer: length=${value.byteLength}]`;\n    }\n    if (value instanceof Uint8Array) {\n        return `[Uint8Array: length=${value.byteLength}, offset=${value.byteOffset}]`;\n    }\n    if (value instanceof Blob) {\n        return `[Blob: length=${value.size}, type=${value.type}]`;\n    }\n    if (value.constructor === Object) {\n        const object = {};\n        for (const [k, v] of Object.entries(value)) {\n            object[k] = censor(v);\n        }\n        return object;\n    }\n    return `[${value.constructor.name}]`;\n}\nexport class BaseConfidential {\n}\nexport class ConfidentialArray extends BaseConfidential {\n    constructor(array) {\n        super();\n        this.array = array;\n    }\n    get uncensored() {\n        return this.array.map((item) => item.uncensored);\n    }\n    censored() {\n        return this.array.map((item) => item.censored());\n    }\n}\nexport class ConfidentialObjectValues extends BaseConfidential {\n    constructor(object) {\n        super();\n        this.uncensored = object;\n    }\n    censored() {\n        return censor(this.uncensored);\n    }\n}\nexport class ConfidentialWireMessage extends BaseConfidential {\n    constructor(message) {\n        super();\n        this.uncensored = message;\n    }\n    censored() {\n        const message = Object.assign({}, this.uncensored);\n        if (message.args !== undefined) {\n            message.args = censor(message.args);\n        }\n        if (message.data !== undefined) {\n            message.data = censor(message.data);\n        }\n        return message;\n    }\n}\nexport class ConfidentialIceCandidate extends BaseConfidential {\n    constructor(candidateSdp) {\n        super();\n        this.uncensored = candidateSdp;\n    }\n    censored() {\n        try {\n            const candidate = SDPUtils.parseCandidate(this.uncensored);\n            if (candidate.type !== 'relay') {\n                candidate.address = candidate.ip = ConfidentialIceCandidate.censorIp(candidate.address);\n            }\n            if (candidate.relatedAddress !== undefined) {\n                candidate.relatedAddress = ConfidentialIceCandidate.censorIp(candidate.relatedAddress);\n            }\n            return SDPUtils.writeCandidate(candidate);\n        }\n        catch (error) {\n            return this.uncensored;\n        }\n    }\n    static censorIp(ip) {\n        if (ip.includes('-')) {\n            return ip;\n        }\n        const ipv4 = ip.split('.');\n        if (ipv4.length > 1) {\n            return `${ipv4.slice(0, 2).join('.')}.*.*`;\n        }\n        const ipv6 = ip.split(':');\n        const head = ipv6.shift();\n        return `${head}:${ipv6.map((item) => item.length > 0 ? '*' : item).join(':')}`;\n    }\n}\n","export class FlowControlledDataChannel {\n    constructor(dc, logService, logLevel, lowWaterMark = 256 * 1024, highWaterMark = 1024 * 1024) {\n        this.log = null;\n        this._ready = new Future();\n        this.log = logService.getLogger(`FlowControlledDataChannel.${dc.id}`, 'color: #fff; background-color: #009688', logLevel);\n        this.dc = dc;\n        this.highWaterMark = highWaterMark;\n        this._ready.resolve();\n        this.dc.bufferedAmountLowThreshold = lowWaterMark;\n        this.dc.onbufferedamountlow = () => {\n            if (!this._ready.done) {\n                this.log.debug(`${this.dc.label} resumed (buffered=${this.dc.bufferedAmount})`);\n                this._ready.resolve();\n            }\n        };\n    }\n    get ready() {\n        return this._ready;\n    }\n    write(message) {\n        if (!this._ready.done) {\n            throw new Error('Unable to write, data channel is paused!');\n        }\n        this.dc.send(message);\n        if (this.dc.bufferedAmount >= this.highWaterMark) {\n            this._ready = new Future();\n            this.log.debug(`${this.dc.label} paused (buffered=${this.dc.bufferedAmount})`);\n        }\n    }\n}\nexport class UnboundedFlowControlledDataChannel extends FlowControlledDataChannel {\n    constructor() {\n        super(...arguments);\n        this.queue = this.ready;\n    }\n    write(message) {\n        this.queue = this.queue.then(() => this.writeWhenReady(message));\n    }\n    async writeWhenReady(message) {\n        await this.ready;\n        super.write(message);\n    }\n}\n","import { ConfidentialIceCandidate } from '../helpers/confidential';\nimport { UnboundedFlowControlledDataChannel } from '../helpers/data_channel';\nexport class PeerConnectionHelper {\n    constructor($q, $rootScope, config, logService, timeoutService, webrtcTask, iceServers) {\n        this.connectionFailedTimer = null;\n        this.sdc = null;\n        this.closed = false;\n        this.connectionState = \"new\";\n        this.onConnectionStateChange = null;\n        this.log = logService.getLogger('PeerConnection', 'color: #fff; background-color: #3333ff');\n        this.log.info('Initialize WebRTC PeerConnection');\n        this.log.debug('ICE servers used:', [].concat(...iceServers.map((server) => server.urls)));\n        this.$q = $q;\n        this.$rootScope = $rootScope;\n        this.config = config;\n        this.logService = logService;\n        this.timeoutService = timeoutService;\n        this.webrtcTask = webrtcTask;\n        this.pc = new RTCPeerConnection({ iceServers: iceServers });\n        this.pc.onnegotiationneeded = () => {\n            this.log.debug('RTCPeerConnection: negotiation needed');\n            this.initiatorFlow()\n                .then(() => this.log.debug('Initiator flow done'));\n        };\n        this.pc.onconnectionstatechange = () => {\n            this.log.debug('Connection state change:', this.pc.connectionState);\n        };\n        this.pc.onsignalingstatechange = () => {\n            this.log.debug('Signaling state change:', this.pc.signalingState);\n        };\n        this.setupIceCandidateHandling();\n        this.pc.ondatachannel = (e) => {\n            this.log.debug('New data channel was created:', e.channel.label);\n        };\n    }\n    get peerConnection() {\n        return this.pc;\n    }\n    setupIceCandidateHandling() {\n        this.log.debug('Setting up ICE candidate handling');\n        this.pc.onicecandidate = (e) => {\n            if (e.candidate) {\n                this.log.debug('Gathered local ICE candidate:', new ConfidentialIceCandidate(e.candidate.candidate));\n                this.webrtcTask.sendCandidate({\n                    candidate: e.candidate.candidate,\n                    sdpMid: e.candidate.sdpMid,\n                    sdpMLineIndex: e.candidate.sdpMLineIndex,\n                });\n            }\n            else {\n                this.log.debug('No more local ICE candidates');\n            }\n        };\n        this.pc.onicecandidateerror = (e) => {\n            this.log.warn(`ICE candidate error: ${e.errorText} ` +\n                `(url=${e.url}, host-candidate=${e.hostCandidate}, code=${e.errorCode})`);\n        };\n        this.pc.oniceconnectionstatechange = () => {\n            this.log.debug('ICE connection state change:', this.pc.iceConnectionState);\n            this.$rootScope.$apply(() => {\n                if (this.connectionFailedTimer !== null) {\n                    this.timeoutService.cancel(this.connectionFailedTimer);\n                    this.connectionFailedTimer = null;\n                }\n                switch (this.pc.iceConnectionState) {\n                    case 'new':\n                        this.setConnectionState(\"new\");\n                        break;\n                    case 'checking':\n                    case 'disconnected':\n                        this.setConnectionState(\"connecting\");\n                        this.connectionFailedTimer = this.timeoutService.register(() => {\n                            this.connectionFailedTimer = null;\n                            this.log.debug('ICE connection considered failed');\n                            this.closed = true;\n                            this.close();\n                            this.setConnectionState(\"disconnected\");\n                        }, PeerConnectionHelper.CONNECTION_FAILED_TIMEOUT_MS, true, 'connectionFailedTimer');\n                        break;\n                    case 'connected':\n                    case 'completed':\n                        this.setConnectionState(\"connected\");\n                        break;\n                    case 'failed':\n                    case 'closed':\n                        this.closed = true;\n                        this.setConnectionState(\"disconnected\");\n                        break;\n                    default:\n                        this.log.warn('Ignored ICE connection state change to', this.pc.iceConnectionState);\n                }\n            });\n        };\n        this.pc.onicegatheringstatechange = () => {\n            this.log.debug('ICE gathering state change:', this.pc.iceGatheringState);\n        };\n        this.webrtcTask.on('candidates', (e) => {\n            for (const candidateInit of e.data) {\n                if (candidateInit) {\n                    this.log.debug('Adding remote ICE candidate:', new ConfidentialIceCandidate(candidateInit.candidate));\n                }\n                else {\n                    this.log.debug('No more remote ICE candidates');\n                }\n                this.pc.addIceCandidate(candidateInit)\n                    .catch((error) => this.log.warn('Unable to add ice candidate:', error));\n            }\n        });\n    }\n    async initiatorFlow() {\n        const offer = await this.pc.createOffer();\n        await this.pc.setLocalDescription(offer);\n        this.log.debug('Created offer, set local description');\n        this.webrtcTask.sendOffer(offer);\n        const receiveAnswer = () => {\n            return new Promise((resolve) => {\n                this.webrtcTask.once('answer', (e) => {\n                    resolve(e.data);\n                });\n            });\n        };\n        const answer = await receiveAnswer();\n        await this.pc.setRemoteDescription(answer);\n        this.log.debug('Received answer, set remote description');\n    }\n    handover() {\n        if (this.sdc !== null) {\n            throw new Error('Handover already inintiated');\n        }\n        const link = this.webrtcTask.getTransportLink();\n        const dc = this.pc.createDataChannel(link.label, {\n            id: link.id,\n            negotiated: true,\n            ordered: true,\n            protocol: link.protocol,\n        });\n        dc.binaryType = 'arraybuffer';\n        this.sdc = new UnboundedFlowControlledDataChannel(dc, this.logService, this.config.TRANSPORT_LOG_LEVEL);\n        const self = this;\n        const handler = {\n            get maxMessageSize() {\n                return self.pc.sctp.maxMessageSize;\n            },\n            close() {\n                if (self.closed) {\n                    self.log.debug('Ignoring signalling data channel close request, already closed');\n                }\n                else {\n                    self.log.debug(`Signalling data channel close request`);\n                    dc.close();\n                }\n            },\n            send(message) {\n                self.log.debug(`Signalling data channel outgoing signaling message of ` +\n                    `length ${message.byteLength}`);\n                self.sdc.write(message);\n            },\n        };\n        dc.onopen = () => {\n            this.log.info(`Signalling data channel open`);\n            dc.onclose = () => {\n                if (this.closed) {\n                    this.log.debug('Ignoring signalling data channel closed');\n                }\n                else {\n                    this.log.info(`Signalling data channel closed`);\n                    link.closed();\n                }\n            };\n            this.webrtcTask.handover(handler);\n        };\n        dc.onclose = () => {\n            this.log.error(`Signalling data channel closed`);\n        };\n        dc.onerror = (event) => {\n            this.log.warn(`Signalling data channel error (closed=${this.closed}):`, event.error);\n        };\n        dc.onmessage = (event) => {\n            this.log.debug(`Signalling data channel incoming message of length ${event.data.byteLength}`);\n            link.receive(new Uint8Array(event.data));\n        };\n    }\n    setConnectionState(state) {\n        if (state !== this.connectionState) {\n            this.connectionState = state;\n            if (this.onConnectionStateChange !== null) {\n                this.onConnectionStateChange(state);\n            }\n        }\n    }\n    close() {\n        if (this.connectionFailedTimer !== null) {\n            this.timeoutService.cancel(this.connectionFailedTimer);\n            this.connectionFailedTimer = null;\n        }\n        this.webrtcTask.off();\n        this.pc.onnegotiationneeded = null;\n        this.pc.onconnectionstatechange = null;\n        this.pc.onsignalingstatechange = null;\n        this.pc.onicecandidate = null;\n        this.pc.onicecandidateerror = null;\n        this.pc.oniceconnectionstatechange = null;\n        this.pc.onicegatheringstatechange = null;\n        this.pc.ondatachannel = null;\n        this.pc.close();\n    }\n}\nPeerConnectionHelper.CONNECTION_FAILED_TIMEOUT_MS = 15000;\n","export class TimeoutError extends Error {\n}\nexport class PushError extends Error {\n    constructor(msg, statusCode) {\n        super(msg);\n        this.statusCode = statusCode;\n    }\n}\n","import { u8aToHex } from '../helpers';\nexport async function sha256(bytes) {\n    if (window.crypto === undefined) {\n        throw new Error('window.crypto API not available');\n    }\n    if (window.crypto.subtle === undefined) {\n        throw new Error('window.subtle API not available');\n    }\n    const buf = await crypto.subtle.digest('SHA-256', bytes);\n    return u8aToHex(new Uint8Array(buf));\n}\n","import { PushError, TimeoutError } from '../exceptions';\nimport { randomString, sleep } from '../helpers';\nimport { sha256 } from '../helpers/crypto';\nexport class PushSession {\n    constructor(service, session, config) {\n        this.doneFuture = new Future();\n        this.affiliation = randomString(6);\n        this.running = false;\n        this.tries = 0;\n        this.log = service.logService.getLogger(`Push.${this.affiliation}`, 'color: #fff; background-color: #9900cc');\n        this.service = service;\n        this.session = session;\n        this.config = config !== undefined ? config : PushSession.defaultConfig;\n        this.retryTimeoutMs = this.config.retryTimeoutInitMs;\n        if (this.config.timeToLiveRange.length === 0) {\n            throw new Error('timeToLiveRange must not be an empty array');\n        }\n        if (this.config.triesMax < 1) {\n            throw new Error('triesMax must be >= 1');\n        }\n    }\n    static get defaultConfig() {\n        return {\n            retryTimeoutInitMs: 2000,\n            retryTimeoutMaxMs: 30000,\n            triesMax: 3,\n            timeToLiveRange: [0, 15, 90],\n        };\n    }\n    static expectedPeriodMaxMs(config) {\n        if (config === undefined) {\n            config = PushSession.defaultConfig;\n        }\n        if (config.triesMax === Number.POSITIVE_INFINITY) {\n            return Number.POSITIVE_INFINITY;\n        }\n        let retryTimeoutMs = config.retryTimeoutInitMs;\n        let sumMs = 0;\n        for (let i = 0; i < config.triesMax; ++i) {\n            sumMs += retryTimeoutMs;\n            retryTimeoutMs = Math.min(retryTimeoutMs * 2, config.retryTimeoutMaxMs);\n        }\n        return sumMs;\n    }\n    start() {\n        if (!this.running) {\n            this.run().catch((error) => {\n                this.log.error('Push runner failed:', error);\n                this.doneFuture.reject(error);\n            });\n            this.running = true;\n        }\n        return this.doneFuture;\n    }\n    done() {\n        this.log.info('Push done');\n        this.doneFuture.resolve();\n    }\n    async run() {\n        const sessionHash = await sha256(this.session.buffer);\n        const data = new URLSearchParams();\n        data.set(PushService.ARG_TYPE, this.service.pushType);\n        data.set(PushService.ARG_SESSION, sessionHash);\n        data.set(PushService.ARG_VERSION, `${this.service.version}`);\n        data.set(PushService.ARG_AFFILIATION, this.affiliation);\n        if (this.service.pushType === \"apns\") {\n            const parts = this.service.pushToken.split(';');\n            if (parts.length < 3) {\n                throw new Error(`APNS push token contains ${parts.length} parts, but at least 3 are required`);\n            }\n            data.set(PushService.ARG_TOKEN, parts[0]);\n            data.set(PushService.ARG_ENDPOINT, parts[1]);\n            data.set(PushService.ARG_BUNDLE_ID, parts[2]);\n        }\n        else if (this.service.pushType === \"gcm\") {\n            data.set(PushService.ARG_TOKEN, this.service.pushToken);\n        }\n        else {\n            throw new Error(`Invalid push type: ${this.service.pushType}`);\n        }\n        while (!this.doneFuture.done) {\n            let timeToLive = this.config.timeToLiveRange[this.tries];\n            if (timeToLive === undefined) {\n                timeToLive = this.config.timeToLiveRange[this.config.timeToLiveRange.length - 1];\n            }\n            if (timeToLive === 0) {\n                data.delete(PushService.ARG_COLLAPSE_KEY);\n            }\n            else {\n                data.set(PushService.ARG_COLLAPSE_KEY, sessionHash.slice(0, 6));\n            }\n            data.set(PushService.ARG_TIME_TO_LIVE, `${timeToLive}`);\n            ++this.tries;\n            this.log.debug(`Sending push ${this.tries}/${this.config.triesMax} (ttl=${timeToLive})`);\n            if (this.service.config.ARP_LOG_TRACE) {\n                this.log.debug('Push data:', `${data}`);\n            }\n            try {\n                const response = await fetch(this.service.url, {\n                    method: 'POST',\n                    headers: {\n                        'Content-Type': 'application/x-www-form-urlencoded',\n                    },\n                    body: data,\n                });\n                if (response.ok) {\n                    this.log.debug('Push sent successfully');\n                }\n                else if (response.status >= 400 && response.status < 500) {\n                    const error = `Push rejected (client error), status: ${response.status}`;\n                    this.log.warn(error);\n                    this.doneFuture.reject(new PushError(error, response.status));\n                }\n                else {\n                    this.log.warn(`Push rejected (server error), status: ${response.status}`);\n                }\n            }\n            catch (error) {\n                this.log.warn('Sending push failed:', error);\n            }\n            await sleep(this.retryTimeoutMs);\n            this.retryTimeoutMs = Math.min(this.retryTimeoutMs * 2, this.config.retryTimeoutMaxMs);\n            if (!this.doneFuture.done && this.tries === this.config.triesMax) {\n                const error = `Push session timeout after ${this.tries} tries`;\n                this.log.warn(error);\n                this.doneFuture.reject(new TimeoutError(error));\n            }\n        }\n    }\n}\nexport class PushService {\n    constructor(CONFIG, PROTOCOL_VERSION, logService) {\n        this.version = null;\n        this._pushToken = null;\n        this._pushType = \"gcm\";\n        this.config = CONFIG;\n        this.url = CONFIG.PUSH_URL;\n        this.version = PROTOCOL_VERSION;\n        this.logService = logService;\n        this.log = logService.getLogger(`Push-S`, 'color: #fff; background-color: #9900ff');\n    }\n    get pushToken() {\n        return this._pushToken;\n    }\n    get pushType() {\n        return this._pushType;\n    }\n    init(pushToken, pushTokenType) {\n        this.log.info('Initialized with', pushTokenType, 'token');\n        this._pushToken = pushToken;\n        this._pushType = pushTokenType;\n    }\n    reset() {\n        this._pushToken = null;\n    }\n    isAvailable() {\n        return this._pushToken != null;\n    }\n    createSession(session, config) {\n        if (!this.isAvailable()) {\n            throw new Error('Push service unavailable');\n        }\n        return new PushSession(this, session, config);\n    }\n}\nPushService.$inject = ['CONFIG', 'PROTOCOL_VERSION', 'LogService'];\nPushService.ARG_TYPE = 'type';\nPushService.ARG_TOKEN = 'token';\nPushService.ARG_SESSION = 'session';\nPushService.ARG_VERSION = 'version';\nPushService.ARG_AFFILIATION = 'affiliation';\nPushService.ARG_ENDPOINT = 'endpoint';\nPushService.ARG_BUNDLE_ID = 'bundleid';\nPushService.ARG_TIME_TO_LIVE = 'ttl';\nPushService.ARG_COLLAPSE_KEY = 'collapse_key';\n","import EMOJI_REGEX from 'emojibase-regex';\nimport twemoji from 'twemoji';\nimport { isEmojiInfo } from './../typeguards';\nconst SHORTNAMES = {\n    '+1': '��️',\n    '+1_tone1': '����',\n    '+1_tone2': '����',\n    '+1_tone3': '����',\n    '+1_tone4': '����',\n    '+1_tone5': '����',\n    '-1': '��️',\n    '-1_tone1': '����',\n    '-1_tone2': '����',\n    '-1_tone3': '����',\n    '-1_tone4': '����',\n    '-1_tone5': '����',\n    '100': '��',\n    '1234': '��',\n    '8ball': '��',\n    'a_blood': '��️',\n    'ab_blood': '��',\n    'abacus': '��',\n    'abc': '��',\n    'abcd': '��',\n    'adhesive_bandage': '��',\n    'admission': '��️',\n    'adult': '��',\n    'adult_tone1': '����',\n    'adult_tone2': '����',\n    'adult_tone3': '����',\n    'adult_tone4': '����',\n    'adult_tone5': '����',\n    'aerial_tramway': '��',\n    'airplane': '✈️',\n    'airplane_arriving': '��',\n    'airplane_departure': '��',\n    'alarm_clock': '⏰',\n    'alembic': '⚗️',\n    'alien': '��️',\n    'alien_monster': '��',\n    'ambulance': '��️',\n    'amphora': '��',\n    'amused': '��',\n    'anchor': '⚓️',\n    'android': '��',\n    'anger': '��',\n    'angry': '��',\n    'angry_imp': '��',\n    'anguished': '��',\n    'annoyed': '��',\n    'ant': '��',\n    'antenna_bars': '��',\n    'anxious': '��',\n    'apathetic': '��',\n    'apple': '��',\n    'aquarius': '♒️',\n    'aries': '♈️',\n    'arrow_down': '⬇️',\n    'arrow_heading_down': '⤵️',\n    'arrow_heading_up': '⤴️',\n    'arrow_left': '⬅️',\n    'arrow_left_hook': '↩️',\n    'arrow_left_right': '↔️',\n    'arrow_lower_left': '↙️',\n    'arrow_lower_right': '↘️',\n    'arrow_right': '➡️',\n    'arrow_right_hook': '↪️',\n    'arrow_up': '⬆️',\n    'arrow_up_down': '↕️',\n    'arrow_upper_left': '↖️',\n    'arrow_upper_right': '↗️',\n    'art': '��',\n    'asterisk': '*️⃣',\n    'astonished': '��',\n    'athletic_shoe': '��',\n    'atm': '��',\n    'atom': '⚛️',\n    'auto_rickshaw': '��',\n    'avocado': '��',\n    'axe': '��',\n    'b_blood': '��️',\n    'baby': '��',\n    'baby_angel': '��',\n    'baby_angel_tone1': '����',\n    'baby_angel_tone2': '����',\n    'baby_angel_tone3': '����',\n    'baby_angel_tone4': '����',\n    'baby_angel_tone5': '����',\n    'baby_bottle': '��',\n    'baby_chick': '��',\n    'baby_symbol': '��️',\n    'baby_tone1': '����',\n    'baby_tone2': '����',\n    'baby_tone3': '����',\n    'baby_tone4': '����',\n    'baby_tone5': '����',\n    'back': '��',\n    'backhand_point_up': '��️',\n    'backhand_point_up_tone1': '����',\n    'backhand_point_up_tone2': '����',\n    'backhand_point_up_tone3': '����',\n    'backhand_point_up_tone4': '����',\n    'backhand_point_up_tone5': '����',\n    'backpack': '��',\n    'bacon': '��',\n    'badger': '��',\n    'badminton': '��',\n    'bagel': '��',\n    'baggage_claim': '��',\n    'bald_man': '��‍��',\n    'bald_man_tone1': '����‍��',\n    'bald_man_tone2': '����‍��',\n    'bald_man_tone3': '����‍��',\n    'bald_man_tone4': '����‍��',\n    'bald_man_tone5': '����‍��',\n    'bald_woman': '��‍��',\n    'bald_woman_tone1': '����‍��',\n    'bald_woman_tone2': '����‍��',\n    'bald_woman_tone3': '����‍��',\n    'bald_woman_tone4': '����‍��',\n    'bald_woman_tone5': '����‍��',\n    'ballet_shoes': '��',\n    'balloon': '��',\n    'ballot_box': '��️',\n    'bamboo': '��',\n    'banana': '��',\n    'bandaid': '��',\n    'bangbang': '‼️',\n    'banjo': '��',\n    'bank': '��',\n    'bar_chart': '��',\n    'barber': '��',\n    'baseball': '⚾️',\n    'basket': '��',\n    'basketball': '��',\n    'bat': '��',\n    'bath': '��',\n    'bath_tone1': '����',\n    'bath_tone2': '����',\n    'bath_tone3': '����',\n    'bath_tone4': '����',\n    'bath_tone5': '����',\n    'bathroom': '��',\n    'bathtub': '��',\n    'battery': '��',\n    'beach': '��️',\n    'beach_umbrella': '⛱️',\n    'bear_face': '��',\n    'bearded_person': '��',\n    'bearded_person_tone1': '����',\n    'bearded_person_tone2': '����',\n    'bearded_person_tone3': '����',\n    'bearded_person_tone4': '����',\n    'bearded_person_tone5': '����',\n    'bed': '��️',\n    'bee': '��',\n    'beer': '��',\n    'beers': '��',\n    'beetle': '��',\n    'bell': '��',\n    'bellhop': '��️',\n    'bento': '��',\n    'beverage_box': '��',\n    'bike': '��️',\n    'bikini': '��',\n    'billed_cap': '��',\n    'biohazard': '☣️',\n    'bird': '��️',\n    'birthday': '��',\n    'black_circle': '⚫️',\n    'black_flag': '��',\n    'black_heart': '��',\n    'black_joker': '��',\n    'black_nib': '✒️',\n    'black_square_button': '��',\n    'blissful': '��',\n    'blond_man': '��‍♂️',\n    'blond_man_tone1': '����‍♂️',\n    'blond_man_tone2': '����‍♂️',\n    'blond_man_tone3': '����‍♂️',\n    'blond_man_tone4': '����‍♂️',\n    'blond_man_tone5': '����‍♂️',\n    'blond_person': '��',\n    'blond_person_tone1': '����',\n    'blond_person_tone2': '����',\n    'blond_person_tone3': '����',\n    'blond_person_tone4': '����',\n    'blond_person_tone5': '����',\n    'blond_woman': '��‍♀️',\n    'blond_woman_tone1': '����‍♀️',\n    'blond_woman_tone2': '����‍♀️',\n    'blond_woman_tone3': '����‍♀️',\n    'blond_woman_tone4': '����‍♀️',\n    'blond_woman_tone5': '����‍♀️',\n    'blood_drop': '��',\n    'blossom': '��',\n    'blouse': '��',\n    'blowfish': '��',\n    'blue_book': '��',\n    'blue_car': '��',\n    'blue_circle': '��',\n    'blue_heart': '��',\n    'blue_square': '��',\n    'blush': '��',\n    'boar': '��',\n    'bomb': '��️',\n    'bone': '��',\n    'book': '��',\n    'bookmark': '��',\n    'bookmark_tabs': '��',\n    'books': '��️',\n    'boom': '��',\n    'bored': '��',\n    'bouquet': '��',\n    'bow': '��',\n    'bowl_spoon': '��',\n    'bowling': '��',\n    'boxing_glove': '��',\n    'boy': '��',\n    'boy_tone1': '����',\n    'boy_tone2': '����',\n    'boy_tone3': '����',\n    'boy_tone4': '����',\n    'boy_tone5': '����',\n    'brain': '��',\n    'bread': '��',\n    'breast_feeding': '��',\n    'breast_feeding_tone1': '����',\n    'breast_feeding_tone2': '����',\n    'breast_feeding_tone3': '����',\n    'breast_feeding_tone4': '����',\n    'breast_feeding_tone5': '����',\n    'brick': '��',\n    'bride_veil': '��',\n    'bride_veil_tone1': '����',\n    'bride_veil_tone2': '����',\n    'bride_veil_tone3': '����',\n    'bride_veil_tone4': '����',\n    'bride_veil_tone5': '����',\n    'bridge_at_night': '��',\n    'briefcase': '��',\n    'briefs': '��',\n    'bright': '��',\n    'broccoli': '��',\n    'broken_heart': '��',\n    'broom': '��',\n    'brown_circle': '��',\n    'brown_heart': '��',\n    'brown_square': '��',\n    'bug': '��',\n    'bulb': '��',\n    'bullettrain': '��',\n    'bullettrain_side': '��',\n    'burrito': '��',\n    'bus': '��',\n    'bus_stop': '��',\n    'bust_silhouette': '��',\n    'busts_silhouette': '��',\n    'butter': '��',\n    'butterfly': '��',\n    'cactus': '��',\n    'cake': '��',\n    'calendar': '��',\n    'calendar_spiral': '��️',\n    'call_me': '��',\n    'call_me_tone1': '����',\n    'call_me_tone2': '����',\n    'call_me_tone3': '����',\n    'call_me_tone4': '����',\n    'call_me_tone5': '����',\n    'camel': '��',\n    'camera': '��️',\n    'camera_flash': '��',\n    'camping': '��️',\n    'cancer': '♋️',\n    'candle': '��️',\n    'candy': '��',\n    'canned_food': '��',\n    'canoe': '��',\n    'capricorn': '♑️',\n    'card_box': '��️',\n    'card_index': '��',\n    'carousel_horse': '��',\n    'carp_streamer': '��',\n    'carrot': '��',\n    'castle': '��',\n    'cat': '��️',\n    'cat_face': '��',\n    'cd': '��️',\n    'celebrating': '��',\n    'censored': '��',\n    'chains': '⛓️',\n    'chair': '��',\n    'champagne': '��',\n    'champagne_glass': '��',\n    'chart_down': '��',\n    'chart_up': '��',\n    'check_mark': '✔️',\n    'checked_ballot': '☑️',\n    'checkered_flag': '��',\n    'cheerless': '��',\n    'cheese': '��',\n    'cherries': '��',\n    'cherry_blossom': '��',\n    'chess_pawn': '♟️',\n    'chestnut': '��',\n    'chicken': '��',\n    'child': '��',\n    'child_tone1': '����',\n    'child_tone2': '����',\n    'child_tone3': '����',\n    'child_tone4': '����',\n    'child_tone5': '����',\n    'children_crossing': '��',\n    'chipmunk': '��️',\n    'chocolate_bar': '��',\n    'chopsticks': '��',\n    'christmas_tree': '��',\n    'church': '⛪️',\n    'cigarette': '��',\n    'cinema': '��',\n    'circus_tent': '��',\n    'cityscape': '��️',\n    'cl': '��',\n    'clamp': '��️',\n    'clap': '��',\n    'clap_tone1': '����',\n    'clap_tone2': '����',\n    'clap_tone3': '����',\n    'clap_tone4': '����',\n    'clap_tone5': '����',\n    'clapper': '��️',\n    'classical_building': '��️',\n    'clipboard': '��️',\n    'clock': '��️',\n    'clock1': '��️',\n    'clock10': '��️',\n    'clock1030': '��️',\n    'clock11': '��️',\n    'clock1130': '��️',\n    'clock12': '��️',\n    'clock1230': '��️',\n    'clock130': '��️',\n    'clock2': '��️',\n    'clock230': '��️',\n    'clock3': '��️',\n    'clock330': '��️',\n    'clock4': '��️',\n    'clock430': '��️',\n    'clock5': '��️',\n    'clock530': '��️',\n    'clock6': '��️',\n    'clock630': '��️',\n    'clock7': '��️',\n    'clock730': '��️',\n    'clock8': '��️',\n    'clock830': '��️',\n    'clock9': '��️',\n    'clock930': '��️',\n    'clockwise': '��',\n    'closed_book': '��',\n    'closed_umbrella': '��',\n    'cloud': '☁️',\n    'cloudy': '��️',\n    'clown': '��',\n    'clubs': '♣️',\n    'clutch_bag': '��',\n    'coat': '��',\n    'cocktail': '��️',\n    'cocky': '��',\n    'coconut': '��',\n    'coffee': '☕️',\n    'coffin': '⚰️',\n    'cold_sweat': '��',\n    'collision': '��',\n    'comet': '☄️',\n    'compass': '��',\n    'compression': '��️',\n    'computer': '��️',\n    'computer_mouse': '��️',\n    'confetti_ball': '��',\n    'confident': '��',\n    'confounded': '��',\n    'confused': '��',\n    'construction': '��',\n    'construction_site': '��️',\n    'construction_worker': '��',\n    'construction_worker_tone1': '����',\n    'construction_worker_tone2': '����',\n    'construction_worker_tone3': '����',\n    'construction_worker_tone4': '����',\n    'construction_worker_tone5': '����',\n    'contempt': '��',\n    'control_knobs': '��️',\n    'convenience_store': '��',\n    'cookie': '��',\n    'cooking': '��',\n    'cool': '��',\n    'copyright': '©️',\n    'corn': '��',\n    'couch': '��️',\n    'counter_clockwise': '��',\n    'couple': '��',\n    'couple_heart': '��',\n    'couple_mm': '��‍❤️‍��',\n    'couple_mw': '��‍❤️‍��',\n    'couple_wm': '��‍❤️‍��',\n    'couple_ww': '��‍❤️‍��',\n    'cow': '��',\n    'cow_face': '��',\n    'cowboy': '��',\n    'coy': '��',\n    'crab': '��',\n    'crayon': '��️',\n    'crazy': '��',\n    'credit_card': '��️',\n    'crescent_moon': '��',\n    'cricket': '��',\n    'cricket_game': '��',\n    'crocodile': '��',\n    'croissant': '��',\n    'cross': '✝️',\n    'cross_mark': '❌',\n    'cross_mark_button': '❎',\n    'crossbones': '☠️',\n    'crossed_flags': '��',\n    'crossed_swords': '⚔️',\n    'crown': '��',\n    'cruise_ship': '��️',\n    'cry': '��',\n    'crying_cat': '��',\n    'crystal_ball': '��',\n    'cucumber': '��',\n    'cup_straw': '��',\n    'cupcake': '��',\n    'cupid': '��',\n    'curious': '��',\n    'curling_stone': '��',\n    'curly_haired_man': '��‍��',\n    'curly_haired_man_tone1': '����‍��',\n    'curly_haired_man_tone2': '����‍��',\n    'curly_haired_man_tone3': '����‍��',\n    'curly_haired_man_tone4': '����‍��',\n    'curly_haired_man_tone5': '����‍��',\n    'curly_haired_woman': '��‍��',\n    'curly_haired_woman_tone1': '����‍��',\n    'curly_haired_woman_tone2': '����‍��',\n    'curly_haired_woman_tone3': '����‍��',\n    'curly_haired_woman_tone4': '����‍��',\n    'curly_haired_woman_tone5': '����‍��',\n    'curly_loop': '➰',\n    'currency_exchange': '��',\n    'curry': '��',\n    'custard': '��',\n    'customs': '��',\n    'cut_of_meat': '��',\n    'cyclone': '��',\n    'dagger': '��️',\n    'dancer': '��',\n    'dancer_tone1': '����',\n    'dancer_tone2': '����',\n    'dancer_tone3': '����',\n    'dancer_tone4': '����',\n    'dancer_tone5': '����',\n    'dango': '��',\n    'dart': '��',\n    'dash': '��',\n    'date': '��',\n    'deciduous_tree': '��',\n    'decorative_notebook': '��',\n    'deer': '��',\n    'department_store': '��',\n    'desert': '��️',\n    'desktop': '��️',\n    'detective': '��️',\n    'detective_tone1': '����',\n    'detective_tone2': '����',\n    'detective_tone3': '����',\n    'detective_tone4': '����',\n    'detective_tone5': '����',\n    'diamond_dot': '��',\n    'diamonds': '♦️',\n    'dim': '��',\n    'disappointed': '��',\n    'disbelief': '��',\n    'disk': '��️',\n    'distressed': '��',\n    'dividers': '��️',\n    'diving_mask': '��',\n    'division': '➗',\n    'diya_lamp': '��',\n    'dizzy': '��',\n    'dizzy_star': '��',\n    'dna': '��',\n    'do_not_litter': '��',\n    'dog': '��️',\n    'dog_face': '��',\n    'dollar': '��',\n    'dollar_sign': '��',\n    'dolls': '��',\n    'dolphin': '��',\n    'door': '��',\n    'double_curly_loop': '➿',\n    'double_exclamation': '‼️',\n    'double_helix': '��',\n    'doughnut': '��',\n    'dove': '��️',\n    'down_button': '��',\n    'down_red_triangle': '��',\n    'dragon': '��',\n    'dragon_face': '��',\n    'dress': '��',\n    'dress_shoe': '��',\n    'drooling': '��',\n    'droplet': '��',\n    'drum': '��',\n    'duck': '��',\n    'dumpling': '��',\n    'dusk': '��',\n    'dvd': '��',\n    'eagle': '��',\n    'ear': '��️',\n    'ear_of_rice': '��',\n    'ear_tone1': '����',\n    'ear_tone2': '����',\n    'ear_tone3': '����',\n    'ear_tone4': '����',\n    'ear_tone5': '����',\n    'earth_africa': '��️',\n    'earth_americas': '��️',\n    'earth_asia': '��️',\n    'ecstatic': '��',\n    'egg': '��',\n    'eggplant': '��',\n    'eight': '8️⃣',\n    'eight_pointed_star': '✴️',\n    'eight_spoked_asterisk': '✳️',\n    'eject': '⏏️',\n    'electric_plug': '��',\n    'elephant': '��',\n    'elf': '��',\n    'elf_tone1': '����',\n    'elf_tone2': '����',\n    'elf_tone3': '����',\n    'elf_tone4': '����',\n    'elf_tone5': '����',\n    'email': '��',\n    'embarassed': '��',\n    'end': '��',\n    'england': '��������������',\n    'enraged': '��',\n    'entertained': '��',\n    'envelope': '✉️',\n    'envelope_arrow': '��',\n    'euro': '��',\n    'european_castle': '��',\n    'evergreen_tree': '��',\n    'exclamation': '❗️',\n    'exclamation_question': '⁉️',\n    'exhausted': '��',\n    'exploding_head': '��',\n    'expressionless': '��',\n    'eye': '��️',\n    'eye_bubble': '��️‍��️',\n    'eyes': '��',\n    'facetious': '��',\n    'factory': '��️',\n    'fairy': '��',\n    'fairy_tone1': '����',\n    'fairy_tone2': '����',\n    'fairy_tone3': '����',\n    'fairy_tone4': '����',\n    'fairy_tone5': '����',\n    'falafel': '��',\n    'fallen_leaf': '��',\n    'family': '��️',\n    'family_mb': '��‍��',\n    'family_mbb': '��‍��‍��',\n    'family_mg': '��‍��',\n    'family_mgb': '��‍��‍��',\n    'family_mgg': '��‍��‍��',\n    'family_mmb': '��‍��‍��',\n    'family_mmbb': '��‍��‍��‍��',\n    'family_mmg': '��‍��‍��',\n    'family_mmgb': '��‍��‍��‍��',\n    'family_mmgg': '��‍��‍��‍��',\n    'family_mwb': '��‍��‍��',\n    'family_mwbb': '��‍��‍��‍��',\n    'family_mwg': '��‍��‍��',\n    'family_mwgb': '��‍��‍��‍��',\n    'family_mwgg': '��‍��‍��‍��',\n    'family_wb': '��‍��',\n    'family_wbb': '��‍��‍��',\n    'family_wg': '��‍��',\n    'family_wgb': '��‍��‍��',\n    'family_wgg': '��‍��‍��',\n    'family_wwb': '��‍��‍��',\n    'family_wwbb': '��‍��‍��‍��',\n    'family_wwg': '��‍��‍��',\n    'family_wwgb': '��‍��‍��‍��',\n    'family_wwgg': '��‍��‍��‍��',\n    'fast_down_button': '⏬',\n    'fast_forward': '⏩️',\n    'fast_up_button': '⏫',\n    'fax': '��',\n    'fearful': '��',\n    'feet': '��',\n    'female': '♀️',\n    'female_sign': '♀️',\n    'ferris_wheel': '��',\n    'ferry': '⛴️',\n    'field_hockey': '��',\n    'file_cabinet': '��️',\n    'file_folder': '��',\n    'film_frames': '��️',\n    'fingers_crossed': '��',\n    'fingers_crossed_tone1': '����',\n    'fingers_crossed_tone2': '����',\n    'fingers_crossed_tone3': '����',\n    'fingers_crossed_tone4': '����',\n    'fingers_crossed_tone5': '����',\n    'fire': '��',\n    'fire_engine': '��',\n    'fire_extinguisher': '��',\n    'firecracker': '��',\n    'fireworks': '��',\n    'first_place': '��',\n    'first_quarter_moon': '��',\n    'first_quarter_moon_face': '��',\n    'fish': '��️',\n    'fish_cake': '��',\n    'fishing_pole': '��',\n    'fist': '✊',\n    'fist_tone1': '✊��',\n    'fist_tone2': '✊��',\n    'fist_tone3': '✊��',\n    'fist_tone4': '✊��',\n    'fist_tone5': '✊��',\n    'five': '5️⃣',\n    'flag_ad': '����',\n    'flag_ae': '����',\n    'flag_af': '����',\n    'flag_ag': '����',\n    'flag_ai': '����',\n    'flag_al': '����',\n    'flag_am': '����',\n    'flag_ao': '����',\n    'flag_aq': '����',\n    'flag_ar': '����',\n    'flag_as': '����',\n    'flag_at': '����',\n    'flag_au': '����',\n    'flag_aw': '����',\n    'flag_ax': '����',\n    'flag_az': '����',\n    'flag_ba': '����',\n    'flag_bb': '����',\n    'flag_bd': '����',\n    'flag_be': '����',\n    'flag_bf': '����',\n    'flag_bg': '����',\n    'flag_bh': '����',\n    'flag_bi': '����',\n    'flag_bj': '����',\n    'flag_bl': '����',\n    'flag_bm': '����',\n    'flag_bn': '����',\n    'flag_bo': '����',\n    'flag_bq': '����',\n    'flag_br': '����',\n    'flag_bs': '����',\n    'flag_bt': '����',\n    'flag_bw': '����',\n    'flag_by': '����',\n    'flag_bz': '����',\n    'flag_ca': '����',\n    'flag_cc': '����',\n    'flag_cd': '����',\n    'flag_cf': '����',\n    'flag_cg': '����',\n    'flag_ch': '����',\n    'flag_ci': '����',\n    'flag_ck': '����',\n    'flag_cl': '����',\n    'flag_cm': '����',\n    'flag_cn': '����',\n    'flag_co': '����',\n    'flag_cr': '����',\n    'flag_cu': '����',\n    'flag_cv': '����',\n    'flag_cw': '����',\n    'flag_cx': '����',\n    'flag_cy': '����',\n    'flag_cz': '����',\n    'flag_de': '����',\n    'flag_dj': '����',\n    'flag_dk': '����',\n    'flag_dm': '����',\n    'flag_do': '����',\n    'flag_dz': '����',\n    'flag_ec': '����',\n    'flag_ee': '����',\n    'flag_eg': '����',\n    'flag_eh': '����',\n    'flag_er': '����',\n    'flag_es': '����',\n    'flag_et': '����',\n    'flag_eu': '����',\n    'flag_fi': '����',\n    'flag_fj': '����',\n    'flag_fk': '����',\n    'flag_fm': '����',\n    'flag_fo': '����',\n    'flag_fr': '����',\n    'flag_ga': '����',\n    'flag_gb': '����',\n    'flag_gbeng': '��������������',\n    'flag_gbsct': '��������������',\n    'flag_gbwls': '��������������',\n    'flag_gd': '����',\n    'flag_ge': '����',\n    'flag_gf': '����',\n    'flag_gg': '����',\n    'flag_gh': '����',\n    'flag_gi': '����',\n    'flag_gl': '����',\n    'flag_gm': '����',\n    'flag_gn': '����',\n    'flag_gp': '����',\n    'flag_gq': '����',\n    'flag_gr': '����',\n    'flag_gs': '����',\n    'flag_gt': '����',\n    'flag_gu': '����',\n    'flag_gw': '����',\n    'flag_gy': '����',\n    'flag_hk': '����',\n    'flag_hn': '����',\n    'flag_hr': '����',\n    'flag_ht': '����',\n    'flag_hu': '����',\n    'flag_ic': '����',\n    'flag_id': '����',\n    'flag_ie': '����',\n    'flag_il': '����',\n    'flag_im': '����',\n    'flag_in': '����',\n    'flag_io': '����',\n    'flag_iq': '����',\n    'flag_ir': '����',\n    'flag_is': '����',\n    'flag_it': '����',\n    'flag_je': '����',\n    'flag_jm': '����',\n    'flag_jo': '����',\n    'flag_jp': '����',\n    'flag_ke': '����',\n    'flag_kg': '����',\n    'flag_kh': '����',\n    'flag_ki': '����',\n    'flag_km': '����',\n    'flag_kn': '����',\n    'flag_kp': '����',\n    'flag_kr': '����',\n    'flag_kw': '����',\n    'flag_ky': '����',\n    'flag_kz': '����',\n    'flag_la': '����',\n    'flag_lb': '����',\n    'flag_lc': '����',\n    'flag_li': '����',\n    'flag_lk': '����',\n    'flag_lr': '����',\n    'flag_ls': '����',\n    'flag_lt': '����',\n    'flag_lu': '����',\n    'flag_lv': '����',\n    'flag_ly': '����',\n    'flag_ma': '����',\n    'flag_mc': '����',\n    'flag_md': '����',\n    'flag_me': '����',\n    'flag_mg': '����',\n    'flag_mh': '����',\n    'flag_mk': '����',\n    'flag_ml': '����',\n    'flag_mm': '����',\n    'flag_mn': '����',\n    'flag_mo': '����',\n    'flag_mp': '����',\n    'flag_mq': '����',\n    'flag_mr': '����',\n    'flag_ms': '����',\n    'flag_mt': '����',\n    'flag_mu': '����',\n    'flag_mv': '����',\n    'flag_mw': '����',\n    'flag_mx': '����',\n    'flag_my': '����',\n    'flag_mz': '����',\n    'flag_na': '����',\n    'flag_nc': '����',\n    'flag_ne': '����',\n    'flag_nf': '����',\n    'flag_ng': '����',\n    'flag_ni': '����',\n    'flag_nl': '����',\n    'flag_no': '����',\n    'flag_np': '����',\n    'flag_nr': '����',\n    'flag_nu': '����',\n    'flag_nz': '����',\n    'flag_om': '����',\n    'flag_pa': '����',\n    'flag_pe': '����',\n    'flag_pf': '����',\n    'flag_pg': '����',\n    'flag_ph': '����',\n    'flag_pk': '����',\n    'flag_pl': '����',\n    'flag_pm': '����',\n    'flag_pn': '����',\n    'flag_pr': '����',\n    'flag_ps': '����',\n    'flag_pt': '����',\n    'flag_pw': '����',\n    'flag_py': '����',\n    'flag_qa': '����',\n    'flag_re': '����',\n    'flag_ro': '����',\n    'flag_rs': '����',\n    'flag_ru': '����',\n    'flag_rw': '����',\n    'flag_sa': '����',\n    'flag_sb': '����',\n    'flag_sc': '����',\n    'flag_sd': '����',\n    'flag_se': '����',\n    'flag_sg': '����',\n    'flag_sh': '����',\n    'flag_si': '����',\n    'flag_sk': '����',\n    'flag_sl': '����',\n    'flag_sm': '����',\n    'flag_sn': '����',\n    'flag_so': '����',\n    'flag_sr': '����',\n    'flag_ss': '����',\n    'flag_st': '����',\n    'flag_sv': '����',\n    'flag_sx': '����',\n    'flag_sy': '����',\n    'flag_sz': '����',\n    'flag_tc': '����',\n    'flag_td': '����',\n    'flag_tf': '����',\n    'flag_tg': '����',\n    'flag_th': '����',\n    'flag_tj': '����',\n    'flag_tk': '����',\n    'flag_tl': '����',\n    'flag_tm': '����',\n    'flag_tn': '����',\n    'flag_to': '����',\n    'flag_tr': '����',\n    'flag_tt': '����',\n    'flag_tv': '����',\n    'flag_tw': '����',\n    'flag_tz': '����',\n    'flag_ua': '����',\n    'flag_ug': '����',\n    'flag_us': '����',\n    'flag_uy': '����',\n    'flag_uz': '����',\n    'flag_va': '����',\n    'flag_vc': '����',\n    'flag_ve': '����',\n    'flag_vg': '����',\n    'flag_vi': '����',\n    'flag_vn': '����',\n    'flag_vu': '����',\n    'flag_wf': '����',\n    'flag_ws': '����',\n    'flag_xk': '����',\n    'flag_ye': '����',\n    'flag_yt': '����',\n    'flag_za': '����',\n    'flag_zm': '����',\n    'flag_zw': '����',\n    'flamingo': '��',\n    'flashlight': '��',\n    'flat_shoe': '��',\n    'fleur-de-lis': '⚜️',\n    'flirty': '��',\n    'floppy_disk': '��',\n    'flower_cards': '��',\n    'flushed': '��',\n    'flying_disc': '��',\n    'flying_saucer': '��',\n    'fog': '��️',\n    'foggy': '��',\n    'foot': '��',\n    'foot_tone1': '����',\n    'foot_tone2': '����',\n    'foot_tone3': '����',\n    'foot_tone4': '����',\n    'foot_tone5': '����',\n    'football': '��',\n    'footprints': '��',\n    'fork_knife_plate': '��️',\n    'fortune_cookie': '��',\n    'fountain': '⛲️',\n    'fountain_pen': '��️',\n    'four': '4️⃣',\n    'four_leaf_clover': '��',\n    'fox_face': '��',\n    'frame_photo': '��️',\n    'free': '��',\n    'freezing': '��',\n    'french_bread': '��',\n    'fried_shrimp': '��',\n    'fries': '��',\n    'frightened': '��',\n    'frog_face': '��',\n    'frowning': '☹️',\n    'frustrated': '��',\n    'fuel_pump': '⛽️',\n    'full_moon': '��️',\n    'full_moon_face': '��',\n    'game_die': '��',\n    'garlic': '��',\n    'gasp': '��',\n    'gear': '⚙️',\n    'gem': '��',\n    'gemini': '♊️',\n    'genie': '��',\n    'germ': '��',\n    'ghost': '��',\n    'gi': '��',\n    'gift': '��',\n    'giraffe': '��',\n    'girl': '��',\n    'girl_tone1': '����',\n    'girl_tone2': '����',\n    'girl_tone3': '����',\n    'girl_tone4': '����',\n    'girl_tone5': '����',\n    'glad': '��',\n    'glasses': '��️',\n    'gleeful': '��',\n    'globe': '��',\n    'gloves': '��',\n    'glowing_star': '��',\n    'goal': '��',\n    'goat': '��',\n    'goblin': '��',\n    'goggles': '��',\n    'golf': '⛳️',\n    'gorilla': '��',\n    'graduation_cap': '��️',\n    'grapes': '��',\n    'green_apple': '��',\n    'green_book': '��',\n    'green_circle': '��',\n    'green_heart': '��',\n    'green_square': '��',\n    'grimaced': '��',\n    'grin': '��',\n    'grinning_cat': '��',\n    'guard': '��',\n    'guard_tone1': '����',\n    'guard_tone2': '����',\n    'guard_tone3': '����',\n    'guard_tone4': '����',\n    'guard_tone5': '����',\n    'guide_dog': '��',\n    'guitar': '��',\n    'gun': '��',\n    'haha': '��',\n    'halo': '��',\n    'hamburger': '��',\n    'hammer': '��',\n    'hammer_pick': '⚒️',\n    'hammer_wrench': '��️',\n    'hamster_face': '��',\n    'handbag': '��',\n    'handicapped': '♿️',\n    'handshake': '��',\n    'happy': '��',\n    'happy_kiss': '��',\n    'hash': '#️⃣',\n    'hatched_chick': '��',\n    'hatching_chick': '��',\n    'headphones': '��️',\n    'hear_no_evil': '��',\n    'hearing_aid': '��',\n    'hearing_aid_tone1': '����',\n    'hearing_aid_tone2': '����',\n    'hearing_aid_tone3': '����',\n    'hearing_aid_tone4': '����',\n    'hearing_aid_tone5': '����',\n    'heart': '❤️',\n    'heart_decoration': '��',\n    'heart_exclamation': '❣️',\n    'heart_ribbon': '��',\n    'heartbeat': '��',\n    'heartpulse': '��',\n    'hearts': '♥️',\n    'hedgehog': '��',\n    'helicopter': '��',\n    'helmet_cross': '⛑️',\n    'herb': '��',\n    'hero': '��',\n    'hero_tone1': '����',\n    'hero_tone2': '����',\n    'hero_tone3': '����',\n    'hero_tone4': '����',\n    'hero_tone5': '����',\n    'hibiscus': '��',\n    'high_brightness': '��',\n    'high_heel': '��',\n    'high_voltage': '⚡️',\n    'hiking_boot': '��',\n    'hindu_temple': '��',\n    'hippo': '��',\n    'hockey': '��',\n    'holding_hands_mm': '��',\n    'holding_hands_mm_tone1': '����',\n    'holding_hands_mm_tone2': '����',\n    'holding_hands_mm_tone3': '����',\n    'holding_hands_mm_tone4': '����',\n    'holding_hands_mm_tone5': '����',\n    'holding_hands_mw': '��',\n    'holding_hands_mw_tone1': '����',\n    'holding_hands_mw_tone2': '����',\n    'holding_hands_mw_tone3': '����',\n    'holding_hands_mw_tone4': '����',\n    'holding_hands_mw_tone5': '����',\n    'holding_hands_people': '��‍��‍��',\n    'holding_hands_people_tone1': '����‍��‍����',\n    'holding_hands_people_tone2': '����‍��‍����',\n    'holding_hands_people_tone3': '����‍��‍����',\n    'holding_hands_people_tone4': '����‍��‍����',\n    'holding_hands_people_tone5': '����‍��‍����',\n    'holding_hands_wm': '��',\n    'holding_hands_wm_tone1': '����',\n    'holding_hands_wm_tone2': '����',\n    'holding_hands_wm_tone3': '����',\n    'holding_hands_wm_tone4': '����',\n    'holding_hands_wm_tone5': '����',\n    'holding_hands_ww': '��',\n    'holding_hands_ww_tone1': '����',\n    'holding_hands_ww_tone2': '����',\n    'holding_hands_ww_tone3': '����',\n    'holding_hands_ww_tone4': '����',\n    'holding_hands_ww_tone5': '����',\n    'hole': '��️',\n    'homes': '��️',\n    'honey_pot': '��',\n    'hopeful': '��',\n    'horse': '��',\n    'horse_face': '��',\n    'horse_racing': '��',\n    'horse_racing_tone1': '����',\n    'horse_racing_tone2': '����',\n    'horse_racing_tone3': '����',\n    'horse_racing_tone4': '����',\n    'horse_racing_tone5': '����',\n    'hospital': '��',\n    'hot_pepper': '��️',\n    'hotdog': '��',\n    'hotel': '��',\n    'hotsprings': '♨️',\n    'hourglass': '⌛️',\n    'hourglass_flowing': '⏳️',\n    'house': '��️',\n    'house_abandoned': '��️',\n    'house_garden': '��',\n    'hrmph': '��',\n    'hugging': '��',\n    'hushed': '��',\n    'ice': '��',\n    'ice_cream': '��',\n    'ice_skate': '⛸️',\n    'icecream': '��',\n    'id': '��',\n    'ill': '��',\n    'imp': '��',\n    'in_bed': '��',\n    'in_bed_tone1': '����',\n    'in_bed_tone2': '����',\n    'in_bed_tone3': '����',\n    'in_bed_tone4': '����',\n    'in_bed_tone5': '����',\n    'inbox_tray': '��️',\n    'incoming_envelope': '��',\n    'indifferent': '��️',\n    'infinity': '♾️',\n    'info': 'ℹ️',\n    'injured': '��',\n    'innocent': '��',\n    'interrobang': '⁉️',\n    'iphone': '��',\n    'island': '��️',\n    'ja_acceptable': '��',\n    'ja_application': '��',\n    'ja_bargain': '��',\n    'ja_beginner': '��',\n    'ja_chart': '��',\n    'ja_congratulations': '㊗️',\n    'ja_discount': '��',\n    'ja_free_of_charge': '��️',\n    'ja_here': '��',\n    'ja_monthly_amount': '��️',\n    'ja_no_vacancy': '��',\n    'ja_not_free_of_carge': '��',\n    'ja_open_for_business': '��',\n    'ja_passing_grade': '��',\n    'ja_post_office': '��',\n    'ja_prohibited': '��',\n    'ja_reserved': '��️',\n    'ja_secret': '㊙️',\n    'ja_service_charge': '��️',\n    'ja_vacancy': '��',\n    'jack_o_lantern': '��',\n    'japan': '��',\n    'japanese_castle': '��',\n    'jeans': '��',\n    'jigsaw': '��',\n    'jolly_roger': '��‍☠️',\n    'joy': '��',\n    'joyful': '��',\n    'joyful_cat': '��',\n    'joystick': '��️',\n    'juice_box': '��',\n    'kaaba': '��',\n    'kangaroo': '��',\n    'key': '��',\n    'keyboard': '⌨️',\n    'kimono': '��',\n    'kiss': '��',\n    'kiss_lips': '��',\n    'kiss_mm': '��‍❤️‍��‍��',\n    'kiss_mw': '��‍❤️‍��‍��',\n    'kiss_wm': '��‍❤️‍��‍��',\n    'kiss_ww': '��‍❤️‍��‍��',\n    'kissing_cat': '��',\n    'kite': '��',\n    'kiwi': '��',\n    'knife': '��',\n    'koala_face': '��',\n    'koko': '��',\n    'lab_coat': '��',\n    'label': '��️',\n    'lacrosse': '��',\n    'laptop': '��️',\n    'large_black_square': '⬛️',\n    'large_blue_diamond': '��',\n    'large_orange_diamond': '��',\n    'large_white_square': '⬜️',\n    'last_quarter_moon': '��',\n    'last_quarter_moon_face': '��️',\n    'laugh': '��',\n    'leafy_green': '��',\n    'leaves': '��',\n    'ledger': '��',\n    'left_facing_fist': '��',\n    'left_facing_fist_tone1': '����',\n    'left_facing_fist_tone2': '����',\n    'left_facing_fist_tone3': '����',\n    'left_facing_fist_tone4': '����',\n    'left_facing_fist_tone5': '����',\n    'left_luggage': '��',\n    'left_speech': '��️',\n    'leg': '��',\n    'leg_tone1': '����',\n    'leg_tone2': '����',\n    'leg_tone3': '����',\n    'leg_tone4': '����',\n    'leg_tone5': '����',\n    'lemon': '��',\n    'leo': '♌️',\n    'leopard': '��',\n    'level_slider': '��️',\n    'levitate': '��️',\n    'levitate_tone1': '����',\n    'levitate_tone2': '����',\n    'levitate_tone3': '����',\n    'levitate_tone4': '����',\n    'levitate_tone5': '����',\n    'libra': '♎️',\n    'light_bulb': '��',\n    'light_rail': '��',\n    'lightning': '��️',\n    'link': '��',\n    'lion_face': '��',\n    'lips': '��',\n    'lipstick': '��',\n    'litter_bin': '��',\n    'lizard': '��',\n    'llama': '��',\n    'lmao': '��',\n    'lobster': '��',\n    'lock': '��️',\n    'locked_key': '��',\n    'locked_pen': '��',\n    'lol': '��',\n    'lollipop': '��',\n    'lorry': '��',\n    'lotion': '��',\n    'loud_sound': '��',\n    'loudspeaker': '��',\n    'love': '��',\n    'love_hotel': '��',\n    'love_letter': '��',\n    'love_you_gesture': '��',\n    'love_you_gesture_tone1': '����',\n    'love_you_gesture_tone2': '����',\n    'love_you_gesture_tone3': '����',\n    'love_you_gesture_tone4': '����',\n    'love_you_gesture_tone5': '����',\n    'lovestruck': '��',\n    'lovestruck_cat': '��',\n    'loving_kiss': '��',\n    'low_brightness': '��',\n    'low_sound': '��️',\n    'luggage': '��',\n    'lying': '��',\n    'm': 'Ⓜ️',\n    'mag': '��️',\n    'mag_right': '��',\n    'mage': '��',\n    'mage_tone1': '����',\n    'mage_tone2': '����',\n    'mage_tone3': '����',\n    'mage_tone4': '����',\n    'mage_tone5': '����',\n    'magnet': '��',\n    'mahjong': '��️',\n    'mailbox': '��️',\n    'mailbox_closed': '��️',\n    'mailbox_mail': '��️',\n    'mailbox_no_mail': '��️',\n    'male': '♂️',\n    'male_sign': '♂️',\n    'man': '��',\n    'man_artist': '��‍��',\n    'man_artist_tone1': '����‍��',\n    'man_artist_tone2': '����‍��',\n    'man_artist_tone3': '����‍��',\n    'man_artist_tone4': '����‍��',\n    'man_artist_tone5': '����‍��',\n    'man_astronaut': '��‍��',\n    'man_astronaut_tone1': '����‍��',\n    'man_astronaut_tone2': '����‍��',\n    'man_astronaut_tone3': '����‍��',\n    'man_astronaut_tone4': '����‍��',\n    'man_astronaut_tone5': '����‍��',\n    'man_biking': '��‍♂️',\n    'man_biking_tone1': '����‍♂️',\n    'man_biking_tone2': '����‍♂️',\n    'man_biking_tone3': '����‍♂️',\n    'man_biking_tone4': '����‍♂️',\n    'man_biking_tone5': '����‍♂️',\n    'man_bowing': '��‍♂️',\n    'man_bowing_tone1': '����‍♂️',\n    'man_bowing_tone2': '����‍♂️',\n    'man_bowing_tone3': '����‍♂️',\n    'man_bowing_tone4': '����‍♂️',\n    'man_bowing_tone5': '����‍♂️',\n    'man_cartwheeling': '��‍♂️',\n    'man_cartwheeling_tone1': '����‍♂️',\n    'man_cartwheeling_tone2': '����‍♂️',\n    'man_cartwheeling_tone3': '����‍♂️',\n    'man_cartwheeling_tone4': '����‍♂️',\n    'man_cartwheeling_tone5': '����‍♂️',\n    'man_chinese_cap': '��',\n    'man_chinese_cap_tone1': '����',\n    'man_chinese_cap_tone2': '����',\n    'man_chinese_cap_tone3': '����',\n    'man_chinese_cap_tone4': '����',\n    'man_chinese_cap_tone5': '����',\n    'man_climbing': '��‍♂️',\n    'man_climbing_tone1': '����‍♂️',\n    'man_climbing_tone2': '����‍♂️',\n    'man_climbing_tone3': '����‍♂️',\n    'man_climbing_tone4': '����‍♂️',\n    'man_climbing_tone5': '����‍♂️',\n    'man_construction_worker': '��‍♂️',\n    'man_construction_worker_tone1': '����‍♂️',\n    'man_construction_worker_tone2': '����‍♂️',\n    'man_construction_worker_tone3': '����‍♂️',\n    'man_construction_worker_tone4': '����‍♂️',\n    'man_construction_worker_tone5': '����‍♂️',\n    'man_cook': '��‍��',\n    'man_cook_tone1': '����‍��',\n    'man_cook_tone2': '����‍��',\n    'man_cook_tone3': '����‍��',\n    'man_cook_tone4': '����‍��',\n    'man_cook_tone5': '����‍��',\n    'man_dancing': '��',\n    'man_dancing_tone1': '����',\n    'man_dancing_tone2': '����',\n    'man_dancing_tone3': '����',\n    'man_dancing_tone4': '����',\n    'man_dancing_tone5': '����',\n    'man_deaf': '��‍♂️',\n    'man_deaf_tone1': '����‍♂️',\n    'man_deaf_tone2': '����‍♂️',\n    'man_deaf_tone3': '����‍♂️',\n    'man_deaf_tone4': '����‍♂️',\n    'man_deaf_tone5': '����‍♂️',\n    'man_elf': '��‍♂️',\n    'man_elf_tone1': '����‍♂️',\n    'man_elf_tone2': '����‍♂️',\n    'man_elf_tone3': '����‍♂️',\n    'man_elf_tone4': '����‍♂️',\n    'man_elf_tone5': '����‍♂️',\n    'man_facepalming': '��‍♂️',\n    'man_facepalming_tone1': '����‍♂️',\n    'man_facepalming_tone2': '����‍♂️',\n    'man_facepalming_tone3': '����‍♂️',\n    'man_facepalming_tone4': '����‍♂️',\n    'man_facepalming_tone5': '����‍♂️',\n    'man_factory_worker': '��‍��',\n    'man_factory_worker_tone1': '����‍��',\n    'man_factory_worker_tone2': '����‍��',\n    'man_factory_worker_tone3': '����‍��',\n    'man_factory_worker_tone4': '����‍��',\n    'man_factory_worker_tone5': '����‍��',\n    'man_fairy': '��‍♂️',\n    'man_fairy_tone1': '����‍♂️',\n    'man_fairy_tone2': '����‍♂️',\n    'man_fairy_tone3': '����‍♂️',\n    'man_fairy_tone4': '����‍♂️',\n    'man_fairy_tone5': '����‍♂️',\n    'man_farmer': '��‍��',\n    'man_farmer_tone1': '����‍��',\n    'man_farmer_tone2': '����‍��',\n    'man_farmer_tone3': '����‍��',\n    'man_farmer_tone4': '����‍��',\n    'man_farmer_tone5': '����‍��',\n    'man_firefighter': '��‍��',\n    'man_firefighter_tone1': '����‍��',\n    'man_firefighter_tone2': '����‍��',\n    'man_firefighter_tone3': '����‍��',\n    'man_firefighter_tone4': '����‍��',\n    'man_firefighter_tone5': '����‍��',\n    'man_frowning': '��‍♂️',\n    'man_frowning_tone1': '����‍♂️',\n    'man_frowning_tone2': '����‍♂️',\n    'man_frowning_tone3': '����‍♂️',\n    'man_frowning_tone4': '����‍♂️',\n    'man_frowning_tone5': '����‍♂️',\n    'man_genie': '��‍♂️',\n    'man_gesturing_no': '��‍♂️',\n    'man_gesturing_no_tone1': '����‍♂️',\n    'man_gesturing_no_tone2': '����‍♂️',\n    'man_gesturing_no_tone3': '����‍♂️',\n    'man_gesturing_no_tone4': '����‍♂️',\n    'man_gesturing_no_tone5': '����‍♂️',\n    'man_gesturing_ok': '��‍♂️',\n    'man_gesturing_ok_tone1': '����‍♂️',\n    'man_gesturing_ok_tone2': '����‍♂️',\n    'man_gesturing_ok_tone3': '����‍♂️',\n    'man_gesturing_ok_tone4': '����‍♂️',\n    'man_gesturing_ok_tone5': '����‍♂️',\n    'man_getting_face_massage': '��‍♂️',\n    'man_getting_face_massage_tone1': '����‍♂️',\n    'man_getting_face_massage_tone2': '����‍♂️',\n    'man_getting_face_massage_tone3': '����‍♂️',\n    'man_getting_face_massage_tone4': '����‍♂️',\n    'man_getting_face_massage_tone5': '����‍♂️',\n    'man_getting_haircut': '��‍♂️',\n    'man_getting_haircut_tone1': '����‍♂️',\n    'man_getting_haircut_tone2': '����‍♂️',\n    'man_getting_haircut_tone3': '����‍♂️',\n    'man_getting_haircut_tone4': '����‍♂️',\n    'man_getting_haircut_tone5': '����‍♂️',\n    'man_guard': '��‍♂️',\n    'man_guard_tone1': '����‍♂️',\n    'man_guard_tone2': '����‍♂️',\n    'man_guard_tone3': '����‍♂️',\n    'man_guard_tone4': '����‍♂️',\n    'man_guard_tone5': '����‍♂️',\n    'man_handball': '��‍♂️',\n    'man_handball_tone1': '����‍♂️',\n    'man_handball_tone2': '����‍♂️',\n    'man_handball_tone3': '����‍♂️',\n    'man_handball_tone4': '����‍♂️',\n    'man_handball_tone5': '����‍♂️',\n    'man_health_worker': '��‍⚕️',\n    'man_health_worker_tone1': '����‍⚕️',\n    'man_health_worker_tone2': '����‍⚕️',\n    'man_health_worker_tone3': '����‍⚕️',\n    'man_health_worker_tone4': '����‍⚕️',\n    'man_health_worker_tone5': '����‍⚕️',\n    'man_hero': '��‍♂️',\n    'man_hero_tone1': '����‍♂️',\n    'man_hero_tone2': '����‍♂️',\n    'man_hero_tone3': '����‍♂️',\n    'man_hero_tone4': '����‍♂️',\n    'man_hero_tone5': '����‍♂️',\n    'man_judge': '��‍⚖️',\n    'man_judge_tone1': '����‍⚖️',\n    'man_judge_tone2': '����‍⚖️',\n    'man_judge_tone3': '����‍⚖️',\n    'man_judge_tone4': '����‍⚖️',\n    'man_judge_tone5': '����‍⚖️',\n    'man_juggling': '��‍♂️',\n    'man_juggling_tone1': '����‍♂️',\n    'man_juggling_tone2': '����‍♂️',\n    'man_juggling_tone3': '����‍♂️',\n    'man_juggling_tone4': '����‍♂️',\n    'man_juggling_tone5': '����‍♂️',\n    'man_kneeling': '��‍♂️',\n    'man_kneeling_tone1': '����‍♂️',\n    'man_kneeling_tone2': '����‍♂️',\n    'man_kneeling_tone3': '����‍♂️',\n    'man_kneeling_tone4': '����‍♂️',\n    'man_kneeling_tone5': '����‍♂️',\n    'man_lotus_position': '��‍♂️',\n    'man_lotus_position_tone1': '����‍♂️',\n    'man_lotus_position_tone2': '����‍♂️',\n    'man_lotus_position_tone3': '����‍♂️',\n    'man_lotus_position_tone4': '����‍♂️',\n    'man_lotus_position_tone5': '����‍♂️',\n    'man_mage': '��‍♂️',\n    'man_mage_tone1': '����‍♂️',\n    'man_mage_tone2': '����‍♂️',\n    'man_mage_tone3': '����‍♂️',\n    'man_mage_tone4': '����‍♂️',\n    'man_mage_tone5': '����‍♂️',\n    'man_mechanic': '��‍��',\n    'man_mechanic_tone1': '����‍��',\n    'man_mechanic_tone2': '����‍��',\n    'man_mechanic_tone3': '����‍��',\n    'man_mechanic_tone4': '����‍��',\n    'man_mechanic_tone5': '����‍��',\n    'man_motor_wheelchair': '��‍��',\n    'man_motor_wheelchair_tone1': '����‍��',\n    'man_motor_wheelchair_tone2': '����‍��',\n    'man_motor_wheelchair_tone3': '����‍��',\n    'man_motor_wheelchair_tone4': '����‍��',\n    'man_motor_wheelchair_tone5': '����‍��',\n    'man_mountain_biking': '��‍♂️',\n    'man_mountain_biking_tone1': '����‍♂️',\n    'man_mountain_biking_tone2': '����‍♂️',\n    'man_mountain_biking_tone3': '����‍♂️',\n    'man_mountain_biking_tone4': '����‍♂️',\n    'man_mountain_biking_tone5': '����‍♂️',\n    'man_office_worker': '��‍��',\n    'man_office_worker_tone1': '����‍��',\n    'man_office_worker_tone2': '����‍��',\n    'man_office_worker_tone3': '����‍��',\n    'man_office_worker_tone4': '����‍��',\n    'man_office_worker_tone5': '����‍��',\n    'man_pilot': '��‍✈️',\n    'man_pilot_tone1': '����‍✈️',\n    'man_pilot_tone2': '����‍✈️',\n    'man_pilot_tone3': '����‍✈️',\n    'man_pilot_tone4': '����‍✈️',\n    'man_pilot_tone5': '����‍✈️',\n    'man_police_officer': '��‍♂️',\n    'man_police_officer_tone1': '����‍♂️',\n    'man_police_officer_tone2': '����‍♂️',\n    'man_police_officer_tone3': '����‍♂️',\n    'man_police_officer_tone4': '����‍♂️',\n    'man_police_officer_tone5': '����‍♂️',\n    'man_pouting': '��‍♂️',\n    'man_pouting_tone1': '����‍♂️',\n    'man_pouting_tone2': '����‍♂️',\n    'man_pouting_tone3': '����‍♂️',\n    'man_pouting_tone4': '����‍♂️',\n    'man_pouting_tone5': '����‍♂️',\n    'man_probing_cane': '��‍��',\n    'man_probing_cane_tone1': '����‍��',\n    'man_probing_cane_tone2': '����‍��',\n    'man_probing_cane_tone3': '����‍��',\n    'man_probing_cane_tone4': '����‍��',\n    'man_probing_cane_tone5': '����‍��',\n    'man_raising_hand': '��‍♂️',\n    'man_raising_hand_tone1': '����‍♂️',\n    'man_raising_hand_tone2': '����‍♂️',\n    'man_raising_hand_tone3': '����‍♂️',\n    'man_raising_hand_tone4': '����‍♂️',\n    'man_raising_hand_tone5': '����‍♂️',\n    'man_rowing_boat': '��‍♂️',\n    'man_rowing_boat_tone1': '����‍♂️',\n    'man_rowing_boat_tone2': '����‍♂️',\n    'man_rowing_boat_tone3': '����‍♂️',\n    'man_rowing_boat_tone4': '����‍♂️',\n    'man_rowing_boat_tone5': '����‍♂️',\n    'man_running': '��‍♂️',\n    'man_running_tone1': '����‍♂️',\n    'man_running_tone2': '����‍♂️',\n    'man_running_tone3': '����‍♂️',\n    'man_running_tone4': '����‍♂️',\n    'man_running_tone5': '����‍♂️',\n    'man_scientist': '��‍��',\n    'man_scientist_tone1': '����‍��',\n    'man_scientist_tone2': '����‍��',\n    'man_scientist_tone3': '����‍��',\n    'man_scientist_tone4': '����‍��',\n    'man_scientist_tone5': '����‍��',\n    'man_shrugging': '��‍♂️',\n    'man_shrugging_tone1': '����‍♂️',\n    'man_shrugging_tone2': '����‍♂️',\n    'man_shrugging_tone3': '����‍♂️',\n    'man_shrugging_tone4': '����‍♂️',\n    'man_shrugging_tone5': '����‍♂️',\n    'man_singer': '��‍��',\n    'man_singer_tone1': '����‍��',\n    'man_singer_tone2': '����‍��',\n    'man_singer_tone3': '����‍��',\n    'man_singer_tone4': '����‍��',\n    'man_singer_tone5': '����‍��',\n    'man_standing': '��‍♂️',\n    'man_standing_tone1': '����‍♂️',\n    'man_standing_tone2': '����‍♂️',\n    'man_standing_tone3': '����‍♂️',\n    'man_standing_tone4': '����‍♂️',\n    'man_standing_tone5': '����‍♂️',\n    'man_steamy_room': '��‍♂️',\n    'man_steamy_room_tone1': '����‍♂️',\n    'man_steamy_room_tone2': '����‍♂️',\n    'man_steamy_room_tone3': '����‍♂️',\n    'man_steamy_room_tone4': '����‍♂️',\n    'man_steamy_room_tone5': '����‍♂️',\n    'man_student': '��‍��',\n    'man_student_tone1': '����‍��',\n    'man_student_tone2': '����‍��',\n    'man_student_tone3': '����‍��',\n    'man_student_tone4': '����‍��',\n    'man_student_tone5': '����‍��',\n    'man_surfing': '��‍♂️',\n    'man_surfing_tone1': '����‍♂️',\n    'man_surfing_tone2': '����‍♂️',\n    'man_surfing_tone3': '����‍♂️',\n    'man_surfing_tone4': '����‍♂️',\n    'man_surfing_tone5': '����‍♂️',\n    'man_swimming': '��‍♂️',\n    'man_swimming_tone1': '����‍♂️',\n    'man_swimming_tone2': '����‍♂️',\n    'man_swimming_tone3': '����‍♂️',\n    'man_swimming_tone4': '����‍♂️',\n    'man_swimming_tone5': '����‍♂️',\n    'man_teacher': '��‍��',\n    'man_teacher_tone1': '����‍��',\n    'man_teacher_tone2': '����‍��',\n    'man_teacher_tone3': '����‍��',\n    'man_teacher_tone4': '����‍��',\n    'man_teacher_tone5': '����‍��',\n    'man_technologist': '��‍��',\n    'man_technologist_tone1': '����‍��',\n    'man_technologist_tone2': '����‍��',\n    'man_technologist_tone3': '����‍��',\n    'man_technologist_tone4': '����‍��',\n    'man_technologist_tone5': '����‍��',\n    'man_tipping_hand': '��‍♂️',\n    'man_tipping_hand_tone1': '����‍♂️',\n    'man_tipping_hand_tone2': '����‍♂️',\n    'man_tipping_hand_tone3': '����‍♂️',\n    'man_tipping_hand_tone4': '����‍♂️',\n    'man_tipping_hand_tone5': '����‍♂️',\n    'man_tone1': '����',\n    'man_tone2': '����',\n    'man_tone3': '����',\n    'man_tone4': '����',\n    'man_tone5': '����',\n    'man_turban': '��‍♂️',\n    'man_turban_tone1': '����‍♂️',\n    'man_turban_tone2': '����‍♂️',\n    'man_turban_tone3': '����‍♂️',\n    'man_turban_tone4': '����‍♂️',\n    'man_turban_tone5': '����‍♂️',\n    'man_tuxedo': '��',\n    'man_tuxedo_tone1': '����',\n    'man_tuxedo_tone2': '����',\n    'man_tuxedo_tone3': '����',\n    'man_tuxedo_tone4': '����',\n    'man_tuxedo_tone5': '����',\n    'man_vampire': '��‍♂️',\n    'man_vampire_tone1': '����‍♂️',\n    'man_vampire_tone2': '����‍♂️',\n    'man_vampire_tone3': '����‍♂️',\n    'man_vampire_tone4': '����‍♂️',\n    'man_vampire_tone5': '����‍♂️',\n    'man_villain': '��‍♂️',\n    'man_villain_tone1': '����‍♂️',\n    'man_villain_tone2': '����‍♂️',\n    'man_villain_tone3': '����‍♂️',\n    'man_villain_tone4': '����‍♂️',\n    'man_villain_tone5': '����‍♂️',\n    'man_walking': '��‍♂️',\n    'man_walking_tone1': '����‍♂️',\n    'man_walking_tone2': '����‍♂️',\n    'man_walking_tone3': '����‍♂️',\n    'man_walking_tone4': '����‍♂️',\n    'man_walking_tone5': '����‍♂️',\n    'man_water_polo': '��‍♂️',\n    'man_water_polo_tone1': '����‍♂️',\n    'man_water_polo_tone2': '����‍♂️',\n    'man_water_polo_tone3': '����‍♂️',\n    'man_water_polo_tone4': '����‍♂️',\n    'man_water_polo_tone5': '����‍♂️',\n    'man_wheelchair': '��‍��',\n    'man_wheelchair_tone1': '����‍��',\n    'man_wheelchair_tone2': '����‍��',\n    'man_wheelchair_tone3': '����‍��',\n    'man_wheelchair_tone4': '����‍��',\n    'man_wheelchair_tone5': '����‍��',\n    'man_zombie': '��‍♂️',\n    'mango': '��',\n    'mans_shoe': '��',\n    'map': '��️',\n    'maple_leaf': '��',\n    'martial_arts_uniform': '��',\n    'mask': '��',\n    'mate': '��',\n    'meat_on_bone': '��',\n    'mech_arm': '��',\n    'mech_leg': '��',\n    'medal': '��',\n    'medical': '⚕️',\n    'medium_black_square': '◼️',\n    'medium_small_black_square': '◾️',\n    'medium_small_white_square': '◽️',\n    'medium_white_square': '◻️',\n    'megaphone': '��',\n    'melon': '��',\n    'memo': '��',\n    'men_bunny_ears_partying': '��‍♂️',\n    'men_wrestling': '��‍♂️',\n    'menorah': '��',\n    'mens': '��️',\n    'mermaid': '��‍♀️',\n    'mermaid_tone1': '����‍♀️',\n    'mermaid_tone2': '����‍♀️',\n    'mermaid_tone3': '����‍♀️',\n    'mermaid_tone4': '����‍♀️',\n    'mermaid_tone5': '����‍♀️',\n    'merman': '��‍♂️',\n    'merman_tone1': '����‍♂️',\n    'merman_tone2': '����‍♂️',\n    'merman_tone3': '����‍♂️',\n    'merman_tone4': '����‍♂️',\n    'merman_tone5': '����‍♂️',\n    'merperson': '��',\n    'merperson_tone1': '����',\n    'merperson_tone2': '����',\n    'merperson_tone3': '����',\n    'merperson_tone4': '����',\n    'merperson_tone5': '����',\n    'metal': '��',\n    'metal_tone1': '����',\n    'metal_tone2': '����',\n    'metal_tone3': '����',\n    'metal_tone4': '����',\n    'metal_tone5': '����',\n    'metro': '��️',\n    'microbe': '��',\n    'microphone': '��',\n    'microscope': '��',\n    'middle_finger': '��',\n    'middle_finger_tone1': '����',\n    'middle_finger_tone2': '����',\n    'middle_finger_tone3': '����',\n    'middle_finger_tone4': '����',\n    'middle_finger_tone5': '����',\n    'military_medal': '��️',\n    'milk': '��',\n    'milky_way': '��',\n    'minibus': '��',\n    'minidisc': '��',\n    'minus': '➖',\n    'mischievous': '��',\n    'moai': '��',\n    'mobile': '��',\n    'mobile_calling': '��',\n    'mobile_phone_off': '��',\n    'money_mouth': '��',\n    'money_wings': '��',\n    'moneybag': '��️',\n    'monkey': '��',\n    'monkey_face': '��',\n    'monocle': '��',\n    'monorail': '��',\n    'moon_cake': '��',\n    'moon_ceremony': '��',\n    'mosque': '��',\n    'mosquito': '��',\n    'motor_scooter': '��',\n    'motor_wheelchair': '��',\n    'motorboat': '��️',\n    'motorcycle': '��️',\n    'motorway': '��️',\n    'mount_fuji': '��',\n    'mountain': '⛰️',\n    'mountain_cableway': '��',\n    'mountain_railway': '��',\n    'mouse': '��',\n    'mouse_face': '��',\n    'movie_camera': '��',\n    'mrs_claus': '��',\n    'mrs_claus_tone1': '����',\n    'mrs_claus_tone2': '����',\n    'mrs_claus_tone3': '����',\n    'mrs_claus_tone4': '����',\n    'mrs_claus_tone5': '����',\n    'multiplication': '✖️',\n    'muscle': '��',\n    'muscle_tone1': '����',\n    'muscle_tone2': '����',\n    'muscle_tone3': '����',\n    'muscle_tone4': '����',\n    'muscle_tone5': '����',\n    'mushroom': '��',\n    'musical_keyboard': '��',\n    'musical_note': '��',\n    'musical_notes': '��',\n    'musical_score': '��',\n    'mute': '��',\n    'nail_care': '��',\n    'nail_care_tone1': '����',\n    'nail_care_tone2': '����',\n    'nail_care_tone3': '����',\n    'nail_care_tone4': '����',\n    'nail_care_tone5': '����',\n    'name_badge': '��',\n    'nauseated': '��',\n    'nazar_amulet': '��',\n    'necktie': '��',\n    'nerd': '��',\n    'neutral': '��️',\n    'new': '��',\n    'new_moon': '��',\n    'new_moon_face': '��',\n    'newspaper': '��',\n    'next_track': '⏭️',\n    'ng': '��',\n    'night_stars': '��',\n    'nine': '9️⃣',\n    'no': '��️',\n    'no_bell': '��',\n    'no_bicycles': '��',\n    'no_entry': '⛔️',\n    'no_entry_sign': '��',\n    'no_mobile_phones': '��',\n    'no_mouth': '��',\n    'no_pedestrians': '��',\n    'no_smoking': '��️',\n    'no_sound': '��',\n    'no_tone1': '����',\n    'no_tone2': '����',\n    'no_tone3': '����',\n    'no_tone4': '����',\n    'no_tone5': '����',\n    'non_potable_water': '��',\n    'nose': '��',\n    'nose_tone1': '����',\n    'nose_tone2': '����',\n    'nose_tone3': '����',\n    'nose_tone4': '����',\n    'nose_tone5': '����',\n    'notebook': '��',\n    'notepad_spiral': '��️',\n    'nut_and_bolt': '��',\n    'o': '⭕️',\n    'o_blood': '��️',\n    'ocean': '��',\n    'octagonal_sign': '��',\n    'octopus': '��',\n    'oden': '��',\n    'office': '��',\n    'ogre': '��',\n    'oil_drum': '��️',\n    'ok': '��',\n    'ok_hand': '��',\n    'ok_hand_tone1': '����',\n    'ok_hand_tone2': '����',\n    'ok_hand_tone3': '����',\n    'ok_hand_tone4': '����',\n    'ok_hand_tone5': '����',\n    'old_key': '��️',\n    'older_adult': '��',\n    'older_adult_tone1': '����',\n    'older_adult_tone2': '����',\n    'older_adult_tone3': '����',\n    'older_adult_tone4': '����',\n    'older_adult_tone5': '����',\n    'older_man': '��',\n    'older_man_tone1': '����',\n    'older_man_tone2': '����',\n    'older_man_tone3': '����',\n    'older_man_tone4': '����',\n    'older_man_tone5': '����',\n    'older_woman': '��',\n    'older_woman_tone1': '����',\n    'older_woman_tone2': '����',\n    'older_woman_tone3': '����',\n    'older_woman_tone4': '����',\n    'older_woman_tone5': '����',\n    'om_symbol': '��️',\n    'on': '��',\n    'oncoming_automobile': '��️',\n    'oncoming_bus': '��️',\n    'oncoming_police_car': '��️',\n    'oncoming_taxi': '��',\n    'one': '1️⃣',\n    'one_piece_swimsuit': '��',\n    'onion': '��',\n    'open_file_folder': '��',\n    'open_hands': '��',\n    'open_hands_tone1': '����',\n    'open_hands_tone2': '����',\n    'open_hands_tone3': '����',\n    'open_hands_tone4': '����',\n    'open_hands_tone5': '����',\n    'ophiuchus': '⛎',\n    'orange_book': '��',\n    'orange_circle': '��',\n    'orange_heart': '��',\n    'orange_square': '��',\n    'orangutan': '��',\n    'orthodox_cross': '☦️',\n    'otter': '��',\n    'outbox_tray': '��️',\n    'overcast': '��️',\n    'overheating': '��',\n    'owl': '��',\n    'ox': '��',\n    'oyster': '��',\n    'p': '��️',\n    'package': '��️',\n    'page_curl': '��',\n    'page_facing_up': '��',\n    'pager': '��️',\n    'paintbrush': '��️',\n    'palette': '��',\n    'palm_tree': '��',\n    'palms_up': '��',\n    'palms_up_tone1': '����',\n    'palms_up_tone2': '����',\n    'palms_up_tone3': '����',\n    'palms_up_tone4': '����',\n    'palms_up_tone5': '����',\n    'pancakes': '��',\n    'panda_face': '��',\n    'paperclip': '��',\n    'paperclips': '��️',\n    'parachute': '��',\n    'park': '��️',\n    'parrot': '��',\n    'part_alternation_mark': '〽️',\n    'partly_sunny': '⛅️',\n    'party': '��',\n    'partying': '��',\n    'passport_control': '��',\n    'pause': '⏸️',\n    'peace': '☮️',\n    'peach': '��',\n    'peacock': '��',\n    'peanuts': '��',\n    'pear': '��',\n    'pen': '��️',\n    'pencil': '✏️',\n    'penguin': '��',\n    'pensive': '��',\n    'people_bunny_ears_partying': '��',\n    'people_wrestling': '��',\n    'performing_arts': '��️',\n    'persevered': '��',\n    'person_biking': '��',\n    'person_biking_tone1': '����',\n    'person_biking_tone2': '����',\n    'person_biking_tone3': '����',\n    'person_biking_tone4': '����',\n    'person_biking_tone5': '����',\n    'person_bouncing_ball': '⛹️',\n    'person_bouncing_ball_tone1': '⛹��',\n    'person_bouncing_ball_tone2': '⛹��',\n    'person_bouncing_ball_tone3': '⛹��',\n    'person_bouncing_ball_tone4': '⛹��',\n    'person_bouncing_ball_tone5': '⛹��',\n    'person_bowing': '��',\n    'person_bowing_tone1': '����',\n    'person_bowing_tone2': '����',\n    'person_bowing_tone3': '����',\n    'person_bowing_tone4': '����',\n    'person_bowing_tone5': '����',\n    'person_cartwheel': '��',\n    'person_cartwheel_tone1': '����',\n    'person_cartwheel_tone2': '����',\n    'person_cartwheel_tone3': '����',\n    'person_cartwheel_tone4': '����',\n    'person_cartwheel_tone5': '����',\n    'person_climbing': '��',\n    'person_climbing_tone1': '����',\n    'person_climbing_tone2': '����',\n    'person_climbing_tone3': '����',\n    'person_climbing_tone4': '����',\n    'person_climbing_tone5': '����',\n    'person_deaf': '��',\n    'person_deaf_tone1': '����',\n    'person_deaf_tone2': '����',\n    'person_deaf_tone3': '����',\n    'person_deaf_tone4': '����',\n    'person_deaf_tone5': '����',\n    'person_facepalming': '��',\n    'person_facepalming_tone1': '����',\n    'person_facepalming_tone2': '����',\n    'person_facepalming_tone3': '����',\n    'person_facepalming_tone4': '����',\n    'person_facepalming_tone5': '����',\n    'person_fencing': '��',\n    'person_frowning': '��',\n    'person_frowning_tone1': '����',\n    'person_frowning_tone2': '����',\n    'person_frowning_tone3': '����',\n    'person_frowning_tone4': '����',\n    'person_frowning_tone5': '����',\n    'person_gesturing_no': '��',\n    'person_gesturing_no_tone1': '����',\n    'person_gesturing_no_tone2': '����',\n    'person_gesturing_no_tone3': '����',\n    'person_gesturing_no_tone4': '����',\n    'person_gesturing_no_tone5': '����',\n    'person_gesturing_ok': '��',\n    'person_gesturing_ok_tone1': '����',\n    'person_gesturing_ok_tone2': '����',\n    'person_gesturing_ok_tone3': '����',\n    'person_gesturing_ok_tone4': '����',\n    'person_gesturing_ok_tone5': '����',\n    'person_getting_haircut': '��',\n    'person_getting_haircut_tone1': '����',\n    'person_getting_haircut_tone2': '����',\n    'person_getting_haircut_tone3': '����',\n    'person_getting_haircut_tone4': '����',\n    'person_getting_haircut_tone5': '����',\n    'person_getting_massage': '��',\n    'person_getting_massage_tone1': '����',\n    'person_getting_massage_tone2': '����',\n    'person_getting_massage_tone3': '����',\n    'person_getting_massage_tone4': '����',\n    'person_getting_massage_tone5': '����',\n    'person_golfing': '��️',\n    'person_golfing_tone1': '����',\n    'person_golfing_tone2': '����',\n    'person_golfing_tone3': '����',\n    'person_golfing_tone4': '����',\n    'person_golfing_tone5': '����',\n    'person_handball': '��',\n    'person_handball_tone1': '����',\n    'person_handball_tone2': '����',\n    'person_handball_tone3': '����',\n    'person_handball_tone4': '����',\n    'person_handball_tone5': '����',\n    'person_juggling': '��',\n    'person_juggling_tone1': '����',\n    'person_juggling_tone2': '����',\n    'person_juggling_tone3': '����',\n    'person_juggling_tone4': '����',\n    'person_juggling_tone5': '����',\n    'person_kneeling': '��',\n    'person_kneeling_tone1': '����',\n    'person_kneeling_tone2': '����',\n    'person_kneeling_tone3': '����',\n    'person_kneeling_tone4': '����',\n    'person_kneeling_tone5': '����',\n    'person_lifting_weights': '��️',\n    'person_lifting_weights_tone1': '����',\n    'person_lifting_weights_tone2': '����',\n    'person_lifting_weights_tone3': '����',\n    'person_lifting_weights_tone4': '����',\n    'person_lifting_weights_tone5': '����',\n    'person_lotus_position': '��',\n    'person_lotus_position_tone1': '����',\n    'person_lotus_position_tone2': '����',\n    'person_lotus_position_tone3': '����',\n    'person_lotus_position_tone4': '����',\n    'person_lotus_position_tone5': '����',\n    'person_mountain_biking': '��',\n    'person_mountain_biking_tone1': '����',\n    'person_mountain_biking_tone2': '����',\n    'person_mountain_biking_tone3': '����',\n    'person_mountain_biking_tone4': '����',\n    'person_mountain_biking_tone5': '����',\n    'person_pouting': '��',\n    'person_pouting_tone1': '����',\n    'person_pouting_tone2': '����',\n    'person_pouting_tone3': '����',\n    'person_pouting_tone4': '����',\n    'person_pouting_tone5': '����',\n    'person_raising_hand': '��',\n    'person_raising_hand_tone1': '����',\n    'person_raising_hand_tone2': '����',\n    'person_raising_hand_tone3': '����',\n    'person_raising_hand_tone4': '����',\n    'person_raising_hand_tone5': '����',\n    'person_rowing_boat': '��',\n    'person_rowing_boat_tone1': '����',\n    'person_rowing_boat_tone2': '����',\n    'person_rowing_boat_tone3': '����',\n    'person_rowing_boat_tone4': '����',\n    'person_rowing_boat_tone5': '����',\n    'person_running': '��',\n    'person_running_tone1': '����',\n    'person_running_tone2': '����',\n    'person_running_tone3': '����',\n    'person_running_tone4': '����',\n    'person_running_tone5': '����',\n    'person_shrugging': '��',\n    'person_shrugging_tone1': '����',\n    'person_shrugging_tone2': '����',\n    'person_shrugging_tone3': '����',\n    'person_shrugging_tone4': '����',\n    'person_shrugging_tone5': '����',\n    'person_standing': '��',\n    'person_standing_tone1': '����',\n    'person_standing_tone2': '����',\n    'person_standing_tone3': '����',\n    'person_standing_tone4': '����',\n    'person_standing_tone5': '����',\n    'person_steamy_room': '��',\n    'person_steamy_room_tone1': '����',\n    'person_steamy_room_tone2': '����',\n    'person_steamy_room_tone3': '����',\n    'person_steamy_room_tone4': '����',\n    'person_steamy_room_tone5': '����',\n    'person_surfing': '��️',\n    'person_surfing_tone1': '����',\n    'person_surfing_tone2': '����',\n    'person_surfing_tone3': '����',\n    'person_surfing_tone4': '����',\n    'person_surfing_tone5': '����',\n    'person_swimming': '��️',\n    'person_swimming_tone1': '����',\n    'person_swimming_tone2': '����',\n    'person_swimming_tone3': '����',\n    'person_swimming_tone4': '����',\n    'person_swimming_tone5': '����',\n    'person_tipping_hand': '��',\n    'person_tipping_hand_tone1': '����',\n    'person_tipping_hand_tone2': '����',\n    'person_tipping_hand_tone3': '����',\n    'person_tipping_hand_tone4': '����',\n    'person_tipping_hand_tone5': '����',\n    'person_turban': '��',\n    'person_turban_tone1': '����',\n    'person_turban_tone2': '����',\n    'person_turban_tone3': '����',\n    'person_turban_tone4': '����',\n    'person_turban_tone5': '����',\n    'person_walking': '��',\n    'person_walking_tone1': '����',\n    'person_walking_tone2': '����',\n    'person_walking_tone3': '����',\n    'person_walking_tone4': '����',\n    'person_walking_tone5': '����',\n    'person_water_polo': '��',\n    'person_water_polo_tone1': '����',\n    'person_water_polo_tone2': '����',\n    'person_water_polo_tone3': '����',\n    'person_water_polo_tone4': '����',\n    'person_water_polo_tone5': '����',\n    'petri_dish': '��',\n    'pick': '⛏️',\n    'pie': '��',\n    'pig': '��',\n    'pig_face': '��',\n    'pig_nose': '��',\n    'pill': '��',\n    'pinch': '��',\n    'pinch_tone1': '����',\n    'pinch_tone2': '����',\n    'pinch_tone3': '����',\n    'pinch_tone4': '����',\n    'pinch_tone5': '����',\n    'pine_decor': '��',\n    'pineapple': '��',\n    'ping_pong': '��',\n    'pirate_flag': '��‍☠️',\n    'pisces': '♓️',\n    'pistol': '��',\n    'pizza': '��',\n    'place_of_worship': '��',\n    'play': '▶️',\n    'play_pause': '⏯️',\n    'playful': '��',\n    'pleading': '��',\n    'pleased': '��',\n    'plus': '➕',\n    'point_down': '��️',\n    'point_down_tone1': '����',\n    'point_down_tone2': '����',\n    'point_down_tone3': '����',\n    'point_down_tone4': '����',\n    'point_down_tone5': '����',\n    'point_left': '��️',\n    'point_left_tone1': '����',\n    'point_left_tone2': '����',\n    'point_left_tone3': '����',\n    'point_left_tone4': '����',\n    'point_left_tone5': '����',\n    'point_right': '��️',\n    'point_right_tone1': '����',\n    'point_right_tone2': '����',\n    'point_right_tone3': '����',\n    'point_right_tone4': '����',\n    'point_right_tone5': '����',\n    'point_up': '☝️',\n    'point_up_tone1': '☝��',\n    'point_up_tone2': '☝��',\n    'point_up_tone3': '☝��',\n    'point_up_tone4': '☝��',\n    'point_up_tone5': '☝��',\n    'police_car': '��',\n    'police_light': '��',\n    'police_officer': '��',\n    'police_officer_tone1': '����',\n    'police_officer_tone2': '����',\n    'police_officer_tone3': '����',\n    'police_officer_tone4': '����',\n    'police_officer_tone5': '����',\n    'poodle': '��',\n    'poop': '��',\n    'popcorn': '��',\n    'post_office': '��',\n    'postal_horn': '��',\n    'postbox': '��',\n    'potable_water': '��',\n    'potato': '��',\n    'pouch': '��',\n    'poultry_leg': '��',\n    'pound': '��',\n    'pout': '��',\n    'pouting_cat': '��',\n    'pray': '��',\n    'pray_tone1': '����',\n    'pray_tone2': '����',\n    'pray_tone3': '����',\n    'pray_tone4': '����',\n    'pray_tone5': '����',\n    'prayer_beads': '��',\n    'pregnant_woman': '��',\n    'pregnant_woman_tone1': '����',\n    'pregnant_woman_tone2': '����',\n    'pregnant_woman_tone3': '����',\n    'pregnant_woman_tone4': '����',\n    'pregnant_woman_tone5': '����',\n    'pretentious': '��',\n    'pretzel': '��',\n    'previous_track': '⏮️',\n    'prince': '��',\n    'prince_tone1': '����',\n    'prince_tone2': '����',\n    'prince_tone3': '����',\n    'prince_tone4': '����',\n    'prince_tone5': '����',\n    'princess': '��',\n    'princess_tone1': '����',\n    'princess_tone2': '����',\n    'princess_tone3': '����',\n    'princess_tone4': '����',\n    'princess_tone5': '����',\n    'printer': '��️',\n    'probing_cane': '��',\n    'projector': '��️',\n    'punch': '��',\n    'punch_tone1': '����',\n    'punch_tone2': '����',\n    'punch_tone3': '����',\n    'punch_tone4': '����',\n    'punch_tone5': '����',\n    'purple_circle': '��',\n    'purple_heart': '��',\n    'purple_square': '��',\n    'purse': '��',\n    'pushpin': '��',\n    'puzzle_piece': '��',\n    'question': '❓️',\n    'rabbit': '��',\n    'rabbit_face': '��',\n    'raccoon': '��',\n    'race_car': '��️',\n    'radio': '��️',\n    'radio_button': '��',\n    'radioactive': '☢️',\n    'railway_car': '��',\n    'railway_track': '��️',\n    'rain': '��️',\n    'rainbow': '��',\n    'rainbow_flag': '��️‍��',\n    'raised_backhand': '��',\n    'raised_backhand_tone1': '����',\n    'raised_backhand_tone2': '����',\n    'raised_backhand_tone3': '����',\n    'raised_backhand_tone4': '����',\n    'raised_backhand_tone5': '����',\n    'raised_hand': '✋',\n    'raised_hand_tone1': '✋��',\n    'raised_hand_tone2': '✋��',\n    'raised_hand_tone3': '✋��',\n    'raised_hand_tone4': '✋��',\n    'raised_hand_tone5': '✋��',\n    'raised_hands': '��',\n    'raised_hands_tone1': '����',\n    'raised_hands_tone2': '����',\n    'raised_hands_tone3': '����',\n    'raised_hands_tone4': '����',\n    'raised_hands_tone5': '����',\n    'ram': '��',\n    'ramen': '��',\n    'rat': '��',\n    'razor': '��',\n    'receipt': '��',\n    'record': '⏺️',\n    'recycle': '♻️',\n    'red_car': '��',\n    'red_circle': '��',\n    'red_envelope': '��',\n    'red_haired_man': '��‍��',\n    'red_haired_man_tone1': '����‍��',\n    'red_haired_man_tone2': '����‍��',\n    'red_haired_man_tone3': '����‍��',\n    'red_haired_man_tone4': '����‍��',\n    'red_haired_man_tone5': '����‍��',\n    'red_haired_woman': '��‍��',\n    'red_haired_woman_tone1': '����‍��',\n    'red_haired_woman_tone2': '����‍��',\n    'red_haired_woman_tone3': '����‍��',\n    'red_haired_woman_tone4': '����‍��',\n    'red_haired_woman_tone5': '����‍��',\n    'red_lantern': '��',\n    'red_square': '��',\n    'registered': '®️',\n    'relaxed': '☺️',\n    'relieved': '��',\n    'reminder_ribbon': '��️',\n    'repeat': '��',\n    'repeat_single': '��',\n    'restroom': '��',\n    'reverse': '◀️',\n    'revolving_hearts': '��',\n    'rewind': '⏪️',\n    'rhino': '��',\n    'ribbon': '��',\n    'rice': '��',\n    'rice_ball': '��',\n    'rice_cracker': '��',\n    'rice_scene': '��',\n    'right_anger_speech': '��️',\n    'right_bicep': '��',\n    'right_bicep_tone1': '����',\n    'right_bicep_tone2': '����',\n    'right_bicep_tone3': '����',\n    'right_bicep_tone4': '����',\n    'right_bicep_tone5': '����',\n    'right_facing_fist': '��',\n    'right_facing_fist_tone1': '����',\n    'right_facing_fist_tone2': '����',\n    'right_facing_fist_tone3': '����',\n    'right_facing_fist_tone4': '����',\n    'right_facing_fist_tone5': '����',\n    'ring': '��',\n    'ringed_planet': '��',\n    'robot': '��',\n    'rocket': '��',\n    'rofl': '��',\n    'rolled_newspaper': '��️',\n    'roller_coaster': '��',\n    'rooster': '��',\n    'rose': '��',\n    'rosette': '��️',\n    'rotating_light': '��',\n    'round_pushpin': '��',\n    'rugby': '��',\n    'running_shirt': '��',\n    'sad': '☹️',\n    'safety_pin': '��',\n    'safety_vest': '��',\n    'sagittarius': '♐️',\n    'sailboat': '⛵️',\n    'sake': '��',\n    'salad': '��',\n    'salt': '��',\n    'sandwich': '��',\n    'santa': '��',\n    'santa_tone1': '����',\n    'santa_tone2': '����',\n    'santa_tone3': '����',\n    'santa_tone4': '����',\n    'santa_tone5': '����',\n    'sari': '��',\n    'satellite': '��️',\n    'satellite_antenna': '��',\n    'saturn': '��',\n    'sauropod': '��',\n    'savour': '��',\n    'saxophone': '��',\n    'scales': '⚖️',\n    'scarf': '��',\n    'school': '��',\n    'scissors': '✂️',\n    'scooter': '��',\n    'scorpion': '��',\n    'scorpius': '♏️',\n    'scotland': '��������������',\n    'scream': '��',\n    'scroll': '��',\n    'scuba_mask': '��',\n    'seat': '��',\n    'second_place': '��',\n    'see_no_evil': '��',\n    'seedling': '��',\n    'selfie': '��',\n    'selfie_tone1': '����',\n    'selfie_tone2': '����',\n    'selfie_tone3': '����',\n    'selfie_tone4': '����',\n    'selfie_tone5': '����',\n    'service_dog': '��‍��',\n    'seven': '7️⃣',\n    'shallow_pan_of_food': '��',\n    'shamed': '��',\n    'shamrock': '☘️',\n    'shark': '��',\n    'shaved_ice': '��',\n    'sheep': '��',\n    'shell': '��',\n    'shield': '��️',\n    'shinto_shrine': '⛩️',\n    'ship': '��',\n    'shirt': '��',\n    'shocked': '��',\n    'shooting_star': '��',\n    'shopping_bags': '��️',\n    'shopping_cart': '��',\n    'shorts': '��',\n    'shower': '��',\n    'shrimp': '��',\n    'shuffle': '��',\n    'shushing': '��',\n    'sick': '��',\n    'signal_strength': '��',\n    'silenced': '��',\n    'six': '6️⃣',\n    'six_pointed_star': '��',\n    'skateboard': '��',\n    'ski': '��',\n    'skier': '⛷️',\n    'skull': '��',\n    'skunk': '��',\n    'sled': '��',\n    'sleeping': '��',\n    'sleepy': '��',\n    'slight_frown': '��',\n    'slight_smile': '��',\n    'slot_machine': '��',\n    'sloth': '��',\n    'small_airplane': '��️',\n    'small_black_square': '▪️',\n    'small_blue_diamond': '��',\n    'small_orange_diamond': '��',\n    'small_white_square': '▫️',\n    'smile': '��',\n    'smiling_cat': '��',\n    'smirk': '��',\n    'smirking_cat': '��',\n    'smoking': '��',\n    'snail': '��',\n    'snake': '��',\n    'sneaker': '��',\n    'sneezing': '��',\n    'snow': '��️',\n    'snowboarder': '��️',\n    'snowboarder_tone1': '����',\n    'snowboarder_tone2': '����',\n    'snowboarder_tone3': '����',\n    'snowboarder_tone4': '����',\n    'snowboarder_tone5': '����',\n    'snowflake': '❄️',\n    'snowman': '⛄️',\n    'snowy_mountain': '��️',\n    'snowy_snowman': '☃️',\n    'soap': '��',\n    'sob': '��',\n    'soccer': '⚽️',\n    'socks': '��',\n    'softball': '��',\n    'soon': '��',\n    'sos': '��',\n    'sound': '��',\n    'space_invader': '��',\n    'spades': '♠️',\n    'spaghetti': '��',\n    'sparkle': '❇️',\n    'sparkler': '��',\n    'sparkles': '✨',\n    'sparkling_heart': '��',\n    'speak_no_evil': '��',\n    'speaker': '��️',\n    'speaking_head': '��️',\n    'speech': '��',\n    'speedboat': '��',\n    'spider': '��️',\n    'spider_web': '��️',\n    'splayed_hand': '��️',\n    'splayed_hand_tone1': '����',\n    'splayed_hand_tone2': '����',\n    'splayed_hand_tone3': '����',\n    'splayed_hand_tone4': '����',\n    'splayed_hand_tone5': '����',\n    'sponge': '��',\n    'spool': '��',\n    'spoon': '��',\n    'spouting_whale': '��',\n    'squid': '��',\n    'stadium': '��️',\n    'star': '⭐️',\n    'star2': '��',\n    'star3': '��',\n    'star_and_crescent': '☪️',\n    'star_of_david': '✡️',\n    'starstruck': '��',\n    'station': '��',\n    'statue_of_liberty': '��',\n    'steam_locomotive': '��',\n    'stethoscope': '��',\n    'stew': '��',\n    'stop': '⏹️',\n    'stop_sign': '��',\n    'stopwatch': '⏱️',\n    'storm': '⛈️',\n    'straight_ruler': '��',\n    'strawberry': '��',\n    'studio_microphone': '��️',\n    'stuffed_flatbread': '��',\n    'sun': '☀️',\n    'sun_face': '��',\n    'sunflower': '��',\n    'sunglasses': '��️',\n    'sunrise': '��',\n    'sunrise_over_mountains': '��',\n    'sunset': '��',\n    'sunshower': '��️',\n    'superhero': '��',\n    'superhero_tone1': '����',\n    'superhero_tone2': '����',\n    'superhero_tone3': '����',\n    'superhero_tone4': '����',\n    'superhero_tone5': '����',\n    'supervillain': '��',\n    'supervillain_tone1': '����',\n    'supervillain_tone2': '����',\n    'supervillain_tone3': '����',\n    'supervillain_tone4': '����',\n    'supervillain_tone5': '����',\n    'surprised': '��',\n    'sushi': '��',\n    'suspension_railway': '��',\n    'swan': '��',\n    'sweat_drops': '��',\n    'sweet_potato': '��',\n    'symbols': '��',\n    'synagogue': '��',\n    'syringe': '��',\n    'taco': '��',\n    'tada': '��',\n    'takeout_box': '��',\n    'tanabata_tree': '��',\n    'tangerine': '��',\n    'taurus': '♉️',\n    'taxi': '��',\n    'tea': '��',\n    'teddy_bear': '��',\n    'telephone': '☎️',\n    'telephone_receiver': '��',\n    'telescope': '��',\n    'ten': '��',\n    'tennis': '��',\n    'tent': '⛺️',\n    'test_tube': '��',\n    'thermometer': '��️',\n    'thinking': '��',\n    'third_place': '��',\n    'thought': '��',\n    'three': '3️⃣',\n    'thumbsdown': '��️',\n    'thumbsdown_tone1': '����',\n    'thumbsdown_tone2': '����',\n    'thumbsdown_tone3': '����',\n    'thumbsdown_tone4': '����',\n    'thumbsdown_tone5': '����',\n    'thumbsup': '��️',\n    'thumbsup_tone1': '����',\n    'thumbsup_tone2': '����',\n    'thumbsup_tone3': '����',\n    'thumbsup_tone4': '����',\n    'thumbsup_tone5': '����',\n    'ticket': '��',\n    'tickets': '��️',\n    'tie': '��',\n    'tiger': '��',\n    'tiger_face': '��',\n    'timer': '⏲️',\n    'tired': '��',\n    'tm': '™️',\n    'toilet': '��',\n    'toilet_paper': '��',\n    'tokyo_tower': '��',\n    'tomato': '��',\n    'tongue': '��',\n    'tongue_out': '��',\n    'toolbox': '��',\n    'tools': '��️',\n    'tooth': '��',\n    'top': '��',\n    'top_hat': '��',\n    'torn_calendar': '��',\n    'tornado': '��️',\n    'trackball': '��️',\n    'tractor': '��',\n    'traffic_light': '��',\n    'train': '��',\n    'tram': '��',\n    'tram_car': '��',\n    'trashcan': '��️',\n    'trex': '��',\n    'triangle_flag': '��',\n    'triangular_ruler': '��',\n    'trident': '��',\n    'trolleybus': '��',\n    'trophy': '��️',\n    'tropical_drink': '��',\n    'tropical_fish': '��',\n    'truck': '��',\n    'trumpet': '��',\n    'tulip': '��',\n    'tumbler_glass': '��',\n    'turkey': '��',\n    'turtle': '��',\n    'tv': '��️',\n    'two': '2️⃣',\n    'two_hearts': '��',\n    'two_hump_camel': '��',\n    'umbrella': '☂️',\n    'umbrella_rain': '☔️',\n    'unamused': '��',\n    'underage': '��',\n    'unicorn_face': '��',\n    'unlock': '��️',\n    'up': '��',\n    'up_button': '��',\n    'up_red_triangle': '��',\n    'upper_abcd': '��',\n    'upset': '��',\n    'upside_down': '��',\n    'urn': '⚱️',\n    'usa': '����',\n    'utensils': '��',\n    'vacant': '��',\n    'vampire': '��',\n    'vampire_tone1': '����',\n    'vampire_tone2': '����',\n    'vampire_tone3': '����',\n    'vampire_tone4': '����',\n    'vampire_tone5': '����',\n    'vertical_traffic_light': '��',\n    'vhs': '��',\n    'vibration_mode': '��',\n    'victory': '✌️',\n    'victory_tone1': '✌��',\n    'victory_tone2': '✌��',\n    'victory_tone3': '✌��',\n    'victory_tone4': '✌��',\n    'victory_tone5': '✌��',\n    'video_camera': '��️',\n    'video_game': '��️',\n    'villain': '��',\n    'villain_tone1': '����',\n    'villain_tone2': '����',\n    'villain_tone3': '����',\n    'villain_tone4': '����',\n    'villain_tone5': '����',\n    'violin': '��',\n    'virgo': '♍️',\n    'volcano': '��',\n    'volleyball': '��',\n    'vomiting': '��',\n    'vs': '��',\n    'vulcan': '��',\n    'vulcan_tone1': '����',\n    'vulcan_tone2': '����',\n    'vulcan_tone3': '����',\n    'vulcan_tone4': '����',\n    'vulcan_tone5': '����',\n    'waffle': '��',\n    'wales': '��������������',\n    'waning_crescent_moon': '��',\n    'waning_gibbous_moon': '��',\n    'warning': '⚠️',\n    'wastebasket': '��️',\n    'watch': '⌚️',\n    'water_buffalo': '��',\n    'watermelon': '��',\n    'wave': '��',\n    'wave_tone1': '����',\n    'wave_tone2': '����',\n    'wave_tone3': '����',\n    'wave_tone4': '����',\n    'wave_tone5': '����',\n    'wavy_dash': '〰️',\n    'waxing_crescent_moon': '��',\n    'waxing_gibbous_moon': '��',\n    'wc': '��',\n    'weary': '��',\n    'weary_cat': '��',\n    'wedding': '��',\n    'whale': '��',\n    'wheel_of_dharma': '☸️',\n    'wheelchair': '��',\n    'white_check_mark': '✅',\n    'white_circle': '⚪️',\n    'white_exclamation': '❕',\n    'white_flag': '��️',\n    'white_flower': '��',\n    'white_haired_man': '��‍��',\n    'white_haired_man_tone1': '����‍��',\n    'white_haired_man_tone2': '����‍��',\n    'white_haired_man_tone3': '����‍��',\n    'white_haired_man_tone4': '����‍��',\n    'white_haired_man_tone5': '����‍��',\n    'white_haired_woman': '��‍��',\n    'white_haired_woman_tone1': '����‍��',\n    'white_haired_woman_tone2': '����‍��',\n    'white_haired_woman_tone3': '����‍��',\n    'white_haired_woman_tone4': '����‍��',\n    'white_haired_woman_tone5': '����‍��',\n    'white_heart': '��',\n    'white_question': '❔',\n    'white_square_button': '��',\n    'wilted_rose': '��',\n    'wind_chime': '��',\n    'wind_face': '��️',\n    'wine_glass': '��',\n    'wink': '��',\n    'wolf_face': '��',\n    'woman': '��',\n    'woman_artist': '��‍��',\n    'woman_artist_tone1': '����‍��',\n    'woman_artist_tone2': '����‍��',\n    'woman_artist_tone3': '����‍��',\n    'woman_artist_tone4': '����‍��',\n    'woman_artist_tone5': '����‍��',\n    'woman_astronaut': '��‍��',\n    'woman_astronaut_tone1': '����‍��',\n    'woman_astronaut_tone2': '����‍��',\n    'woman_astronaut_tone3': '����‍��',\n    'woman_astronaut_tone4': '����‍��',\n    'woman_astronaut_tone5': '����‍��',\n    'woman_biking': '��‍♀️',\n    'woman_biking_tone1': '����‍♀️',\n    'woman_biking_tone2': '����‍♀️',\n    'woman_biking_tone3': '����‍♀️',\n    'woman_biking_tone4': '����‍♀️',\n    'woman_biking_tone5': '����‍♀️',\n    'woman_bowing': '��‍♀️',\n    'woman_bowing_tone1': '����‍♀️',\n    'woman_bowing_tone2': '����‍♀️',\n    'woman_bowing_tone3': '����‍♀️',\n    'woman_bowing_tone4': '����‍♀️',\n    'woman_bowing_tone5': '����‍♀️',\n    'woman_cartwheeling': '��‍♀️',\n    'woman_cartwheeling_tone1': '����‍♀️',\n    'woman_cartwheeling_tone2': '����‍♀️',\n    'woman_cartwheeling_tone3': '����‍♀️',\n    'woman_cartwheeling_tone4': '����‍♀️',\n    'woman_cartwheeling_tone5': '����‍♀️',\n    'woman_climbing': '��‍♀️',\n    'woman_climbing_tone1': '����‍♀️',\n    'woman_climbing_tone2': '����‍♀️',\n    'woman_climbing_tone3': '����‍♀️',\n    'woman_climbing_tone4': '����‍♀️',\n    'woman_climbing_tone5': '����‍♀️',\n    'woman_construction_worker': '��‍♀️',\n    'woman_construction_worker_tone1': '����‍♀️',\n    'woman_construction_worker_tone2': '����‍♀️',\n    'woman_construction_worker_tone3': '����‍♀️',\n    'woman_construction_worker_tone4': '����‍♀️',\n    'woman_construction_worker_tone5': '����‍♀️',\n    'woman_cook': '��‍��',\n    'woman_cook_tone1': '����‍��',\n    'woman_cook_tone2': '����‍��',\n    'woman_cook_tone3': '����‍��',\n    'woman_cook_tone4': '����‍��',\n    'woman_cook_tone5': '����‍��',\n    'woman_dancing': '��',\n    'woman_dancing_tone1': '����',\n    'woman_dancing_tone2': '����',\n    'woman_dancing_tone3': '����',\n    'woman_dancing_tone4': '����',\n    'woman_dancing_tone5': '����',\n    'woman_deaf': '��‍♀️',\n    'woman_deaf_tone1': '����‍♀️',\n    'woman_deaf_tone2': '����‍♀️',\n    'woman_deaf_tone3': '����‍♀️',\n    'woman_deaf_tone4': '����‍♀️',\n    'woman_deaf_tone5': '����‍♀️',\n    'woman_elf': '��‍♀️',\n    'woman_elf_tone1': '����‍♀️',\n    'woman_elf_tone2': '����‍♀️',\n    'woman_elf_tone3': '����‍♀️',\n    'woman_elf_tone4': '����‍♀️',\n    'woman_elf_tone5': '����‍♀️',\n    'woman_facepalming': '��‍♀️',\n    'woman_facepalming_tone1': '����‍♀️',\n    'woman_facepalming_tone2': '����‍♀️',\n    'woman_facepalming_tone3': '����‍♀️',\n    'woman_facepalming_tone4': '����‍♀️',\n    'woman_facepalming_tone5': '����‍♀️',\n    'woman_factory_worker': '��‍��',\n    'woman_factory_worker_tone1': '����‍��',\n    'woman_factory_worker_tone2': '����‍��',\n    'woman_factory_worker_tone3': '����‍��',\n    'woman_factory_worker_tone4': '����‍��',\n    'woman_factory_worker_tone5': '����‍��',\n    'woman_fairy': '��‍♀️',\n    'woman_fairy_tone1': '����‍♀️',\n    'woman_fairy_tone2': '����‍♀️',\n    'woman_fairy_tone3': '����‍♀️',\n    'woman_fairy_tone4': '����‍♀️',\n    'woman_fairy_tone5': '����‍♀️',\n    'woman_farmer': '��‍��',\n    'woman_farmer_tone1': '����‍��',\n    'woman_farmer_tone2': '����‍��',\n    'woman_farmer_tone3': '����‍��',\n    'woman_farmer_tone4': '����‍��',\n    'woman_farmer_tone5': '����‍��',\n    'woman_firefighter': '��‍��',\n    'woman_firefighter_tone1': '����‍��',\n    'woman_firefighter_tone2': '����‍��',\n    'woman_firefighter_tone3': '����‍��',\n    'woman_firefighter_tone4': '����‍��',\n    'woman_firefighter_tone5': '����‍��',\n    'woman_frowning': '��‍♀️',\n    'woman_frowning_tone1': '����‍♀️',\n    'woman_frowning_tone2': '����‍♀️',\n    'woman_frowning_tone3': '����‍♀️',\n    'woman_frowning_tone4': '����‍♀️',\n    'woman_frowning_tone5': '����‍♀️',\n    'woman_genie': '��‍♀️',\n    'woman_gesturing_no': '��‍♀️',\n    'woman_gesturing_no_tone1': '����‍♀️',\n    'woman_gesturing_no_tone2': '����‍♀️',\n    'woman_gesturing_no_tone3': '����‍♀️',\n    'woman_gesturing_no_tone4': '����‍♀️',\n    'woman_gesturing_no_tone5': '����‍♀️',\n    'woman_gesturing_ok': '��‍♀️',\n    'woman_gesturing_ok_tone1': '����‍♀️',\n    'woman_gesturing_ok_tone2': '����‍♀️',\n    'woman_gesturing_ok_tone3': '����‍♀️',\n    'woman_gesturing_ok_tone4': '����‍♀️',\n    'woman_gesturing_ok_tone5': '����‍♀️',\n    'woman_getting_face_massage': '��‍♀️',\n    'woman_getting_face_massage_tone1': '����‍♀️',\n    'woman_getting_face_massage_tone2': '����‍♀️',\n    'woman_getting_face_massage_tone3': '����‍♀️',\n    'woman_getting_face_massage_tone4': '����‍♀️',\n    'woman_getting_face_massage_tone5': '����‍♀️',\n    'woman_getting_haircut': '��‍♀️',\n    'woman_getting_haircut_tone1': '����‍♀️',\n    'woman_getting_haircut_tone2': '����‍♀️',\n    'woman_getting_haircut_tone3': '����‍♀️',\n    'woman_getting_haircut_tone4': '����‍♀️',\n    'woman_getting_haircut_tone5': '����‍♀️',\n    'woman_guard': '��‍♀️',\n    'woman_guard_tone1': '����‍♀️',\n    'woman_guard_tone2': '����‍♀️',\n    'woman_guard_tone3': '����‍♀️',\n    'woman_guard_tone4': '����‍♀️',\n    'woman_guard_tone5': '����‍♀️',\n    'woman_handball': '��‍♀️',\n    'woman_handball_tone1': '����‍♀️',\n    'woman_handball_tone2': '����‍♀️',\n    'woman_handball_tone3': '����‍♀️',\n    'woman_handball_tone4': '����‍♀️',\n    'woman_handball_tone5': '����‍♀️',\n    'woman_headscarf': '��',\n    'woman_headscarf_tone1': '����',\n    'woman_headscarf_tone2': '����',\n    'woman_headscarf_tone3': '����',\n    'woman_headscarf_tone4': '����',\n    'woman_headscarf_tone5': '����',\n    'woman_health_worker': '��‍⚕️',\n    'woman_health_worker_tone1': '����‍⚕️',\n    'woman_health_worker_tone2': '����‍⚕️',\n    'woman_health_worker_tone3': '����‍⚕️',\n    'woman_health_worker_tone4': '����‍⚕️',\n    'woman_health_worker_tone5': '����‍⚕️',\n    'woman_hero': '��‍♀️',\n    'woman_hero_tone1': '����‍♀️',\n    'woman_hero_tone2': '����‍♀️',\n    'woman_hero_tone3': '����‍♀️',\n    'woman_hero_tone4': '����‍♀️',\n    'woman_hero_tone5': '����‍♀️',\n    'woman_judge': '��‍⚖️',\n    'woman_judge_tone1': '����‍⚖️',\n    'woman_judge_tone2': '����‍⚖️',\n    'woman_judge_tone3': '����‍⚖️',\n    'woman_judge_tone4': '����‍⚖️',\n    'woman_judge_tone5': '����‍⚖️',\n    'woman_juggling': '��‍♀️',\n    'woman_juggling_tone1': '����‍♀️',\n    'woman_juggling_tone2': '����‍♀️',\n    'woman_juggling_tone3': '����‍♀️',\n    'woman_juggling_tone4': '����‍♀️',\n    'woman_juggling_tone5': '����‍♀️',\n    'woman_kneeling': '��‍♀️',\n    'woman_kneeling_tone1': '����‍♀️',\n    'woman_kneeling_tone2': '����‍♀️',\n    'woman_kneeling_tone3': '����‍♀️',\n    'woman_kneeling_tone4': '����‍♀️',\n    'woman_kneeling_tone5': '����‍♀️',\n    'woman_lotus_position': '��‍♀️',\n    'woman_lotus_position_tone1': '����‍♀️',\n    'woman_lotus_position_tone2': '����‍♀️',\n    'woman_lotus_position_tone3': '����‍♀️',\n    'woman_lotus_position_tone4': '����‍♀️',\n    'woman_lotus_position_tone5': '����‍♀️',\n    'woman_mage': '��‍♀️',\n    'woman_mage_tone1': '����‍♀️',\n    'woman_mage_tone2': '����‍♀️',\n    'woman_mage_tone3': '����‍♀️',\n    'woman_mage_tone4': '����‍♀️',\n    'woman_mage_tone5': '����‍♀️',\n    'woman_mechanic': '��‍��',\n    'woman_mechanic_tone1': '����‍��',\n    'woman_mechanic_tone2': '����‍��',\n    'woman_mechanic_tone3': '����‍��',\n    'woman_mechanic_tone4': '����‍��',\n    'woman_mechanic_tone5': '����‍��',\n    'woman_motor_wheelchair': '��‍��',\n    'woman_motor_wheelchair_tone1': '����‍��',\n    'woman_motor_wheelchair_tone2': '����‍��',\n    'woman_motor_wheelchair_tone3': '����‍��',\n    'woman_motor_wheelchair_tone4': '����‍��',\n    'woman_motor_wheelchair_tone5': '����‍��',\n    'woman_mountain_biking': '��‍♀️',\n    'woman_mountain_biking_tone1': '����‍♀️',\n    'woman_mountain_biking_tone2': '����‍♀️',\n    'woman_mountain_biking_tone3': '����‍♀️',\n    'woman_mountain_biking_tone4': '����‍♀️',\n    'woman_mountain_biking_tone5': '����‍♀️',\n    'woman_office_worker': '��‍��',\n    'woman_office_worker_tone1': '����‍��',\n    'woman_office_worker_tone2': '����‍��',\n    'woman_office_worker_tone3': '����‍��',\n    'woman_office_worker_tone4': '����‍��',\n    'woman_office_worker_tone5': '����‍��',\n    'woman_pilot': '��‍✈️',\n    'woman_pilot_tone1': '����‍✈️',\n    'woman_pilot_tone2': '����‍✈️',\n    'woman_pilot_tone3': '����‍✈️',\n    'woman_pilot_tone4': '����‍✈️',\n    'woman_pilot_tone5': '����‍✈️',\n    'woman_police_officer': '��‍♀️',\n    'woman_police_officer_tone1': '����‍♀️',\n    'woman_police_officer_tone2': '����‍♀️',\n    'woman_police_officer_tone3': '����‍♀️',\n    'woman_police_officer_tone4': '����‍♀️',\n    'woman_police_officer_tone5': '����‍♀️',\n    'woman_pouting': '��‍♀️',\n    'woman_pouting_tone1': '����‍♀️',\n    'woman_pouting_tone2': '����‍♀️',\n    'woman_pouting_tone3': '����‍♀️',\n    'woman_pouting_tone4': '����‍♀️',\n    'woman_pouting_tone5': '����‍♀️',\n    'woman_probing_cane': '��‍��',\n    'woman_probing_cane_tone1': '����‍��',\n    'woman_probing_cane_tone2': '����‍��',\n    'woman_probing_cane_tone3': '����‍��',\n    'woman_probing_cane_tone4': '����‍��',\n    'woman_probing_cane_tone5': '����‍��',\n    'woman_raising_hand': '��‍♀️',\n    'woman_raising_hand_tone1': '����‍♀️',\n    'woman_raising_hand_tone2': '����‍♀️',\n    'woman_raising_hand_tone3': '����‍♀️',\n    'woman_raising_hand_tone4': '����‍♀️',\n    'woman_raising_hand_tone5': '����‍♀️',\n    'woman_rowing_boat': '��‍♀️',\n    'woman_rowing_boat_tone1': '����‍♀️',\n    'woman_rowing_boat_tone2': '����‍♀️',\n    'woman_rowing_boat_tone3': '����‍♀️',\n    'woman_rowing_boat_tone4': '����‍♀️',\n    'woman_rowing_boat_tone5': '����‍♀️',\n    'woman_running': '��‍♀️',\n    'woman_running_tone1': '����‍♀️',\n    'woman_running_tone2': '����‍♀️',\n    'woman_running_tone3': '����‍♀️',\n    'woman_running_tone4': '����‍♀️',\n    'woman_running_tone5': '����‍♀️',\n    'woman_scientist': '��‍��',\n    'woman_scientist_tone1': '����‍��',\n    'woman_scientist_tone2': '����‍��',\n    'woman_scientist_tone3': '����‍��',\n    'woman_scientist_tone4': '����‍��',\n    'woman_scientist_tone5': '����‍��',\n    'woman_shrugging': '��‍♀️',\n    'woman_shrugging_tone1': '����‍♀️',\n    'woman_shrugging_tone2': '����‍♀️',\n    'woman_shrugging_tone3': '����‍♀️',\n    'woman_shrugging_tone4': '����‍♀️',\n    'woman_shrugging_tone5': '����‍♀️',\n    'woman_singer': '��‍��',\n    'woman_singer_tone1': '����‍��',\n    'woman_singer_tone2': '����‍��',\n    'woman_singer_tone3': '����‍��',\n    'woman_singer_tone4': '����‍��',\n    'woman_singer_tone5': '����‍��',\n    'woman_standing': '��‍♀️',\n    'woman_standing_tone1': '����‍♀️',\n    'woman_standing_tone2': '����‍♀️',\n    'woman_standing_tone3': '����‍♀️',\n    'woman_standing_tone4': '����‍♀️',\n    'woman_standing_tone5': '����‍♀️',\n    'woman_steamy_room': '��‍♀️',\n    'woman_steamy_room_tone1': '����‍♀️',\n    'woman_steamy_room_tone2': '����‍♀️',\n    'woman_steamy_room_tone3': '����‍♀️',\n    'woman_steamy_room_tone4': '����‍♀️',\n    'woman_steamy_room_tone5': '����‍♀️',\n    'woman_student': '��‍��',\n    'woman_student_tone1': '����‍��',\n    'woman_student_tone2': '����‍��',\n    'woman_student_tone3': '����‍��',\n    'woman_student_tone4': '����‍��',\n    'woman_student_tone5': '����‍��',\n    'woman_surfing': '��‍♀️',\n    'woman_surfing_tone1': '����‍♀️',\n    'woman_surfing_tone2': '����‍♀️',\n    'woman_surfing_tone3': '����‍♀️',\n    'woman_surfing_tone4': '����‍♀️',\n    'woman_surfing_tone5': '����‍♀️',\n    'woman_swimming': '��‍♀️',\n    'woman_swimming_tone1': '����‍♀️',\n    'woman_swimming_tone2': '����‍♀️',\n    'woman_swimming_tone3': '����‍♀️',\n    'woman_swimming_tone4': '����‍♀️',\n    'woman_swimming_tone5': '����‍♀️',\n    'woman_teacher': '��‍��',\n    'woman_teacher_tone1': '����‍��',\n    'woman_teacher_tone2': '����‍��',\n    'woman_teacher_tone3': '����‍��',\n    'woman_teacher_tone4': '����‍��',\n    'woman_teacher_tone5': '����‍��',\n    'woman_technologist': '��‍��',\n    'woman_technologist_tone1': '����‍��',\n    'woman_technologist_tone2': '����‍��',\n    'woman_technologist_tone3': '����‍��',\n    'woman_technologist_tone4': '����‍��',\n    'woman_technologist_tone5': '����‍��',\n    'woman_tipping_hand': '��‍♀️',\n    'woman_tipping_hand_tone1': '����‍♀️',\n    'woman_tipping_hand_tone2': '����‍♀️',\n    'woman_tipping_hand_tone3': '����‍♀️',\n    'woman_tipping_hand_tone4': '����‍♀️',\n    'woman_tipping_hand_tone5': '����‍♀️',\n    'woman_tone1': '����',\n    'woman_tone2': '����',\n    'woman_tone3': '����',\n    'woman_tone4': '����',\n    'woman_tone5': '����',\n    'woman_turban': '��‍♀️',\n    'woman_turban_tone1': '����‍♀️',\n    'woman_turban_tone2': '����‍♀️',\n    'woman_turban_tone3': '����‍♀️',\n    'woman_turban_tone4': '����‍♀️',\n    'woman_turban_tone5': '����‍♀️',\n    'woman_vampire': '��‍♀️',\n    'woman_vampire_tone1': '����‍♀️',\n    'woman_vampire_tone2': '����‍♀️',\n    'woman_vampire_tone3': '����‍♀️',\n    'woman_vampire_tone4': '����‍♀️',\n    'woman_vampire_tone5': '����‍♀️',\n    'woman_villain': '��‍♀️',\n    'woman_villain_tone1': '����‍♀️',\n    'woman_villain_tone2': '����‍♀️',\n    'woman_villain_tone3': '����‍♀️',\n    'woman_villain_tone4': '����‍♀️',\n    'woman_villain_tone5': '����‍♀️',\n    'woman_walking': '��‍♀️',\n    'woman_walking_tone1': '����‍♀️',\n    'woman_walking_tone2': '����‍♀️',\n    'woman_walking_tone3': '����‍♀️',\n    'woman_walking_tone4': '����‍♀️',\n    'woman_walking_tone5': '����‍♀️',\n    'woman_water_polo': '��‍♀️',\n    'woman_water_polo_tone1': '����‍♀️',\n    'woman_water_polo_tone2': '����‍♀️',\n    'woman_water_polo_tone3': '����‍♀️',\n    'woman_water_polo_tone4': '����‍♀️',\n    'woman_water_polo_tone5': '����‍♀️',\n    'woman_wheelchair': '��‍��',\n    'woman_wheelchair_tone1': '����‍��',\n    'woman_wheelchair_tone2': '����‍��',\n    'woman_wheelchair_tone3': '����‍��',\n    'woman_wheelchair_tone4': '����‍��',\n    'woman_wheelchair_tone5': '����‍��',\n    'woman_zombie': '��‍♀️',\n    'womans_boot': '��',\n    'womans_clothes': '��',\n    'womans_hat': '��',\n    'womans_sandal': '��',\n    'women_bunny_ears_partying': '��‍♀️',\n    'women_wrestling': '��‍♀️',\n    'womens': '��️',\n    'woozy': '��',\n    'worried': '��',\n    'wrench': '��',\n    'writing_hand': '✍️',\n    'writing_hand_tone1': '✍��',\n    'writing_hand_tone2': '✍��',\n    'writing_hand_tone3': '✍��',\n    'writing_hand_tone4': '✍��',\n    'writing_hand_tone5': '✍��',\n    'wtf': '��',\n    'x': '❌',\n    'xmas_tree': '��',\n    'yarn': '��',\n    'yawn': '��',\n    'yellow_circle': '��',\n    'yellow_heart': '��',\n    'yellow_square': '��',\n    'yen': '��',\n    'yerba_mate': '��',\n    'yes': '��️',\n    'yes_tone1': '����',\n    'yes_tone2': '����',\n    'yes_tone3': '����',\n    'yes_tone4': '����',\n    'yes_tone5': '����',\n    'yin_yang': '☯️',\n    'yoyo': '��',\n    'yum': '��',\n    'zap': '⚡️',\n    'zebra': '��',\n    'zero': '0️⃣',\n    'zipper_mouth': '��',\n    'zombie': '��',\n    'zzz': '��',\n};\nconst TEXT_WHEN_UNQUALIFIED = ['©', '®', '™'];\nexport function emojify(text) {\n    const tokens = parseEmoji(text);\n    let output = '';\n    for (const token of tokens) {\n        if (isEmojiInfo(token)) {\n            output += `<img class=\"em\" draggable=\"false\" `;\n            output += `alt=\"${token.emojiString}\" src=\"${token.imgPath}\" data-c=\"${token.codepoint}\">`;\n        }\n        else {\n            output += token;\n        }\n    }\n    return output;\n}\nexport function parseEmoji(text) {\n    const regex = new RegExp(EMOJI_REGEX, 'g');\n    const result = [];\n    const textVariantSelector = '\\ufe0e';\n    let match;\n    let startIndex = 0;\n    let endIndex = 0;\n    while ((match = regex.exec(text)) !== null) {\n        const emoji = match[0];\n        const prevEndIndex = endIndex;\n        startIndex = regex.lastIndex - emoji.length;\n        endIndex = regex.lastIndex;\n        if (prevEndIndex < startIndex) {\n            result.push(text.substring(prevEndIndex, startIndex));\n        }\n        let forceText = false;\n        if (TEXT_WHEN_UNQUALIFIED.includes(emoji)) {\n            forceText = true;\n        }\n        else if (emoji.length > 1 && emoji.slice(-1) === textVariantSelector) {\n            forceText = true;\n        }\n        if (forceText) {\n            result.push(emoji);\n        }\n        else {\n            const codepoint = twemoji.convert.toCodePoint(emoji);\n            const strippedCodepoint = codepoint\n                .replace(/-fe0[ef]$/, '')\n                .replace(/-fe0[ef]-20e3$/, '-20e3');\n            result.push({\n                emojiString: emoji,\n                imgPath: `emoji/png32/${strippedCodepoint}.png`,\n                codepoint: codepoint,\n            });\n        }\n    }\n    if (endIndex < text.length) {\n        result.push(text.substring(endIndex, text.length));\n    }\n    return result.filter((x) => x !== null);\n}\nexport function shortnameToUtf8(shortname) {\n    return SHORTNAMES[shortname.toLowerCase()] || null;\n}\nconst pattern = /<img class=\"em([\" ])([^>]*>)/g;\nconst singleEmojiThreshold = 3;\nconst singleEmojiClassName = 'large-emoji';\nexport function enlargeSingleEmoji(text, enlarge = false) {\n    if (!enlarge) {\n        return text;\n    }\n    const matches = text.match(pattern);\n    if (matches != null && matches.length >= 1 && matches.length <= singleEmojiThreshold) {\n        if (text.replace(pattern, '').length === 0) {\n            text = text\n                .replace(pattern, '<img class=\"em ' + singleEmojiClassName + '$1$2')\n                .replace(/\\/png32\\//g, '/png64/');\n        }\n    }\n    return text;\n}\n","import { DialogController } from '../controllers/dialog';\nimport { TroubleshootingController } from '../controllers/troubleshooting';\nimport { bufferToUrl, hasValue, supportsPassive, u8aToHex } from '../helpers';\nimport { emojify } from '../helpers/emoji';\nimport { controllerModelHasMembers, isContactReceiver } from '../typeguards';\nclass SendFileController extends DialogController {\n    constructor($scope, $mdDialog, logService, themeService, preview) {\n        super($scope, $mdDialog, themeService);\n        this.sendAsFile = false;\n        this.preview = null;\n        this.previewDataUrl = null;\n        const log = logService.getLogger('SendFile-C');\n        this.preview = preview;\n        if (preview !== null) {\n            this.previewDataUrl = bufferToUrl(this.preview.data, this.preview.fileType, log);\n        }\n    }\n    send() {\n        this.hide({\n            caption: this.caption,\n            sendAsFile: this.sendAsFile,\n            previewDataUrl: this.previewDataUrl,\n        });\n    }\n    keypress($event) {\n        if ($event.key === 'Enter') {\n            this.send();\n        }\n    }\n    hasPreview() {\n        return this.previewDataUrl !== null && this.previewDataUrl !== undefined;\n    }\n}\nSendFileController.$inject = ['$scope', '$mdDialog', 'LogService', 'ThemeService', 'preview'];\nexport class DeviceUnreachableController extends DialogController {\n    constructor($rootScope, $window, $mdDialog, $translate, stateService, themeService, webClientService, logService) {\n        super($rootScope, $mdDialog, themeService);\n        this.retrying = false;\n        this.progress = 0;\n        this.$rootScope = $rootScope;\n        this.$window = $window;\n        this.$translate = $translate;\n        this.stateService = stateService;\n        this.webClientService = webClientService;\n        this.log = logService.getLogger('DeviceUnreachableDialog-C');\n        this.log.info(`Showing \"device unreachable\" dialog (canRetry=${this.canRetry})`);\n    }\n    get canRetry() {\n        switch (this.webClientService.salty.state) {\n            case 'closing':\n            case 'closed':\n                return false;\n            default:\n                return true;\n        }\n    }\n    async retry() {\n        this.log.debug('Retrying...');\n        this.stateService.attempt = 0;\n        const [expectedPeriodMaxMs, pushSessionPromise] = this.webClientService.sendPush();\n        this.retrying = true;\n        this.progress = 0;\n        const interval = setInterval(() => this.$rootScope.$apply(() => ++this.progress), expectedPeriodMaxMs / 100);\n        try {\n            await pushSessionPromise;\n        }\n        finally {\n            clearInterval(interval);\n            this.$rootScope.$apply(() => this.retrying = false);\n        }\n    }\n    reload() {\n        this.log.info('Reloading page');\n        this.$window.location.reload();\n    }\n    closeWithWarning() {\n        this.log.info('Dialog dismissed by user');\n        this.cancel();\n        this.$mdDialog.show(this.$mdDialog.alert()\n            .title(this.$translate.instant('common.WARNING'))\n            .textContent(this.$translate.instant('deviceUnreachable.DISMISS_WARNING'))\n            .ok(this.$translate.instant('common.OK')));\n    }\n}\nDeviceUnreachableController.$inject = [\n    '$rootScope', '$window', '$mdDialog', '$translate',\n    'StateService', 'ThemeService', 'WebClientService', 'LogService',\n];\nexport class PushRejectedDialogController extends DialogController {\n    constructor($scope, $mdDialog, $window, themeService, trustedKeyStore, logService) {\n        super($scope, $mdDialog, themeService);\n        this.$window = $window;\n        this.log = logService.getLogger('PushRejectedDialog-C');\n        this.trustedKeyStore = trustedKeyStore;\n    }\n    forget() {\n        this.log.info('Forgetting stored session');\n        this.trustedKeyStore.clearTrustedKey();\n        this.cancel();\n        this.$window.location.reload();\n    }\n}\nPushRejectedDialogController.$inject = [\n    '$scope', '$mdDialog', '$window', 'ThemeService', 'TrustedKeyStore', 'LogService',\n];\nclass SettingsController extends DialogController {\n    constructor($scope, $mdDialog, $window, settingsService, themeService, notificationService) {\n        super($scope, $mdDialog, themeService);\n        this.$window = $window;\n        this.settingsService = settingsService;\n        this.notificationService = notificationService;\n        this.desktopNotifications = notificationService.getWantsNotifications();\n        this.notificationApiAvailable = notificationService.isNotificationApiAvailable();\n        this.notificationPermission = notificationService.getNotificationPermission();\n        this.notificationPreview = notificationService.getWantsPreview();\n        this.notificationSound = notificationService.getWantsSound();\n    }\n    setWantsNotifications(desktopNotifications) {\n        this.notificationService.setWantsNotifications(desktopNotifications);\n    }\n    setWantsPreview(notificationPreview) {\n        this.notificationService.setWantsPreview(notificationPreview);\n    }\n    setWantsSound(notificationSound) {\n        this.notificationService.setWantsSound(notificationSound);\n    }\n}\nSettingsController.$inject = [\n    '$scope', '$mdDialog', '$window', 'SettingsService', 'ThemeService', 'NotificationService',\n];\nclass ConversationController {\n    constructor($stateParams, $scope, $rootScope, $mdDialog, $mdToast, $translate, $filter, $state, $transitions, logService, webClientService, stateService, receiverService, mimeService, versionService, controllerModelService, timeoutService) {\n        this.name = 'navigation';\n        this.showScrollJump = false;\n        this.initialized = false;\n        this.allMentions = [];\n        this.currentMentions = [];\n        this.currentMentionFilterWord = null;\n        this.selectedMention = null;\n        this.message = '';\n        this.lastReadMsg = null;\n        this.msgReadReportPending = false;\n        this.hasMore = true;\n        this.latestRefMsgId = null;\n        this.initialData = {\n            draft: '',\n            initialText: '',\n        };\n        this.locked = false;\n        this.isTyping = () => false;\n        this.uploading = {\n            enabled: false,\n            value1: 0,\n            value2: 0,\n        };\n        this.submit = (type, contents) => {\n            return new Promise((resolve, reject) => {\n                if (!this.webClientService.readyToSubmit) {\n                    this.showError(this.$translate.instant('error.NO_CONNECTION'));\n                    return reject();\n                }\n                let success = true;\n                const nextCallback = (index) => {\n                    if (index === contents.length - 1) {\n                        if (success) {\n                            resolve();\n                        }\n                        else {\n                            reject('Message sending unsuccessful');\n                        }\n                    }\n                };\n                switch (type) {\n                    case 'file':\n                        let showSendAsFileCheckbox = false;\n                        let captionSupported = false;\n                        for (const msg of contents) {\n                            if (!msg.fileType) {\n                                msg.fileType = 'application/octet-stream';\n                            }\n                            captionSupported = this.mimeService.isImage(msg.fileType);\n                            if (this.mimeService.isImage(msg.fileType)\n                                || this.mimeService.isAudio(msg.fileType, this.webClientService.clientInfo.os)\n                                || this.mimeService.isVideo(msg.fileType)) {\n                                showSendAsFileCheckbox = true;\n                                break;\n                            }\n                        }\n                        let preview = null;\n                        if (contents.length === 1) {\n                            const msg = contents[0];\n                            if (this.mimeService.isImage(msg.fileType)) {\n                                preview = msg;\n                            }\n                        }\n                        const title = this.$translate.instant('messenger.CONFIRM_FILE_SEND', {\n                            senderName: emojify(this.$filter('emptyToPlaceholder')(this.receiver.displayName, '-')),\n                        });\n                        const placeholder = this.$translate.instant('messenger.CONFIRM_FILE_CAPTION');\n                        const confirmSendAsFile = this.$translate.instant('messenger.CONFIRM_SEND_AS_FILE');\n                        this.$mdDialog.show({\n                            clickOutsideToClose: false,\n                            locals: { preview: preview },\n                            controller: 'SendFileController',\n                            controllerAs: 'ctrl',\n                            template: `\n                            <md-dialog class=\"send-file-dialog\">\n                                <md-dialog-content class=\"md-dialog-content\">\n                                    <h2 class=\"md-title\">${title}</h2>\n                                    <img class=\"preview\" ng-if=\"ctrl.hasPreview()\" ng-src=\"{{ ctrl.previewDataUrl }}\">\n                                    <md-input-container md-no-float class=\"input-caption md-prompt-input-container\" ng-show=\"!${showSendAsFileCheckbox} || ctrl.sendAsFile || ${captionSupported}\">\n                                        <input maxlength=\"1000\" md-autofocus ng-keypress=\"ctrl.keypress($event)\" ng-model=\"ctrl.caption\" placeholder=\"${placeholder}\" aria-label=\"${placeholder}\">\n                                    </md-input-container>\n                                    <md-input-container md-no-float class=\"input-send-as-file md-prompt-input-container\" ng-show=\"${showSendAsFileCheckbox}\">\n                                        <md-checkbox ng-model=\"ctrl.sendAsFile\" aria-label=\"${confirmSendAsFile}\">\n                                            ${confirmSendAsFile}\n                                        </md-checkbox>\n                                    </md-input-container>\n                                </md-dialog-content>\n                                <md-dialog-actions>\n                                    <button class=\"md-primary md-cancel-button md-button\" md-ink-ripple type=\"button\" ng-click=\"ctrl.cancel()\">\n                                        <span translate>common.CANCEL</span>\n                                    </button>\n                                    <button class=\"md-primary md-cancel-button md-button\" md-ink-ripple type=\"button\" ng-click=\"ctrl.send()\">\n                                        <span translate>common.SEND</span>\n                                    </button>\n                                </md-dialog-actions>\n                            </md-dialog>\n                        `,\n                        }).then((data) => {\n                            const caption = data.caption;\n                            const sendAsFile = data.sendAsFile;\n                            const options = { previewDataUrl: data.previewDataUrl || undefined };\n                            contents.forEach((msg, index) => {\n                                if (caption !== undefined && caption.length > 0) {\n                                    msg.caption = caption;\n                                }\n                                msg.sendAsFile = sendAsFile;\n                                this.webClientService.sendMessage(this.$stateParams, type, msg, options)\n                                    .then(() => {\n                                    nextCallback(index);\n                                })\n                                    .catch((error) => {\n                                    this.log.error(error);\n                                    this.showError(error);\n                                    success = false;\n                                    nextCallback(index);\n                                });\n                            });\n                        }, angular.noop);\n                        break;\n                    case 'text':\n                        contents.forEach((msg, index) => {\n                            const quote = this.webClientService.getQuote(this.receiver);\n                            if (hasValue(quote)) {\n                                msg.quote = quote;\n                            }\n                            this.webClientService.setQuote(this.receiver, null);\n                            this.webClientService.sendMessage(this.$stateParams, type, msg)\n                                .then(() => {\n                                nextCallback(index);\n                            })\n                                .catch((error) => {\n                                this.log.error(error);\n                                this.showError(error);\n                                success = false;\n                                nextCallback(index);\n                            });\n                        });\n                        return;\n                    default:\n                        this.log.warn('Invalid message type:', type);\n                        reject();\n                }\n            });\n        };\n        this.onTyping = (text) => {\n            this.webClientService.setDraft(this.receiver, text);\n        };\n        this.getSelectedMention = () => {\n            if (this.selectedMention === null\n                || this.selectedMention < 0\n                || this.selectedMention > this.currentMentions.length - 1) {\n                return null;\n            }\n            return this.currentMentions[this.selectedMention];\n        };\n        this.showMentionSelector = () => {\n            return this.type === 'group'\n                && this.currentMentionFilterWord != null\n                && this.currentMentions.length > 0;\n        };\n        this.onComposeKeyDown = (ev) => {\n            return true;\n        };\n        this.onUploading = (inProgress, percentCurrent = null, percentFull = null) => {\n            this.uploading.enabled = inProgress;\n            this.uploading.value1 = Number(percentCurrent);\n            this.uploading.value2 = Number(percentCurrent);\n        };\n        this.startTyping = () => {\n            if (isContactReceiver(this.receiver)) {\n                this.webClientService.sendMeIsTyping(this.receiver, true);\n            }\n        };\n        this.stopTyping = () => {\n            if (isContactReceiver(this.receiver)) {\n                this.webClientService.sendMeIsTyping(this.receiver, false);\n            }\n        };\n        this.$stateParams = $stateParams;\n        this.webClientService = webClientService;\n        this.receiverService = receiverService;\n        this.stateService = stateService;\n        this.mimeService = mimeService;\n        this.timeoutService = timeoutService;\n        this.log = logService.getLogger('Conversation-C');\n        this.$state = $state;\n        this.$scope = $scope;\n        this.$filter = $filter;\n        this.$rootScope = $rootScope;\n        this.$mdDialog = $mdDialog;\n        this.$mdToast = $mdToast;\n        this.$translate = $translate;\n        this.$mdDialog.cancel();\n        this.maxTextLength = this.webClientService.getMaxTextLength();\n        this.allText = this.$translate.instant('messenger.ALL');\n        $transitions.onStart({}, function (trans) {\n            const $mdDialogInner = trans.injector().get('$mdDialog');\n            $mdDialogInner.cancel();\n        });\n        versionService.checkForUpdate();\n        if (stateService.state === 'error') {\n            this.log.debug('WebClient not yet running, redirecting to welcome screen');\n            $state.go('welcome');\n            return;\n        }\n        if (!this.locked) {\n            this.domChatElement = document.querySelector('#conversation-chat');\n            this.domChatElement.addEventListener('scroll', () => {\n                $rootScope.$apply(() => {\n                    this.updateScrollJump();\n                });\n            }, supportsPassive() ? { passive: true } : false);\n        }\n        try {\n            this.receiver = webClientService.receivers.getData({ type: $stateParams.type, id: $stateParams.id });\n            this._conversation = this.webClientService.conversations.find(this.receiver);\n            this.type = $stateParams.type;\n            if (this.receiver.type === undefined) {\n                this.receiver.type = this.type;\n            }\n            const mode = \"chat\";\n            switch (this.receiver.type) {\n                case 'me':\n                    this.controllerModel = controllerModelService.me(this.receiver, mode);\n                    break;\n                case 'contact':\n                    this.controllerModel = controllerModelService.contact(this.receiver, mode);\n                    break;\n                case 'group':\n                    this.controllerModel = controllerModelService.group(this.receiver, mode);\n                    break;\n                case 'distributionList':\n                    this.controllerModel = controllerModelService.distributionList(this.receiver, mode);\n                    break;\n                default:\n                    this.log.error('Cannot initialize controller model:', 'Invalid receiver type \"' + this.receiver.type + '\"');\n                    $state.go('messenger.home');\n                    return;\n            }\n            if (this.controllerModel.canChat() === false) {\n                this.log.warn('Cannot chat with this receiver, redirecting to home');\n                $state.go('messenger.home');\n                return;\n            }\n            this.locked = this.receiver.locked;\n            this.receiverService.setActive(this.receiver);\n            if (!this.receiver.locked) {\n                let latestHeight = 0;\n                this.messages = this.webClientService.messages.register(this.receiver, this.$scope, (e, allMessages, hasMore) => {\n                    this.messages = allMessages;\n                    const wasInitialized = this.initialized;\n                    this.initialized = true;\n                    this.hasMore = hasMore;\n                    if (!wasInitialized) {\n                        this.webClientService.messages.updateFirstUnreadMessage(this.receiver);\n                    }\n                    if (this.latestRefMsgId !== null) {\n                        this.domChatElement.scrollTop = this.domChatElement.scrollHeight - latestHeight;\n                        this.latestRefMsgId = null;\n                    }\n                    latestHeight = this.domChatElement.scrollHeight;\n                });\n                this.webClientService.messages.updateFirstUnreadMessage(this.receiver);\n                if (this.type === 'group' && controllerModelHasMembers(this.controllerModel)) {\n                    this.allMentions.push({\n                        identity: null,\n                        query: this.$translate.instant('messenger.ALL').toLowerCase(),\n                        isAll: true,\n                    });\n                    this.controllerModel.getMembers().forEach((identity) => {\n                        const contactReceiver = this.webClientService.contacts.get(identity);\n                        if (contactReceiver) {\n                            this.allMentions.push({\n                                identity: identity,\n                                query: (contactReceiver.displayName + ' ' + identity).toLowerCase(),\n                                isAll: false,\n                            });\n                        }\n                    });\n                }\n                this.initialData = {\n                    draft: webClientService.getDraft(this.receiver),\n                    initialText: $stateParams.initParams ? $stateParams.initParams.text : '',\n                };\n                if (isContactReceiver(this.receiver)) {\n                    this.isTyping = () => this.webClientService.isTyping(this.receiver);\n                }\n                if (this.webClientService.messages.getList(this.receiver).length === 0) {\n                    this.requestMessages();\n                }\n            }\n        }\n        catch (error) {\n            this.log.error('Could not set receiver and type');\n            $state.go('messenger.home');\n        }\n        $scope.$watch(() => {\n            return this.receiver.locked;\n        }, () => {\n            if (this.locked !== this.receiver.locked) {\n                $state.reload().catch((error) => {\n                    this.log.error('Unable to reload state:', error);\n                });\n            }\n        });\n    }\n    get conversation() {\n        if (!hasValue(this._conversation)) {\n            this._conversation = this.webClientService.conversations.find(this.receiver);\n        }\n        return this._conversation;\n    }\n    isEnabled() {\n        return this.type !== 'group'\n            || !this.receiver.disabled;\n    }\n    isQuoting() {\n        return this.getQuote() !== undefined;\n    }\n    getQuote() {\n        return this.webClientService.getQuote(this.receiver);\n    }\n    cancelQuoting() {\n        this.webClientService.setQuote(this.receiver, null);\n    }\n    showError(errorMessage, hideDelayMs = 3000) {\n        if (errorMessage === undefined || errorMessage.length === 0) {\n            errorMessage = this.$translate.instant('error.ERROR_OCCURRED');\n        }\n        this.$mdToast.show(this.$mdToast.simple()\n            .textContent(errorMessage)\n            .position('bottom center')\n            .hideDelay(hideDelayMs));\n    }\n    showMessage(msgTranslation, hideDelayMs = 3000) {\n        this.$mdToast.show(this.$mdToast.simple()\n            .textContent(this.$translate.instant(msgTranslation))\n            .position('bottom center')\n            .hideDelay(hideDelayMs));\n    }\n    onMentionSelected(identity = null) {\n        this.$rootScope.$broadcast('onMentionSelected', {\n            query: '@' + this.currentMentionFilterWord,\n            mention: '@[' + (identity === null ? '@@@@@@@@' : identity.toUpperCase()) + ']',\n        });\n    }\n    topOfChat() {\n        this.requestMessages();\n    }\n    requestMessages() {\n        const refMsgId = this.webClientService.requestMessages(this.$stateParams);\n        if (hasValue(refMsgId)) {\n            this.latestRefMsgId = refMsgId;\n        }\n        else {\n            this.latestRefMsgId = null;\n        }\n    }\n    showReceiver(ev) {\n        this.$state.go('messenger.home.detail', this.receiver);\n    }\n    hasMoreMessages() {\n        return this.hasMore;\n    }\n    msgRead(message) {\n        if (message.type === 'status') {\n            return;\n        }\n        if (this.lastReadMsg === null || message.sortKey >= this.lastReadMsg.sortKey) {\n            this.lastReadMsg = message;\n        }\n        if (!this.msgReadReportPending) {\n            if (!message.isOutbox && !message.unread) {\n                return;\n            }\n            const conversation = this.webClientService.conversations.find(this.receiver);\n            if (conversation !== null && conversation.unreadCount === 0) {\n                return;\n            }\n            this.msgReadReportPending = true;\n            const receiver = angular.copy(this.receiver);\n            receiver.type = this.type;\n            this.timeoutService.register(() => {\n                this.webClientService.requestRead(receiver, this.lastReadMsg);\n                this.msgReadReportPending = false;\n            }, 300, false, 'requestRead');\n        }\n    }\n    goBack() {\n        this.receiverService.setActive(undefined);\n        this.$state.go('messenger.home');\n    }\n    scrollDown() {\n        this.domChatElement.scrollTop = this.domChatElement.scrollHeight;\n    }\n    updateScrollJump() {\n        const chat = this.domChatElement;\n        this.showScrollJump = chat.scrollHeight - (chat.scrollTop + chat.offsetHeight) > 1;\n    }\n    pinConversation() {\n        if (!hasValue(this.conversation)) {\n            this.log.warn('Cannot pin, no conversation exists');\n            return;\n        }\n        this.webClientService\n            .modifyConversation(this.conversation, true)\n            .then(() => this.showMessage('messenger.PINNED_CONVERSATION_OK'))\n            .catch((e) => {\n            this.showMessage('messenger.PINNED_CONVERSATION_ERROR');\n            this.log.error('Pinning conversation failed: ' + e);\n        });\n    }\n    unpinConversation() {\n        if (!hasValue(this.conversation)) {\n            this.log.warn('Cannot unpin, no conversation exists');\n            return;\n        }\n        this.webClientService\n            .modifyConversation(this.conversation, false)\n            .then(() => this.showMessage('messenger.UNPINNED_CONVERSATION_OK'))\n            .catch((e) => {\n            this.showMessage('messenger.UNPINNED_CONVERSATION_ERROR');\n            this.log.error('Unpinning conversation failed: ' + e);\n        });\n    }\n}\nConversationController.$inject = [\n    '$stateParams', '$scope', '$rootScope',\n    '$mdDialog', '$mdToast', '$translate', '$filter',\n    '$state', '$transitions',\n    'LogService', 'WebClientService', 'StateService', 'ReceiverService', 'MimeService',\n    'VersionService', 'ControllerModelService', 'TimeoutService',\n];\nclass AboutDialogController extends DialogController {\n    constructor($scope, $mdDialog, themeService, config) {\n        super($scope, $mdDialog, themeService);\n        this.config = config;\n    }\n}\nAboutDialogController.$inject = ['$scope', '$mdDialog', 'ThemeService', 'CONFIG'];\nclass NavigationController {\n    constructor($state, $mdDialog, $translate, logService, webClientService, stateService, receiverService, notificationService, trustedKeyStoreService) {\n        this.name = 'navigation';\n        this.activeTab = 'conversations';\n        this.searchVisible = false;\n        this.searchText = '';\n        this.searchConversation = (value, index, array) => {\n            return this.searchText === ''\n                || this.matches(value.receiver.displayName, this.searchText)\n                || (value.latestMessage && value.latestMessage.body\n                    && this.matches(value.latestMessage.body, this.searchText))\n                || (value.receiver.id.length === 8 && this.matches(value.receiver.id, this.searchText));\n        };\n        this.searchContact = (value, index, array) => {\n            return this.searchText === ''\n                || value.displayName.toLowerCase().indexOf(this.searchText.toLowerCase()) !== -1\n                || value.id.toLowerCase().indexOf(this.searchText.toLowerCase()) !== -1;\n        };\n        const log = logService.getLogger('Navigation-C');\n        if (stateService.state === 'error') {\n            log.debug('WebClient not yet running, redirecting to welcome screen');\n            $state.go('welcome');\n            return;\n        }\n        this.webClientService = webClientService;\n        this.receiverService = receiverService;\n        this.stateService = stateService;\n        this.trustedKeyStoreService = trustedKeyStoreService;\n        this.notificationService = notificationService;\n        this.$mdDialog = $mdDialog;\n        this.$translate = $translate;\n        this.$state = $state;\n    }\n    contacts() {\n        const contacts = [];\n        for (const contact of this.webClientService.contacts.values()) {\n            if (contact.id === this.webClientService.receivers.me.id) {\n                continue;\n            }\n            if (contact.hidden === true) {\n                continue;\n            }\n            contacts.push(contact);\n        }\n        return contacts;\n    }\n    matches(haystack, needle) {\n        return haystack.toLowerCase().replace('\\n', ' ').indexOf(needle.trim().toLowerCase()) !== -1;\n    }\n    isVisible(conversation) {\n        return conversation.receiver.visible;\n    }\n    conversations() {\n        return this.webClientService.conversations.get();\n    }\n    isActive(value) {\n        return this.receiverService.isConversationActive(value);\n    }\n    startupDone() {\n        return this.webClientService.startupDone;\n    }\n    hideInactiveContacts() {\n        return !this.webClientService.appConfig.showInactiveIDs;\n    }\n    showDialog(name, ev, controller = DialogController) {\n        this.$mdDialog.show({\n            controller: controller,\n            controllerAs: 'ctrl',\n            templateUrl: 'partials/dialog.' + name + '.html',\n            parent: angular.element(document.body),\n            targetEvent: ev,\n            clickOutsideToClose: true,\n            fullscreen: true,\n        });\n    }\n    about(ev) {\n        this.showDialog('about', ev, AboutDialogController);\n    }\n    troubleshooting() {\n        this.$mdDialog.show({\n            controller: TroubleshootingController,\n            controllerAs: 'ctrl',\n            templateUrl: 'partials/dialog.troubleshooting.html',\n            parent: angular.element(document.body),\n            clickOutsideToClose: true,\n            fullscreen: true,\n        });\n    }\n    settings(ev) {\n        this.$mdDialog.show({\n            controller: SettingsController,\n            controllerAs: 'ctrl',\n            templateUrl: 'partials/dialog.settings.html',\n            parent: angular.element(document.body),\n            targetEvent: ev,\n            clickOutsideToClose: true,\n            fullscreen: true,\n        });\n    }\n    showProfile(ev) {\n        this.receiverService.setActive(undefined);\n        this.$state.go('messenger.home.detail', this.webClientService.me);\n    }\n    isPersistent() {\n        return this.trustedKeyStoreService.hasTrustedKey();\n    }\n    closeSession(ev) {\n        const confirm = this.$mdDialog.confirm()\n            .title(this.$translate.instant('common.SESSION_CLOSE'))\n            .textContent(this.$translate.instant('common.CONFIRM_CLOSE_BODY'))\n            .targetEvent(ev)\n            .ok(this.$translate.instant('common.YES'))\n            .cancel(this.$translate.instant('common.CANCEL'));\n        this.$mdDialog.show(confirm).then(() => {\n            this.webClientService.stop({\n                reason: \"stop\",\n                send: true,\n                close: 'welcome',\n                connectionBuildupState: 'closed',\n            });\n        }, () => {\n        });\n    }\n    deleteSession(ev) {\n        const confirm = this.$mdDialog.confirm()\n            .title(this.$translate.instant('common.SESSION_DELETE'))\n            .textContent(this.$translate.instant('common.CONFIRM_DELETE_CLOSE_BODY'))\n            .targetEvent(ev)\n            .ok(this.$translate.instant('common.YES'))\n            .cancel(this.$translate.instant('common.CANCEL'));\n        this.$mdDialog.show(confirm).then(() => {\n            this.webClientService.stop({\n                reason: \"delete\",\n                send: true,\n                close: 'welcome',\n                connectionBuildupState: 'closed',\n            });\n        }, () => {\n        });\n    }\n    addContact(ev) {\n        this.$state.go('messenger.home.create', {\n            type: 'contact',\n        });\n    }\n    createGroup(ev) {\n        this.$state.go('messenger.home.create', {\n            type: 'group',\n        });\n    }\n    createDistributionList(ev) {\n        this.$state.go('messenger.home.create', {\n            type: 'distributionList',\n        });\n    }\n    toggleSearch() {\n        this.searchVisible = !this.searchVisible;\n    }\n    getMe() {\n        return this.webClientService.me;\n    }\n    showCreateDistributionListButton() {\n        return this.webClientService.appCapabilities.distributionLists;\n    }\n    dndModeSimplified(conversation) {\n        return this.notificationService.getDndModeSimplified(conversation);\n    }\n}\nNavigationController.$inject = [\n    '$state', '$mdDialog', '$translate',\n    'LogService', 'WebClientService', 'StateService', 'ReceiverService', 'NotificationService', 'TrustedKeyStore',\n];\nclass MessengerController {\n    constructor($scope, $state, $mdDialog, $translate, logService, stateService, receiverService, webClientService, controllerService) {\n        this.name = 'messenger';\n        const log = logService.getLogger('Messenger-C');\n        if (stateService.state === 'error') {\n            log.debug('WebClient not yet running, redirecting to welcome screen');\n            $state.go('welcome');\n            return;\n        }\n        controllerService.setControllerName('messenger');\n        this.receiverService = receiverService;\n        this.$state = $state;\n        this.webClientService = webClientService;\n        $scope.$watch(() => webClientService.alerts, (alerts) => {\n            if (alerts.length > 0) {\n                angular.forEach(alerts, (alert) => {\n                    $mdDialog.show($mdDialog.alert()\n                        .clickOutsideToClose(true)\n                        .title(alert.type)\n                        .textContent(alert.message)\n                        .ok($translate.instant('common.OK')));\n                });\n                webClientService.alerts = [];\n            }\n        }, true);\n        this.webClientService.setReceiverListener({\n            onConversationRemoved(receiver) {\n                switch ($state.current.name) {\n                    case 'messenger.home.conversation':\n                    case 'messenger.home.detail':\n                    case 'messenger.home.edit':\n                        if ($state.params !== undefined\n                            && $state.params.type !== undefined\n                            && $state.params.id !== undefined) {\n                            if ($state.params.type === receiver.type\n                                && $state.params.id === receiver.id) {\n                                $state.go('messenger.home');\n                            }\n                        }\n                        break;\n                    default:\n                        log.debug('Ignored onRemoved event for state', $state.current.name);\n                }\n            },\n        });\n    }\n    showDetail() {\n        return !this.$state.is('messenger.home');\n    }\n}\nMessengerController.$inject = [\n    '$scope', '$state', '$mdDialog', '$translate',\n    'LogService', 'StateService', 'ReceiverService', 'WebClientService', 'ControllerService',\n];\nclass QrDialogController extends DialogController {\n    constructor($scope, $mdDialog, themeService, webClientService) {\n        super($scope, $mdDialog, themeService);\n        this.profile = webClientService.me;\n        this.qrCode = {\n            errorCorrectionLevel: 'L',\n            size: '400px',\n            data: '3mid:'\n                + this.profile.id\n                + ','\n                + u8aToHex(new Uint8Array(this.profile.publicKey)),\n        };\n    }\n}\nQrDialogController.$inject = ['$scope', '$mdDialog', 'ThemeService', 'WebClientService'];\nclass ReceiverDetailController {\n    constructor($scope, $stateParams, $state, $mdDialog, $translate, logService, webClientService, fingerPrintService, contactService, controllerModelService) {\n        this.fingerPrint = { value: null };\n        this.showGroups = false;\n        this.showDistributionLists = false;\n        this.inGroups = [];\n        this.inDistributionLists = [];\n        this.hasSystemEmails = false;\n        this.hasSystemPhones = false;\n        this.isWorkReceiver = false;\n        this.showBlocked = () => false;\n        this.$mdDialog = $mdDialog;\n        this.$scope = $scope;\n        this.$state = $state;\n        this.fingerPrintService = fingerPrintService;\n        this.contactService = contactService;\n        this.webClientService = webClientService;\n        this.receiver = webClientService.receivers.getData($stateParams);\n        this.me = webClientService.me;\n        const log = logService.getLogger('ReceiverDetail-C');\n        if (isContactReceiver(this.receiver)) {\n            const contactReceiver = this.receiver;\n            this.contactService.requiredDetails(contactReceiver)\n                .then(() => {\n                this.hasSystemEmails = contactReceiver.systemContact !== undefined\n                    && contactReceiver.systemContact.emails.length > 0;\n                this.hasSystemPhones = contactReceiver.systemContact !== undefined &&\n                    contactReceiver.systemContact.phoneNumbers.length > 0;\n            })\n                .catch((error) => {\n                log.error(`Contact detail request has been rejected: ${error}`);\n            });\n            this.isWorkReceiver = contactReceiver.identityType === 1;\n            this.fingerPrintService\n                .generate(contactReceiver.publicKey)\n                .then(this.setFingerPrint.bind(this));\n            webClientService.groups.forEach((groupReceiver) => {\n                if (groupReceiver.members.indexOf(contactReceiver.id) !== -1) {\n                    this.inGroups.push(groupReceiver);\n                    this.showGroups = true;\n                }\n            });\n            webClientService.distributionLists.forEach((distributionListReceiver) => {\n                if (distributionListReceiver.members.indexOf(contactReceiver.id) !== -1) {\n                    this.inDistributionLists.push(distributionListReceiver);\n                    this.showDistributionLists = true;\n                }\n            });\n            this.showBlocked = () => contactReceiver.isBlocked;\n        }\n        switch (this.receiver.type) {\n            case 'me':\n                const meReceiver = this.receiver;\n                this.fingerPrintService\n                    .generate(meReceiver.publicKey)\n                    .then(this.setFingerPrint.bind(this));\n                this.controllerModel = controllerModelService.me(meReceiver, \"view\");\n                break;\n            case 'contact':\n                const contactReceiver = this.receiver;\n                this.fingerPrintService\n                    .generate(contactReceiver.publicKey)\n                    .then(this.setFingerPrint.bind(this));\n                this.controllerModel = controllerModelService\n                    .contact(contactReceiver, \"view\");\n                break;\n            case 'group':\n                this.controllerModel = controllerModelService\n                    .group(this.receiver, \"view\");\n                break;\n            case 'distributionList':\n                this.controllerModel = controllerModelService\n                    .distributionList(this.receiver, \"view\");\n                break;\n            default:\n                log.error('Cannot initialize controller model:', 'Invalid receiver type \"' + this.receiver.type + '\"');\n                $state.go('messenger.home');\n                return;\n        }\n        this.controllerModel.setOnRemoved((receiverId) => {\n            log.warn('Receiver removed, redirecting to home');\n            this.$state.go('messenger.home');\n        });\n    }\n    setFingerPrint(fingerPrint) {\n        this.fingerPrint.value = fingerPrint;\n        this.$scope.$digest();\n    }\n    chat() {\n        this.$state.go('messenger.home.conversation', {\n            type: this.receiver.type,\n            id: this.receiver.id,\n            initParams: null,\n        });\n    }\n    edit() {\n        if (!this.controllerModel.canEdit()) {\n            return;\n        }\n        this.$state.go('messenger.home.edit', {\n            type: this.receiver.type,\n            id: this.receiver.id,\n            initParams: null,\n        });\n    }\n    showQr() {\n        const $mdDialog = this.$mdDialog;\n        $mdDialog.show({\n            controllerAs: 'ctrl',\n            controller: QrDialogController,\n            templateUrl: 'partials/dialog.qr.html',\n            parent: angular.element(document.body),\n            clickOutsideToClose: true,\n            fullscreen: true,\n        });\n    }\n    goBack() {\n        window.history.back();\n    }\n}\nReceiverDetailController.$inject = [\n    '$scope', '$stateParams', '$state', '$mdDialog', '$translate',\n    'LogService', 'WebClientService', 'FingerPrintService', 'ContactService', 'ControllerModelService',\n];\nclass ReceiverEditController {\n    constructor($scope, $stateParams, $state, $mdDialog, $timeout, $translate, logService, webClientService, controllerModelService) {\n        this.$scope = $scope;\n        this.$mdDialog = $mdDialog;\n        this.$state = $state;\n        this.$timeout = $timeout;\n        this.$translate = $translate;\n        const log = logService.getLogger('ReceiverEdit-C');\n        const receiver = webClientService.receivers.getData($stateParams);\n        switch (receiver.type) {\n            case 'me':\n                this.controllerModel = controllerModelService.me(receiver, \"edit\");\n                break;\n            case 'contact':\n                this.controllerModel = controllerModelService.contact(receiver, \"edit\");\n                break;\n            case 'group':\n                this.controllerModel = controllerModelService.group(receiver, \"edit\");\n                break;\n            case 'distributionList':\n                this.controllerModel = controllerModelService.distributionList(receiver, \"edit\");\n                break;\n            default:\n                log.error('Cannot initialize controller model:', 'Invalid receiver type \"' + receiver.type + '\"');\n                $state.go('messenger.home');\n                return;\n        }\n        this.type = receiver.type;\n    }\n    keypress($event) {\n        if ($event.key === 'Enter' && this.controllerModel.isValid()) {\n            this.save();\n        }\n    }\n    save() {\n        this.future = Future.withMinDuration(this.controllerModel.save(), 100);\n        this.future\n            .then(() => {\n            this.$scope.$apply(() => {\n                this.goBack();\n            });\n        })\n            .catch((errorCode) => {\n            this.$scope.$apply(() => {\n                this.showEditError(errorCode);\n            });\n        });\n    }\n    isSaving() {\n        return this.future !== undefined && !this.future.done;\n    }\n    showEditError(errorCode) {\n        if (errorCode === undefined) {\n            errorCode = 'unknown';\n        }\n        this.$mdDialog.show(this.$mdDialog.alert()\n            .clickOutsideToClose(true)\n            .title(this.controllerModel.subject)\n            .textContent(this.$translate.instant('validationError.modifyReceiver.' + errorCode))\n            .ok(this.$translate.instant('common.OK')));\n    }\n    goBack() {\n        window.history.back();\n    }\n}\nReceiverEditController.$inject = [\n    '$scope', '$stateParams', '$state', '$mdDialog',\n    '$timeout', '$translate', 'LogService', 'WebClientService', 'ControllerModelService',\n];\nclass ReceiverCreateController {\n    constructor($stateParams, $mdDialog, $scope, $mdToast, $translate, $timeout, $state, logService, controllerModelService) {\n        this.identity = '';\n        this.$mdDialog = $mdDialog;\n        this.$scope = $scope;\n        this.$timeout = $timeout;\n        this.$state = $state;\n        this.$mdToast = $mdToast;\n        this.$translate = $translate;\n        const log = logService.getLogger('ReceiverEdit-C');\n        this.type = $stateParams.type;\n        switch (this.type) {\n            case 'me':\n                log.warn('Cannot create own contact');\n                $state.go('messenger.home');\n                return;\n            case 'contact':\n                this.controllerModel = controllerModelService.contact(null, \"new\");\n                if ($stateParams.initParams !== null) {\n                    this.controllerModel\n                        .identity = $stateParams.initParams.identity;\n                }\n                break;\n            case 'group':\n                this.controllerModel = controllerModelService.group(null, \"new\");\n                break;\n            case 'distributionList':\n                this.controllerModel = controllerModelService.distributionList(null, \"new\");\n                break;\n            default:\n                log.error('Invalid type', this.type);\n        }\n    }\n    isSaving() {\n        return this.future !== undefined && !this.future.done;\n    }\n    goBack() {\n        if (!this.isSaving()) {\n            window.history.back();\n        }\n    }\n    showAddError(errorCode) {\n        if (errorCode === undefined) {\n            errorCode = 'unknown';\n        }\n        this.$mdDialog.show(this.$mdDialog.alert()\n            .clickOutsideToClose(true)\n            .title(this.controllerModel.subject)\n            .textContent(this.$translate.instant('validationError.modifyReceiver.' + errorCode))\n            .ok(this.$translate.instant('common.OK')));\n    }\n    keypress($event) {\n        if ($event.key === 'Enter' && this.controllerModel.isValid()) {\n            this.create();\n        }\n    }\n    create() {\n        this.future = Future.withMinDuration(this.controllerModel.save(), 100);\n        this.future\n            .then((receiver) => {\n            this.$scope.$apply(() => {\n                this.$state.go('messenger.home.detail', receiver, { location: 'replace' });\n            });\n        })\n            .catch((errorCode) => {\n            this.$scope.$apply(() => {\n                this.showAddError(errorCode);\n            });\n        });\n    }\n}\nReceiverCreateController.$inject = ['$stateParams', '$mdDialog', '$scope', '$mdToast', '$translate',\n    '$timeout', '$state', 'LogService', 'ControllerModelService'];\nangular.module('3ema.messenger', ['ngMaterial'])\n    .config(['$stateProvider', function ($stateProvider) {\n        $stateProvider\n            .state('messenger', {\n            abstract: true,\n            templateUrl: 'partials/messenger.html',\n            controller: 'MessengerController',\n            controllerAs: 'ctrl',\n        })\n            .state('messenger.home', {\n            url: '/messenger',\n            views: {\n                navigation: {\n                    templateUrl: 'partials/messenger.navigation.html',\n                    controller: 'NavigationController',\n                    controllerAs: 'ctrl',\n                },\n                content: {\n                    template: '<div ui-view></div>',\n                },\n            },\n        })\n            .state('messenger.home.conversation', {\n            url: '/conversation/{type}/{id}',\n            templateUrl: 'partials/messenger.conversation.html',\n            controller: 'ConversationController',\n            controllerAs: 'ctrl',\n            params: { initParams: null },\n        })\n            .state('messenger.home.detail', {\n            url: '/conversation/{type}/{id}/detail',\n            templateUrl: 'partials/messenger.receiver.html',\n            controller: 'ReceiverDetailController',\n            controllerAs: 'ctrl',\n        })\n            .state('messenger.home.edit', {\n            url: '/conversation/{type}/{id}/detail/edit',\n            templateUrl: 'partials/messenger.receiver.edit.html',\n            controller: 'ReceiverEditController',\n            controllerAs: 'ctrl',\n        })\n            .state('messenger.home.create', {\n            url: '/receiver/create/{type}',\n            templateUrl: 'partials/messenger.receiver.create.html',\n            controller: 'ReceiverCreateController',\n            controllerAs: 'ctrl',\n            params: { initParams: null },\n        });\n    }])\n    .controller('SendFileController', SendFileController)\n    .controller('MessengerController', MessengerController)\n    .controller('ConversationController', ConversationController)\n    .controller('NavigationController', NavigationController)\n    .controller('ReceiverDetailController', ReceiverDetailController)\n    .controller('ReceiverEditController', ReceiverEditController)\n    .controller('ReceiverCreateController', ReceiverCreateController);\n","export class ChunkCache {\n    constructor(sequenceNumber) {\n        this._byteLength = 0;\n        this.cache = [];\n        this._sequenceNumber = sequenceNumber;\n    }\n    get sequenceNumber() {\n        return this._sequenceNumber;\n    }\n    get byteLength() {\n        return this._byteLength;\n    }\n    get chunks() {\n        return this.cache.filter((chunk) => chunk !== null);\n    }\n    transfer(cache) {\n        cache = cache.filter((chunk) => chunk !== null);\n        const count = cache.length;\n        for (const chunk of cache) {\n            this.append(chunk);\n        }\n        return count;\n    }\n    append(chunk) {\n        this._sequenceNumber.increment();\n        if (chunk !== null) {\n            this._byteLength += chunk.byteLength;\n        }\n        this.cache.push(chunk);\n    }\n    prune(theirSequenceNumber) {\n        try {\n            this._sequenceNumber.validate(theirSequenceNumber);\n        }\n        catch (error) {\n            throw new Error(`Remote sent us an invalid sequence number: ${theirSequenceNumber}`);\n        }\n        const beginOffset = theirSequenceNumber - this._sequenceNumber.get();\n        if (beginOffset > 0) {\n            throw new Error('Remote travelled through time and acknowledged a chunk which is in the future');\n        }\n        else if (-beginOffset > this.cache.length) {\n            throw new Error('Remote travelled back in time and acknowledged a chunk it has already acknowledged');\n        }\n        const chunkCountBefore = this.cache.length;\n        this.cache = beginOffset === 0 ? [] : this.cache.slice(beginOffset);\n        this._byteLength = this.cache\n            .filter((chunk) => chunk !== null)\n            .reduce((sum, chunk) => sum + chunk.byteLength, 0);\n        return {\n            acknowledged: chunkCountBefore + beginOffset,\n            left: this.cache.length,\n        };\n    }\n}\n","export class SequenceNumber {\n    constructor(initialValue = 0, minValue, maxValue) {\n        this.minValue = minValue;\n        this.maxValue = maxValue;\n        this.value = initialValue;\n    }\n    validate(other) {\n        if (other < this.minValue) {\n            throw new Error(`Invalid sequence number: ${other} < 0`);\n        }\n        if (other > this.maxValue) {\n            throw new Error(`Invalid sequence number: ${other} > ${this.maxValue}`);\n        }\n    }\n    get() {\n        return this.value;\n    }\n    set(value) {\n        this.validate(value);\n        this.value = value;\n    }\n    increment(by = 1) {\n        if (by < 0) {\n            throw new Error('Cannot decrement the sequence number');\n        }\n        const value = this.value;\n        this.set(value + by);\n        return value;\n    }\n}\n","import * as msgpack from 'msgpack-lite';\nimport * as nacl from 'tweetnacl';\nimport { arraysAreEqual, base64ToU8a, bufferToUrl, copyDeepOrReference, copyShallow, hasFeature, hasValue, hexToU8a, msgpackVisualizer, randomString, stringToUtf8a, u8aToHex, } from '../helpers';\nimport { isContactReceiver, isDistributionListReceiver, isGroupReceiver, isValidReceiverType, } from '../typeguards';\nimport { PeerConnectionHelper } from './peerconnection';\nimport { PushSession } from './push';\nimport { PushError, TimeoutError } from '../exceptions';\nimport { ConfidentialWireMessage } from '../helpers/confidential';\nimport { UnboundedFlowControlledDataChannel } from '../helpers/data_channel';\nimport { DeviceUnreachableController, PushRejectedDialogController } from '../partials/messenger';\nimport { ChunkCache } from '../protocol/cache';\nimport { SequenceNumber } from '../protocol/sequence_number';\nconst fakeConnectionId = Uint8Array.from([\n    1, 2, 3, 4, 5, 6, 7, 8,\n    1, 2, 3, 4, 5, 6, 7, 8,\n    1, 2, 3, 4, 5, 6, 7, 8,\n    1, 2, 3, 4, 5, 6, 7, 8,\n]);\nexport class WebClientService {\n    constructor($rootScope, $q, $state, $window, $translate, $filter, $timeout, $mdDialog, logService, container, trustedKeyStore, stateService, notificationService, messageService, pushService, browserService, titleService, qrCodeService, mimeService, receiverService, versionService, batteryStatusService, themeService, timeoutService, CONFIG) {\n        this.startupPromise = null;\n        this.startupDone = false;\n        this.handoverDone = false;\n        this.pendingInitializationStepRoutines = new Set();\n        this.initialized = new Set();\n        this.saltyRtcHost = null;\n        this.salty = null;\n        this.connectionInfoFuture = null;\n        this.relayedDataTask = null;\n        this.secureDataChannel = null;\n        this.secureDataChannelCrypto = null;\n        this.secureDataChannelChunkLength = null;\n        this.secureDataChannelMessageId = 0;\n        this.chosenTask = \"none\";\n        this.previousConnectionId = null;\n        this.currentConnectionId = null;\n        this.previousIncomingChunkSequenceNumber = null;\n        this.previousChunkCache = null;\n        this.currentChunkCache = null;\n        this.handshakeCompleted = false;\n        this.ackTimer = null;\n        this.pendingAckRequest = null;\n        this.unchunker = null;\n        this.alerts = [];\n        this.pushToken = null;\n        this.pushTokenType = null;\n        this.pushSession = null;\n        this.pushPromise = null;\n        this.deviceUnreachableDialog = null;\n        this.pushTimer = null;\n        this.schedulePushAfterCooldown = false;\n        this.batteryStatusTimeout = null;\n        this.pcHelper = null;\n        this.clientInfo = null;\n        this.version = null;\n        this.blobCache = new Map();\n        this.loadingMessages = new Map();\n        this.receiverListener = [];\n        this.msgpackEncoderOptions = {\n            codec: msgpack.createCodec({ binarraybuffer: true }),\n        };\n        this.msgpackDecoderOptions = {\n            codec: msgpack.createCodec({ binarraybuffer: true }),\n        };\n        this.wireMessageFutures = new Map();\n        this.$rootScope = $rootScope;\n        this.$q = $q;\n        this.$state = $state;\n        this.$window = $window;\n        this.$translate = $translate;\n        this.$filter = $filter;\n        this.$timeout = $timeout;\n        this.$mdDialog = $mdDialog;\n        this.batteryStatusService = batteryStatusService;\n        this.browserService = browserService;\n        this.logService = logService;\n        this.messageService = messageService;\n        this.mimeService = mimeService;\n        this.notificationService = notificationService;\n        this.pushService = pushService;\n        this.qrCodeService = qrCodeService;\n        this.receiverService = receiverService;\n        this.themeService = themeService;\n        this.timeoutService = timeoutService;\n        this.titleService = titleService;\n        this.versionService = versionService;\n        this.config = CONFIG;\n        this.log = logService.getLogger('WebClient-S', 'color: #fff; background-color: #0066cc');\n        this.arpLog = logService.getLogger('AppRemoteProtocol', 'color: #fff; background-color: #0099cc', CONFIG.ARP_LOG_LEVEL);\n        this.arpLogV = logService.getLogger('AppRemoteProtocol', 'color: #fff; background-color: #00ace6', CONFIG.ARP_LOG_TRACE ? 'debug' : 'none');\n        this.msgpackLog = logService.getLogger('MessagePack', 'color: #fff; background-color: #006699', CONFIG.MSGPACK_LOG_TRACE ? 'debug' : 'none');\n        this.stateService = stateService;\n        this.pushSessionConfig = PushSession.defaultConfig;\n        this.pushSessionConfig.triesMax = WebClientService.MAX_CONNECT_ATTEMPTS;\n        this.pushSessionConfig = {\n            retryTimeoutInitMs: 14000, retryTimeoutMaxMs: 30000, triesMax: 1, timeToLiveRange: [90],\n        };\n        this.pushSessionExpectedPeriodMaxMs = PushSession.expectedPeriodMaxMs(this.pushSessionConfig);\n        this.container = container;\n        this.trustedKeyStore = trustedKeyStore;\n        this.drafts = this.container.createDrafts();\n        this._resetFields();\n        this.stateService.evtConnectionBuildupStateChange.attach((stateChange) => {\n            if (this.startupPromise !== null) {\n                this.startupPromise.notify(stateChange);\n            }\n        });\n        this.stateService.evtGlobalConnectionStateChange.attach(this.handleGlobalConnectionStateChange.bind(this));\n    }\n    get readyToSubmit() {\n        return this.stateService.readyToSubmit(this.chosenTask, this.startupDone);\n    }\n    get me() {\n        return this.receivers.me;\n    }\n    get contacts() {\n        return this.receivers.contacts;\n    }\n    get groups() {\n        return this.receivers.groups;\n    }\n    get distributionLists() {\n        return this.receivers.distributionLists;\n    }\n    get typing() {\n        return this.typingInstance;\n    }\n    get unacknowledgedWireMessages() {\n        return this.wireMessageFutures.size;\n    }\n    get requiresTemporaryIdBackwardsCompatibility() {\n        return this.chosenTask !== \"relayed-data\";\n    }\n    buildQrCodePayload(persistent) {\n        return this.qrCodeService.buildQrCodePayload(this.salty.permanentKeyBytes, this.salty.authTokenBytes, hexToU8a(this.config.SALTYRTC_SERVER_KEY), this.saltyRtcHost, this.config.SALTYRTC_PORT, persistent);\n    }\n    init(flags) {\n        let keyStore = flags.keyStore;\n        let resumeSession = flags.resume;\n        this.log.info(`Initializing (keyStore=${keyStore !== undefined ? 'yes' : 'no'}, peerTrustedKey=` +\n            `${flags.peerTrustedKey !== undefined ? 'yes' : 'no'}, resume=${resumeSession})`);\n        if (!resumeSession) {\n            this.clearCache();\n            this.wireMessageFutures.clear();\n            this.timeoutService.cancelAll();\n        }\n        if (resumeSession) {\n            if (this.previousConnectionId) {\n                this.arpLog.debug(`Trying to resume previous session (id=${u8aToHex(this.previousConnectionId)}, ` +\n                    `sn-out=${this.previousChunkCache.sequenceNumber.get()})`);\n            }\n            else {\n                resumeSession = false;\n                this.arpLog.debug('Wanted to resume previous session but none exists');\n            }\n        }\n        else {\n            this.discardSession({ resetMessageSequenceNumber: true });\n            resumeSession = false;\n            this.arpLog.debug('Discarded previous session');\n        }\n        this.handshakeCompleted = false;\n        this.currentConnectionId = null;\n        this.currentIncomingChunkSequenceNumber = new SequenceNumber(0, WebClientService.SEQUENCE_NUMBER_MIN, WebClientService.SEQUENCE_NUMBER_MAX);\n        const outgoingChunkSequenceNumber = new SequenceNumber(0, WebClientService.SEQUENCE_NUMBER_MIN, WebClientService.SEQUENCE_NUMBER_MAX);\n        this.currentChunkCache = new ChunkCache(outgoingChunkSequenceNumber);\n        this.pendingAckRequest = null;\n        this.connectionInfoFuture = new Future();\n        const tasks = [];\n        if (this.browserService.supportsWebrtcTask()) {\n            tasks.push(new saltyrtcTaskWebrtc.WebRTCTaskBuilder()\n                .withLoggingLevel(this.config.SALTYRTC_LOG_LEVEL)\n                .withVersion('v1')\n                .withHandover(true)\n                .build());\n            tasks.push(new saltyrtcTaskWebrtc.WebRTCTaskBuilder()\n                .withLoggingLevel(this.config.SALTYRTC_LOG_LEVEL)\n                .withVersion('v0')\n                .withHandover(true)\n                .withMaxChunkLength(this.browserService.getBrowser().isFirefox(false) ? 16384 : 65536)\n                .build());\n        }\n        this.relayedDataTask = new saltyrtcTaskRelayedData.RelayedDataTask(this.config.SALTYRTC_LOG_LEVEL === 'debug');\n        tasks.push(this.relayedDataTask);\n        if (!keyStore) {\n            keyStore = new saltyrtcClient.KeyStore();\n        }\n        this.saltyRtcHost = this.config.SALTYRTC_HOST.replace('{prefix}', keyStore.publicKeyHex.substr(0, 2));\n        let builder = new saltyrtcClient.SaltyRTCBuilder()\n            .connectTo(this.saltyRtcHost, this.config.SALTYRTC_PORT)\n            .withLoggingLevel(this.config.SALTYRTC_LOG_LEVEL)\n            .withServerKey(this.config.SALTYRTC_SERVER_KEY)\n            .withKeyStore(keyStore)\n            .usingTasks(tasks)\n            .withPingInterval(30);\n        if (flags.peerTrustedKey !== undefined) {\n            builder = builder.withTrustedPeerKey(flags.peerTrustedKey);\n        }\n        this.salty = builder.asInitiator();\n        this.arpLog.info('Public key:', this.salty.permanentKeyHex);\n        this.arpLogV.debug('Auth token:', this.salty.authTokenHex);\n        this.salty.on('state-change', (ev) => {\n            const state = ev.data;\n            if (!this.startupDone) {\n                switch (state) {\n                    case 'new':\n                    case 'ws-connecting':\n                    case 'server-handshake':\n                        if (this.stateService.connectionBuildupState !== 'push'\n                            && this.stateService.connectionBuildupState !== 'manual_start') {\n                            this.stateService.updateConnectionBuildupState('connecting');\n                        }\n                        break;\n                    case 'peer-handshake':\n                        if (this.stateService.connectionBuildupState !== 'push'\n                            && this.stateService.connectionBuildupState !== 'manual_start') {\n                            this.stateService.updateConnectionBuildupState('waiting');\n                        }\n                        break;\n                    case 'task':\n                        this.onTaskEstablished(resumeSession);\n                        break;\n                    case 'closing':\n                    case 'closed':\n                        this.stateService.updateConnectionBuildupState('closed');\n                        break;\n                    default:\n                        this.arpLog.warn('Unknown signaling state:', state);\n                }\n            }\n            this.stateService.updateSignalingConnectionState(state, this.chosenTask, this.handoverDone);\n        });\n        this.salty.on('peer-disconnected', (ev) => {\n            this.$rootScope.$apply(() => {\n                this.onPeerDisconnected(ev.data);\n            });\n        });\n        this.salty.on('handover', () => {\n            this.arpLog.debug('Handover done');\n            this.onHandover(resumeSession);\n        });\n        this.salty.on('connection-error', (ev) => {\n            this.arpLog.error('Connection error:', ev);\n        });\n        this.salty.on('connection-closed', (ev) => {\n            this.arpLog.info('Connection closed:', ev);\n        });\n        this.salty.on('no-shared-task', (ev) => {\n            this.arpLog.warn('No shared task found:', ev.data);\n            const offeredWebrtc = ev.data.offered.filter((t) => t.endsWith('webrtc.tasks.saltyrtc.org')).length > 0;\n            this.$rootScope.$apply(() => {\n                if (!this.browserService.supportsWebrtcTask() && offeredWebrtc) {\n                    this.failSession(false);\n                    this.showWebrtcAndroidWarning();\n                }\n                else {\n                    this.failSession();\n                }\n            });\n        });\n    }\n    showWebrtcAndroidWarning() {\n        this.$translate.onReady().then(() => {\n            const confirm = this.$mdDialog.alert()\n                .title(this.$translate.instant('welcome.BROWSER_NOT_SUPPORTED_ANDROID'))\n                .htmlContent(this.$translate.instant('welcome.BROWSER_NOT_SUPPORTED_ANDROID_DETAILS', {\n                firefoxLink: '<a href=\"https://www.mozilla.org/firefox/\" target=\"_blank\" rel=\"noopener noreferrer\">Firefox</a>',\n                chromeLink: '<a href=\"https://www.google.com/chrome/browser/desktop/\" target=\"_blank\" rel=\"noopener noreferrer\">Chrome</a>',\n                operaLink: '<a href=\"https://www.opera.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Opera</a>',\n                edgeLink: '<a href=\"https://www.microsoft.com/edge\" target=\"_blank\" rel=\"noopener noreferrer\">Edge</a>',\n            }))\n                .ok(this.$translate.instant('welcome.ABORT'));\n            this.$mdDialog.show(confirm).then(() => {\n                window.location.replace('https://threema.ch/threema-web');\n            });\n        });\n    }\n    showAlert(alertMessage) {\n        this.$timeout(() => {\n            this.$mdDialog.show(this.$mdDialog.alert()\n                .title(this.$translate.instant('connection.SESSION_CLOSED_TITLE'))\n                .textContent(this.$translate.instant(alertMessage))\n                .ok(this.$translate.instant('common.OK')));\n        }, 0);\n    }\n    failSession(showAlert = true) {\n        const stop = () => {\n            this.stop({\n                reason: \"error\",\n                send: true,\n                close: 'welcome',\n                connectionBuildupState: 'closed',\n            });\n            if (showAlert) {\n                this.showAlert('connection.SESSION_ERROR');\n            }\n        };\n        if (!this.$rootScope.$$phase) {\n            this.$rootScope.$apply(() => stop());\n        }\n        else {\n            stop();\n        }\n    }\n    failSessionOnReject(type, subType) {\n        return ((error) => {\n            this.logOnReject(type, subType)(error);\n            this.failSession();\n        });\n    }\n    logOnReject(type, subType) {\n        return ((error) => {\n            this.arpLog.error(`Message ${type}/${subType} has been rejected by the remote: ${error}`);\n        });\n    }\n    maybeResumeSession(resumeSession, remoteInfo) {\n        const remoteCurrentConnectionId = new Uint8Array(remoteInfo.id);\n        if (arraysAreEqual(fakeConnectionId, remoteCurrentConnectionId)) {\n            this.arpLog.debug('Cannot resume session: Remote did not implement deriving the connection ID');\n            return false;\n        }\n        if (!arraysAreEqual(this.currentConnectionId, remoteCurrentConnectionId)) {\n            this.arpLog.info(`Cannot resume session: IDs of previous connection do not match (local=`\n                + `${u8aToHex(this.currentConnectionId)}, remote=${u8aToHex(remoteCurrentConnectionId)}`);\n            throw new Error('Derived connection IDs do not match!');\n        }\n        if (!resumeSession || remoteInfo.resume === undefined) {\n            this.arpLog.info(`No resumption (local requested: ${resumeSession ? 'yes' : 'no'}, ` +\n                `remote requested: ${remoteInfo.resume ? 'yes' : 'no'})`);\n            return false;\n        }\n        const remotePreviousConnectionId = new Uint8Array(remoteInfo.resume.id);\n        if (!arraysAreEqual(this.previousConnectionId, remotePreviousConnectionId)) {\n            this.arpLog.info(`Cannot resume session: IDs of previous connection do not match (local=`\n                + `${u8aToHex(this.previousConnectionId)}, remote=${u8aToHex(remotePreviousConnectionId)}`);\n            return false;\n        }\n        const size = this.previousChunkCache.byteLength;\n        let result;\n        this.arpLog.debug(`Pruning cache (local-sn=${this.previousChunkCache.sequenceNumber.get()}, ` +\n            `remote-sn=${remoteInfo.resume.sequenceNumber})`);\n        try {\n            result = this.previousChunkCache.prune(remoteInfo.resume.sequenceNumber);\n        }\n        catch (error) {\n            throw new Error(`Unable to resume session: ${error}`);\n        }\n        this.arpLog.debug(`Chunk cache pruned, acknowledged: ${result.acknowledged}, left: ${result.left}, size: ` +\n            `${size} -> ${this.previousChunkCache.byteLength}`);\n        if (this.config.ARP_LOG_TRACE) {\n            this.arpLog.debug(`Chunks that require acknowledgement: ${this.previousChunkCache.chunks.length}`);\n        }\n        const transferred = this.currentChunkCache.transfer(this.previousChunkCache.chunks);\n        this.arpLog.debug(`Chunk cache transferred (${transferred} chunks)`);\n        this.previousConnectionId = null;\n        this.previousIncomingChunkSequenceNumber = null;\n        this.previousChunkCache = null;\n        const chunks = this.currentChunkCache.chunks;\n        this.arpLog.debug(`Sending cached chunks: ${chunks.length}`);\n        for (const chunk of chunks) {\n            this.sendChunk(chunk, true, false, false);\n        }\n        return true;\n    }\n    discardSession(flags) {\n        if (flags.resetMessageSequenceNumber) {\n            this.outgoingMessageSequenceNumber = new SequenceNumber(0, WebClientService.SEQUENCE_NUMBER_MIN, WebClientService.SEQUENCE_NUMBER_MAX);\n        }\n        this.unchunker = new chunkedDc.UnreliableUnorderedUnchunker();\n        this.unchunker.onMessage = this.handleIncomingMessageBytes.bind(this);\n        this.previousConnectionId = null;\n        this.previousIncomingChunkSequenceNumber = null;\n        this.previousChunkCache = null;\n    }\n    scheduleConnectionAck(timeout = 10000) {\n        if (this.ackTimer === null) {\n            this.ackTimer = self.setTimeout(() => {\n                this.ackTimer = null;\n                this._sendConnectionAck();\n            }, timeout);\n        }\n    }\n    schedulePush(timeoutMs = 3000) {\n        if (this.pushTimer !== null) {\n            this.schedulePushAfterCooldown = true;\n            return;\n        }\n        this.pushTimer = self.setTimeout(() => {\n            this.pushTimer = null;\n            this.schedulePushAfterCooldown = false;\n            this.log.debug('Connection appears to be lost, sending push');\n            this.sendPush();\n        }, timeoutMs);\n        this._requestConnectionAck();\n    }\n    cancelPush(cooldownMs = 10000) {\n        if (this.pushTimer !== null) {\n            self.clearTimeout(this.pushTimer);\n            this.pushTimer = null;\n        }\n        this.schedulePushAfterCooldown = false;\n        if (cooldownMs > 0) {\n            this.pushTimer = self.setTimeout(() => {\n                this.pushTimer = null;\n                if (this.schedulePushAfterCooldown) {\n                    this.schedulePush();\n                }\n            }, cooldownMs);\n        }\n    }\n    onTaskEstablished(resumeSession) {\n        this.resetPushSession(true);\n        this.stateService.updateConnectionBuildupState('peer_handshake');\n        const task = this.salty.getTask();\n        if (task.getName().indexOf('webrtc.tasks.saltyrtc.org') !== -1) {\n            this.chosenTask = \"webrtc\";\n        }\n        else if (task.getName().indexOf('relayed-data.tasks.saltyrtc.org') !== -1) {\n            this.chosenTask = \"relayed-data\";\n        }\n        else {\n            throw new Error('Invalid or unknown task name: ' + task.getName());\n        }\n        if (this.chosenTask === \"webrtc\") {\n            const browser = this.browserService.getBrowser();\n            const prefix = u8aToHex(nacl.randomBytes(1));\n            const iceServers = this.config.ICE_SERVERS.map((server) => {\n                server = copyShallow(server);\n                const urls = Array.isArray(server.urls) ? server.urls : [server.urls];\n                server.urls = urls.map((url) => url.replace('{prefix}', prefix));\n                return server;\n            });\n            this.pcHelper = new PeerConnectionHelper(this.$q, this.$rootScope, this.config, this.logService, this.timeoutService, task, iceServers);\n            this.pcHelper.onConnectionStateChange = (state) => {\n                this.stateService.updateTaskConnectionState(state);\n            };\n            this.pcHelper.handover();\n        }\n        else {\n            this.onHandover(resumeSession);\n        }\n    }\n    async onConnectionEstablished(resumeSession) {\n        if (resumeSession) {\n            const incomingSequenceNumber = this.previousIncomingChunkSequenceNumber.get();\n            this.arpLog.debug(`Sending connection info (resume=yes, sn-in=${incomingSequenceNumber})`);\n            this._sendConnectionInfo(this.currentConnectionId.buffer, this.previousConnectionId.buffer, incomingSequenceNumber);\n        }\n        else {\n            this.arpLog.debug('Sending connection info (resume=no)');\n            this._sendConnectionInfo(this.currentConnectionId.buffer);\n        }\n        let remoteInfo;\n        try {\n            remoteInfo = await this.connectionInfoFuture;\n        }\n        catch (error) {\n            this.arpLog.error(error);\n            this.failSession();\n            return;\n        }\n        let outgoingSequenceNumber = 'n/a';\n        let remoteResume = 'no';\n        if (remoteInfo.resume !== undefined) {\n            outgoingSequenceNumber = remoteInfo.resume.sequenceNumber;\n            remoteResume = 'yes';\n        }\n        this.arpLog.debug(`Received connection info (resume=${remoteResume}, ` +\n            `sn-out=${outgoingSequenceNumber})`);\n        let sessionWasResumed;\n        try {\n            sessionWasResumed = this.maybeResumeSession(resumeSession, remoteInfo);\n        }\n        catch (error) {\n            this.arpLog.error(error);\n            this.failSession();\n            return;\n        }\n        this.handshakeCompleted = true;\n        const requiredInitializationSteps = [];\n        if (!resumeSession || !sessionWasResumed) {\n            this.discardSession({ resetMessageSequenceNumber: false });\n            this.arpLog.debug('Session discarded');\n            this.clearCache();\n            this.wireMessageFutures.clear();\n            this.timeoutService.cancelAll();\n            requiredInitializationSteps.push(\"client info\", \"conversations\", \"receivers\", \"profile\");\n            this._requestInitialData();\n        }\n        else {\n            this.arpLog.debug('Session resumed');\n        }\n        if (this.startupPromise !== null) {\n            this.runAfterInitializationSteps(requiredInitializationSteps, () => {\n                this.stateService.updateConnectionBuildupState('done');\n                this.startupPromise.resolve();\n                this.startupPromise = null;\n                this.startupDone = true;\n                this._resetInitializationSteps();\n                if (this.chosenTask !== \"relayed-data\" && this.$state.includes('messenger')) {\n                    this.$state.reload().catch((error) => {\n                        this.log.error('Unable to reload state:', error);\n                    });\n                }\n            });\n        }\n        if (resumeSession && !sessionWasResumed && this.clientInfo !== null) {\n            this.$rootScope.$apply(() => {\n                if (this.chosenTask !== \"relayed-data\") {\n                    return;\n                }\n                if (this.$state.includes('messenger')) {\n                    this.$state.go('messenger.home');\n                }\n            });\n        }\n        this.timeoutService.register(() => this.versionService.checkForUpdate(), 7000, true, 'checkForUpdate');\n        this.stateService.updateConnectionBuildupState('loading');\n    }\n    onHandover(resumeSession) {\n        this.log.debug('Initializing NotificationService...');\n        this.notificationService.init();\n        const connectionIdBox = this.salty.encryptForPeer(new Uint8Array(0), WebClientService.CONNECTION_ID_NONCE);\n        this.currentConnectionId = new Uint8Array(connectionIdBox.data);\n        if (this.chosenTask === \"webrtc\") {\n            const task = this.salty.getTask();\n            this.arpLog.debug(`Creating data channel ${WebClientService.DC_LABEL}`);\n            const pc = this.pcHelper.pc;\n            const dc = pc.createDataChannel(WebClientService.DC_LABEL);\n            dc.binaryType = 'arraybuffer';\n            this.secureDataChannel = new UnboundedFlowControlledDataChannel(dc, this.logService, this.config.TRANSPORT_LOG_LEVEL);\n            this.secureDataChannelCrypto = task.createCryptoContext(dc.id);\n            const unchunker = new chunkedDc.UnreliableUnorderedUnchunker();\n            dc.onopen = () => {\n                this.arpLog.info(`Data channel ${dc.label} open`);\n                this.secureDataChannelChunkLength = Math.min(WebClientService.DATA_CHANNEL_MAX_CHUNK_SIZE, pc.sctp.maxMessageSize);\n                this.arpLog.debug(`Using chunk length: ${this.secureDataChannelChunkLength} for data channel` +\n                    dc.label);\n                this.onConnectionEstablished(resumeSession).catch((error) => {\n                    this.arpLog.error('Error during handshake:', error);\n                });\n            };\n            dc.onclose = () => {\n                this.arpLog.warn(`Data channel ${dc.label} closed (ICE state: ${pc.iceConnectionState})`);\n            };\n            dc.onerror = (event) => {\n                this.arpLog.warn(`Data channel ${dc.label} error (closed=${dc.onclose === null}):`, event.error);\n            };\n            dc.onmessage = (event) => {\n                this.arpLogV.debug(`Data channel ${dc.label} incoming chunk of length ${event.data.byteLength}`);\n                unchunker.add(new Uint8Array(event.data));\n            };\n            unchunker.onMessage = (array) => {\n                const box = saltyrtcClient.Box.fromUint8Array(array, saltyrtcTaskWebrtc.DataChannelCryptoContext.NONCE_LENGTH);\n                const message = this.secureDataChannelCrypto.decrypt(box);\n                this.handleIncomingMessageBytes(message);\n            };\n            this.handoverDone = true;\n        }\n        else if (this.chosenTask === \"relayed-data\") {\n            this.relayedDataTask.on('data', (ev) => {\n                this.receiveChunk(new Uint8Array(ev.data));\n            });\n            this.onConnectionEstablished(resumeSession).catch((error) => {\n                this.arpLog.error('Error during handshake:', error);\n            });\n        }\n    }\n    onPeerDisconnected(peerId) {\n        switch (this.chosenTask) {\n            case \"relayed-data\":\n                if (this.stateService.taskConnectionState === \"connected\") {\n                    this.stateService.updateTaskConnectionState(\"reconnecting\");\n                }\n                else {\n                    this.arpLog.debug('Ignoring peer-disconnected event (state is '\n                        + this.stateService.taskConnectionState + ')');\n                }\n                break;\n            default:\n                this.arpLog.debug('Ignoring peer-disconnected event (chosen task is ' + this.chosenTask + ')');\n        }\n    }\n    sendPush() {\n        if (this.pushSession === null) {\n            this.pushSession = this.pushService.createSession(this.salty.permanentKeyBytes, this.pushSessionConfig);\n            this.pushPromise = this.pushSession.start()\n                .then(() => this.resetPushSession(true))\n                .catch((error) => {\n                this.resetPushSession(false);\n                if (error instanceof TimeoutError) {\n                    this.showDeviceUnreachableDialog();\n                }\n                else if (error instanceof PushError && error.statusCode === 400) {\n                    this.showPushRejectedDialog();\n                }\n                else {\n                    this.failSession();\n                }\n            });\n            if (!this.$rootScope.$$phase) {\n                this.$rootScope.$apply(() => this.stateService.updateConnectionBuildupState('push'));\n            }\n            else {\n                this.stateService.updateConnectionBuildupState('push');\n            }\n        }\n        return [this.pushSessionExpectedPeriodMaxMs, this.pushPromise];\n    }\n    resetPushSession(hideDeviceUnreachableDialog = true) {\n        if (hideDeviceUnreachableDialog && this.deviceUnreachableDialog !== null) {\n            this.$mdDialog.hide();\n        }\n        if (this.pushSession !== null) {\n            this.pushSession.done();\n            this.pushSession = null;\n            this.pushPromise = null;\n        }\n    }\n    showDeviceUnreachableDialog() {\n        if (this.pushService.isAvailable() && this.$state.includes('messenger')\n            && this.deviceUnreachableDialog === null) {\n            this.deviceUnreachableDialog = this.$mdDialog.show({\n                controller: DeviceUnreachableController,\n                controllerAs: 'ctrl',\n                templateUrl: 'partials/dialog.device-unreachable.html',\n                parent: angular.element(document.body),\n                escapeToClose: false,\n            })\n                .finally(() => this.deviceUnreachableDialog = null);\n        }\n    }\n    showPushRejectedDialog() {\n        this.$mdDialog.show({\n            controller: PushRejectedDialogController,\n            controllerAs: 'ctrl',\n            templateUrl: 'partials/dialog.push-rejected.html',\n            parent: angular.element(document.body),\n            escapeToClose: false,\n        });\n    }\n    start(skipPush = false) {\n        this.log.debug('Starting WebClientService...');\n        if (this.startupPromise !== null) {\n            this.log.debug('Reusing startup promise (was not resolved)');\n        }\n        else {\n            this.log.debug('Creating new startup promise');\n            this.startupPromise = this.$q.defer();\n        }\n        this.startupDone = false;\n        this.handoverDone = false;\n        this.salty.connect();\n        if (this.pushService.isAvailable()) {\n            if (skipPush === true) {\n                this.log.debug('start(): Skipping push notification');\n            }\n            else {\n                this.sendPush();\n            }\n        }\n        else if (this.trustedKeyStore.hasTrustedKey()) {\n            this.log.debug('Push service not available');\n            this.stateService.updateConnectionBuildupState('manual_start');\n        }\n        return this.startupPromise.promise;\n    }\n    stop(args) {\n        if (args.close === true) {\n            throw new Error('args.close has been set to \"true\" but requires a redirect state instead');\n        }\n        this.log.info(`Stopping (reason=${args.reason}, send=${args.send}, close=${args.close}, ` +\n            'connectionBuildupState=' +\n            `${args.connectionBuildupState !== undefined ? args.connectionBuildupState : 'n/a'})`);\n        let close = args.close !== false;\n        let remove = false;\n        this.resetPushSession(true);\n        if (args.reason === \"delete\") {\n            close = true;\n            remove = true;\n        }\n        if (args.reason === \"replace\" || args.reason === \"oom\" ||\n            args.reason === \"error\") {\n            close = true;\n        }\n        if (args.send && this.stateService.state === \"ok\") {\n            this.sendUpdateWireMessage(WebClientService.SUB_TYPE_CONNECTION_DISCONNECT, false, undefined, { reason: args.reason });\n        }\n        if (this.ackTimer !== null) {\n            self.clearTimeout(this.ackTimer);\n            this.ackTimer = null;\n        }\n        if (this.pushTimer !== null) {\n            this.cancelPush(0);\n        }\n        this.log.debug('Timer stopped');\n        this.stateService.reset(args.connectionBuildupState);\n        this.resetUnreadCount();\n        if (remove) {\n            this.trustedKeyStore.clearTrustedKey();\n        }\n        if (close) {\n            this.previousConnectionId = null;\n            this.previousIncomingChunkSequenceNumber = null;\n            this.previousChunkCache = null;\n            this.chosenTask = \"none\";\n            this.clientInfo = null;\n            this.clearCache();\n            this.wireMessageFutures.clear();\n            this.timeoutService.cancelAll();\n            this.pushService.reset();\n            this.arpLog.debug('Session closed (cannot be resumed)');\n        }\n        else {\n            if (this.handshakeCompleted) {\n                this.previousConnectionId = this.currentConnectionId;\n                this.previousIncomingChunkSequenceNumber = this.currentIncomingChunkSequenceNumber;\n                this.previousChunkCache = this.currentChunkCache;\n            }\n            this.arpLog.debug('Session remains open');\n        }\n        if (this.secureDataChannel !== null) {\n            this.arpLog.debug('Closing data channel');\n            this.secureDataChannel.dc.onopen = null;\n            this.secureDataChannel.dc.onmessage = null;\n            this.secureDataChannel.dc.onbufferedamountlow = null;\n            this.secureDataChannel.dc.onerror = null;\n            this.secureDataChannel.dc.onclose = null;\n            this.secureDataChannel.dc.close();\n        }\n        if (this.relayedDataTask !== null) {\n            this.relayedDataTask.off();\n        }\n        if (this.salty !== null) {\n            this.arpLog.debug('Closing signaling');\n            this.salty.off();\n            this.salty.disconnect(true);\n        }\n        if (this.pcHelper !== null) {\n            this.pcHelper.onConnectionStateChange = null;\n            this.pcHelper.close();\n            this.arpLog.debug('Peer connection closed');\n        }\n        else {\n            this.arpLog.debug('Peer connection was null');\n        }\n        if (close) {\n            if (this.startupPromise !== null) {\n                this.startupPromise.reject();\n                this.startupPromise = null;\n                this._resetInitializationSteps();\n            }\n            const state = args.close !== false ? args.close : 'welcome';\n            this.$state.go(state);\n        }\n    }\n    registerInitializationStep(name) {\n        if (this.initialized.has(name)) {\n            this.arpLog.warn('Initialization step \"' + name + '\" already registered');\n            return;\n        }\n        this.arpLog.debug('Initialization step \"' + name + '\" done');\n        this.initialized.add(name);\n        for (const routine of this.pendingInitializationStepRoutines) {\n            const ready = routine.requiredSteps.every((requiredStep) => {\n                return this.initialized.has(requiredStep);\n            });\n            if (ready) {\n                this.arpLog.debug('Running routine after initialization \"' + name + '\" completed');\n                this.pendingInitializationStepRoutines.delete(routine);\n                routine.callback.apply(this);\n            }\n        }\n    }\n    setReceiverListener(listener) {\n        this.receiverListener.push(listener);\n    }\n    _sendConnectionInfo(connectionId, resumeId, sequenceNumber) {\n        const data = { id: connectionId };\n        if (resumeId !== undefined && sequenceNumber !== undefined) {\n            data.resume = {\n                id: resumeId,\n                sequenceNumber: sequenceNumber,\n            };\n        }\n        this.sendUpdateWireMessage(WebClientService.SUB_TYPE_CONNECTION_INFO, false, undefined, data);\n    }\n    _requestConnectionAck() {\n        this.sendRequestWireMessage(WebClientService.SUB_TYPE_CONNECTION_ACK, false);\n    }\n    _sendConnectionAck() {\n        this.sendUpdateWireMessage(WebClientService.SUB_TYPE_CONNECTION_ACK, false, undefined, {\n            sequenceNumber: this.currentIncomingChunkSequenceNumber.get(),\n        });\n        if (this.ackTimer !== null) {\n            self.clearTimeout(this.ackTimer);\n            this.ackTimer = null;\n        }\n    }\n    requestClientInfo() {\n        this.arpLog.debug('Sending client info request');\n        const browser = this.browserService.getBrowser();\n        const data = {\n            [WebClientService.ARGUMENT_USER_AGENT]: navigator.userAgent,\n        };\n        if (browser.name) {\n            data[WebClientService.ARGUMENT_BROWSER_NAME] = browser.name;\n        }\n        if (browser.version) {\n            data[WebClientService.ARGUMENT_BROWSER_VERSION] = browser.version;\n        }\n        const subType = WebClientService.SUB_TYPE_CLIENT_INFO;\n        this.sendRequestWireMessage(subType, !this.requiresTemporaryIdBackwardsCompatibility, undefined, data)\n            .catch(this.failSessionOnReject(WebClientService.TYPE_REQUEST, subType));\n    }\n    requestReceivers() {\n        this.arpLog.debug('Sending receivers request');\n        const subType = WebClientService.SUB_TYPE_RECEIVERS;\n        this.sendRequestWireMessage(subType, !this.requiresTemporaryIdBackwardsCompatibility)\n            .catch(this.failSessionOnReject(WebClientService.TYPE_REQUEST, subType));\n    }\n    requestConversations() {\n        this.arpLog.debug('Sending conversation request');\n        const subType = WebClientService.SUB_TYPE_CONVERSATIONS;\n        const args = { [WebClientService.ARGUMENT_MAX_SIZE]: WebClientService.AVATAR_LOW_MAX_SIZE };\n        this.sendRequestWireMessage(subType, !this.requiresTemporaryIdBackwardsCompatibility, args)\n            .catch(this.failSessionOnReject(WebClientService.TYPE_REQUEST, subType));\n    }\n    requestBatteryStatus() {\n        this.arpLog.debug('Sending battery status request');\n        const subType = WebClientService.SUB_TYPE_BATTERY_STATUS;\n        this.sendRequestWireMessage(subType, !this.requiresTemporaryIdBackwardsCompatibility)\n            .catch(this.failSessionOnReject(WebClientService.TYPE_REQUEST, subType));\n    }\n    requestProfile() {\n        this.arpLog.debug('Sending profile request');\n        const subType = WebClientService.SUB_TYPE_PROFILE;\n        this.sendRequestWireMessage(subType, !this.requiresTemporaryIdBackwardsCompatibility)\n            .catch(this.failSessionOnReject(WebClientService.TYPE_REQUEST, subType));\n    }\n    requestMessages(receiver) {\n        this.arpLog.debug('requestMessages');\n        if (!this.messages.hasMore(receiver)) {\n            this.messages.notify(receiver, this.$rootScope);\n            this.arpLog.debug('requestMessages: No more messages available');\n            return null;\n        }\n        this.loadingMessages.set(receiver.type + receiver.id, true);\n        if (this.messages.isRequested(receiver)) {\n            this.arpLog.debug('requestMessages: Already requested');\n            return null;\n        }\n        const refMsgId = this.messages.getReferenceMsgId(receiver);\n        this.messages.setRequested(receiver);\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,\n            [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,\n        };\n        const msgId = this.messages.getReferenceMsgId(receiver);\n        if (msgId !== null) {\n            args[WebClientService.ARGUMENT_REFERENCE_MSG_ID] = msgId;\n        }\n        this.arpLog.debug('Sending message request for', receiver.type, receiver.id, 'with message id', msgId);\n        const subType = WebClientService.SUB_TYPE_MESSAGES;\n        this.sendRequestWireMessage(subType, !this.requiresTemporaryIdBackwardsCompatibility, args)\n            .catch(this.logOnReject(WebClientService.TYPE_REQUEST, subType));\n        return refMsgId;\n    }\n    requestAvatar(receiver, highResolution) {\n        const resolution = highResolution ? 'high' : 'low';\n        const receiverInfo = this.receivers.getData(receiver);\n        if (receiverInfo && receiverInfo.avatar && receiverInfo.avatar[resolution]) {\n            return Promise.resolve(receiverInfo.avatar[resolution]);\n        }\n        let receiverType = receiver.type;\n        if (receiverType === 'me') {\n            receiverType = 'contact';\n        }\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiverType,\n            [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,\n            [WebClientService.ARGUMENT_AVATAR_HIGH_RESOLUTION]: highResolution,\n        };\n        if (!highResolution) {\n            args[WebClientService.ARGUMENT_MAX_SIZE] = WebClientService.AVATAR_LOW_MAX_SIZE;\n        }\n        this.arpLog.debug('Sending', resolution, 'res avatar request for', receiver.type, receiver.id);\n        const subType = WebClientService.SUB_TYPE_AVATAR;\n        return this.sendRequestWireMessage(subType, true, args);\n    }\n    requestThumbnail(receiver, message) {\n        if (message.thumbnail !== undefined && message.thumbnail.img !== undefined) {\n            return new Promise((e) => {\n                e(message.thumbnail.img);\n            });\n        }\n        const args = {\n            [WebClientService.ARGUMENT_MESSAGE_ID]: message.id.toString(),\n            [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,\n            [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,\n        };\n        this.arpLog.debug('Sending thumbnail request for', receiver.type, message.id);\n        const subType = WebClientService.SUB_TYPE_THUMBNAIL;\n        return this.sendRequestWireMessage(subType, true, args);\n    }\n    requestBlob(msgId, receiver) {\n        const cached = this.blobCache.get(msgId + receiver.type);\n        if (cached !== undefined) {\n            this.arpLog.debug('Use cached blob');\n            return new Promise((resolve) => {\n                resolve(cached);\n            });\n        }\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,\n            [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,\n            [WebClientService.ARGUMENT_MESSAGE_ID]: msgId,\n        };\n        this.arpLog.debug('Sending blob request for message', msgId);\n        return this.sendRequestWireMessage(WebClientService.SUB_TYPE_BLOB, true, args);\n    }\n    requestRead(receiver, newestMessage) {\n        if (newestMessage.id === undefined) {\n            this.arpLog.warn('Called requestRead on a message without id');\n            return;\n        }\n        if (newestMessage.type === 'status') {\n            this.arpLog.warn('Called requestRead on a status message');\n            return;\n        }\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,\n            [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,\n            [WebClientService.ARGUMENT_MESSAGE_ID]: newestMessage.id.toString(),\n        };\n        this.arpLog.debug('Sending read request for', receiver.type, receiver.id, '(msg ' + newestMessage.id + ')');\n        const subType = WebClientService.SUB_TYPE_READ;\n        this.sendRequestWireMessage(subType, !this.requiresTemporaryIdBackwardsCompatibility, args)\n            .catch(this.logOnReject(WebClientService.TYPE_REQUEST, subType));\n    }\n    requestContactDetail(contactReceiver) {\n        const args = {\n            [WebClientService.ARGUMENT_IDENTITY]: contactReceiver.id,\n        };\n        return this.sendRequestWireMessage(WebClientService.SUB_TYPE_CONTACT_DETAIL, true, args);\n    }\n    async sendMessage(baseReceiver, sendType, data, options = {}) {\n        let reflectedType;\n        const receiver = this.receivers.getData(baseReceiver);\n        if (isContactReceiver(receiver)) {\n            if (receiver.isBlocked) {\n                throw this.$translate.instant('error.CONTACT_BLOCKED');\n            }\n            if (receiver.state === 'INVALID') {\n                throw this.$translate.instant('error.CONTACT_INVALID');\n            }\n        }\n        let subType;\n        switch (sendType) {\n            case 'text':\n                reflectedType = 'text';\n                subType = WebClientService.SUB_TYPE_TEXT_MESSAGE;\n                const textData = data;\n                const msgLength = textData.text.length;\n                if (msgLength === 0) {\n                    this.log.warn('Ignored empty text message');\n                    throw this.$translate.instant('error.ERROR_OCCURRED');\n                }\n                break;\n            case 'file':\n                const fileData = data;\n                if (this.chosenTask === \"webrtc\") {\n                    const task = this.salty.getTask();\n                    if (task.version === 'v0' && fileData.size > WebClientService.MAX_FILE_SIZE_WEBRTC_TASK_V0) {\n                        throw this.$translate.instant('error.FILE_TOO_LARGE_WEB');\n                    }\n                }\n                else {\n                    if (fileData.size > this.clientInfo.capabilities.maxFileSize) {\n                        throw this.$translate.instant('error.FILE_TOO_LARGE', {\n                            maxmb: Math.floor(this.clientInfo.capabilities.maxFileSize / 1024 / 1024),\n                        });\n                    }\n                }\n                reflectedType = 'file';\n                let requiredFeature = 8;\n                let invalidFeatureMessage = 'error.FILE_MESSAGES_NOT_SUPPORTED';\n                if (fileData.sendAsFile !== true) {\n                    const mimeType = fileData.fileType;\n                    if (this.mimeService.isAudio(mimeType, this.clientInfo.os)) {\n                        reflectedType = 'audio';\n                        requiredFeature = 1;\n                        invalidFeatureMessage = 'error.AUDIO_MESSAGES_NOT_SUPPORTED';\n                    }\n                    else if (this.mimeService.isImage(mimeType)) {\n                        reflectedType = 'image';\n                        requiredFeature = 0;\n                    }\n                    else if (this.mimeService.isVideo(mimeType)) {\n                        reflectedType = 'video';\n                        requiredFeature = 0;\n                    }\n                }\n                subType = WebClientService.SUB_TYPE_FILE_MESSAGE;\n                switch (receiver.type) {\n                    case 'group':\n                    case 'distributionList':\n                        const unsupportedMembers = [];\n                        let members;\n                        switch (receiver.type) {\n                            case 'group':\n                                const group = this.groups.get(receiver.id);\n                                if (group === undefined) {\n                                    this.log.error(`Group ${receiver.id} not found`);\n                                    throw this.$translate.instant('error.ERROR_OCCURRED');\n                                }\n                                members = group.members;\n                                break;\n                            case 'distributionList':\n                                const distributionList = this.distributionLists.get(receiver.id);\n                                if (distributionList === undefined) {\n                                    this.log.error(`Distribution list ${receiver.id} not found`);\n                                    throw this.$translate.instant('error.ERROR_OCCURRED');\n                                }\n                                members = distributionList.members;\n                                break;\n                        }\n                        for (const identity of members) {\n                            if (identity !== this.me.id) {\n                                const contact = this.contacts.get(identity);\n                                if (contact === undefined) {\n                                    this.log.error(`Cannot retrieve contact ${identity}`);\n                                }\n                                else if (!hasFeature(contact, requiredFeature, this.log)) {\n                                    this.log.warn(`Contact ${identity} has feature masks ${contact.featureMask} ` +\n                                        `which does not include ${requiredFeature}`);\n                                    unsupportedMembers.push(contact.displayName);\n                                }\n                            }\n                        }\n                        if (unsupportedMembers.length > 0) {\n                            throw this.$translate.instant(invalidFeatureMessage, { receiverName: unsupportedMembers.join(',') });\n                        }\n                        break;\n                    case 'contact':\n                        const contact = this.contacts.get(receiver.id);\n                        if (contact === undefined) {\n                            this.log.error('Cannot retrieve contact');\n                            throw this.$translate.instant('error.ERROR_OCCURRED');\n                        }\n                        else if (!hasFeature(contact, requiredFeature, this.log)) {\n                            this.log.debug('Cannot send message: Feature level mismatch:', contact.featureMask, 'does not include', requiredFeature);\n                            throw this.$translate.instant(invalidFeatureMessage, {\n                                receiverName: contact.displayName\n                            });\n                        }\n                        break;\n                    default:\n                        this.log.error('Invalid receiver type:', receiver.type);\n                        throw this.$translate.instant('error.ERROR_OCCURRED');\n                }\n                break;\n            default:\n                this.log.error('Invalid message type:', sendType);\n                throw this.$translate.instant('error.ERROR_OCCURRED');\n        }\n        if (this.messages.getList(receiver).length === 0) {\n            await this.requestMessages(receiver);\n        }\n        const id = this.createRandomWireMessageId();\n        let temporaryMessage;\n        try {\n            temporaryMessage = this.messageService.createTemporary(id, receiver, reflectedType, data, options.previewDataUrl);\n        }\n        catch (error) {\n            this.log.error(error);\n            throw this.$translate.instant('error.ERROR_OCCURRED');\n        }\n        this.messages.addNewer(receiver, [temporaryMessage]);\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,\n            [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,\n        };\n        const sendPromise = this.sendCreateWireMessage(subType, true, args, data, id);\n        sendPromise.catch((error) => {\n            this.arpLog.error('Error sending message:', error);\n            this.messages.removeTemporary(receiver, temporaryMessage.temporaryId);\n            let errorMessage;\n            switch (error) {\n                case 'fileTooLarge':\n                    errorMessage = this.$translate.instant('error.FILE_TOO_LARGE_GENERIC');\n                    break;\n                case 'valueTooLong':\n                    errorMessage = this.$translate.instant('validationError.modifyReceiver.valueTooLong');\n                    break;\n                case 'blocked':\n                    errorMessage = this.$translate.instant('error.CONTACT_BLOCKED');\n                    break;\n                default:\n                    errorMessage = this.$translate.instant('error.ERROR_OCCURRED');\n            }\n            this.alerts.push({\n                source: 'sendMessage',\n                type: 'alert',\n                message: errorMessage,\n            });\n        });\n        if (options.waitUntilAcknowledged) {\n            await sendPromise;\n        }\n    }\n    ackMessage(receiver, message, acknowledged = true) {\n        if (message === null\n            || message === undefined\n            || message.isOutbox) {\n            return;\n        }\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,\n            [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,\n            [WebClientService.ARGUMENT_MESSAGE_ID]: message.id.toString(),\n            [WebClientService.ARGUMENT_MESSAGE_ACKNOWLEDGED]: acknowledged,\n        };\n        const subType = WebClientService.SUB_TYPE_ACK;\n        this.sendRequestWireMessage(subType, !this.requiresTemporaryIdBackwardsCompatibility, args)\n            .catch(this.logOnReject(WebClientService.TYPE_REQUEST, subType));\n    }\n    deleteMessage(receiver, message) {\n        if (message === null || message === undefined) {\n            return;\n        }\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,\n            [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,\n            [WebClientService.ARGUMENT_MESSAGE_ID]: message.id.toString(),\n        };\n        const subType = WebClientService.SUB_TYPE_MESSAGE;\n        this.sendDeleteWireMessage(subType, true, args)\n            .catch(this.logOnReject(WebClientService.TYPE_DELETE, subType));\n    }\n    sendMeIsTyping(receiver, isTyping) {\n        const args = { [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id };\n        const data = { [WebClientService.ARGUMENT_IS_TYPING]: isTyping };\n        this.sendUpdateWireMessage(WebClientService.SUB_TYPE_TYPING, false, args, data);\n    }\n    sendKeyPersisted() {\n        const subType = WebClientService.SUB_TYPE_KEY_PERSISTED;\n        this.sendRequestWireMessage(subType, !this.requiresTemporaryIdBackwardsCompatibility)\n            .catch(this.logOnReject(WebClientService.TYPE_REQUEST, subType));\n    }\n    addContact(threemaId) {\n        const data = {\n            [WebClientService.ARGUMENT_IDENTITY]: threemaId,\n        };\n        const subType = WebClientService.SUB_TYPE_CONTACT;\n        return this.sendCreateWireMessage(subType, true, undefined, data);\n    }\n    modifyContact(threemaId, firstName, lastName, avatar) {\n        const data = {};\n        if (firstName !== undefined) {\n            data[WebClientService.ARGUMENT_FIRST_NAME] = firstName;\n        }\n        if (lastName !== undefined) {\n            data[WebClientService.ARGUMENT_LAST_NAME] = lastName;\n        }\n        if (avatar !== undefined) {\n            data[WebClientService.ARGUMENT_AVATAR] = avatar;\n        }\n        const contact = this.contacts.get(threemaId);\n        if (Object.keys(data).length === 0) {\n            this.arpLog.warn('Trying to modify contact without any changes');\n            return Promise.resolve(contact);\n        }\n        const args = {\n            [WebClientService.ARGUMENT_IDENTITY]: threemaId,\n        };\n        const subType = WebClientService.SUB_TYPE_CONTACT;\n        const promise = this.sendUpdateWireMessage(subType, true, args, data);\n        if (avatar !== undefined) {\n            this.contacts.get(threemaId).avatar = {};\n            this.requestAvatar(contact, false);\n        }\n        return promise;\n    }\n    modifyConversation(conversation, isPinned) {\n        const DATA_STARRED = 'isStarred';\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_TYPE]: conversation.type,\n            [WebClientService.ARGUMENT_RECEIVER_ID]: conversation.id,\n        };\n        const data = {};\n        if (hasValue(isPinned)) {\n            data[DATA_STARRED] = isPinned;\n        }\n        if (Object.keys(data).length === 0) {\n            this.arpLog.warn('Trying to modify conversation without any changes');\n            return Promise.resolve(null);\n        }\n        const subType = WebClientService.SUB_TYPE_CONVERSATION;\n        return this.sendUpdateWireMessage(subType, true, args, data);\n    }\n    createGroup(members, name = null, avatar) {\n        const data = {\n            [WebClientService.ARGUMENT_MEMBERS]: members,\n            [WebClientService.ARGUMENT_NAME]: name,\n        };\n        if (hasValue(avatar)) {\n            data[WebClientService.ARGUMENT_AVATAR] = avatar;\n        }\n        const subType = WebClientService.SUB_TYPE_GROUP;\n        return this.sendCreateWireMessage(subType, true, undefined, data);\n    }\n    modifyGroup(id, members, name, avatar) {\n        const data = {\n            [WebClientService.ARGUMENT_MEMBERS]: members,\n        };\n        if (name !== undefined) {\n            data[WebClientService.ARGUMENT_NAME] = name;\n        }\n        if (avatar !== undefined) {\n            data[WebClientService.ARGUMENT_AVATAR] = avatar;\n        }\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_ID]: id,\n        };\n        const subType = WebClientService.SUB_TYPE_GROUP;\n        const promise = this.sendUpdateWireMessage(subType, true, args, data);\n        if (avatar !== undefined) {\n            this.groups.get(id).avatar = {};\n        }\n        return promise;\n    }\n    leaveGroup(group) {\n        if (group === null || group === undefined || !group.access.canLeave) {\n            return Promise.reject('not allowed');\n        }\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_ID]: group.id,\n            [WebClientService.ARGUMENT_DELETE_TYPE]: WebClientService.DELETE_GROUP_TYPE_LEAVE,\n        };\n        const subType = WebClientService.SUB_TYPE_GROUP;\n        return this.sendDeleteWireMessage(subType, true, args);\n    }\n    deleteGroup(group) {\n        if (group === null || group === undefined || !group.access.canDelete) {\n            return Promise.reject('not allowed');\n        }\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_ID]: group.id,\n            [WebClientService.ARGUMENT_DELETE_TYPE]: WebClientService.DELETE_GROUP_TYPE_DELETE,\n        };\n        const subType = WebClientService.SUB_TYPE_GROUP;\n        return this.sendDeleteWireMessage(subType, true, args);\n    }\n    syncGroup(group) {\n        if (group === null || group === undefined || !group.access.canSync) {\n            return Promise.reject('not allowed');\n        }\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_ID]: group.id,\n        };\n        const subType = WebClientService.SUB_TYPE_GROUP_SYNC;\n        return this.sendRequestWireMessage(subType, true, args);\n    }\n    createDistributionList(members, name = null) {\n        const data = {\n            [WebClientService.ARGUMENT_MEMBERS]: members,\n            [WebClientService.ARGUMENT_NAME]: name,\n        };\n        const subType = WebClientService.SUB_TYPE_DISTRIBUTION_LIST;\n        return this.sendCreateWireMessage(subType, true, undefined, data);\n    }\n    modifyDistributionList(id, members, name = null) {\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_ID]: id,\n        };\n        const data = {\n            [WebClientService.ARGUMENT_MEMBERS]: members,\n            [WebClientService.ARGUMENT_NAME]: name,\n        };\n        const subType = WebClientService.SUB_TYPE_DISTRIBUTION_LIST;\n        return this.sendUpdateWireMessage(subType, true, args, data);\n    }\n    deleteDistributionList(distributionList) {\n        if (distributionList === null || distributionList === undefined || !distributionList.access.canDelete) {\n            return Promise.reject('not allowed');\n        }\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_ID]: distributionList.id,\n        };\n        const subType = WebClientService.SUB_TYPE_DISTRIBUTION_LIST;\n        return this.sendDeleteWireMessage(subType, true, args);\n    }\n    cleanReceiverConversation(receiver) {\n        if (receiver === null || receiver === undefined) {\n            return Promise.reject('invalidIdentity');\n        }\n        const args = {\n            [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,\n            [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,\n        };\n        const subType = WebClientService.SUB_TYPE_CLEAN_RECEIVER_CONVERSATION;\n        return this.sendDeleteWireMessage(subType, true, args);\n    }\n    modifyProfile(nickname, avatar) {\n        const data = {};\n        if (nickname !== undefined && nickname !== null) {\n            data[WebClientService.ARGUMENT_NICKNAME] = nickname;\n        }\n        if (avatar !== undefined) {\n            data[WebClientService.ARGUMENT_AVATAR] = avatar;\n        }\n        if (Object.keys(data).length === 0) {\n            this.arpLog.warn('Trying to modify profile without any changes');\n            return Promise.resolve(null);\n        }\n        const subType = WebClientService.SUB_TYPE_PROFILE;\n        return this.sendUpdateWireMessage(subType, true, undefined, data);\n    }\n    isTyping(contact) {\n        return this.typing.isTyping(contact);\n    }\n    getQuote(receiver) {\n        return this.drafts.getQuote(receiver);\n    }\n    setQuote(receiver, message) {\n        this.drafts.removeQuote(receiver);\n        if (message !== null) {\n            const quoteText = this.messageService.getQuoteText(message);\n            if (quoteText !== undefined && quoteText !== null) {\n                const quote = {\n                    identity: message.isOutbox ? this.me.id : message.partnerId,\n                    text: quoteText,\n                };\n                this.drafts.setQuote(receiver, quote);\n                this.$rootScope.$broadcast('onQuoted', {\n                    receiver: receiver,\n                    quote: quote,\n                });\n            }\n        }\n    }\n    setDraft(receiver, message = null) {\n        if (message === null || message.trim().length === 0) {\n            this.drafts.removeText(receiver);\n        }\n        else {\n            this.drafts.setText(receiver, message.trim());\n        }\n    }\n    getDraft(receiver) {\n        return this.drafts.getText(receiver);\n    }\n    _resetInitializationSteps() {\n        this.arpLog.debug('Reset initialization steps');\n        this.initialized.clear();\n        this.pendingInitializationStepRoutines = new Set();\n    }\n    _resetFields() {\n        this._resetInitializationSteps();\n        this.receivers = this.container.createReceivers();\n        this.conversations = this.container.createConversations();\n        this.messages = this.container.createMessages();\n        this.typingInstance = this.container.createTyping();\n        this.conversations.setConverter(this.container.Converter.addReceiverToConversation(this.receivers));\n        this.conversations.setFilter(this.container.Filters.hasData(this.receivers));\n    }\n    _requestInitialData() {\n        this.messages.clear(this.$rootScope);\n        this.requestClientInfo();\n        this.requestProfile();\n        this.requestReceivers();\n        this.requestConversations();\n        this.requestBatteryStatus();\n    }\n    _receiveResponseConfirmAction(message) {\n        this.arpLog.debug('Received confirmAction response');\n        const future = this.popWireMessageFuture(message);\n        if (!message.ack.success) {\n            future.reject(message.ack.error);\n        }\n        else {\n            future.resolve();\n        }\n    }\n    _receiveResponseReceivers(message) {\n        this.arpLog.debug('Received receivers response');\n        const future = this.popWireMessageFuture(message, this.requiresTemporaryIdBackwardsCompatibility);\n        if ((!this.requiresTemporaryIdBackwardsCompatibility && message.ack !== undefined) && !message.ack.success) {\n            future.reject(message.ack.error);\n        }\n        const data = message.data;\n        if (data === undefined) {\n            this.arpLog.warn('Invalid receivers response, data missing');\n            return future.reject('invalidResponse');\n        }\n        this.runAfterInitializationSteps([\n            \"profile\",\n        ], () => {\n            this.sortContacts(data.contact);\n            this.receivers.set(data);\n            this.registerInitializationStep(\"receivers\");\n            future.resolve();\n        });\n    }\n    _receiveResponseContactDetail(message) {\n        this.arpLog.debug('Received contact detail response');\n        const future = this.popWireMessageFuture(message);\n        if (!message.ack.success) {\n            return future.reject(message.ack.error);\n        }\n        const args = message.args;\n        const data = message.data;\n        if (args === undefined || data === undefined) {\n            this.arpLog.error('Invalid contact response, args or data missing');\n            return future.reject('invalidResponse');\n        }\n        const contactReceiver = this.receivers.contacts\n            .get(args[WebClientService.ARGUMENT_IDENTITY]);\n        const receiver = data[WebClientService.SUB_TYPE_RECEIVER];\n        if (hasValue(receiver)) {\n            contactReceiver.systemContact =\n                receiver[WebClientService.ARGUMENT_SYSTEM_CONTACT];\n        }\n        future.resolve(contactReceiver);\n    }\n    _receiveUpdateAlert(message) {\n        this.arpLog.debug('Received alert');\n        this.alerts.push({\n            source: message.args.source,\n            type: message.args.type,\n            message: message.data.message,\n        });\n    }\n    _receiveRequestConnectionAck(message) {\n        this._sendConnectionAck();\n    }\n    _receiveUpdateConnectionAck(message) {\n        this.arpLog.debug('Received connection ack');\n        if (!hasValue(message.data)) {\n            this.arpLog.warn('Invalid connectionAck message: data missing');\n            return;\n        }\n        if (!hasValue(message.data.sequenceNumber)) {\n            this.arpLog.warn('Invalid connectionAck message: sequenceNumber missing');\n            return;\n        }\n        const sequenceNumber = message.data.sequenceNumber;\n        const size = this.currentChunkCache.byteLength;\n        let result;\n        this.arpLog.debug(`Pruning cache (local-sn=${this.currentChunkCache.sequenceNumber.get()}, ` +\n            `remote-sn=${sequenceNumber})`);\n        try {\n            result = this.currentChunkCache.prune(sequenceNumber);\n        }\n        catch (error) {\n            this.arpLog.error(error);\n            this.failSession();\n            return;\n        }\n        this.arpLog.debug(`Chunk cache pruned, acknowledged: ${result.acknowledged}, left: ${result.left}, size: ` +\n            `${size} -> ${this.currentChunkCache.byteLength}`);\n        if (this.pendingAckRequest !== null && sequenceNumber >= this.pendingAckRequest) {\n            this.pendingAckRequest = null;\n        }\n    }\n    _receiveUpdateConnectionDisconnect(message) {\n        this.arpLog.debug('Received connectionDisconnect');\n        if (!hasValue(message.data) || !hasValue(message.data.reason)) {\n            this.arpLog.warn('Invalid connectionDisconnect message: data or reason missing');\n            return;\n        }\n        const reason = message.data.reason;\n        this.arpLog.debug(`Disconnecting requested (reason: ${reason})`);\n        let alertMessage;\n        switch (reason) {\n            case \"stop\":\n                alertMessage = 'connection.SESSION_STOPPED';\n                break;\n            case \"delete\":\n                alertMessage = 'connection.SESSION_DELETED';\n                break;\n            case \"disable\":\n                alertMessage = 'connection.WEBCLIENT_DISABLED';\n                break;\n            case \"replace\":\n                alertMessage = 'connection.SESSION_REPLACED';\n                break;\n            case \"oom\":\n                alertMessage = 'connection.OUT_OF_MEMORY';\n                break;\n            case \"error\":\n                alertMessage = 'connection.SESSION_ERROR';\n                break;\n            default:\n                alertMessage = 'connection.SESSION_ERROR';\n                this.arpLog.error('Unknown disconnect reason:', reason);\n                break;\n        }\n        const isWelcome = this.$state.includes('welcome');\n        this.stop({\n            reason: reason,\n            send: false,\n            close: 'welcome',\n        });\n        if (isWelcome) {\n            this.$state.reload().catch((error) => {\n                this.log.error('Unable to reload state:', error);\n            });\n        }\n        this.showAlert(alertMessage);\n    }\n    _receiveConnectionInfo(message) {\n        this.arpLog.debug('Received connectionInfo from device');\n        if (!hasValue(message.data)) {\n            this.connectionInfoFuture.reject('Invalid connectionInfo message: data missing');\n            return;\n        }\n        if (!hasValue(message.data.id)) {\n            this.connectionInfoFuture.reject('Invalid connectionInfo message: data.id is missing');\n            return;\n        }\n        if (!(message.data.id instanceof ArrayBuffer)) {\n            this.connectionInfoFuture.reject('Invalid connectionInfo message: data.id is of invalid type');\n            return;\n        }\n        const resume = message.data.resume;\n        if (resume !== undefined) {\n            if (!hasValue(resume.id)) {\n                this.connectionInfoFuture.reject('Invalid connectionInfo message: data.resume.id is missing');\n                return;\n            }\n            if (!hasValue(resume.sequenceNumber)) {\n                const error = 'Invalid connectionInfo message: data.resume.sequenceNumber is missing';\n                this.connectionInfoFuture.reject(error);\n                return;\n            }\n            if (!(resume.id instanceof ArrayBuffer)) {\n                this.connectionInfoFuture.reject('Invalid connectionInfo message: data.resume.id is of invalid type');\n                return;\n            }\n            if (resume.sequenceNumber < 0 || resume.sequenceNumber > WebClientService.SEQUENCE_NUMBER_MAX) {\n                const error = 'Invalid connectionInfo message: data.resume.sequenceNumber is invalid';\n                this.connectionInfoFuture.reject(error);\n                return;\n            }\n        }\n        this.connectionInfoFuture.resolve(message.data);\n    }\n    _receiveReplyReceiver(message, receiverType, future) {\n        this.arpLog.debug(`Received ${receiverType} ${message.subType}`);\n        if (message.ack !== undefined && !message.ack.success) {\n            return future.reject(message.ack.error);\n        }\n        const data = message.data;\n        if (data === undefined) {\n            this.arpLog.error(`Invalid ${receiverType} response, 'data' is missing`);\n            return future.reject('invalidResponse');\n        }\n        const receiver = data[WebClientService.SUB_TYPE_RECEIVER];\n        if (receiver.type === undefined) {\n            receiver.type = receiverType;\n        }\n        if (isContactReceiver(receiver)) {\n            this.receivers.extendContact(receiver);\n        }\n        else if (isGroupReceiver(receiver)) {\n            this.receivers.extendGroup(receiver);\n        }\n        else if (isDistributionListReceiver(receiver)) {\n            this.receivers.extendDistributionList(receiver);\n        }\n        future.resolve(receiver);\n    }\n    _receiveCreateContact(message) {\n        const future = this.popWireMessageFuture(message);\n        this._receiveReplyReceiver(message, 'contact', future);\n    }\n    _receiveCreateGroup(message) {\n        const future = this.popWireMessageFuture(message);\n        this._receiveReplyReceiver(message, 'group', future);\n    }\n    _receiveCreateDistributionList(message) {\n        const future = this.popWireMessageFuture(message);\n        this._receiveReplyReceiver(message, 'distributionList', future);\n    }\n    _receiveCreateMessage(wireMessage) {\n        this.arpLog.debug('Received create message response');\n        const future = this.popWireMessageFuture(wireMessage);\n        if (!wireMessage.ack.success) {\n            return future.reject(wireMessage.ack.error);\n        }\n        const args = wireMessage.args;\n        const data = wireMessage.data;\n        if (args === undefined || data === undefined) {\n            this.arpLog.warn('Invalid create message received, arguments or data missing');\n            return future.reject('invalidResponse');\n        }\n        const receiverType = args[WebClientService.ARGUMENT_RECEIVER_TYPE];\n        const receiverId = args[WebClientService.ARGUMENT_RECEIVER_ID];\n        const messageId = data[WebClientService.ARGUMENT_MESSAGE_ID];\n        if (receiverType === undefined || receiverId === undefined || messageId === undefined) {\n            this.arpLog.warn(\"Invalid create received: 'type', 'id' or 'messageId' missing\");\n            return future.reject('invalidResponse');\n        }\n        const receiver = {\n            type: receiverType,\n            id: receiverId,\n        };\n        const message = this.messages.bindTemporaryToMessageId(receiver, wireMessage.ack.id, messageId);\n        future.resolve(messageId);\n        if (!this.messageService.isSentOrSendingFailed(message)) {\n            const sentId = `${message.id}-sent`;\n            this.wireMessageFutures.set(sentId, new Future());\n            this.arpLogV.debug(`Added special wire message future: ${sentId}`);\n        }\n    }\n    _receiveResponseConversations(message) {\n        this.arpLog.debug('Received conversations response');\n        const future = this.popWireMessageFuture(message, this.requiresTemporaryIdBackwardsCompatibility);\n        if ((!this.requiresTemporaryIdBackwardsCompatibility && message.ack !== undefined) && !message.ack.success) {\n            future.reject(message.ack.error);\n        }\n        const data = message.data;\n        if (data === undefined) {\n            this.arpLog.warn('Invalid conversation response, data missing');\n            return future.reject('invalidResponse');\n        }\n        this.runAfterInitializationSteps([\n            \"receivers\",\n        ], () => {\n            for (const conversation of data) {\n                if (conversation.avatar !== undefined && conversation.avatar !== null) {\n                    const receiver = this.receivers.getData({\n                        id: conversation.id,\n                        type: conversation.type,\n                    });\n                    if (receiver !== undefined && receiver.avatar === undefined) {\n                        receiver.avatar = {\n                            low: conversation.avatar,\n                        };\n                    }\n                    delete conversation.avatar;\n                }\n            }\n            this.conversations.set(data);\n            this.updateUnreadCount();\n            this.registerInitializationStep(\"conversations\");\n            future.resolve();\n        });\n    }\n    _receiveResponseMessages(message) {\n        this.arpLog.debug('Received messages response');\n        const future = this.popWireMessageFuture(message, this.requiresTemporaryIdBackwardsCompatibility);\n        if ((!this.requiresTemporaryIdBackwardsCompatibility && message.ack !== undefined) && !message.ack.success) {\n            future.reject(message.ack.error);\n        }\n        const args = message.args;\n        const data = message.data;\n        if (args === undefined || data === undefined) {\n            this.arpLog.warn('Invalid messages response, data or arguments missing');\n            return future.reject('invalidResponse');\n        }\n        const type = args[WebClientService.ARGUMENT_RECEIVER_TYPE];\n        const id = args[WebClientService.ARGUMENT_RECEIVER_ID];\n        let more = args[WebClientService.ARGUMENT_HAS_MORE];\n        if (type === undefined || id === undefined || more === undefined) {\n            this.arpLog.warn('Invalid messages response, argument field missing');\n            return future.reject('invalidResponse');\n        }\n        if (!isValidReceiverType(type)) {\n            this.arpLog.warn('Invalid messages response, unknown receiver type (' + type + ')');\n            return future.reject('invalidResponse');\n        }\n        if (this.config.ARP_LOG_TRACE) {\n            this.logChatMessages(message.type, message.subType, type, id, 'new', data);\n        }\n        const receiver = { type: type, id: id };\n        if (data.length === 0) {\n            more = false;\n        }\n        this.loadingMessages.delete(receiver.type + receiver.id);\n        if (!this.messages.isRequested(receiver)) {\n            this.arpLog.warn(\"Ignoring message response that hasn't been requested\");\n            return future.reject('invalidResponse');\n        }\n        this.messages.addOlder(receiver, data);\n        this.messages.clearRequested(receiver);\n        this.messages.setMore(receiver, more);\n        this.messages.notify(receiver, this.$rootScope);\n        future.resolve();\n    }\n    _receiveResponseAvatar(message) {\n        this.arpLog.debug('Received avatar response');\n        const future = this.popWireMessageFuture(message);\n        if (!message.ack.success) {\n            future.reject(message.ack.error);\n        }\n        const args = message.args;\n        if (args === undefined) {\n            this.arpLog.warn('Invalid message response: arguments missing');\n            return future.reject('invalidResponse');\n        }\n        const avatar = message.data;\n        if (avatar === undefined) {\n            return future.resolve(null);\n        }\n        const type = args[WebClientService.ARGUMENT_RECEIVER_TYPE];\n        const id = args[WebClientService.ARGUMENT_RECEIVER_ID];\n        const highResolution = args[WebClientService.ARGUMENT_AVATAR_HIGH_RESOLUTION];\n        if (type === undefined || id === undefined || highResolution === undefined) {\n            this.arpLog.warn('Invalid avatar response, argument field missing');\n            return future.reject('invalidResponse');\n        }\n        const field = highResolution ? 'high' : 'low';\n        const receiverData = this.receivers.getData(args);\n        if (!hasValue(receiverData.avatar)) {\n            receiverData.avatar = {};\n        }\n        receiverData.avatar[field] = avatar;\n        future.resolve(avatar);\n    }\n    _receiveResponseThumbnail(message) {\n        this.arpLog.debug('Received thumbnail response');\n        const future = this.popWireMessageFuture(message);\n        if (!message.ack.success) {\n            future.reject(message.ack.error);\n        }\n        const args = message.args;\n        if (args === undefined) {\n            this.arpLog.warn('Invalid message response: arguments missing');\n            return future.reject('invalidResponse');\n        }\n        const thumbnail = message.data;\n        if (thumbnail === undefined) {\n            return future.resolve(null);\n        }\n        const type = args[WebClientService.ARGUMENT_RECEIVER_TYPE];\n        const id = args[WebClientService.ARGUMENT_RECEIVER_ID];\n        const messageId = args[WebClientService.ARGUMENT_MESSAGE_ID];\n        if (type === undefined || id === undefined || messageId === undefined) {\n            this.arpLog.warn('Invalid thumbnail response, argument field missing');\n            return future.reject('invalidResponse');\n        }\n        this.messages.setThumbnail(this.receivers.getData(args), messageId, thumbnail);\n        future.resolve(thumbnail);\n    }\n    _receiveResponseBlob(message) {\n        this.arpLog.debug('Received blob response');\n        const future = this.popWireMessageFuture(message);\n        if (!message.ack.success) {\n            return future.reject(message.ack.error);\n        }\n        const args = message.args;\n        const data = message.data;\n        if (args === undefined) {\n            this.arpLog.warn('Invalid message response, args missing');\n            return future.reject('invalidResponse');\n        }\n        const receiverType = args[WebClientService.ARGUMENT_RECEIVER_TYPE];\n        const receiverId = args[WebClientService.ARGUMENT_RECEIVER_ID];\n        const msgId = args[WebClientService.ARGUMENT_MESSAGE_ID];\n        if (receiverType === undefined || receiverId === undefined || msgId === undefined) {\n            this.arpLog.warn('Invalid blob response, argument field missing');\n            return future.reject('invalidResponse');\n        }\n        const blobInfo = {\n            buffer: data[WebClientService.DATA_FIELD_BLOB_BLOB],\n            mimetype: data[WebClientService.DATA_FIELD_BLOB_TYPE],\n            filename: data[WebClientService.DATA_FIELD_BLOB_NAME],\n        };\n        if (blobInfo.buffer === undefined || blobInfo.mimetype === undefined || blobInfo.filename === undefined) {\n            this.arpLog.warn('Invalid blob response, data field missing');\n            return future.reject('invalidResponse');\n        }\n        this.blobCache.set(msgId + receiverType, blobInfo);\n        future.resolve(blobInfo);\n    }\n    _receiveUpdateConfirm(message) {\n        this.arpLog.debug('Received wire message acknowledgement');\n        const future = this.popWireMessageFuture(message);\n        if (!message.ack.success) {\n            future.reject(message.ack.error);\n        }\n        else {\n            future.resolve();\n        }\n    }\n    _receiveUpdateMessages(wireMessage) {\n        this.arpLog.debug('Received messages update');\n        const future = this.popWireMessageFuture(wireMessage, true);\n        if (wireMessage.ack !== undefined && !wireMessage.ack.success) {\n            return future.reject(wireMessage.ack.error);\n        }\n        const args = wireMessage.args;\n        const data = wireMessage.data;\n        if (args === undefined || data === undefined) {\n            this.arpLog.warn('Invalid message update, data or arguments missing');\n            return future.reject('invalidResponse');\n        }\n        const type = args[WebClientService.ARGUMENT_RECEIVER_TYPE];\n        const id = args[WebClientService.ARGUMENT_RECEIVER_ID];\n        const mode = args[WebClientService.ARGUMENT_MODE];\n        if (type === undefined || id === undefined || mode === undefined) {\n            this.arpLog.warn('Invalid message update, argument field missing');\n            return future.reject('invalidResponse');\n        }\n        if (!isValidReceiverType(type)) {\n            this.arpLog.warn('Invalid messages update, unknown receiver type (' + type + ')');\n            return future.reject('invalidResponse');\n        }\n        if (this.config.ARP_LOG_TRACE) {\n            this.logChatMessages(wireMessage.type, wireMessage.subType, type, id, mode, data);\n        }\n        const receiver = { type: type, id: id };\n        let notify = false;\n        for (const message of data) {\n            if (this.messageService.isSentOrSendingFailed(message)) {\n                const sentId = `${message.id}-sent`;\n                const sentFuture = this.wireMessageFutures.get(sentId);\n                if (sentFuture !== undefined) {\n                    this.wireMessageFutures.delete(sentId);\n                    this.arpLogV.debug(`Removed special wire message future: ${sentId}`);\n                    sentFuture.resolve();\n                }\n            }\n            switch (mode) {\n                case WebClientService.ARGUMENT_MODE_NEW:\n                    if (!this.messages.update(receiver, message)) {\n                        this.messages.addNewer(receiver, [message]);\n                        this.typing.unsetTyping(receiver);\n                    }\n                    notify = true;\n                    break;\n                case WebClientService.ARGUMENT_MODE_MODIFIED:\n                    if (!this.messages.update(receiver, message)) {\n                        const log = `Received message update for unknown message (id ${message.id})`;\n                        this.arpLog.error(log);\n                        if (this.config.ARP_LOG_TRACE) {\n                            this.messages.addStatusMessage(receiver, 'Warning: ' + log);\n                            notify = true;\n                        }\n                    }\n                    break;\n                case WebClientService.ARGUMENT_MODE_REMOVED:\n                    if (!this.messages.remove(receiver, message.id)) {\n                        this.arpLog.error(`Received message deletion for unknown message (id ${message.id})`);\n                    }\n                    notify = true;\n                    break;\n                default:\n                    this.arpLog.warn('Invalid message response, unknown mode:', mode);\n            }\n        }\n        if (notify) {\n            this.messages.notify(receiver, this.$rootScope);\n        }\n        future.resolve();\n    }\n    _receiveUpdateReceiver(message) {\n        this.arpLog.debug('Received receiver update');\n        const args = message.args;\n        const data = message.data;\n        if (args === undefined || data === undefined) {\n            this.arpLog.warn('Invalid receiver update, data or arguments missing');\n            return;\n        }\n        const type = args[WebClientService.ARGUMENT_RECEIVER_TYPE];\n        const id = args[WebClientService.ARGUMENT_RECEIVER_ID];\n        const mode = args[WebClientService.ARGUMENT_MODE];\n        if (type === undefined || mode === undefined || id === undefined) {\n            this.arpLog.warn('Invalid receiver update, argument field missing');\n            return;\n        }\n        switch (mode) {\n            case WebClientService.ARGUMENT_MODE_NEW:\n            case WebClientService.ARGUMENT_MODE_MODIFIED:\n                const updatedReceiver = this.receivers.extend(type, data);\n                if (updatedReceiver !== undefined && updatedReceiver.locked) {\n                    this.messages.clearReceiverMessages(updatedReceiver);\n                }\n                break;\n            case WebClientService.ARGUMENT_MODE_REMOVED:\n                this.receivers.get(type).delete(id);\n                break;\n            default:\n                this.arpLog.warn('Invalid receiver response, unknown mode:', mode);\n        }\n    }\n    _receiveUpdateReceivers(message) {\n        this.arpLog.debug('Received receivers update');\n        const args = message.args;\n        const data = message.data;\n        if (args === undefined || data === undefined) {\n            this.arpLog.warn('Invalid receiver update, data or arguments missing');\n            return;\n        }\n        const type = args[WebClientService.ARGUMENT_RECEIVER_TYPE];\n        if (type === undefined) {\n            this.arpLog.warn('Invalid receivers update, argument field missing');\n            return;\n        }\n        switch (type) {\n            case 'contact':\n                this.sortContacts(data);\n                this.receivers.setContacts(data);\n                break;\n            case 'group':\n                this.receivers.setGroups(data);\n                break;\n            case 'distributionList':\n                this.receivers.setDistributionLists(data);\n                break;\n            default:\n                this.arpLog.warn('Unknown receiver type:', type);\n        }\n    }\n    _receiveUpdateTyping(message) {\n        this.arpLog.debug('Received typing update');\n        const args = message.args;\n        const data = message.data;\n        if (args === undefined || data === undefined) {\n            this.arpLog.warn('Invalid typing update, data or arguments missing');\n            return;\n        }\n        const identity = args[WebClientService.ARGUMENT_RECEIVER_ID];\n        if (identity === undefined) {\n            this.arpLog.warn('Invalid typing update, argument field missing');\n            return;\n        }\n        const isTyping = data[WebClientService.ARGUMENT_IS_TYPING];\n        if (isTyping === undefined) {\n            this.arpLog.warn('Invalid typing update, data field missing');\n            return;\n        }\n        const receiver = { id: identity, type: 'contact' };\n        if (isTyping === true) {\n            this.typing.setTyping(receiver);\n        }\n        else {\n            this.typing.unsetTyping(receiver);\n        }\n    }\n    _receiveUpdateConversation(message) {\n        this.arpLog.debug('Received conversation update');\n        const args = message.args;\n        const data = message.data;\n        if (args === undefined || data === undefined) {\n            this.arpLog.warn('Invalid conversation update, data or arguments missing');\n            return;\n        }\n        const receiver = this.receivers.getData({ type: data.type, id: data.id });\n        if (!hasValue(receiver)) {\n            const log = `Received conversation update for unknown ${data.type} receiver`;\n            this.arpLog.error(log);\n            return;\n        }\n        const type = args[WebClientService.ARGUMENT_MODE];\n        switch (type) {\n            case WebClientService.ARGUMENT_MODE_NEW:\n                if (this.conversations.find(data) !== null) {\n                    this.arpLog.error('Received update/conversation with mode=new for existing conversation');\n                    break;\n                }\n                this.conversations.add(data);\n                break;\n            case WebClientService.ARGUMENT_MODE_MODIFIED:\n                if (data.unreadCount > 0) {\n                    const oldConversation = this.conversations.updateOrAdd(data, true);\n                    if (oldConversation === null) {\n                        this.onNewMessage(data.latestMessage, data, receiver);\n                    }\n                    else {\n                        const unreadCountIncreased = data.unreadCount > oldConversation.unreadCount;\n                        const unreadCountDecreased = data.unreadCount < oldConversation.unreadCount;\n                        if (unreadCountIncreased) {\n                            this.onNewMessage(data.latestMessage, data, receiver);\n                        }\n                        else if (unreadCountDecreased) {\n                            this.notificationService.hideNotification(data.type + '-' + data.id);\n                        }\n                    }\n                }\n                else {\n                    this.conversations.updateOrAdd(data, false);\n                    this.notificationService.hideNotification(data.type + '-' + data.id);\n                }\n                break;\n            case WebClientService.ARGUMENT_MODE_REMOVED:\n                this.conversations.remove(data);\n                this.messages.clearReceiverMessages(receiver);\n                this.receiverListener.forEach((listener) => {\n                    this.arpLog.debug('Call on removed listener');\n                    listener.onConversationRemoved(receiver);\n                });\n                break;\n            default:\n                this.arpLog.warn('Received conversation without a mode');\n                break;\n        }\n        this.updateUnreadCount();\n    }\n    _receiveUpdateAvatar(message) {\n        this.arpLog.debug('Received avatar update');\n        const args = message.args;\n        const data = message.data;\n        if (args === undefined) {\n            this.arpLog.warn('Invalid avatar update, arguments missing');\n            return;\n        }\n        const receiver = this.receivers.getData({ type: args.type, id: args.id });\n        if (receiver === undefined) {\n            this.arpLog.error('Received avatar update for nonexistent receiver');\n            return;\n        }\n        receiver.avatar = {\n            low: hasValue(data) ? data : undefined,\n            high: undefined,\n        };\n    }\n    _receiveUpdateBatteryStatus(message) {\n        this.arpLog.debug('Received battery status');\n        const future = this.popWireMessageFuture(message, true);\n        if (message.ack !== undefined && !message.ack.success) {\n            return future.reject(message.ack.error);\n        }\n        const data = message.data;\n        if (data === undefined) {\n            this.arpLog.warn('Invalid battery status message, data missing');\n            return future.reject('invalidResponse');\n        }\n        this.batteryStatusService.setStatus(data);\n        future.resolve();\n    }\n    _receiveUpdateContact(message) {\n        const future = this.popWireMessageFuture(message);\n        this._receiveReplyReceiver(message, 'contact', future);\n    }\n    _receiveUpdateGroup(message) {\n        const future = this.popWireMessageFuture(message);\n        this._receiveReplyReceiver(message, 'group', future);\n    }\n    _receiveUpdateDistributionList(message) {\n        const future = this.popWireMessageFuture(message);\n        this._receiveReplyReceiver(message, 'distributionList', future);\n    }\n    _receiveUpdateProfile(message) {\n        this.arpLog.debug('Received profile update');\n        const data = message.data;\n        if (data === undefined) {\n            this.arpLog.warn('Invalid profile update message, data missing');\n            return;\n        }\n        if (data.publicNickname !== undefined) {\n            this.me.publicNickname = data.publicNickname;\n            this.me.displayName = this.me.publicNickname || this.me.id;\n        }\n        if (data.avatar !== undefined) {\n            if (data.avatar === null) {\n                this.me.avatar = {};\n            }\n            else {\n                this.me.avatar = { high: data.avatar };\n            }\n            this.requestAvatar(this.me, false);\n        }\n    }\n    _receiveResponseClientInfo(message) {\n        this.arpLog.debug('Received client info response');\n        const future = this.popWireMessageFuture(message, this.requiresTemporaryIdBackwardsCompatibility);\n        if ((!this.requiresTemporaryIdBackwardsCompatibility && message.ack !== undefined) && !message.ack.success) {\n            future.reject(message.ack.error);\n        }\n        const data = message.data;\n        if (data === undefined) {\n            this.arpLog.warn('Invalid client info, data field missing');\n            return future.reject('invalidResponse');\n        }\n        function getOrDefault(field, defaultVal) {\n            if (field === undefined) {\n                return defaultVal;\n            }\n            return field;\n        }\n        this.clientInfo = {\n            device: data.device,\n            os: data.os,\n            osVersion: data.osVersion,\n            isWork: hasValue(data.isWork) ? data.isWork : false,\n            pushToken: data.pushToken,\n            configuration: {\n                voipEnabled: getOrDefault(data.configuration.voipEnabled, true),\n                voipForceTurn: getOrDefault(data.configuration.voipForceTurn, false),\n                largeSingleEmoji: getOrDefault(data.configuration.largeSingleEmoji, true),\n                showInactiveIDs: getOrDefault(data.configuration.showInactiveIDs, true),\n            },\n            capabilities: {\n                maxGroupSize: getOrDefault(data.capabilities.maxGroupSize, 50),\n                maxFileSize: getOrDefault(data.capabilities.maxFileSize, 50 * 1024 * 1024),\n                maxMessageBodySize: getOrDefault(data.capabilities.maxMessageBodySize, 3500),\n                distributionLists: getOrDefault(data.capabilities.distributionLists, true),\n                imageFormat: data.capabilities.imageFormat,\n                mdm: data.capabilities.mdm,\n            },\n        };\n        this.arpLog.debug('Client device:', this.clientInfo.device);\n        if (this.clientInfo.pushToken) {\n            this.pushToken = this.clientInfo.pushToken;\n            switch (this.clientInfo.os) {\n                case \"android\":\n                    this.pushTokenType = \"gcm\";\n                    break;\n                case \"ios\":\n                    this.pushTokenType = \"apns\";\n                    break;\n                default:\n                    this.arpLog.error('Invalid operating system in client info');\n            }\n        }\n        if (this.pushToken !== null && this.pushTokenType !== null) {\n            this.pushService.init(this.pushToken, this.pushTokenType);\n        }\n        if (this.clientInfo.isWork) {\n            this.themeService.changeTheme(\"threemawork\");\n        }\n        this.registerInitializationStep(\"client info\");\n        future.resolve();\n    }\n    _receiveResponseProfile(message) {\n        this.arpLog.debug('Received profile response');\n        const future = this.popWireMessageFuture(message, this.requiresTemporaryIdBackwardsCompatibility);\n        if ((!this.requiresTemporaryIdBackwardsCompatibility && message.ack !== undefined) && !message.ack.success) {\n            future.reject(message.ack.error);\n        }\n        const data = message.data;\n        if (data === undefined) {\n            this.arpLog.warn('Invalid client info, data field missing');\n            return future.reject('invalidResponse');\n        }\n        this.receivers.setMe({\n            type: 'me',\n            id: data.identity,\n            publicNickname: data.publicNickname,\n            displayName: data.publicNickname || data.identity,\n            publicKey: data.publicKey,\n            avatar: {\n                high: data.avatar,\n            },\n            featureMask: 0xFF,\n            verificationLevel: 3,\n            state: 'ACTIVE',\n            locked: false,\n            visible: true,\n            hidden: false,\n            access: {\n                canChangeAvatar: true,\n                canChangeFirstName: true,\n                canChangeLastName: true,\n            },\n            color: '#000000',\n        });\n        this.registerInitializationStep(\"profile\");\n        future.resolve();\n    }\n    setPassword(password) {\n        if (this._maybeTrustKeys(password)) {\n            this.sendKeyPersisted();\n        }\n    }\n    clearCache() {\n        this._resetFields();\n        this.blobCache.clear();\n    }\n    getMaxTextLength() {\n        return this.clientInfo.capabilities.maxMessageBodySize;\n    }\n    getMaxGroupMemberSize() {\n        return this.clientInfo.capabilities.maxGroupSize;\n    }\n    shouldNotify(settings, message) {\n        if (settings.dnd.enabled) {\n            if (settings.dnd.mentionOnly) {\n                let textToSearch = '';\n                if (message.type === 'text') {\n                    textToSearch = message.body;\n                }\n                else if (message.caption) {\n                    textToSearch = message.caption;\n                }\n                let quotedMe = false;\n                if (message.quote) {\n                    textToSearch += ' ' + message.quote.text;\n                    quotedMe = message.quote.identity === this.me.id;\n                }\n                const forMe = textToSearch.indexOf('@[' + this.me.id + ']') !== -1;\n                const forAll = textToSearch.indexOf('@[@@@@@@@@]') !== -1;\n                return forMe || forAll || quotedMe;\n            }\n            else {\n                return false;\n            }\n        }\n        else {\n            return true;\n        }\n    }\n    onNewMessage(message, conversation, sender) {\n        if (document.hasFocus()\n            && this.receiverService.compare(conversation, this.receiverService.getActive())) {\n            return;\n        }\n        if (sender.locked === true) {\n            return;\n        }\n        const simplifiedNotification = this.notificationService.getAppNotificationSettings(conversation);\n        if (!this.shouldNotify(simplifiedNotification, message)) {\n            return;\n        }\n        let senderName = sender.id;\n        if (sender.displayName) {\n            senderName = sender.displayName;\n        }\n        else if (isContactReceiver(sender)) {\n            senderName = '~' + sender.publicNickname;\n        }\n        const partner = this.receivers.getData({\n            id: message.partnerId,\n            type: 'contact',\n        });\n        const partnerName = partner.displayName || ('~' + partner.publicNickname);\n        this.$translate('messenger.MESSAGE_NOTIFICATION_SUBJECT', { messageCount: conversation.unreadCount })\n            .then((titlePrefix) => {\n            const title = `${titlePrefix} ${senderName}`;\n            let body = '';\n            const messageType = message.type;\n            const caption = message.caption;\n            let captionString = '';\n            if (caption !== undefined) {\n                captionString = captionString + ': ' + caption;\n            }\n            const messageTypeString = this.$translate.instant('messageTypes.' + messageType);\n            switch (messageType) {\n                case 'text':\n                    body = message.body;\n                    break;\n                case 'location':\n                    body = messageTypeString + ': ' + message.location.description;\n                    break;\n                case 'file':\n                    if (message.file.type === 'image/gif') {\n                        body = this.$translate.instant('messageTypes.' + 'gif') + captionString;\n                        break;\n                    }\n                    if (captionString.length > 0) {\n                        body = messageTypeString + captionString;\n                    }\n                    else {\n                        body = messageTypeString + ': ' + message.file.name;\n                    }\n                    break;\n                case 'ballot':\n                    body = messageTypeString;\n                    break;\n                case 'voipStatus':\n                    let translationKey;\n                    switch (message.voip.status) {\n                        case 1:\n                            translationKey = 'CALL_MISSED';\n                            break;\n                        case 2:\n                            translationKey = message.isOutbox ? 'CALL_FINISHED_IN' : 'CALL_FINISHED_OUT';\n                            break;\n                        case 3:\n                            translationKey = 'CALL_REJECTED';\n                            break;\n                        case 4:\n                            translationKey = 'CALL_ABORTED';\n                            break;\n                        default:\n                    }\n                    if (translationKey !== undefined) {\n                        body = this.$translate.instant('voip.' + translationKey);\n                    }\n                    break;\n                default:\n                    body = messageTypeString + captionString;\n            }\n            if (conversation.type === 'group') {\n                body = partnerName + ': ' + body;\n            }\n            const tag = conversation.type + '-' + conversation.id;\n            const avatar = (sender.avatar && sender.avatar.low)\n                ? bufferToUrl(sender.avatar.low, 'image/png', this.arpLog)\n                : null;\n            this.notificationService.showNotification(tag, title, body, avatar, () => {\n                this.$state.go('messenger.home.conversation', {\n                    type: conversation.type,\n                    id: conversation.id,\n                    initParams: null,\n                });\n            }, undefined, undefined, simplifiedNotification.sound.muted);\n        });\n    }\n    _maybeTrustKeys(password) {\n        if (password !== undefined && password !== null && password.length > 0) {\n            this.trustedKeyStore.storeTrustedKey(this.salty.keyStore.publicKeyBytes, this.salty.keyStore.secretKeyBytes, this.salty.peerPermanentKeyBytes, this.pushToken, this.pushTokenType, password);\n            this.log.info('Stored trusted key');\n            return true;\n        }\n        return false;\n    }\n    updatePushToken(token, tokenType) {\n        this.pushToken = token;\n        this.pushTokenType = tokenType;\n    }\n    sendRequestWireMessage(subType, retransmit, args, data, id) {\n        return this.sendWireMessage(WebClientService.TYPE_REQUEST, subType, retransmit, args, data, id);\n    }\n    sendUpdateWireMessage(subType, retransmit, args, data, id) {\n        return this.sendWireMessage(WebClientService.TYPE_UPDATE, subType, retransmit, args, data, id);\n    }\n    sendCreateWireMessage(subType, retransmit, args, data, id) {\n        return this.sendWireMessage(WebClientService.TYPE_CREATE, subType, retransmit, args, data, id);\n    }\n    sendDeleteWireMessage(subType, retransmit, args, data, id) {\n        return this.sendWireMessage(WebClientService.TYPE_DELETE, subType, retransmit, args, data, id);\n    }\n    createRandomWireMessageId() {\n        let id;\n        do {\n            id = randomString(6);\n        } while (this.wireMessageFutures.has(id));\n        return id;\n    }\n    sendWireMessage(type, subType, retransmit, args, data, id) {\n        const message = {\n            type: type,\n            subType: subType,\n        };\n        let promise;\n        if (retransmit) {\n            if (id === undefined) {\n                id = this.createRandomWireMessageId();\n            }\n            else if (this.wireMessageFutures.has(id)) {\n                throw new Error('Duplicate id for wire message detected');\n            }\n            message.id = id;\n            if (args === undefined) {\n                args = {};\n            }\n            args[WebClientService.ARGUMENT_TEMPORARY_ID] = message.id;\n            const future = new Future();\n            this.arpLogV.debug(`Added wire message future: ${id} -> ${type}/${subType}`);\n            this.wireMessageFutures.set(message.id, future);\n            promise = future;\n        }\n        else {\n            promise = Promise.resolve({\n                id: '',\n                success: true,\n            });\n        }\n        if (args !== undefined) {\n            message.args = args;\n        }\n        if (data !== undefined) {\n            message.data = data;\n        }\n        this.send(message, retransmit);\n        return promise;\n    }\n    static validateWireMessageAcknowledgement(ack) {\n        if (!hasValue(ack.id)) {\n            throw new Error(\"Invalid wire message acknowledgement: 'id' is missing\");\n        }\n        if (!hasValue(ack.success)) {\n            throw new Error(\"Invalid wire message acknowledgement: 'success' is missing\");\n        }\n        switch (ack.success) {\n            case true:\n                break;\n            case false:\n                if (!hasValue(ack.error)) {\n                    throw new Error(\"Invalid wire message acknowledgement: 'error' is missing\");\n                }\n                break;\n            default:\n                throw new Error(\"Invalid wire message acknowledgement: 'success' is not a boolean\");\n        }\n    }\n    popWireMessageFuture(message, optional = false) {\n        if (message.ack === undefined &&\n            message.args !== undefined &&\n            message.args[WebClientService.ARGUMENT_TEMPORARY_ID] !== undefined) {\n            if (message.args[WebClientService.ARGUMENT_SUCCESS] === undefined) {\n                message.args[WebClientService.ARGUMENT_SUCCESS] = true;\n            }\n            message.ack = {\n                id: message.args[WebClientService.ARGUMENT_TEMPORARY_ID],\n                success: message.args[WebClientService.ARGUMENT_SUCCESS],\n                error: message.args[WebClientService.ARGUMENT_ERROR],\n            };\n        }\n        let error;\n        if (hasValue(message.ack)) {\n            try {\n                WebClientService.validateWireMessageAcknowledgement(message.ack);\n            }\n            catch (e) {\n                error = e;\n            }\n        }\n        else if (!optional) {\n            throw new Error('Wire message did not contain an acknowledgement');\n        }\n        else {\n            return new Future();\n        }\n        const id = message.ack.id;\n        const future = this.wireMessageFutures.get(id);\n        if (future !== undefined) {\n            this.wireMessageFutures.delete(id);\n            this.arpLogV.debug(`Removed wire message future: ${id} -> ` +\n                `${message.type}/${message.subType}`);\n        }\n        else if (error === undefined) {\n            error = new Error(`Wire message future not found for id: ${id}`);\n        }\n        if (error !== undefined) {\n            if (future !== undefined) {\n                future.reject('invalidResponse');\n            }\n            throw error;\n        }\n        return future;\n    }\n    _receiveRequest(type, message) {\n        switch (type) {\n            case WebClientService.SUB_TYPE_CONNECTION_ACK:\n                this._receiveRequestConnectionAck(message);\n                break;\n            default:\n                this.arpLog.warn(`Ignored request/${type}`);\n                break;\n        }\n    }\n    _receiveResponse(type, message) {\n        switch (type) {\n            case WebClientService.SUB_TYPE_CONFIRM_ACTION:\n                this._receiveResponseConfirmAction(message);\n                break;\n            case WebClientService.SUB_TYPE_RECEIVERS:\n                this._receiveResponseReceivers(message);\n                break;\n            case WebClientService.SUB_TYPE_CONVERSATIONS:\n                this._receiveResponseConversations(message);\n                break;\n            case WebClientService.SUB_TYPE_MESSAGES:\n                this._receiveResponseMessages(message);\n                break;\n            case WebClientService.SUB_TYPE_AVATAR:\n                this._receiveResponseAvatar(message);\n                break;\n            case WebClientService.SUB_TYPE_THUMBNAIL:\n                this._receiveResponseThumbnail(message);\n                break;\n            case WebClientService.SUB_TYPE_BLOB:\n                this._receiveResponseBlob(message);\n                break;\n            case WebClientService.SUB_TYPE_CLIENT_INFO:\n                this._receiveResponseClientInfo(message);\n                break;\n            case WebClientService.SUB_TYPE_PROFILE:\n                this._receiveResponseProfile(message);\n                break;\n            case WebClientService.SUB_TYPE_CONTACT_DETAIL:\n                this._receiveResponseContactDetail(message);\n                break;\n            default:\n                this.arpLog.warn(`Ignored response/${type}`);\n                break;\n        }\n    }\n    _receiveUpdate(type, message) {\n        switch (type) {\n            case WebClientService.SUB_TYPE_CONFIRM:\n                this._receiveUpdateConfirm(message);\n                break;\n            case WebClientService.SUB_TYPE_RECEIVER:\n                this._receiveUpdateReceiver(message);\n                break;\n            case WebClientService.SUB_TYPE_RECEIVERS:\n                this._receiveUpdateReceivers(message);\n                break;\n            case WebClientService.SUB_TYPE_MESSAGES:\n                this._receiveUpdateMessages(message);\n                break;\n            case WebClientService.SUB_TYPE_TYPING:\n                this._receiveUpdateTyping(message);\n                break;\n            case WebClientService.SUB_TYPE_CONVERSATION:\n                this._receiveUpdateConversation(message);\n                break;\n            case WebClientService.SUB_TYPE_AVATAR:\n                this._receiveUpdateAvatar(message);\n                break;\n            case WebClientService.SUB_TYPE_BATTERY_STATUS:\n                this._receiveUpdateBatteryStatus(message);\n                break;\n            case WebClientService.SUB_TYPE_CONTACT:\n                this._receiveUpdateContact(message);\n                break;\n            case WebClientService.SUB_TYPE_GROUP:\n                this._receiveUpdateGroup(message);\n                break;\n            case WebClientService.SUB_TYPE_DISTRIBUTION_LIST:\n                this._receiveUpdateDistributionList(message);\n                break;\n            case WebClientService.SUB_TYPE_PROFILE:\n                this._receiveUpdateProfile(message);\n                break;\n            case WebClientService.SUB_TYPE_ALERT:\n                this._receiveUpdateAlert(message);\n                break;\n            case WebClientService.SUB_TYPE_CONNECTION_ACK:\n                this._receiveUpdateConnectionAck(message);\n                break;\n            case WebClientService.SUB_TYPE_CONNECTION_DISCONNECT:\n                this._receiveUpdateConnectionDisconnect(message);\n                break;\n            default:\n                this.arpLog.warn(`Ignored update/${type}`);\n                break;\n        }\n    }\n    _receiveCreate(type, message) {\n        switch (type) {\n            case WebClientService.SUB_TYPE_CONTACT:\n                this._receiveCreateContact(message);\n                break;\n            case WebClientService.SUB_TYPE_GROUP:\n                this._receiveCreateGroup(message);\n                break;\n            case WebClientService.SUB_TYPE_DISTRIBUTION_LIST:\n                this._receiveCreateDistributionList(message);\n                break;\n            case WebClientService.SUB_TYPE_TEXT_MESSAGE:\n            case WebClientService.SUB_TYPE_FILE_MESSAGE:\n                this._receiveCreateMessage(message);\n                break;\n            default:\n                this.arpLog.warn(`Ignored response/${type}`);\n                break;\n        }\n    }\n    msgpackEncode(data) {\n        return msgpack.encode(data, this.msgpackEncoderOptions);\n    }\n    msgpackDecode(bytes) {\n        return msgpack.decode(bytes, this.msgpackDecoderOptions);\n    }\n    send(message, retransmit) {\n        this.arpLog.debug('Sending', message.type + '/' + message.subType, 'message');\n        if (this.config.ARP_LOG_TRACE) {\n            this.arpLogV.debug('Outgoing:', message.type, '/', message.subType, new ConfidentialWireMessage(message));\n        }\n        switch (this.chosenTask) {\n            case \"webrtc\":\n                {\n                    const bytes = this.msgpackEncode(message);\n                    if (this.config.MSGPACK_LOG_TRACE) {\n                        this.msgpackLog.debug('Outgoing message payload: ' + msgpackVisualizer(bytes));\n                    }\n                    const box = this.secureDataChannelCrypto.encrypt(bytes);\n                    const chunker = new chunkedDc.UnreliableUnorderedChunker(this.secureDataChannelMessageId++, box.toUint8Array(), this.secureDataChannelChunkLength);\n                    for (const chunk of chunker) {\n                        this.arpLogV.debug(`Data channel ${this.secureDataChannel.dc.label} outgoing ` +\n                            `chunk of length ${chunk.byteLength}`);\n                        this.secureDataChannel.write(chunk);\n                    }\n                }\n                break;\n            case \"relayed-data\":\n                {\n                    const canQueue = message.subType !== WebClientService.SUB_TYPE_CONNECTION_INFO;\n                    const bytes = this.msgpackEncode(message);\n                    if (this.config.MSGPACK_LOG_TRACE) {\n                        this.msgpackLog.debug('Outgoing message payload: ' + msgpackVisualizer(bytes));\n                    }\n                    const messageSequenceNumber = this.outgoingMessageSequenceNumber.increment();\n                    const chunker = new chunkedDc.UnreliableUnorderedChunker(messageSequenceNumber, bytes, WebClientService.RELAYED_DATA_CHUNK_SIZE);\n                    for (const chunk of chunker) {\n                        this.sendChunk(chunk, retransmit, canQueue, true);\n                    }\n                    if (this.pendingAckRequest === null &&\n                        this.currentChunkCache.byteLength > WebClientService.CHUNK_CACHE_SIZE_MAX) {\n                        this.pendingAckRequest = this.currentChunkCache.sequenceNumber.get();\n                        this._requestConnectionAck();\n                    }\n                }\n                break;\n            default:\n                this.arpLog.error('Trying to send message, but no chosen task set');\n        }\n    }\n    sendChunk(chunk, retransmit, canQueue, cache) {\n        if (this.chosenTask !== \"relayed-data\") {\n            throw new Error(`Cannot send chunk, not supported by task: ${this.chosenTask}`);\n        }\n        const shouldQueue = canQueue && this.previousChunkCache !== null;\n        let chunkCache;\n        if (shouldQueue) {\n            chunkCache = this.previousChunkCache;\n            this.arpLog.debug('Currently not connected, queueing chunk');\n            if (!this.pushService.isAvailable()) {\n                this.log.warn('Push service not available, cannot wake up peer!');\n                retransmit = false;\n            }\n            if (retransmit) {\n                this.sendPush();\n            }\n        }\n        else {\n            chunkCache = this.currentChunkCache;\n        }\n        if (cache) {\n            this.arpLogV.debug(`Caching chunk (retransmit/push=${retransmit}:`, chunk);\n            try {\n                chunkCache.append(retransmit ? chunk : null);\n            }\n            catch (error) {\n                this.arpLog.error(error);\n                this.failSession();\n                return;\n            }\n        }\n        if (!shouldQueue) {\n            this.arpLogV.debug(`Sending chunk (retransmit/push=${retransmit}:`, chunk);\n            this.relayedDataTask.sendMessage(chunk.buffer);\n            if (retransmit && this.startupDone) {\n                this.schedulePush();\n            }\n        }\n    }\n    receiveChunk(chunk) {\n        this.arpLogV.debug('Received chunk:', chunk);\n        try {\n            this.currentIncomingChunkSequenceNumber.increment();\n        }\n        catch (error) {\n            this.arpLog.error(`Unable to continue session: ${error}`);\n            this.failSession();\n            return;\n        }\n        this.scheduleConnectionAck();\n        this.cancelPush();\n        this.unchunker.add(chunk);\n    }\n    handleIncomingMessageBytes(bytes) {\n        this.arpLog.debug('New incoming message (' + bytes.byteLength + ' bytes)');\n        if (this.config.MSGPACK_LOG_TRACE) {\n            this.msgpackLog.debug('Incoming message payload: ' + msgpackVisualizer(bytes));\n        }\n        const message = this.msgpackDecode(bytes);\n        return this.handleIncomingMessage(message);\n    }\n    handleIncomingMessage(message) {\n        this.arpLog.debug(`Received ${message.type}/${message.subType} message`);\n        if (message.type === undefined) {\n            this.arpLog.warn('Ignoring invalid message (no type attribute)');\n            return;\n        }\n        else if (message.subType === undefined) {\n            this.arpLog.warn('Ignoring invalid message (no subType attribute)');\n            return;\n        }\n        if (this.config.ARP_LOG_TRACE) {\n            this.arpLogV.debug(`Incoming: ${message.type}/${message.subType}`, new ConfidentialWireMessage(copyDeepOrReference(message)));\n        }\n        this.$rootScope.$apply(() => {\n            this.receive(message);\n        });\n    }\n    receive(message) {\n        if (!this.connectionInfoFuture.done) {\n            if (message.type !== WebClientService.TYPE_UPDATE ||\n                message.subType !== WebClientService.SUB_TYPE_CONNECTION_INFO) {\n                this.arpLog.error('Unexpected message before handshake has been completed');\n                this.failSession();\n                return;\n            }\n            this._receiveConnectionInfo(message);\n            return;\n        }\n        let messageHandler;\n        switch (message.type) {\n            case WebClientService.TYPE_REQUEST:\n                messageHandler = this._receiveRequest;\n                break;\n            case WebClientService.TYPE_RESPONSE:\n                messageHandler = this._receiveResponse;\n                break;\n            case WebClientService.TYPE_CREATE:\n                messageHandler = this._receiveCreate;\n                break;\n            case WebClientService.TYPE_UPDATE:\n                messageHandler = this._receiveUpdate;\n                break;\n            default:\n                this.arpLog.warn(`Ignored message ${message.type}/${message.subType}`);\n                break;\n        }\n        if (messageHandler !== undefined) {\n            try {\n                messageHandler.apply(this, [message.subType, message]);\n            }\n            catch (error) {\n                this.arpLog.error('Unable to handle incoming wire message:', error);\n                console.trace(error);\n                return;\n            }\n        }\n        let future;\n        try {\n            future = this.popWireMessageFuture(message);\n        }\n        catch {\n        }\n        if (future !== undefined) {\n            this.arpLog.warn(`Unhandled message acknowledgement for type ${message.type}:`, message.ack);\n            future.reject('unhandled');\n        }\n    }\n    runAfterInitializationSteps(requiredSteps, callback) {\n        for (const requiredStep of requiredSteps) {\n            if (!this.initialized.has(requiredStep)) {\n                this.arpLog.debug('Required initialization step', requiredStep, 'not completed, add pending routine');\n                this.pendingInitializationStepRoutines.add({\n                    requiredSteps: requiredSteps,\n                    callback: callback,\n                });\n                return;\n            }\n        }\n        callback.apply(this);\n    }\n    updateUnreadCount() {\n        const totalUnreadCount = this.conversations\n            .get()\n            .reduce((a, b) => a + b.unreadCount, 0);\n        this.stateService.unreadCount = totalUnreadCount;\n    }\n    resetUnreadCount() {\n        this.stateService.unreadCount = 0;\n    }\n    get appConfig() {\n        return this.clientInfo.configuration;\n    }\n    get appCapabilities() {\n        return this.clientInfo.capabilities;\n    }\n    sortContacts(contacts) {\n        const getSortableName = (name) => name.startsWith('~') ? name.substr(1) : name;\n        let options;\n        if (this.browserService.supportsExtendedLocaleCompare()) {\n            options = {\n                usage: 'sort',\n                sensitivity: 'variant',\n            };\n        }\n        const compareFunc = (a, b) => {\n            if (a.id.startsWith('*') && !b.id.startsWith('*')) {\n                return 1;\n            }\n            if (!a.id.startsWith('*') && b.id.startsWith('*')) {\n                return -1;\n            }\n            const left = getSortableName(a.displayName);\n            const right = getSortableName(b.displayName);\n            return left.localeCompare(right, undefined, options);\n        };\n        contacts.sort(compareFunc);\n    }\n    clearIsTypingFlags() {\n        this.typing.clearAll();\n    }\n    handleGlobalConnectionStateChange(stateChange) {\n        const isOk = stateChange.state === \"ok\";\n        const wasOk = stateChange.prevState === \"ok\";\n        if (!isOk && wasOk && this.batteryStatusService.dataAvailable) {\n            this.batteryStatusTimeout = this.timeoutService.register(() => {\n                this.batteryStatusService.clearStatus();\n                this.batteryStatusTimeout = null;\n            }, 60000, true, 'batteryStatusHide');\n        }\n        else if (isOk && this.batteryStatusTimeout !== null) {\n            this.timeoutService.cancel(this.batteryStatusTimeout);\n            this.batteryStatusTimeout = null;\n        }\n    }\n    logChatMessages(type, subType, receiverType, receiver, mode, messages) {\n        for (const message of messages) {\n            let id = message.id;\n            if (this.clientInfo.os === \"ios\") {\n                try {\n                    id = u8aToHex(base64ToU8a(message.id));\n                }\n                catch { }\n            }\n            this.arpLogV.debug('Chat message:', `${type}/${subType}: receiver=${receiverType}/${receiver}, ` +\n                `mode=${mode}, direction=${message.isOutbox ? 'out' : 'in'}, id=${id}, type=${message.type}, ` +\n                `state=${message.state !== undefined ? message.state : '?'}, is-status=${message.isStatus}, ` +\n                `date=${message.date}`);\n        }\n    }\n}\nWebClientService.MAX_CONNECT_ATTEMPTS = 3;\nWebClientService.DATA_CHANNEL_MAX_CHUNK_SIZE = 256 * 1024;\nWebClientService.RELAYED_DATA_CHUNK_SIZE = 64 * 1024;\nWebClientService.SEQUENCE_NUMBER_MIN = 0;\nWebClientService.SEQUENCE_NUMBER_MAX = (2 ** 32) - 1;\nWebClientService.CHUNK_CACHE_SIZE_MAX = 2 * 1024 * 1024;\nWebClientService.AVATAR_LOW_MAX_SIZE = 48;\nWebClientService.MAX_FILE_SIZE_WEBRTC_TASK_V0 = 15 * 1024 * 1024;\nWebClientService.CONNECTION_ID_NONCE = stringToUtf8a('connectionidconnectionid');\nWebClientService.TYPE_REQUEST = 'request';\nWebClientService.TYPE_RESPONSE = 'response';\nWebClientService.TYPE_UPDATE = 'update';\nWebClientService.TYPE_CREATE = 'create';\nWebClientService.TYPE_DELETE = 'delete';\nWebClientService.SUB_TYPE_RECEIVER = 'receiver';\nWebClientService.SUB_TYPE_RECEIVERS = 'receivers';\nWebClientService.SUB_TYPE_CONVERSATIONS = 'conversations';\nWebClientService.SUB_TYPE_CONVERSATION = 'conversation';\nWebClientService.SUB_TYPE_MESSAGE = 'message';\nWebClientService.SUB_TYPE_MESSAGES = 'messages';\nWebClientService.SUB_TYPE_TEXT_MESSAGE = 'textMessage';\nWebClientService.SUB_TYPE_FILE_MESSAGE = 'fileMessage';\nWebClientService.SUB_TYPE_AVATAR = 'avatar';\nWebClientService.SUB_TYPE_THUMBNAIL = 'thumbnail';\nWebClientService.SUB_TYPE_BLOB = 'blob';\nWebClientService.SUB_TYPE_TYPING = 'typing';\nWebClientService.SUB_TYPE_READ = 'read';\nWebClientService.SUB_TYPE_CLIENT_INFO = 'clientInfo';\nWebClientService.SUB_TYPE_KEY_PERSISTED = 'keyPersisted';\nWebClientService.SUB_TYPE_ACK = 'ack';\nWebClientService.SUB_TYPE_CONTACT_DETAIL = 'contactDetail';\nWebClientService.SUB_TYPE_CONTACT = 'contact';\nWebClientService.SUB_TYPE_GROUP = 'group';\nWebClientService.SUB_TYPE_DISTRIBUTION_LIST = 'distributionList';\nWebClientService.SUB_TYPE_ALERT = 'alert';\nWebClientService.SUB_TYPE_GROUP_SYNC = 'groupSync';\nWebClientService.SUB_TYPE_BATTERY_STATUS = 'batteryStatus';\nWebClientService.SUB_TYPE_CLEAN_RECEIVER_CONVERSATION = 'cleanReceiverConversation';\nWebClientService.SUB_TYPE_CONFIRM = 'confirm';\nWebClientService.SUB_TYPE_CONFIRM_ACTION = 'confirmAction';\nWebClientService.SUB_TYPE_PROFILE = 'profile';\nWebClientService.SUB_TYPE_CONNECTION_ACK = 'connectionAck';\nWebClientService.SUB_TYPE_CONNECTION_DISCONNECT = 'connectionDisconnect';\nWebClientService.SUB_TYPE_CONNECTION_INFO = 'connectionInfo';\nWebClientService.ARGUMENT_MODE = 'mode';\nWebClientService.ARGUMENT_MODE_NEW = 'new';\nWebClientService.ARGUMENT_MODE_MODIFIED = 'modified';\nWebClientService.ARGUMENT_MODE_REMOVED = 'removed';\nWebClientService.ARGUMENT_RECEIVER_TYPE = 'type';\nWebClientService.ARGUMENT_RECEIVER_ID = 'id';\nWebClientService.ARGUMENT_TEMPORARY_ID = 'temporaryId';\nWebClientService.ARGUMENT_REFERENCE_MSG_ID = 'refMsgId';\nWebClientService.ARGUMENT_AVATAR = 'avatar';\nWebClientService.ARGUMENT_AVATAR_HIGH_RESOLUTION = 'highResolution';\nWebClientService.ARGUMENT_NICKNAME = 'publicNickname';\nWebClientService.ARGUMENT_IS_TYPING = 'isTyping';\nWebClientService.ARGUMENT_MESSAGE_ID = 'messageId';\nWebClientService.ARGUMENT_HAS_MORE = 'more';\nWebClientService.ARGUMENT_MESSAGE_ACKNOWLEDGED = 'acknowledged';\nWebClientService.ARGUMENT_IDENTITY = 'identity';\nWebClientService.ARGUMENT_SUCCESS = 'success';\nWebClientService.ARGUMENT_SYSTEM_CONTACT = 'systemContact';\nWebClientService.ARGUMENT_NAME = 'name';\nWebClientService.ARGUMENT_MEMBERS = 'members';\nWebClientService.ARGUMENT_FIRST_NAME = 'firstName';\nWebClientService.ARGUMENT_LAST_NAME = 'lastName';\nWebClientService.ARGUMENT_DELETE_TYPE = 'deleteType';\nWebClientService.ARGUMENT_ERROR = 'error';\nWebClientService.ARGUMENT_MAX_SIZE = 'maxSize';\nWebClientService.ARGUMENT_USER_AGENT = 'userAgent';\nWebClientService.ARGUMENT_BROWSER_NAME = 'browserName';\nWebClientService.ARGUMENT_BROWSER_VERSION = 'browserVersion';\nWebClientService.DELETE_GROUP_TYPE_LEAVE = 'leave';\nWebClientService.DELETE_GROUP_TYPE_DELETE = 'delete';\nWebClientService.DATA_FIELD_BLOB_BLOB = 'blob';\nWebClientService.DATA_FIELD_BLOB_TYPE = 'type';\nWebClientService.DATA_FIELD_BLOB_NAME = 'name';\nWebClientService.DC_LABEL = 'THREEMA';\nWebClientService.$inject = [\n    '$rootScope', '$q', '$state', '$window', '$translate', '$filter', '$timeout', '$mdDialog',\n    'LogService', 'Container', 'TrustedKeyStore',\n    'StateService', 'NotificationService', 'MessageService', 'PushService', 'BrowserService',\n    'TitleService', 'QrCodeService', 'MimeService', 'ReceiverService',\n    'VersionService', 'BatteryStatusService', 'ThemeService', 'TimeoutService',\n    'CONFIG',\n];\n","import { WebClientService } from '../services/webclient';\nexport class StatusController {\n    constructor($scope, $timeout, $state, config, controllerService, stateService, logService, timeoutService, webClientService) {\n        this.state = \"error\";\n        this.unreadCount = 0;\n        this.expandStatusBar = false;\n        this.expandStatusBarTimer = null;\n        this.expandStatusBarTimeout = 3000;\n        this.log = logService.getLogger('Status-C', 'color: #000; background-color: #ffff99');\n        this.config = config;\n        this.$timeout = $timeout;\n        this.$state = $state;\n        this.controllerService = controllerService;\n        this.stateService = stateService;\n        this.timeoutService = timeoutService;\n        this.webClientService = webClientService;\n        this.stateService.evtGlobalConnectionStateChange.attach((stateChange) => {\n            $scope.$apply(() => {\n                this.onStateChange(stateChange.state, stateChange.prevState);\n            });\n        });\n        this.stateService.evtUnreadCountChange.attach((count) => {\n            this.unreadCount = count;\n        });\n    }\n    get statusClass() {\n        const classes = [\n            `status-task-${this.webClientService.chosenTask}`,\n            `status-${this.state}`,\n        ];\n        if (this.config.VISUALIZE_STATE) {\n            classes.push(`visualize-state`);\n        }\n        return classes.join(' ');\n    }\n    onStateChange(newValue, oldValue) {\n        this.log.debug('State change:', oldValue, '->', newValue);\n        if (newValue === oldValue) {\n            return;\n        }\n        this.state = newValue;\n        const isWebrtc = this.webClientService.chosenTask === \"webrtc\";\n        const isRelayedData = this.webClientService.chosenTask === \"relayed-data\";\n        switch (newValue) {\n            case 'ok':\n                this.collapseStatusBar();\n                break;\n            case 'warning':\n                if (oldValue === 'ok' && isWebrtc) {\n                    this.scheduleStatusBar();\n                }\n                this.webClientService.clearIsTypingFlags();\n                if (isRelayedData) {\n                    this.reconnectIos();\n                }\n                break;\n            case 'error':\n                if (isWebrtc) {\n                    this.reconnectAndroid();\n                }\n                if (this.stateService.attempt === 0 && isRelayedData) {\n                    this.reconnectIos();\n                }\n                break;\n            default:\n                this.log.error('Invalid state change: From', oldValue, 'to', newValue);\n        }\n    }\n    scheduleStatusBar() {\n        this.expandStatusBarTimer = this.timeoutService.register(() => {\n            this.expandStatusBar = true;\n        }, this.expandStatusBarTimeout, true, 'expandStatusBar');\n    }\n    collapseStatusBar() {\n        this.expandStatusBar = false;\n        if (this.expandStatusBarTimer !== null) {\n            this.timeoutService.cancel(this.expandStatusBarTimer);\n        }\n    }\n    reconnectAndroid() {\n        this.log.info(`Connection lost (Android). Reconnect attempt #${this.stateService.attempt + 1}`);\n        if (this.$state.includes('messenger')) {\n            this.scheduleStatusBar();\n        }\n        const originalKeyStore = this.webClientService.salty.keyStore;\n        const originalPeerPermanentKeyBytes = this.webClientService.salty.peerPermanentKeyBytes;\n        this.webClientService.stop({\n            reason: \"stop\",\n            send: true,\n            close: false,\n        });\n        this.webClientService.init({\n            keyStore: originalKeyStore,\n            peerTrustedKey: originalPeerPermanentKeyBytes,\n            resume: true,\n        });\n        const pause = this.stateService.attempt >= WebClientService.MAX_CONNECT_ATTEMPTS;\n        if (pause) {\n            this.webClientService.showDeviceUnreachableDialog();\n        }\n        this.webClientService.start(pause)\n            .then(() => { }, (error) => {\n            this.log.error('Error state:', error);\n        }, (progress) => {\n            this.log.debug('Connection buildup advanced:', progress);\n        })\n            .finally(() => {\n            this.collapseStatusBar();\n        });\n        ++this.stateService.attempt;\n    }\n    reconnectIos() {\n        this.log.info(`Connection lost (iOS). Reconnect attempt #${++this.stateService.attempt}`);\n        const originalKeyStore = this.webClientService.salty.keyStore;\n        const originalPeerPermanentKeyBytes = this.webClientService.salty.peerPermanentKeyBytes;\n        const startTimeout = 500;\n        this.log.debug('Stopping old connection');\n        this.webClientService.stop({\n            reason: \"stop\",\n            send: true,\n            close: false,\n            connectionBuildupState: 'push',\n        });\n        const push = (() => {\n            if (this.$state.includes('welcome')) {\n                return {\n                    send: true,\n                    reason: 'still on welcome page',\n                };\n            }\n            const pendingWireMessages = this.webClientService.unacknowledgedWireMessages;\n            if (pendingWireMessages > 0) {\n                return {\n                    send: true,\n                    reason: `${pendingWireMessages} unacknowledged wire messages`,\n                };\n            }\n            return {\n                send: false,\n            };\n        })();\n        this.$timeout.cancel(this.reconnectTimeout);\n        this.reconnectTimeout = this.$timeout(() => {\n            if (push.send) {\n                this.log.debug(`Starting new connection with push, reason: ${push.reason}`);\n            }\n            else {\n                this.log.debug('Starting new connection without push');\n            }\n            this.webClientService.init({\n                keyStore: originalKeyStore,\n                peerTrustedKey: originalPeerPermanentKeyBytes,\n                resume: true,\n            });\n            this.webClientService.start(!push.send).then(() => { }, (error) => {\n                this.log.error('Error state:', error);\n            }, (progress) => {\n                this.log.debug('Connection buildup advanced:', progress);\n            });\n        }, startTimeout);\n    }\n    wide() {\n        return this.controllerService.getControllerName() !== undefined\n            && this.controllerService.getControllerName() === 'messenger';\n    }\n    get faviconFilename() {\n        switch (this.state) {\n            case \"ok\":\n                if (this.unreadCount > 0) {\n                    return 'favicon-32x32-unread.png';\n                }\n                else {\n                    return 'favicon-32x32.png';\n                }\n                break;\n            case \"warning\":\n                const isRelayedData = this.webClientService.chosenTask === \"relayed-data\";\n                if (isRelayedData) {\n                    return 'favicon-32x32.png';\n                }\n                else {\n                    return 'favicon-32x32-warning.png';\n                }\n                break;\n            case \"error\":\n                return 'favicon-32x32-error.png';\n                break;\n        }\n    }\n}\nStatusController.$inject = [\n    '$scope', '$timeout', '$state',\n    'CONFIG',\n    'ControllerService', 'StateService', 'LogService', 'TimeoutService', 'WebClientService',\n];\n","export class ThemeController {\n    constructor($scope, logService, themeService) {\n        this.log = logService.getLogger('Theme-C', 'color: #000; background-color: #ffff99');\n        this.theme = themeService.theme;\n        themeService.evtThemeChange.attach((newTheme) => {\n            this.log.debug(`Updating theme: ${this.theme} -> ${newTheme}`);\n            $scope.$apply(() => this.theme = newTheme);\n        });\n    }\n}\nThemeController.$inject = ['$scope', 'LogService', 'ThemeService'];\n","import { FooterController } from './controllers/footer';\nimport { HeaderController } from './controllers/header';\nimport { StatusController } from './controllers/status';\nimport { ThemeController } from './controllers/theme';\nangular.module('3ema.controllers', ['3ema.services'])\n    .controller('FooterController', FooterController)\n    .controller('HeaderController', HeaderController)\n    .controller('StatusController', StatusController)\n    .controller('ThemeController', ThemeController);\n","import { bufferToUrl, hasValue } from '../helpers';\nimport { isEchoContact, isGatewayContact } from '../receiver_helpers';\nimport { isContactReceiver } from '../typeguards';\nexport default [\n    '$rootScope',\n    'LogService',\n    'TimeoutService',\n    'WebClientService',\n    function ($rootScope, logService, timeoutService, webClientService) {\n        const log = logService.getLogger('Avatar-C');\n        return {\n            restrict: 'E',\n            scope: {},\n            bindToController: {\n                receiver: '=eeeReceiver',\n                resolution: '=eeeResolution',\n            },\n            link: function (scope, elem, attrs) {\n                scope.$watch(() => scope.ctrl.receiver, (newReceiver, oldReceiver) => {\n                    if (!hasValue(newReceiver)) {\n                        return;\n                    }\n                    if (!hasValue(oldReceiver)) {\n                        scope.ctrl.update(false);\n                        return;\n                    }\n                    if (newReceiver.id !== oldReceiver.id ||\n                        newReceiver.type !== oldReceiver.type ||\n                        newReceiver.color !== oldReceiver.color ||\n                        newReceiver.displayName !== oldReceiver.displayName) {\n                        scope.ctrl.update(false);\n                        return;\n                    }\n                    if (hasValue(newReceiver.avatar)) {\n                        if (hasValue(oldReceiver.avatar)) {\n                            if (newReceiver.avatar.high !== oldReceiver.avatar.high ||\n                                newReceiver.avatar.low !== oldReceiver.avatar.low) {\n                                scope.ctrl.update(false);\n                                return;\n                            }\n                        }\n                        else {\n                            scope.ctrl.update(false);\n                            return;\n                        }\n                    }\n                });\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    let loadingPromise = null;\n                    const avatarUri = {\n                        high: null,\n                        low: null,\n                    };\n                    this.avatarToUri = (data, res) => {\n                        if (!hasValue(data)) {\n                            return '';\n                        }\n                        if (avatarUri[res] === null) {\n                            avatarUri[res] = bufferToUrl(data, webClientService.appCapabilities.imageFormat.avatar, log);\n                        }\n                        return avatarUri[res];\n                    };\n                    this.update = (initial) => {\n                        avatarUri.high = null;\n                        avatarUri.low = null;\n                        const receiver = this.receiver;\n                        this.highResolution = this.resolution === 'high';\n                        this.isLoading = this.highResolution;\n                        this.backgroundColor = receiver.color;\n                        this.receiverName = receiver.displayName;\n                    };\n                    this.$onInit = function () {\n                        this.update(true);\n                        this.avatarClass = () => 'avatar-' + this.resolution + (this.isLoading ? ' is-loading' : '');\n                        this.avatarExists = () => {\n                            if (this.receiver.avatar === undefined\n                                || this.receiver.avatar[this.resolution] === undefined\n                                || this.receiver.avatar[this.resolution] === null) {\n                                return false;\n                            }\n                            this.isLoading = false;\n                            this.backgroundColor = null;\n                            return true;\n                        };\n                        this.getDefaultAvatarUri = (type, highResolution) => {\n                            switch (type) {\n                                case 'group':\n                                    return highResolution\n                                        ? 'img/ic_group_picture_big.png'\n                                        : 'img/ic_group_t.png';\n                                case 'distributionList':\n                                    return highResolution\n                                        ? 'img/ic_distribution_list_t.png'\n                                        : 'img/ic_distribution_list_t.png';\n                                case 'contact':\n                                case 'me':\n                                default:\n                                    return highResolution\n                                        ? 'img/ic_contact_picture_big.svg'\n                                        : 'img/ic_contact_picture_t.png';\n                            }\n                        };\n                        this.getAvatarUri = () => {\n                            if (this.avatarExists()) {\n                                return this.avatarToUri(this.receiver.avatar[this.resolution], this.resolution);\n                            }\n                            if (this.highResolution\n                                && this.isLoading\n                                && this.receiver.avatar !== undefined\n                                && this.receiver.avatar.low !== undefined\n                                && this.receiver.avatar.low !== null) {\n                                return this.avatarToUri(this.receiver.avatar.low, 'low');\n                            }\n                            return this.getDefaultAvatarUri(this.receiver.type, this.highResolution);\n                        };\n                        this.requestAvatar = (inView) => {\n                            if (this.avatarExists()) {\n                                return;\n                            }\n                            if (inView) {\n                                if (loadingPromise === null) {\n                                    const loadingTimeout = this.highResolution ? 0 : 500;\n                                    loadingPromise = timeoutService.register(() => {\n                                        webClientService.requestAvatar({\n                                            type: this.receiver.type,\n                                            id: this.receiver.id,\n                                        }, this.highResolution)\n                                            .then((avatar) => {\n                                            $rootScope.$apply(() => this.isLoading = false);\n                                            loadingPromise = null;\n                                        })\n                                            .catch((error) => {\n                                            log.error(`Avatar request has been rejected: ${error}`);\n                                            $rootScope.$apply(() => this.isLoading = false);\n                                            loadingPromise = null;\n                                        });\n                                    }, loadingTimeout, false, 'avatar');\n                                }\n                            }\n                            else if (loadingPromise !== null) {\n                                timeoutService.cancel(loadingPromise);\n                                loadingPromise = null;\n                            }\n                        };\n                        const isWorkApp = webClientService.clientInfo.isWork;\n                        this.showWorkIndicator = () => {\n                            if (!isContactReceiver(this.receiver)) {\n                                return false;\n                            }\n                            const contact = this.receiver;\n                            return isWorkApp === false\n                                && !this.highResolution\n                                && contact.identityType === 1;\n                        };\n                        this.showHomeIndicator = () => {\n                            if (!isContactReceiver(this.receiver)) {\n                                return false;\n                            }\n                            const contact = this.receiver;\n                            return isWorkApp === true\n                                && !isGatewayContact(contact)\n                                && !isEchoContact(contact)\n                                && contact.identityType === 0\n                                && !this.highResolution;\n                        };\n                        this.showBlocked = () => {\n                            if (!isContactReceiver(this.receiver)) {\n                                return false;\n                            }\n                            const contact = this.receiver;\n                            return !this.highResolution && contact.isBlocked;\n                        };\n                    };\n                }],\n            template: `\n                <div class=\"avatar\" ng-class=\"ctrl.avatarClass()\">\n                    <div class=\"avatar-loading\" ng-if=\"ctrl.isLoading\">\n                        <span></span>\n                    </div>\n                    <div class=\"work-indicator\" ng-if=\"ctrl.showWorkIndicator()\"\n                        translate-attr=\"{'aria-label': 'messenger.THREEMA_WORK_CONTACT',\n                            'title': 'messenger.THREEMA_WORK_CONTACT'}\">\n                        <img src=\"img/ic_work_round.svg\" alt=\"Threema Work user\">\n                    </div>\n                    <div class=\"home-indicator\" ng-if=\"ctrl.showHomeIndicator()\"\n                        translate-attr=\"{'aria-label': 'messenger.THREEMA_HOME_CONTACT',\n                            'title': 'messenger.THREEMA_HOME_CONTACT'}\">\n                        <img src=\"img/ic_home_round.svg\" alt=\"Private Threema contact\">\n                    </div>\n                    <div class=\"blocked-indicator\"  ng-if=\"ctrl.showBlocked()\"\n                        translate-attr=\"{'aria-label': 'messenger.THREEMA_BLOCKED_RECEIVER',\n                            'title': 'messenger.THREEMA_BLOCKED_RECEIVER'}\">\n                        <img src=\"img/ic_blocked_24px.svg\" alt=\"blocked icon\">\n                    </div>\n                    <img\n                         ng-class=\"ctrl.avatarClass()\"\n                         ng-style=\"{ 'background-color': ctrl.backgroundColor }\"\n                         ng-src=\"{{ ctrl.getAvatarUri() }}\"\n                         in-view=\"ctrl.requestAvatar($inview)\"\n                         aria-label=\"avatar {{ ctrl.receiverName }}\">\n               </div>\n            `,\n        };\n    },\n];\n","export function isGatewayContact(receiver) {\n    return receiver.id.startsWith('*');\n}\nexport function isEchoContact(receiver) {\n    return receiver.id === 'ECHOECHO';\n}\n","import { bufferToUrl } from '../helpers';\nexport default [\n    '$rootScope',\n    '$mdDialog',\n    'LogService',\n    'WebClientService',\n    function ($rootScope, $mdDialog, logService, webClientService) {\n        const log = logService.getLogger('AvatarArea-C');\n        return {\n            restrict: 'EA',\n            scope: true,\n            bindToController: {\n                onChange: '=',\n                loadAvatar: '=',\n                enableClear: '=?',\n                color: '=?',\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.isLoading = false;\n                    this.avatar = null;\n                    const avatarFormat = webClientService.appCapabilities.imageFormat.avatar;\n                    this.$onInit = function () {\n                        this.setAvatar = (avatarBytes) => {\n                            this.avatar = (avatarBytes === null)\n                                ? null\n                                : bufferToUrl(avatarBytes, avatarFormat, log);\n                        };\n                        this.imageChanged = (image, notify = true) => {\n                            this.isLoading = true;\n                            if (notify === true && this.onChange !== undefined) {\n                                this.onChange(image);\n                            }\n                            this.setAvatar(image);\n                            this.isLoading = false;\n                        };\n                        if (this.loadAvatar !== undefined) {\n                            this.isLoading = true;\n                            this.loadAvatar\n                                .then((image) => {\n                                $rootScope.$apply(() => {\n                                    this.setAvatar(image);\n                                    this.isLoading = false;\n                                });\n                            })\n                                .catch(() => {\n                                $rootScope.$apply(() => {\n                                    this.isLoading = false;\n                                });\n                            });\n                        }\n                        this.delete = () => {\n                            this.imageChanged(null, true);\n                        };\n                        this.modify = (ev) => {\n                            $mdDialog.show({\n                                controllerAs: 'ctrl',\n                                controller: function () {\n                                    this.avatar = null;\n                                    this.apply = () => $mdDialog.hide(this.avatar);\n                                    this.cancel = () => $mdDialog.cancel();\n                                    this.changeAvatar = (image) => this.avatar = image;\n                                },\n                                template: `\n                                <md-dialog translate-attr=\"{'aria-label': 'messenger.UPLOAD_AVATAR'}\">\n                                    <form ng-cloak>\n                                     <md-toolbar>\n                                      <div class=\"md-toolbar-tools\">\n                                       <h2 translate>messenger.UPLOAD_AVATAR</h2>\n                                       </div>\n                                       </md-toolbar>\n                                        <md-dialog-content>\n                                            <div class=\"md-dialog-content avatar-area editor\">\n                                                <avatar-editor on-change=\"ctrl.changeAvatar\"></avatar-editor>\n                                            </div>\n                                        </md-dialog-content>\n                                        <md-dialog-actions layout=\"row\" >\n                                              <md-button ng-click=\"ctrl.cancel()\">\n                                               <span translate>common.CANCEL</span>\n                                                </md-button>\n                                          <md-button ng-click=\"ctrl.apply()\">\n                                             <span translate>common.OK</span>\n                                          </md-button>\n                                        </md-dialog-actions>\n                                    </form>\n                                </md-dialog>\n\n                            `,\n                                parent: angular.element(document.body),\n                                targetEvent: ev,\n                                clickOutsideToClose: true,\n                            })\n                                .then((newImage) => {\n                                if (this.enableClear === true || newImage !== null) {\n                                    this.imageChanged(newImage, true);\n                                }\n                            }, () => null);\n                        };\n                    };\n                }],\n            template: `\n                <div class=\"avatar-area overview\">\n                    <div class=\"avatar-image\" ng-style=\"{ 'background-color': ctrl.color }\">\n                        <div class=\"loading-element\" ng-class=\"{'active': ctrl.isLoading}\">\n                            <md-progress-circular\n                                    class=\"md-primary\"\n                                    md-diameter=\"96\"></md-progress-circular>\n\n                        </div>\n                        <img ng-src=\"{{ ctrl.avatar }}\" ng-if=\"ctrl.avatar !== null\">\n                    </div>\n                    <div class=\"avatar-area-navigation\"  layout=\"row\" layout-wrap layout-margin layout-align=\"center\">\n\n                        <md-button type=\"submit\" class=\"md-raised\" ng-click=\"ctrl.delete()\" ng-if=\"ctrl.enableClear === true\">\n                            <span translate>common.DELETE</span>\n                        </md-button>\n                        <md-button type=\"submit\" class=\"md-raised md-primary\" ng-click=\"ctrl.modify()\">\n                            <span translate>messenger.UPLOAD_AVATAR</span>\n                        </md-button>\n                    </div>\n                    </div>\n                </div>\n            `,\n        };\n    },\n];\n","import { bufferToUrl } from '../helpers';\nexport default [\n    'LogService',\n    function (logService) {\n        const log = logService.getLogger('AvatarEditor-C');\n        return {\n            restrict: 'EA',\n            scope: {\n                onChange: '=',\n            },\n            link(scope, element, attrs, controller) {\n                const DRAGOVER_CSS_CLASS = 'is-dragover';\n                const VIEWPORT_SIZE = 220;\n                const editorArea = angular.element(element[0].querySelector('.avatar-editor'));\n                const fileTrigger = angular.element(element[0].querySelector('.file-trigger'));\n                const fileInput = angular.element(element[0].querySelector('input.file-input'));\n                let croppieInstance = null;\n                const initCroppie = () => {\n                    if (croppieInstance === null) {\n                        const croppieTarget = element[0].querySelector('.croppie-target');\n                        croppieInstance = new Croppie(croppieTarget, {\n                            viewport: {\n                                type: 'square',\n                                width: VIEWPORT_SIZE,\n                                height: VIEWPORT_SIZE,\n                            },\n                            customClass: 'has-image',\n                            showZoomer: true,\n                            update: () => {\n                                if (updateTimeout !== undefined) {\n                                    clearTimeout(updateTimeout);\n                                }\n                                updateTimeout = self.setTimeout(async () => {\n                                    const image = await croppieInstance.result({\n                                        type: 'blob',\n                                        size: { width: 512, height: 512 },\n                                        circle: false,\n                                        format: 'png',\n                                    });\n                                    const fileReader = new FileReader();\n                                    fileReader.onload = function () {\n                                        scope.onChange(fileReader.result);\n                                    };\n                                    fileReader.readAsArrayBuffer(image);\n                                }, 500);\n                            },\n                        });\n                    }\n                    return croppieInstance;\n                };\n                function loading(show) {\n                    if (show) {\n                        editorArea.addClass('loading');\n                    }\n                    else {\n                        editorArea.removeClass('loading');\n                    }\n                }\n                let updateTimeout;\n                function fetchFileContent(file) {\n                    return new Promise((resolve, reject) => {\n                        const reader = new FileReader();\n                        reader.onload = function (ev) {\n                            resolve(this.result);\n                        };\n                        reader.onerror = function (ev) {\n                            reject(ev);\n                        };\n                        reader.onprogress = function (ev) {\n                            if (ev.lengthComputable) {\n                            }\n                        };\n                        reader.readAsArrayBuffer(file);\n                    });\n                }\n                function uploadFiles(fileList) {\n                    if (fileList.length < 1) {\n                        return;\n                    }\n                    fetchFileContent(fileList[0]).then((data) => {\n                        const image = bufferToUrl(data, 'image/jpeg', log);\n                        setImage(image);\n                    }).catch((ev) => {\n                        log.error('Could not load file:', ev.message);\n                    });\n                }\n                function onDrop(ev) {\n                    ev.stopPropagation();\n                    ev.preventDefault();\n                    onDragleave(ev);\n                    uploadFiles(ev.dataTransfer.files);\n                }\n                function onDragover(ev) {\n                    ev.stopPropagation();\n                    ev.preventDefault();\n                    editorArea.addClass(DRAGOVER_CSS_CLASS);\n                }\n                function onDragleave(ev) {\n                    ev.stopPropagation();\n                    ev.preventDefault();\n                    editorArea.removeClass(DRAGOVER_CSS_CLASS);\n                }\n                function onFileTrigger(ev) {\n                    ev.preventDefault();\n                    ev.stopPropagation();\n                    const input = element[0].querySelector('.file-input');\n                    input.click();\n                }\n                function onFileUploaded() {\n                    uploadFiles(this.files);\n                }\n                function setImage(imageBase64Url) {\n                    const croppie = initCroppie();\n                    loading(true);\n                    const img = new Image();\n                    img.addEventListener('load', async () => {\n                        log.debug('Image loaded');\n                        const w = img.naturalWidth;\n                        const h = img.naturalHeight;\n                        const size = Math.min(w, h);\n                        const imageSize = [\n                            (w - size) / 2,\n                            (h - size) / 2,\n                            size,\n                            size,\n                        ];\n                        try {\n                            await croppie.bind({\n                                url: imageBase64Url,\n                                points: imageSize,\n                            });\n                        }\n                        catch (error) {\n                            log.error('Could not bind avatar preview:', error);\n                        }\n                        loading(false);\n                    });\n                    img.addEventListener('error', function (e) {\n                        log.error('Could not load image:', e);\n                        loading(false);\n                    });\n                    img.src = imageBase64Url;\n                }\n                editorArea.on('dragover dragenter', onDragover);\n                editorArea.on('dragleave dragend', onDragleave);\n                editorArea.on('drop', onDrop);\n                fileTrigger.on('click', onFileTrigger);\n                fileInput.on('change', onFileUploaded);\n            },\n            template: `\n                <div class=\"avatar-editor\">\n                    <div class=\"avatar-editor-drag croppie-target\"></div>\n                    <div class=\"avatar-editor-navigation\" layout=\"column\" layout-wrap layout-margin layout-align=\"center center\">\n                        <input class=\"file-input\" type=\"file\" style=\"visibility: hidden\" multiple>\n                          <md-button type=\"submit\" class=\"file-trigger md-raised\">\n                            <span translate>messenger.UPLOAD_AVATAR</span>\n                           </md-button>\n                    </div>\n                </div>\n            `,\n        };\n    },\n];\n","export default [\n    '$timeout',\n    '$state',\n    'UriService',\n    'WebClientService',\n    function ($timeout, $state, uriService, webClientService) {\n        const validateThreemaId = (id) => {\n            return id !== undefined && id !== null && /^([a-zA-Z0-9\\*][a-zA-Z0-9]{7})$/.test(id);\n        };\n        const viewReceiver = (receiver) => {\n            return function (e) {\n                if (!receiver) {\n                    return false;\n                }\n                $state.go('messenger.home.detail', receiver);\n            };\n        };\n        const addAction = (params) => {\n            return function (e) {\n                if (!validateThreemaId(params.id)) {\n                    return false;\n                }\n                e.preventDefault();\n                const contactReceiver = webClientService.contacts.get(params.id);\n                if (contactReceiver) {\n                    return viewReceiver(contactReceiver)(e);\n                }\n                $state.go('messenger.home.create', {\n                    type: 'contact',\n                    initParams: {\n                        identity: params.id,\n                    },\n                });\n            };\n        };\n        const composeAction = (params) => {\n            return function (e) {\n                if (!validateThreemaId(params.id)) {\n                    return false;\n                }\n                const text = params.text || '';\n                $state.go('messenger.home.conversation', {\n                    type: 'contact',\n                    id: params.id,\n                    initParams: {\n                        text: text,\n                    },\n                });\n            };\n        };\n        const getThreemaActionHandler = (name) => {\n            switch (name.toLowerCase()) {\n                case 'add':\n                    return addAction;\n                case 'compose':\n                    return composeAction;\n                default:\n                    return null;\n            }\n        };\n        return {\n            restrict: 'A',\n            scope: {},\n            link(scope, el, attrs) {\n                $timeout(() => {\n                    for (let i = 0; i < el[0].childNodes.length; i++) {\n                        const node = el[0].childNodes[i];\n                        if (node.nodeType === Node.ELEMENT_NODE) {\n                            switch (node.tagName.toLowerCase()) {\n                                case 'a':\n                                    const link = node.innerText;\n                                    if (link !== undefined) {\n                                        if (link.toLowerCase().startsWith('threema://')) {\n                                            const matches = (/\\bthreema:\\/\\/([a-z]+)\\?([^\\s]+)\\b/gi).exec(link);\n                                            if (matches !== null) {\n                                                const handler = getThreemaActionHandler(matches[1]);\n                                                const params = uriService.parseQueryParams(matches[2]);\n                                                if (handler !== null && params !== null) {\n                                                    node.addEventListener('click', handler(params));\n                                                }\n                                            }\n                                        }\n                                        else if (link.toLowerCase().startsWith('https://threema.id/')) {\n                                            const matches = (/\\bhttps:\\/\\/threema\\.id\\/([a-zA-Z0-9\\*][a-zA-Z0-9]{7})\\b/gi).exec(link);\n                                            if (matches !== null) {\n                                                node.addEventListener('click', addAction({ id: matches[1] }));\n                                            }\n                                        }\n                                    }\n                                    break;\n                                case 'span':\n                                    const mentionCssClass = 'mention id';\n                                    const cls = node.getAttribute('class');\n                                    if (cls.substr(0, mentionCssClass.length) === mentionCssClass) {\n                                        const identity = cls.substring(mentionCssClass.length).trim();\n                                        if (validateThreemaId(identity)) {\n                                            const contactReceiver = webClientService.contacts.get(identity);\n                                            node.addEventListener('click', viewReceiver(contactReceiver));\n                                            node.setAttribute('class', cls + ' link');\n                                            node.setAttribute('title', contactReceiver.displayName);\n                                        }\n                                    }\n                                default:\n                            }\n                        }\n                    }\n                }, 0);\n            },\n        };\n    },\n];\n","import { ComposeArea } from '@threema/compose-area';\nimport { isActionTrigger } from '../helpers';\nimport { parseEmoji, shortnameToUtf8 } from '../helpers/emoji';\nimport { isEmojiInfo, isKeyboardEvent } from '../typeguards';\nexport default [\n    'BrowserService',\n    'LogService',\n    'StringService',\n    'TimeoutService',\n    'ReceiverService',\n    '$timeout',\n    '$translate',\n    '$mdDialog',\n    '$filter',\n    '$rootScope',\n    'CONFIG',\n    function (browserService, logService, stringService, timeoutService, receiverService, $timeout, $translate, $mdDialog, $filter, $rootScope, CONFIG) {\n        const log = logService.getLogger('ComposeArea-C');\n        return {\n            restrict: 'EA',\n            scope: {\n                onInit: '=',\n                submit: '=',\n                startTyping: '=',\n                stopTyping: '=',\n                onTyping: '=',\n                onKeyDown: '=',\n                initialData: '=',\n                onUploading: '=',\n                maxTextLength: '=',\n                receiver: '<receiver',\n            },\n            link: function (scope, wrapper) {\n                const TRIGGER_ENABLED_CSS_CLASS = 'is-enabled';\n                const TRIGGER_ACTIVE_CSS_CLASS = 'is-active';\n                const select = (selector) => angular.element(wrapper[0].querySelector(selector));\n                const composeDiv = select('div.compose');\n                const emojiTrigger = select('i.emoji-trigger');\n                const emojiKeyboard = select('.emoji-keyboard');\n                const sendTrigger = select('i.send-trigger');\n                const fileTrigger = select('i.file-trigger');\n                const fileInput = select('input.file-input');\n                const composeArea = ComposeArea.bind_to(composeDiv[0], CONFIG.COMPOSE_AREA_LOG_LEVEL);\n                if (scope.onInit) {\n                    scope.onInit(composeArea);\n                }\n                if (scope.initialData.initialText) {\n                    composeDiv[0].innerText = scope.initialData.initialText;\n                    scope.initialData.initialText = '';\n                }\n                else if (scope.initialData.draft !== undefined) {\n                    composeDiv[0].innerText = scope.initialData.draft;\n                }\n                let chatBlocked = false;\n                function setChatBlocked(blocked) {\n                    chatBlocked = blocked;\n                    log.debug('Receiver blocked:', blocked);\n                    if (blocked) {\n                        sendTrigger.removeClass(TRIGGER_ENABLED_CSS_CLASS);\n                        emojiTrigger.removeClass(TRIGGER_ENABLED_CSS_CLASS);\n                        fileTrigger.removeClass(TRIGGER_ENABLED_CSS_CLASS);\n                        composeDiv.attr('contenteditable', 'false');\n                        if (emojiKeyboard.hasClass('active')) {\n                            hideEmojiPicker();\n                        }\n                    }\n                    else {\n                        if (composeAreaIsEmpty()) {\n                            sendTrigger.removeClass(TRIGGER_ENABLED_CSS_CLASS);\n                        }\n                        else {\n                            sendTrigger.addClass(TRIGGER_ENABLED_CSS_CLASS);\n                        }\n                        emojiTrigger.addClass(TRIGGER_ENABLED_CSS_CLASS);\n                        fileTrigger.addClass(TRIGGER_ENABLED_CSS_CLASS);\n                        composeDiv.attr('contenteditable', 'true');\n                    }\n                }\n                setChatBlocked(receiverService.isBlocked(scope.receiver));\n                scope.$watch((_scope) => receiverService.isBlocked(_scope.receiver), (isBlocked, wasBlocked) => {\n                    if (isBlocked !== wasBlocked) {\n                        setChatBlocked(isBlocked);\n                    }\n                });\n                let stopTypingTimer = null;\n                function stopTyping() {\n                    if (stopTypingTimer !== null) {\n                        timeoutService.cancel(stopTypingTimer);\n                        stopTypingTimer = null;\n                        scope.stopTyping();\n                    }\n                }\n                function startTyping() {\n                    if (stopTypingTimer === null) {\n                        scope.startTyping();\n                    }\n                    else {\n                        timeoutService.cancel(stopTypingTimer);\n                    }\n                    stopTypingTimer = timeoutService.register(stopTyping, 10000, true, 'stopTyping');\n                }\n                function composeAreaIsEmpty() {\n                    return composeArea.get_text().length === 0;\n                }\n                function submitText() {\n                    const text = composeArea.get_text().replace(/\\r/g, '');\n                    return new Promise((resolve, reject) => {\n                        const submitTexts = (strings) => {\n                            const messages = [];\n                            for (const piece of strings) {\n                                messages.push({\n                                    text: piece,\n                                });\n                            }\n                            scope.submit('text', messages)\n                                .then(resolve)\n                                .catch(reject);\n                        };\n                        const byteLength = (new TextEncoder().encode(text)).length;\n                        if (byteLength > scope.maxTextLength) {\n                            const chunkSize = scope.maxTextLength * 0.85;\n                            const pieces = stringService.byteChunk(text, chunkSize, 50);\n                            const confirm = $mdDialog.confirm()\n                                .title($translate.instant('messenger.MESSAGE_TOO_LONG_SPLIT_SUBJECT'))\n                                .textContent($translate.instant('messenger.MESSAGE_TOO_LONG_SPLIT_BODY', {\n                                max: scope.maxTextLength,\n                                count: pieces.length,\n                            }))\n                                .ok($translate.instant('common.YES'))\n                                .cancel($translate.instant('common.NO'));\n                            $mdDialog.show(confirm).then(function () {\n                                submitTexts(pieces);\n                            }, () => {\n                                reject();\n                            });\n                        }\n                        else {\n                            submitTexts([text]);\n                        }\n                    });\n                }\n                function sendText() {\n                    if (!composeAreaIsEmpty()) {\n                        submitText().then(() => {\n                            composeArea.clear();\n                            composeArea.focus();\n                            stopTyping();\n                            scope.onTyping('');\n                            updateView();\n                        }).catch(() => {\n                            log.warn('Failed to submit text');\n                        });\n                        return true;\n                    }\n                    return false;\n                }\n                let isComposing = false;\n                let compositionHasJustEnded = false;\n                function onCompositionStart(ev) {\n                    isComposing = true;\n                }\n                function onCompositionEnd(ev) {\n                    isComposing = false;\n                    compositionHasJustEnded = true;\n                }\n                function onKeyDown(ev) {\n                    if (!ev.shiftKey && ev.key === 'Enter') {\n                        ev.preventDefault();\n                    }\n                    if (scope.onKeyDown && scope.onKeyDown(ev) !== true) {\n                        ev.preventDefault();\n                        return;\n                    }\n                    if (ev.isComposing || isComposing || compositionHasJustEnded) {\n                        return;\n                    }\n                    if (ev.key === ':') {\n                        const modified = onEmojiShortcodeKeyPressed(ev, ':', false);\n                        if (modified) {\n                            ev.preventDefault();\n                            return;\n                        }\n                    }\n                    $timeout(() => {\n                        if (!ev.shiftKey && ev.key === 'Enter') {\n                            if (sendText()) {\n                                return;\n                            }\n                        }\n                        updateView();\n                    }, 0);\n                }\n                function onKeyUp(ev) {\n                    compositionHasJustEnded = false;\n                    const text = composeArea.get_text(true);\n                    if (text === '\\n') {\n                        composeDiv[0].innerText = '';\n                    }\n                    if (text.trim().length === 0) {\n                        stopTyping();\n                        scope.onTyping('');\n                    }\n                    else {\n                        startTyping();\n                        scope.onTyping(text.trim());\n                    }\n                    updateView();\n                }\n                function fetchFileListContents(fileList) {\n                    return new Promise((resolve) => {\n                        const buffers = new Map();\n                        const fileCounter = fileList.length;\n                        const next = (file, res, error) => {\n                            buffers.set(file, res);\n                            if (buffers.size >= fileCounter) {\n                                resolve(buffers);\n                            }\n                        };\n                        for (let n = 0; n < fileCounter; n++) {\n                            const reader = new FileReader();\n                            const file = fileList.item(n);\n                            reader.onload = function (ev) {\n                                next(file, this.result, ev);\n                            };\n                            reader.onerror = function (ev) {\n                                next(file, null, ev);\n                            };\n                            reader.onprogress = function (ev) {\n                                if (ev.lengthComputable) {\n                                    const progress = ((ev.loaded / ev.total) * 100);\n                                    scope.onUploading(true, progress, 100 / fileCounter * n);\n                                }\n                            };\n                            reader.readAsArrayBuffer(file);\n                        }\n                    });\n                }\n                function uploadFiles(fileList) {\n                    scope.onUploading(true, 0, 0);\n                    fetchFileListContents(fileList).then((data) => {\n                        const fileMessages = [];\n                        data.forEach((buffer, file) => {\n                            const fileMessageData = {\n                                name: file.name,\n                                fileType: file.type,\n                                size: file.size,\n                                data: buffer,\n                            };\n                            if (browserService.getBrowser().isFirefox(false)) {\n                                if (fileMessageData.name.endsWith('.ogg') && fileMessageData.fileType === 'video/ogg') {\n                                    fileMessageData.fileType = 'audio/ogg';\n                                }\n                            }\n                            fileMessages.push(fileMessageData);\n                        });\n                        scope\n                            .submit('file', fileMessages)\n                            .catch((e) => log.error('Could not send file:', e));\n                        scope.onUploading(false);\n                    }).catch((ev) => {\n                        log.error('Could not load file:', ev.message);\n                    });\n                }\n                function onPaste(ev) {\n                    ev.preventDefault();\n                    if (!ev.clipboardData) {\n                        return;\n                    }\n                    const items = ev.clipboardData.items;\n                    if (!items) {\n                        return;\n                    }\n                    let fileIdx = null;\n                    let textIdx = null;\n                    for (let i = 0; i < items.length; i++) {\n                        if (items[i].type.indexOf('image/') !== -1 || items[i].type === 'application/x-moz-file') {\n                            fileIdx = i;\n                        }\n                        else if (items[i].type === 'text/plain') {\n                            textIdx = i;\n                        }\n                    }\n                    if (fileIdx !== null) {\n                        const blob = items[fileIdx].getAsFile();\n                        const reader = new FileReader();\n                        reader.onload = function (progressEvent) {\n                            const buffer = this.result;\n                            let fileName;\n                            if (blob.name) {\n                                fileName = blob.name;\n                            }\n                            else if (blob.type && blob.type.match(/^[^;]*\\//) !== null) {\n                                const fileExt = blob.type.split(';')[0].split('/')[1];\n                                fileName = 'clipboard.' + fileExt;\n                            }\n                            else {\n                                log.warn('Pasted file has an invalid MIME type: \"' + blob.type + '\"');\n                                return;\n                            }\n                            const fileMessageData = {\n                                name: fileName,\n                                fileType: blob.type,\n                                size: blob.size,\n                                data: buffer,\n                            };\n                            scope\n                                .submit('file', [fileMessageData])\n                                .catch((msg) => log.error('Could not send file:', msg));\n                        };\n                        reader.readAsArrayBuffer(blob);\n                    }\n                    else if (textIdx !== null) {\n                        const text = ev.clipboardData.getData('text/plain');\n                        if (text) {\n                            const tokens = parseEmoji(text);\n                            for (const token of tokens) {\n                                if (isEmojiInfo(token)) {\n                                    insertEmoji(token);\n                                }\n                                else {\n                                    composeArea.insert_text(token);\n                                }\n                            }\n                            updateView();\n                        }\n                    }\n                }\n                let regularPlaceholder = '';\n                let dragoverPlaceholder = '';\n                $translate('messenger.COMPOSE_MESSAGE').then((translated) => regularPlaceholder = translated);\n                $translate('messenger.COMPOSE_MESSAGE_DRAGOVER').then((translated) => dragoverPlaceholder = translated);\n                function showEmojiPicker() {\n                    $timeout(() => {\n                        const emojiPicker = wrapper[0].querySelector('div.twemoji-picker');\n                        emojiKeyboard.addClass('active');\n                        emojiKeyboard.attr('aria-expanded', 'true');\n                        emojiTrigger.attr('aria-pressed', 'true');\n                        emojiTrigger.addClass(TRIGGER_ACTIVE_CSS_CLASS);\n                        const allEmoji = angular.element(emojiPicker.querySelectorAll('.content .em'));\n                        const allEmojiTabs = angular.element(emojiPicker.querySelectorAll('.tab label img'));\n                        const skinSelectors = angular.element(emojiPicker.querySelectorAll('.skins img'));\n                        allEmoji.on('click', onEmojiChosen);\n                        allEmoji.on('keydown', onEmojiChosen);\n                        allEmojiTabs.on('keydown', onEmojiTabSelected);\n                        skinSelectors.on('click', onSkintoneSelected);\n                        skinSelectors.on('keydown', onSkintoneSelected);\n                        composeArea.focus();\n                    });\n                }\n                function hideEmojiPicker() {\n                    const emojiPicker = wrapper[0].querySelector('div.twemoji-picker');\n                    emojiKeyboard.removeClass('active');\n                    emojiKeyboard.attr('aria-expanded', 'false');\n                    emojiTrigger.attr('aria-pressed', 'false');\n                    emojiTrigger.removeClass(TRIGGER_ACTIVE_CSS_CLASS);\n                    const allEmoji = angular.element(emojiPicker.querySelectorAll('.content .em'));\n                    const allEmojiTabs = angular.element(emojiPicker.querySelectorAll('.tab label img'));\n                    allEmoji.off('click', onEmojiChosen);\n                    allEmoji.off('keydown', onEmojiChosen);\n                    allEmojiTabs.off('keydown', onEmojiTabSelected);\n                }\n                function onEmojiTrigger(ev) {\n                    ev.stopPropagation();\n                    if (chatBlocked) {\n                        hideEmojiPicker();\n                        return;\n                    }\n                    if (emojiKeyboard.hasClass('active')) {\n                        hideEmojiPicker();\n                    }\n                    else {\n                        showEmojiPicker();\n                    }\n                }\n                function onEmojiChosen(ev) {\n                    if (ev.type === 'click' || (isKeyboardEvent(ev) && isActionTrigger(ev))) {\n                        ev.stopPropagation();\n                        if (isKeyboardEvent(ev)) {\n                            ev.preventDefault();\n                        }\n                        insertSingleEmojiString(ev.target.textContent);\n                        updateView();\n                    }\n                }\n                function onSkintoneSelected(ev) {\n                    if (ev.type === 'click' || (isKeyboardEvent(ev) && isActionTrigger(ev))) {\n                        ev.stopPropagation();\n                        if (isKeyboardEvent(ev)) {\n                            ev.preventDefault();\n                        }\n                        const tone = ev.target.getAttribute('data-tone');\n                        log.debug(`Skintone selected: Tone ${tone}`);\n                        const emojiPicker = wrapper[0].querySelector('div.twemoji-picker');\n                        emojiPicker.setAttribute('data-skintone', tone);\n                    }\n                }\n                function onEmojiTabSelected(ev) {\n                    if (isActionTrigger(ev)) {\n                        ev.target.parentElement.previousElementSibling.checked = true;\n                    }\n                }\n                function insertSingleEmojiString(emojiString) {\n                    const tokens = parseEmoji(emojiString);\n                    if (tokens.length !== 1) {\n                        throw new Error(`Emoji parsing failed: Expected 1 element, found ${tokens.length}`);\n                    }\n                    const emoji = tokens[0];\n                    if (!isEmojiInfo(emoji)) {\n                        throw new Error(`Emoji parsing failed: Returned text, not emoji info`);\n                    }\n                    insertEmoji(emoji);\n                }\n                function insertEmoji(emoji) {\n                    const img = composeArea.insert_image(emoji.imgPath, emoji.emojiString, 'em');\n                    img.setAttribute('data-c', emoji.codepoint);\n                    img.draggable = false;\n                    img.ondragstart = () => false;\n                }\n                function onEmojiShortcodeKeyPressed(ev, trigger, alreadyProcessed) {\n                    const word = composeArea.get_word_at_caret();\n                    if (word === undefined) {\n                        return false;\n                    }\n                    let before = word.before();\n                    const after = word.after();\n                    if (!alreadyProcessed) {\n                        before += trigger;\n                    }\n                    if (after.length === 0 && before.length > 2) {\n                        if (before.startsWith(trigger) && before.endsWith(trigger)) {\n                            const trimmed = before.substr(1, before.length - 2);\n                            const unicodeEmoji = shortnameToUtf8(trimmed);\n                            if (unicodeEmoji !== null) {\n                                composeArea.select_word_at_caret();\n                                composeArea.store_selection_range();\n                                insertSingleEmojiString(unicodeEmoji);\n                                return true;\n                            }\n                        }\n                    }\n                    return false;\n                }\n                function onFileTrigger(ev) {\n                    ev.preventDefault();\n                    ev.stopPropagation();\n                    if (chatBlocked) {\n                        return;\n                    }\n                    const input = wrapper[0].querySelector('.file-input');\n                    input.click();\n                }\n                function onSendTrigger(ev) {\n                    ev.preventDefault();\n                    ev.stopPropagation();\n                    if (chatBlocked) {\n                        return;\n                    }\n                    return sendText();\n                }\n                function onFileSelected() {\n                    uploadFiles(this.files);\n                    fileInput.val('');\n                }\n                function updateView() {\n                    if (composeAreaIsEmpty()) {\n                        sendTrigger.removeClass(TRIGGER_ENABLED_CSS_CLASS);\n                    }\n                    else {\n                        sendTrigger.addClass(TRIGGER_ENABLED_CSS_CLASS);\n                    }\n                }\n                composeDiv.on('compositionstart', onCompositionStart);\n                composeDiv.on('compositionend', onCompositionEnd);\n                composeDiv.on('keydown', onKeyDown);\n                composeDiv.on('keyup', onKeyUp);\n                document.addEventListener('selectionchange', () => {\n                    composeArea.store_selection_range();\n                });\n                composeDiv.on('paste', onPaste);\n                emojiTrigger.on('click', onEmojiTrigger);\n                emojiTrigger[0].addEventListener('keypress', (ev) => {\n                    if (isActionTrigger(ev)) {\n                        $rootScope.$apply(() => {\n                            onEmojiTrigger(ev);\n                        });\n                    }\n                });\n                fileTrigger.on('click', onFileTrigger);\n                fileTrigger[0].addEventListener('keypress', (ev) => {\n                    if (isActionTrigger(ev)) {\n                        $rootScope.$apply(() => {\n                            onFileTrigger(ev);\n                        });\n                    }\n                });\n                fileInput.on('change', onFileSelected);\n                sendTrigger.on('click', onSendTrigger);\n                sendTrigger[0].addEventListener('keypress', (ev) => {\n                    if (isActionTrigger(ev)) {\n                        $rootScope.$apply(() => {\n                            onSendTrigger(ev);\n                        });\n                    }\n                });\n                updateView();\n                const unsubscribeListeners = [];\n                unsubscribeListeners.push($rootScope.$on('onQuoted', (event, args) => {\n                    composeArea.focus();\n                }));\n                scope.$on('$destroy', () => {\n                    unsubscribeListeners.forEach((u) => {\n                        u();\n                    });\n                    stopTyping();\n                });\n            },\n            template: `\n                <div>\n                    <div>\n                        <i class=\"md-primary emoji-trigger trigger is-enabled material-icons\" role=\"button\" aria-label=\"emoji\" aria-pressed=\"false\" tabindex=\"0\">tag_faces</i>\n                    </div>\n                    <div>\n                        <div\n                            class=\"compose\"\n                            id=\"composeDiv\"\n                            contenteditable\n                            autofocus\n                            data-gramm=\"false\"\n                            translate\n                            translate-attr-data-placeholder=\"messenger.COMPOSE_MESSAGE\"\n                            translate-attr-aria-label=\"messenger.COMPOSE_MESSAGE\"\n                            tabindex=\"0\"\n                        ></div>\n                    </div>\n                    <div>\n                        <i class=\"md-primary send-trigger trigger material-icons\" role=\"button\" aria-label=\"send\" tabindex=\"0\">send</i>\n                        <i class=\"md-primary file-trigger trigger is-enabled material-icons\" role=\"button\" aria-label=\"attach file\" tabindex=\"0\">attach_file</i>\n                        <input class=\"file-input\" type=\"file\" style=\"visibility: hidden\" multiple>\n                    </div>\n                </div>\n                <div class=\"emoji-keyboard\" aria-expanded=\"false\">\n                    <ng-include src=\"'partials/emoji-picker.html'\" include-replace></ng-include>\n                </div>\n            `,\n        };\n    },\n];\n","import { hasValue } from '../helpers';\nexport default [\n    'WebClientService',\n    '$state',\n    function (webClientService, $state) {\n        return {\n            restrict: 'EA',\n            scope: {},\n            bindToController: {\n                identity: '=?eeeIdentity',\n                contactReceiver: '=?eeeContact',\n                linked: '=?eeeLinked',\n                onRemove: '=?eeeOnRemove',\n            },\n            link: function (scope, elem, attrs) {\n                scope.$watch(() => scope.ctrl.identity, (newIdentity, oldIdentity) => {\n                    if (hasValue(newIdentity) && newIdentity !== oldIdentity) {\n                        scope.ctrl.updateReceiverData();\n                    }\n                });\n                scope.$watch(() => scope.ctrl.contactReceiver, (newReceiver, oldReceiver) => {\n                    if (hasValue(newReceiver)) {\n                        if (!hasValue(oldReceiver) || newReceiver.id !== oldReceiver.id) {\n                            scope.ctrl.updateReceiverData();\n                        }\n                    }\n                });\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.click = () => {\n                        if (this.linked !== undefined\n                            && this.linked === true) {\n                            $state.go('messenger.home.conversation', { type: 'contact', id: this.identity, initParams: null });\n                        }\n                    };\n                    this.showActions = this.onRemove !== undefined;\n                    this.updateReceiverData = () => {\n                        if (this.contactReceiver === undefined) {\n                            this.contactReceiver = webClientService.contacts.get(this.identity);\n                        }\n                        else {\n                            this.identity = this.contactReceiver.id;\n                        }\n                    };\n                    this.$onInit = function () {\n                        this.updateReceiverData();\n                    };\n                }],\n            template: `\n                <div class=\"contact-badge receiver-badge\" ng-class=\"{'inactive': ctrl.contactReceiver.state == 'INACTIVE'}\" ng-click=\"ctrl.click()\">\n                    <section class=\"avatar-box\">\n                        <eee-avatar eee-receiver=\"ctrl.contactReceiver\"\n                                    eee-resolution=\"'low'\"></eee-avatar>\n                    </section>\n                    <div class=\"receiver-badge-name\" ng-bind-html=\"ctrl.contactReceiver | displayName | escapeHtml | emojify\"></div>\n                    <div class=\"contact-badge-identity\">{{ ctrl.contactReceiver.id }}</div>\n                    <div class=\"contact-badge-actions\" ng-if=\"ctrl.showActions\">\n                        <md-button aria-label=\"Remove\" class=\"md-icon-button\" ng-click=\"ctrl.onRemove(ctrl.contactReceiver)\">\n                            <i class=\"material-icons md-dark md-24\">delete</i>\n                        </md-button>\n                    </div>\n\n                </div>\n            `,\n        };\n    },\n];\n","export default [\n    'LogService',\n    function (logService) {\n        const log = logService.getLogger('DragFile-C');\n        return {\n            restrict: 'EA',\n            scope: {\n                submit: '=',\n                onUploading: '=',\n            },\n            link(scope, element) {\n                const DRAGOVER_CSS_CLASS = 'is-dragover';\n                const overlay = angular.element(element[0]);\n                const dragElement = angular.element(element[0]).parent('.drag-container');\n                function fetchFileListContents(fileList) {\n                    return new Promise((resolve) => {\n                        const buffers = new Map();\n                        const next = (file, res, error) => {\n                            buffers.set(file, res);\n                            if (buffers.size >= fileList.length) {\n                                resolve(buffers);\n                            }\n                            if (error !== undefined) {\n                                log.error('Error:', error);\n                            }\n                        };\n                        for (let n = 0; n < fileList.length; n++) {\n                            const reader = new FileReader();\n                            const file = fileList.item(n);\n                            reader.onload = function (ev) {\n                                next(file, this.result);\n                            };\n                            reader.onerror = function (ev) {\n                                next(file, null, ev);\n                            };\n                            reader.onprogress = function (ev) {\n                                if (ev.lengthComputable) {\n                                    const progress = ((ev.loaded / ev.total) * 100);\n                                    scope.onUploading(true, progress, 100 / fileList.length * n);\n                                }\n                            };\n                            reader.readAsArrayBuffer(file);\n                        }\n                    });\n                }\n                function uploadFiles(fileList) {\n                    scope.onUploading(true, 0, 0);\n                    fetchFileListContents(fileList).then((data) => {\n                        const fileMessages = [];\n                        data.forEach((buffer, file) => {\n                            const fileMessageData = {\n                                name: file.name,\n                                fileType: file.type,\n                                size: file.size,\n                                data: buffer,\n                            };\n                            fileMessages.push(fileMessageData);\n                        });\n                        scope.submit('file', fileMessages);\n                        scope.onUploading(false);\n                    }).catch((ev) => {\n                        log.error('Could not load file:', ev.message);\n                    });\n                }\n                function onDrop(ev) {\n                    ev.stopPropagation();\n                    ev.preventDefault();\n                    onDragLeave(ev);\n                    uploadFiles(ev.dataTransfer.files);\n                }\n                function onDragOver(ev) {\n                    ev.stopPropagation();\n                    ev.preventDefault();\n                    dragElement.addClass(DRAGOVER_CSS_CLASS);\n                }\n                function onDragLeave(ev) {\n                    ev.stopPropagation();\n                    ev.preventDefault();\n                    dragElement.removeClass(DRAGOVER_CSS_CLASS);\n                }\n                scope.$on('$destroy', scope.stopTyping);\n                dragElement.on('dragover dragenter', onDragOver);\n                overlay.on('dragleave dragend', onDragLeave);\n                overlay.on('drop', onDrop);\n            },\n            template: `\n                <div class=\"drag-file-overlay\">\n                    <div>\n                        <span translate>messenger.COMPOSE_MESSAGE_DRAGOVER</span>\n                     </div>\n                </div>`,\n        };\n    },\n];\n","export default [\n    '$translate',\n    '$state',\n    function ($translate, $state) {\n        return {\n            restrict: 'EA',\n            scope: {},\n            bindToController: {\n                groupReceiver: '=eeeGroupReceiver',\n                contactReceiver: '=?eeeContactReceiver',\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.click = () => {\n                        $state.go('messenger.home.conversation', {\n                            type: 'group',\n                            id: this.groupReceiver.id,\n                            initParams: null,\n                        });\n                    };\n                    this.$onInit = function () {\n                        this.showRoleIcon = this.contactReceiver !== undefined;\n                        if (this.showRoleIcon) {\n                            if (this.contactReceiver.id === this.groupReceiver.administrator) {\n                                this.roleIcon = 'people';\n                                $translate('messenger.GROUP_ROLE_CREATOR')\n                                    .then((label) => this.roleName = label);\n                            }\n                            else {\n                                this.roleIcon = 'people_outline';\n                                $translate('messenger.GROUP_ROLE_NORMAL')\n                                    .then((label) => this.roleName = label);\n                            }\n                        }\n                    };\n                }],\n            template: `\n                <div class=\"group-badge receiver-badge\" ng-click=\"ctrl.click()\">\n                    <section class=\"avatar-box\">\n                        <eee-avatar eee-receiver=\"ctrl.groupReceiver\"\n                                    eee-resolution=\"'low'\"></eee-avatar>\n                    </section>\n                    <div class=\"receiver-badge-name\"\n                        ng-bind-html=\"ctrl.groupReceiver.displayName | escapeHtml | emojify\">\n                    </div>\n                    <div class=\"receiver-role\" ng-if=\"ctrl.showRoleIcon\" title=\"{{ctrl.roleLabel}}\">\n                        <md-icon aria-label=\"{{ctrl.roleLabel}}\"  class=\"material-icons md-24\">\n                            {{ctrl.roleIcon}}\n                        </md-icon>\n                    </div>\n\n                </div>\n            `,\n        };\n    },\n];\n","export function getSenderIdentity(message, myId) {\n    if (message.isOutbox) {\n        return myId;\n    }\n    if (message.partnerId != null) {\n        return message.partnerId;\n    }\n    return null;\n}\n","import { getSenderIdentity } from '../helpers/messages';\nexport default [\n    'WebClientService', 'ReceiverService', 'MessageService', '$filter',\n    function (webClientService, receiverService, messageService, $filter) {\n        return {\n            restrict: 'EA',\n            scope: {},\n            bindToController: {\n                conversation: '<',\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.$onInit = function () {\n                        this.isGroup = this.conversation.type === 'group';\n                        this.isDistributionList = !this.isGroup && this.conversation.type === 'distributionList';\n                        this.showVoipInfo = () => this.conversation.latestMessage.type === 'voipStatus';\n                        this.getStatusIcon = () => {\n                            if (this.showVoipInfo()) {\n                                return 'phone_locked';\n                            }\n                            else if (this.isGroup) {\n                                return 'group';\n                            }\n                            else if (this.isDistributionList) {\n                                return 'forum';\n                            }\n                            else if (!this.conversation.latestMessage.isOutbox) {\n                                return 'reply';\n                            }\n                            else {\n                                const showStatusIcon = messageService.showStatusIcon(this.conversation.latestMessage, this.conversation.receiver);\n                                return showStatusIcon ? $filter('messageStateIcon')(this.conversation.latestMessage) : null;\n                            }\n                        };\n                        this.getContact = () => {\n                            return webClientService.contacts.get(getSenderIdentity(this.conversation.latestMessage, webClientService.me.id));\n                        };\n                        const contact = this.getContact();\n                        this.isTyping = () => false;\n                        if (this.isGroup === false && this.isDistributionList === false && contact !== null) {\n                            this.isTyping = () => webClientService.isTyping(contact);\n                        }\n                        this.isHidden = () => this.conversation.receiver.locked;\n                        this.showIcon = () => {\n                            const message = this.conversation.latestMessage;\n                            return message.type !== 'text' && message.type !== 'status';\n                        };\n                        this.getDraft = () => webClientService.getDraft(this.conversation.receiver);\n                        this.showDraft = () => {\n                            if (receiverService.isConversationActive(this.conversation.receiver)) {\n                                return false;\n                            }\n                            const draft = this.getDraft();\n                            return draft !== undefined && draft !== null;\n                        };\n                    };\n                }],\n            templateUrl: 'directives/latest_message.html',\n        };\n    },\n];\n","import { saveAs } from 'file-saver';\nimport { bufferToUrl } from '../helpers';\nexport default [\n    '$rootScope',\n    '$document',\n    'LogService',\n    'MediaboxService',\n    function ($rootScope, $document, logService, mediaboxService) {\n        const log = logService.getLogger('Mediabox-C');\n        return {\n            restrict: 'E',\n            scope: {},\n            bindToController: {},\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.imageDataUrl = null;\n                    this.caption = '';\n                    this.close = ($event) => {\n                        if ($event !== undefined) {\n                            if ($event.target === $event.currentTarget) {\n                                this.imageDataUrl = null;\n                            }\n                        }\n                        else {\n                            this.imageDataUrl = null;\n                        }\n                    };\n                    this.save = () => {\n                        saveAs(new Blob([mediaboxService.data]), mediaboxService.filename || 'image.jpg');\n                    };\n                    mediaboxService.evtMediaChanged.attach((dataAvailable) => {\n                        $rootScope.$apply(() => {\n                            if (dataAvailable) {\n                                this.imageDataUrl = bufferToUrl(mediaboxService.data, mediaboxService.mimetype, log);\n                                this.caption = mediaboxService.caption || mediaboxService.filename;\n                            }\n                            else {\n                                this.close();\n                            }\n                        });\n                    });\n                }],\n            link($scope, $element, attrs) {\n                $document.on('keyup', (e) => {\n                    const ke = e;\n                    if (ke.key === 'Escape' && $scope.ctrl.imageDataUrl !== null) {\n                        $scope.$apply($scope.ctrl.close);\n                    }\n                });\n            },\n            template: `\n                <div class=\"box\" ng-if=\"ctrl.imageDataUrl !== null\">\n                    <md-icon class=\"save material-icons md-24\" ng-click=\"ctrl.save()\" aria-label=\"Save\" translate-attr=\"{'aria-label': 'common.SAVE', 'title': 'common.SAVE'}\">save</md-icon>\n                    <md-icon class=\"close material-icons md-24\" ng-click=\"ctrl.close()\" aria-label=\"Close\" translate-attr=\"{'aria-label': 'common.CLOSE', 'title': 'common.CLOSE'}\">close</md-icon>\n                    <div class=\"inner\" ng-click=\"ctrl.close($event)\">\n                        <img ng-src=\"{{ ctrl.imageDataUrl }}\">\n                        <div class=\"caption\" title=\"{{ ctrl.caption | escapeHtml}}\">\n                            <span ng-bind-html=\"ctrl.caption | escapeHtml | markify | emojify\"></span>\n                        </div>\n                    </div>\n                </div>\n            `,\n        };\n    },\n];\n","import { hasFeature } from '../helpers';\nconst AUTOCOMPLETE_MAX_RESULTS = 20;\nexport default [\n    'LogService', 'WebClientService',\n    function (logService, webClientService) {\n        const log = logService.getLogger('MemberListEditor-C');\n        return {\n            restrict: 'EA',\n            scope: {},\n            bindToController: {\n                requiredMemberFeatureMask: '<',\n                members: '=activeMembers',\n                onChange: '=onChange',\n                placeholder: '=placeholder',\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.selectedItemChange = (contactReceiver) => {\n                        if (contactReceiver !== undefined) {\n                            this.members.push(contactReceiver.id);\n                            this.selectedItem = null;\n                            this.onChange(this.members);\n                        }\n                    };\n                    this.querySearch = (query) => {\n                        if (query !== undefined && query.length <= 0) {\n                            return [];\n                        }\n                        else {\n                            const lowercaseQuery = query.toLowerCase();\n                            const hideInactiveContacts = !webClientService.appConfig.showInactiveIDs;\n                            const result = this.allContacts\n                                .filter((contactReceiver) => {\n                                if (this.members.filter((id) => id === contactReceiver.id).length !== 0) {\n                                    return false;\n                                }\n                                if (hideInactiveContacts && contactReceiver.state === 'INACTIVE') {\n                                    return false;\n                                }\n                                if (contactReceiver.displayName.toLowerCase().indexOf(lowercaseQuery) >= 0) {\n                                    return true;\n                                }\n                                if (contactReceiver.id.toLowerCase().indexOf(lowercaseQuery) >= 0) {\n                                    return true;\n                                }\n                                return false;\n                            });\n                            return result.length <= AUTOCOMPLETE_MAX_RESULTS ? result\n                                : result.slice(0, AUTOCOMPLETE_MAX_RESULTS);\n                        }\n                    };\n                    this.onRemoveMember = (contact) => {\n                        if (contact.id === webClientService.me.id) {\n                            return false;\n                        }\n                        this.members = this.members.filter((identity) => identity !== contact.id);\n                        return true;\n                    };\n                    this.$onInit = function () {\n                        this.allContacts = Array.from(webClientService.contacts.values())\n                            .filter((contactReceiver) => hasFeature(contactReceiver, this.requiredMemberFeatureMask, log));\n                    };\n                }],\n            template: `\n                <ul class=\"member-list\">\n                    <li>\n                        <md-autocomplete\n                                md-no-cache=\"false\"\n                                md-delay=\"200\"\n                                md-selected-item=\"ctrl.selectedItem\"\n                                md-search-text=\"ctrl.searchText\"\n                                md-selected-item-change=\"ctrl.selectedItemChange(contactReceiver)\"\n                                md-items=\"contactReceiver in ctrl.querySearch(ctrl.searchText)\"\n                                md-item-text=\"contactReceiver.displayName\"\n                                md-min-length=\"0\"\n                                placeholder=\"{{ctrl.placeholder}}\"\n                                md-menu-class=\"autocomplete-custom-template\">\n                            <md-item-template>\n                                <eee-contact-badge\n                                        eee-contact=\"contactReceiver\"\n                                        eee-disable-click=\"true\"/>\n                            </md-item-template>\n                        </md-autocomplete>\n                    </li>\n                    <li ng-repeat=\"identity in ctrl.members\">\n                        <eee-contact-badge\n                                eee-identity=\"identity\"\n                                eee-disable-click=\"true\"\n                                eee-on-remove=\"ctrl.onRemoveMember\"/>\n                    </li>\n                </ul>\n            `,\n        };\n    },\n];\n","import { saveAs } from 'file-saver';\nimport * as clipboard from '../helpers/clipboard';\nimport { getSenderIdentity } from '../helpers/messages';\nexport default [\n    'BrowserService',\n    'LogService',\n    'MessageService',\n    'ReceiverService',\n    'WebClientService',\n    '$mdDialog',\n    '$mdToast',\n    '$translate',\n    '$rootScope',\n    function (browserService, logService, messageService, receiverService, webClientService, $mdDialog, $mdToast, $translate, $rootScope) {\n        const log = logService.getLogger('Message-C');\n        return {\n            restrict: 'E',\n            scope: {},\n            bindToController: {\n                type: '=eeeType',\n                receiver: '=eeeReceiver',\n                message: '=eeeMessage',\n                resolution: '=?eeeResolution',\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.browserInfo = browserService.getBrowser();\n                    this.$onInit = function () {\n                        if (this.resolution == null) {\n                            this.resolution = 'low';\n                        }\n                        this.contact = webClientService.contacts.get(getSenderIdentity(this.message, webClientService.me.id));\n                        this.isStatusMessage = this.message.isStatus;\n                        this.isContactMessage = !this.message.isStatus\n                            && webClientService.contacts.has(getSenderIdentity(this.message, webClientService.me.id));\n                        this.isGroup = this.type === 'group';\n                        this.isContact = this.type === 'contact';\n                        this.isBusinessReceiver = receiverService.isBusinessContact(this.receiver);\n                        this.showName = !this.message.isOutbox && this.isGroup;\n                        this.showAvatar = this.showName;\n                        this.showText = this.message.type === 'text' || this.message.caption;\n                        this.showMedia = this.message.type !== 'text';\n                        this.showState = messageService.showStatusIcon(this.message, this.receiver);\n                        this.showQuote = this.message.quote !== undefined;\n                        this.showVoipInfo = this.message.type === 'voipStatus';\n                        this.access = messageService.getAccess(this.message, this.receiver);\n                        this.ack = (ack) => {\n                            webClientService.ackMessage(this.receiver, this.message, ack);\n                        };\n                        this.quote = () => {\n                            webClientService.setQuote(this.receiver, this.message);\n                        };\n                        this.delete = (ev) => {\n                            const confirm = $mdDialog.confirm()\n                                .title($translate.instant('messenger.CONFIRM_DELETE_TITLE'))\n                                .textContent($translate.instant('common.ARE_YOU_SURE'))\n                                .targetEvent(ev)\n                                .ok($translate.instant('common.YES'))\n                                .cancel($translate.instant('common.CANCEL'));\n                            $mdDialog.show(confirm).then((result) => {\n                                webClientService.deleteMessage(this.receiver, this.message);\n                            }, () => { });\n                        };\n                        this.copyToClipboard = (ev) => {\n                            const text = messageService.getQuoteText(this.message);\n                            if (text === null) {\n                                return;\n                            }\n                            let toastString = 'messenger.COPIED';\n                            try {\n                                clipboard.copyString(text, this.browserInfo.isSafari());\n                            }\n                            catch (error) {\n                                log.warn('Could not copy text to clipboard:', error);\n                                toastString = 'messenger.COPY_ERROR';\n                            }\n                            const toast = $mdToast.simple()\n                                .textContent($translate.instant(toastString))\n                                .position('bottom center');\n                            $mdToast.show(toast);\n                        };\n                        this.download = (ev) => {\n                            this.downloading = true;\n                            webClientService.requestBlob(this.message.id, this.receiver)\n                                .then((blobInfo) => {\n                                $rootScope.$apply(() => {\n                                    this.downloading = false;\n                                    switch (this.message.type) {\n                                        case 'image':\n                                        case 'video':\n                                        case 'file':\n                                        case 'audio':\n                                            saveAs(new Blob([blobInfo.buffer]), blobInfo.filename);\n                                            break;\n                                        default:\n                                            log.warn('Ignored download request for message type', this.message.type);\n                                    }\n                                });\n                            })\n                                .catch((error) => {\n                                log.error(`Error downloading blob: ${error}`);\n                                this.downloading = false;\n                            });\n                        };\n                        this.isDownloading = () => {\n                            return this.downloading;\n                        };\n                        this.showHistory = (ev) => {\n                            const getEvents = () => this.message.events;\n                            const getMessageId = () => this.message.id;\n                            $mdDialog.show({\n                                controllerAs: 'ctrl',\n                                controller: function () {\n                                    this.getEvents = getEvents;\n                                    this.getMessageId = getMessageId;\n                                    this.close = () => {\n                                        $mdDialog.hide();\n                                    };\n                                },\n                                template: `\n                                <md-dialog class=\"message-history-dialog\" translate-attr=\"{'aria-label': 'messenger.MSG_HISTORY'}\">\n                                    <form ng-cloak>\n                                        <md-toolbar>\n                                            <div class=\"md-toolbar-tools\">\n                                                <h2 translate>messenger.MSG_HISTORY</h2>\n                                            </div>\n                                        </md-toolbar>\n                                        <md-dialog-content>\n                                            <p><span class=\"message-id\">Message ID:</span> {{ ctrl.getMessageId() }}</p>\n                                            <p ng-repeat=\"event in ctrl.getEvents()\">\n                                                <span class=\"event-type\" ng-if=\"event.type === 'created'\" translate>messenger.MSG_HISTORY_CREATED</span>\n                                                <span class=\"event-type\" ng-if=\"event.type === 'sent'\" translate>messenger.MSG_HISTORY_SENT</span>\n                                                <span class=\"event-type\" ng-if=\"event.type === 'delivered'\" translate>messenger.MSG_HISTORY_DELIVERED</span>\n                                                <span class=\"event-type\" ng-if=\"event.type === 'read'\" translate>messenger.MSG_HISTORY_READ</span>\n                                                <span class=\"event-type\" ng-if=\"event.type === 'acked'\" translate>messenger.MSG_HISTORY_ACKED</span>\n                                                <span class=\"event-type\" ng-if=\"event.type === 'modified'\" translate>messenger.MSG_HISTORY_MODIFIED</span>\n                                                {{ event.date | unixToTimestring:true }}\n                                            </p>\n                                        </md-dialog-content>\n                                        <md-dialog-actions layout=\"row\" >\n                                            <md-button ng-click=\"ctrl.close()\">\n                                                <span translate>common.OK</span>\n                                            </md-button>\n                                        </md-dialog-actions>\n                                    </form>\n                                </md-dialog>\n                            `,\n                                parent: angular.element(document.body),\n                                targetEvent: ev,\n                                clickOutsideToClose: true,\n                            });\n                        };\n                    };\n                }],\n            link: function (scope, element, attrs) {\n                const domElement = element[0];\n                if (scope.ctrl.isStatusMessage) {\n                    domElement.ondragstart = () => false;\n                }\n            },\n            templateUrl: 'directives/message.html',\n        };\n    },\n];\n","import { hasValue } from '../helpers';\nexport default [\n    function () {\n        return {\n            restrict: 'EA',\n            scope: {},\n            bindToController: {\n                message: '=eeeMessage',\n            },\n            link: function (scope, elem, attrs) {\n                scope.$watch(() => scope.ctrl.message.id, (newId, oldId) => {\n                    if (hasValue(newId) && newId !== oldId) {\n                        scope.ctrl.update();\n                    }\n                });\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    const getIcon = (msgType) => {\n                        switch (msgType) {\n                            case 'image':\n                                return 'ic_image_24px.svg';\n                            case 'video':\n                                return 'ic_movie_24px.svg';\n                            case 'audio':\n                                return 'ic_mic_24px.svg';\n                            case 'location':\n                                return 'ic_location_on_24px.svg';\n                            case 'file':\n                                if (this.message.file.type === 'image/gif') {\n                                    return 'ic_image_24px.svg';\n                                }\n                                return 'ic_insert_drive_file_24px.svg';\n                            case 'ballot':\n                                return 'ic_poll_24px.svg';\n                            default:\n                                return null;\n                        }\n                    };\n                    this.update = () => {\n                        this.icon = getIcon(this.message.type);\n                        this.altText = this.message.type + ' icon';\n                    };\n                    this.$onInit = function () {\n                        this.update();\n                    };\n                }],\n            template: `\n                <img ng-if=\"ctrl.icon !== null\" ng-src=\"img/{{ ctrl.icon }}\" alt=\"{{ ctrl.altText }}\">\n            `,\n        };\n    },\n];\n","import { saveAs } from 'file-saver';\nimport { bufferToUrl, hasValue } from '../helpers';\nfunction showAudioDialog($mdDialog, logService, blobInfo) {\n    const log = logService.getLogger('AudioPlayerDialog-C');\n    $mdDialog.show({\n        controllerAs: 'ctrl',\n        controller: function () {\n            this.cancel = () => $mdDialog.cancel();\n            this.audioSrc = bufferToUrl(blobInfo.buffer, blobInfo.mimetype, log);\n        },\n        template: `\n            <md-dialog translate-attr=\"{'aria-label': 'messageTypes.AUDIO_MESSAGE'}\">\n                    <md-toolbar>\n                        <div class=\"md-toolbar-tools\">\n                            <h2 translate>messageTypes.AUDIO_MESSAGE</h2>\n                            </div>\n                    </md-toolbar>\n                    <md-dialog-content layout=\"row\" layout-align=\"center\">\n                        <audio controls autoplay ng-src=\"{{ ctrl.audioSrc | unsafeResUrl }}\">\n                            Your browser does not support the <code>audio</code> element.\n                        </audio>\n                    </md-dialog-content>\n                    <md-dialog-actions layout=\"row\" >\n                      <md-button ng-click=\"ctrl.cancel()\">\n                         <span translate>common.OK</span>\n                      </md-button>\n                    </md-dialog-actions>\n            </md-dialog>`,\n        parent: angular.element(document.body),\n        clickOutsideToClose: true,\n    });\n}\nexport default [\n    'LogService',\n    'WebClientService',\n    'MediaboxService',\n    'MessageService',\n    'TimeoutService',\n    '$rootScope',\n    '$mdDialog',\n    '$timeout',\n    '$transitions',\n    '$translate',\n    '$filter',\n    '$window',\n    function (logService, webClientService, mediaboxService, messageService, timeoutService, $rootScope, $mdDialog, $timeout, $transitions, $translate, $filter, $window) {\n        const log = logService.getLogger('MessageMedia-C');\n        return {\n            restrict: 'EA',\n            scope: {},\n            bindToController: {\n                message: '=eeeMessage',\n                receiver: '=eeeReceiver',\n                showDownloading: '=eeeShowDownloading',\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    $transitions.onStart({}, function (trans) {\n                        mediaboxService.clearMedia();\n                    });\n                    this.$onInit = function () {\n                        const message = this.message;\n                        this.type = message.type;\n                        this.downloading = false;\n                        this.thumbnailDownloading = false;\n                        this.downloaded = false;\n                        this.uploading = message.temporaryId !== undefined\n                            && message.temporaryId !== null;\n                        this.isGif = message.type === 'file' && message.file.type === 'image/gif';\n                        this.hasPreviewThumbnail = () => {\n                            return hasValue(message.thumbnail) && (hasValue(message.thumbnail.previewDataUrl) || hasValue(message.thumbnail.preview));\n                        };\n                        this.getThumbnailPreviewUri = () => {\n                            if (hasValue(message.thumbnail.previewDataUrl)) {\n                                return message.thumbnail.previewDataUrl;\n                            }\n                            if (hasValue(message.thumbnail.preview)) {\n                                message.thumbnail.previewDataUrl = bufferToUrl(message.thumbnail.preview, webClientService.appCapabilities.imageFormat.thumbnail, log);\n                                return message.thumbnail.previewDataUrl;\n                            }\n                            return null;\n                        };\n                        this.getThumbnailPreviewUriStyle = () => {\n                            const previewUri = hasValue(message.thumbnail) ? this.getThumbnailPreviewUri() : null;\n                            return previewUri !== null ? `url(${previewUri})` : 'none';\n                        };\n                        this.thumbnail = null;\n                        if (message.thumbnail !== undefined) {\n                            this.thumbnailStyle = {\n                                width: this.message.thumbnail.width + 'px',\n                                height: this.message.thumbnail.height + 'px',\n                            };\n                        }\n                        let loadingThumbnailTimeout = null;\n                        this.wasInView = false;\n                        this.thumbnailInView = (inView) => {\n                            if (this.uploading || message.thumbnail === undefined || this.wasInView === inView) {\n                                return;\n                            }\n                            this.wasInView = inView;\n                            if (!inView) {\n                                if (loadingThumbnailTimeout !== null) {\n                                    timeoutService.cancel(loadingThumbnailTimeout);\n                                }\n                                this.thumbnailDownloading = false;\n                                this.thumbnail = null;\n                            }\n                            else {\n                                if (this.thumbnail === null) {\n                                    const setThumbnail = (buf) => {\n                                        this.thumbnail = bufferToUrl(buf, webClientService.appCapabilities.imageFormat.thumbnail, log);\n                                    };\n                                    if (message.thumbnail.img !== undefined) {\n                                        setThumbnail(message.thumbnail.img);\n                                        return;\n                                    }\n                                    else {\n                                        this.thumbnailDownloading = true;\n                                        loadingThumbnailTimeout = timeoutService.register(() => {\n                                            webClientService\n                                                .requestThumbnail(this.receiver, message)\n                                                .then((img) => $timeout(() => {\n                                                setThumbnail(img);\n                                                this.thumbnailDownloading = false;\n                                            }))\n                                                .catch((error) => {\n                                                const description = `Thumbnail request has been rejected: ${error}`;\n                                                this.log.error(description);\n                                            });\n                                        }, 1000, false, 'thumbnail');\n                                    }\n                                }\n                            }\n                        };\n                        this.location = null;\n                        if (message.location !== undefined) {\n                            this.location = message.location;\n                            this.downloaded = true;\n                        }\n                        this.openMapLink = () => {\n                            $window.open($filter('mapLink')(this.location), '_blank');\n                        };\n                        this.playAudio = (blobInfo) => showAudioDialog($mdDialog, logService, blobInfo);\n                        this.download = () => {\n                            log.debug('Download blob');\n                            if (this.uploading) {\n                                log.debug('Cannot download, still uploading');\n                                return;\n                            }\n                            if (this.downloading) {\n                                log.debug('Download already in progress...');\n                                return;\n                            }\n                            const receiver = this.receiver;\n                            this.downloading = true;\n                            webClientService.requestBlob(message.id, receiver)\n                                .then((blobInfo) => {\n                                $rootScope.$apply(() => {\n                                    log.debug('Blob loaded');\n                                    this.downloading = false;\n                                    this.downloaded = true;\n                                    switch (message.type) {\n                                        case 'image':\n                                            const caption = message.caption || '';\n                                            mediaboxService.setMedia(blobInfo.buffer, blobInfo.filename, blobInfo.mimetype, caption);\n                                            break;\n                                        case 'video':\n                                            saveAs(new Blob([blobInfo.buffer]), blobInfo.filename);\n                                            break;\n                                        case 'file':\n                                            if (message.file.type === 'image/gif') {\n                                                this.blobBufferUrl = bufferToUrl(blobInfo.buffer, 'image/gif', log);\n                                                this.showThumbnail = false;\n                                            }\n                                            else {\n                                                saveAs(new Blob([blobInfo.buffer]), blobInfo.filename);\n                                            }\n                                            break;\n                                        case 'audio':\n                                            this.playAudio(blobInfo);\n                                            break;\n                                        default:\n                                            log.warn('Ignored download request for message type', message.type);\n                                    }\n                                });\n                            })\n                                .catch((error) => {\n                                $rootScope.$apply(() => {\n                                    this.downloading = false;\n                                    let contentString;\n                                    switch (error) {\n                                        case 'blobDownloadFailed':\n                                            contentString = 'error.BLOB_DOWNLOAD_FAILED';\n                                            break;\n                                        case 'blobDecryptFailed':\n                                            contentString = 'error.BLOB_DECRYPT_FAILED';\n                                            break;\n                                        default:\n                                            contentString = 'error.ERROR_OCCURRED';\n                                            break;\n                                    }\n                                    const confirm = $mdDialog.alert()\n                                        .title($translate.instant('common.ERROR'))\n                                        .textContent($translate.instant(contentString))\n                                        .ok($translate.instant('common.OK'));\n                                    $mdDialog.show(confirm);\n                                });\n                            });\n                        };\n                        this.isLoading = () => {\n                            return this.uploading || this.isDownloading();\n                        };\n                        this.isDownloading = () => {\n                            return this.downloading\n                                || this.thumbnailDownloading\n                                || (this.showDownloading && this.showDownloading());\n                        };\n                    };\n                }],\n            templateUrl: 'directives/message_media.html',\n        };\n    },\n];\n","export default [\n    function () {\n        return {\n            restrict: 'EA',\n            transclude: true,\n            scope: {},\n            bindToController: {\n                message: '=eeeMessage',\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.$onInit = function () {\n                        const msg = this.message;\n                        this.type = msg.type;\n                        this.isGif = msg.file !== undefined && msg.file.type === 'image/gif';\n                        this.duration = null;\n                        if (msg.audio !== undefined) {\n                            this.duration = msg.audio.duration;\n                        }\n                        else if (msg.video !== undefined) {\n                            this.duration = msg.video.duration;\n                        }\n                        else if (msg.voip !== undefined && msg.voip.duration) {\n                            this.duration = msg.voip.duration;\n                        }\n                    };\n                }],\n            template: `\n                <span ng-if=\"ctrl.isGif\" class=\"message-meta-item\">GIF</span>\n                <span ng-if=\"ctrl.duration !== null\" class=\"message-meta-item message-duration\">\n                    <md-icon class=\"material-icons\">av_timer</md-icon>\n                    {{ctrl.duration | duration}}\n                </span>\n            `,\n        };\n    },\n];\n","import { hasValue } from '../helpers';\nimport { emojify, enlargeSingleEmoji } from '../helpers/emoji';\nfunction getText(message) {\n    switch (message.type) {\n        case 'text':\n            return message.body;\n        case 'location':\n            return message.location.description;\n        case 'file':\n            if (message.caption && message.caption.length > 0) {\n                return message.caption;\n            }\n            else if (message.file.type === 'image/gif') {\n                return 'GIF';\n            }\n            return message.file.name;\n    }\n    return message.caption;\n}\nexport default [\n    function () {\n        return {\n            restrict: 'EA',\n            scope: {},\n            bindToController: {\n                message: '=',\n                multiLine: '@?multiLine',\n                linkify: '@?linkify',\n            },\n            link: function (scope, elem, attrs) {\n                scope.$watch(() => scope.ctrl.message.id, (newId, oldId) => {\n                    if (hasValue(newId) && newId !== oldId) {\n                        scope.ctrl.updateText();\n                    }\n                });\n                scope.$watch(() => scope.ctrl.message.caption, (newCaption, oldCaption) => {\n                    if (hasValue(newCaption) && newCaption !== oldCaption) {\n                        scope.ctrl.updateText();\n                    }\n                });\n            },\n            controllerAs: 'ctrl',\n            controller: ['WebClientService', '$filter', function (webClientService, $filter) {\n                    const escapeHtml = $filter('escapeHtml');\n                    const markify = $filter('markify');\n                    const mentionify = $filter('mentionify');\n                    const linkify = $filter('linkify');\n                    const nlToBr = $filter('nlToBr');\n                    function processText(text, largeSingleEmoji, multiLine, linkifyText) {\n                        const nonLinkified = mentionify(enlargeSingleEmoji(emojify(markify(escapeHtml(text))), largeSingleEmoji));\n                        const maybeLinkified = linkifyText ? linkify(nonLinkified) : nonLinkified;\n                        return nlToBr(maybeLinkified, multiLine);\n                    }\n                    this.updateText = () => {\n                        const multiLine = (this.multiLine === undefined || this.multiLine !== 'false');\n                        const linkifyText = (this.linkify === undefined || this.linkify !== 'false');\n                        const text = getText(this.message);\n                        this.text = processText(text, this.largeSingleEmoji, multiLine, linkifyText);\n                    };\n                    this.largeSingleEmoji = webClientService.appConfig.largeSingleEmoji;\n                    this.$onInit = function () {\n                        this.updateText();\n                    };\n                }],\n            template: `\n                <span click-action ng-bind-html=\"ctrl.text\"></span>\n            `,\n        };\n    },\n];\n","export default [\n    '$translate', 'LogService',\n    function ($translate, logService) {\n        const log = logService.getLogger('VerificationLevel-C');\n        return {\n            restrict: 'EA',\n            scope: {},\n            bindToController: {\n                contact: '=',\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.$onInit = function () {\n                        const contact = this.contact;\n                        let label;\n                        switch (contact.verificationLevel) {\n                            case 1:\n                                this.cls = 'level1';\n                                label = 'VERIFICATION_LEVEL1_EXPLAIN';\n                                break;\n                            case 2:\n                                this.cls = 'level2';\n                                if (contact.isWork) {\n                                    label = 'VERIFICATION_LEVEL2_WORK_EXPLAIN';\n                                }\n                                else {\n                                    label = 'VERIFICATION_LEVEL2_EXPLAIN';\n                                }\n                                break;\n                            case 3:\n                                this.cls = 'level3';\n                                label = 'VERIFICATION_LEVEL3_EXPLAIN';\n                                break;\n                            default:\n                        }\n                        if (label === undefined) {\n                            log.error('invalid verification level', this.level);\n                            return;\n                        }\n                        if (contact.isWork) {\n                            this.cls += ' work';\n                        }\n                        this.description = $translate.instant('messenger.' + label);\n                    };\n                }],\n            template: `\n                <span class=\"verification-dots {{ctrl.cls}}\" title=\"{{ctrl.description}}\">\n                    <div></div><div></div><div></div>\n                </span>\n            `,\n        };\n    },\n];\n","angular.module('3ema.directives', []);\nimport autofocus from './directives/autofocus';\nimport avatar from './directives/avatar';\nimport avatarArea from './directives/avatar_area';\nimport avatarEditor from './directives/avatar_editor';\nimport batteryStatus from './directives/battery';\nimport clickAction from './directives/click_action';\nimport composeArea from './directives/compose_area';\nimport contactBadge from './directives/contact_badge';\nimport distributionListBadge from './directives/distribution_list_badge';\nimport dragFile from './directives/drag_file';\nimport groupBadge from './directives/group_badge';\nimport includeReplace from './directives/include_replace';\nimport latestMessage from './directives/latest_message';\nimport location from './directives/location';\nimport mediabox from './directives/mediabox';\nimport memberListEditor from './directives/member_list_editor';\nimport message from './directives/message';\nimport messageContact from './directives/message_contact';\nimport messageDate from './directives/message_date';\nimport messageIcon from './directives/message_icon';\nimport messageMedia from './directives/message_media';\nimport messageMeta from './directives/message_meta';\nimport messageQuote from './directives/message_quote';\nimport messageState from './directives/message_state';\nimport messageText from './directives/message_text';\nimport messageVoipStatus from './directives/message_voip_status';\nimport searchbox from './directives/searchbox';\nimport statusBar from './directives/status_bar';\nimport verificationLevel from './directives/verification_level';\nangular.module('3ema.directives').directive('autofocus', autofocus);\nangular.module('3ema.directives').directive('avatarArea', avatarArea);\nangular.module('3ema.directives').directive('avatarEditor', avatarEditor);\nangular.module('3ema.directives').directive('batteryStatus', batteryStatus);\nangular.module('3ema.directives').directive('clickAction', clickAction);\nangular.module('3ema.directives').directive('composeArea', composeArea);\nangular.module('3ema.directives').directive('dragFile', dragFile);\nangular.module('3ema.directives').directive('eeeAvatar', avatar);\nangular.module('3ema.directives').directive('eeeContactBadge', contactBadge);\nangular.module('3ema.directives').directive('eeeDistributionListBadge', distributionListBadge);\nangular.module('3ema.directives').directive('eeeGroupBadge', groupBadge);\nangular.module('3ema.directives').directive('eeeLatestMessage', latestMessage);\nangular.module('3ema.directives').directive('eeeMessage', message);\nangular.module('3ema.directives').directive('eeeMessageContact', messageContact);\nangular.module('3ema.directives').directive('eeeMessageDate', messageDate);\nangular.module('3ema.directives').directive('eeeMessageIcon', messageIcon);\nangular.module('3ema.directives').directive('eeeMessageMedia', messageMedia);\nangular.module('3ema.directives').directive('eeeMessageMeta', messageMeta);\nangular.module('3ema.directives').directive('eeeMessageQuote', messageQuote);\nangular.module('3ema.directives').directive('eeeMessageState', messageState);\nangular.module('3ema.directives').directive('eeeMessageText', messageText);\nangular.module('3ema.directives').directive('eeeMessageVoipStatus', messageVoipStatus);\nangular.module('3ema.directives').directive('eeeVerificationLevel', verificationLevel);\nangular.module('3ema.directives').directive('includeReplace', includeReplace);\nangular.module('3ema.directives').directive('location', location);\nangular.module('3ema.directives').directive('mediabox', mediabox);\nangular.module('3ema.directives').directive('memberListEditor', memberListEditor);\nangular.module('3ema.directives').directive('searchbox', searchbox);\nangular.module('3ema.directives').directive('statusBar', statusBar);\n","export default [\n    '$timeout',\n    function ($timeout) {\n        return {\n            restrict: 'A',\n            link(scope, element, attrs) {\n                $timeout(() => element[0].focus(), 0);\n            },\n        };\n    },\n];\n","export default [\n    '$rootScope',\n    '$translate',\n    'BatteryStatusService',\n    function ($rootScope, $translate, batteryStatusService) {\n        return {\n            restrict: 'E',\n            scope: {},\n            bindToController: {},\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.available = () => batteryStatusService.dataAvailable;\n                    this.alert = () => batteryStatusService.isLow && !batteryStatusService.isCharging;\n                    this.percent = () => batteryStatusService.percent;\n                    this.description = () => {\n                        if (batteryStatusService.isCharging) {\n                            return $translate.instant('battery.CHARGING', {\n                                percent: this.percent(),\n                            });\n                        }\n                        else if (this.alert()) {\n                            return $translate.instant('battery.ALERT', {\n                                percent: this.percent(),\n                            });\n                        }\n                        return $translate.instant('battery.DISCHARGING', {\n                            percent: this.percent(),\n                        });\n                    };\n                    this.icon = () => {\n                        if (batteryStatusService.isCharging) {\n                            return 'battery_charging_full';\n                        }\n                        else if (this.alert()) {\n                            return 'battery_alert';\n                        }\n                        return 'battery_std';\n                    };\n                }],\n            template: `\n                <div class=\"battery-status\" ng-if=\"ctrl.available()\"\" ng-class=\"{'alert': ctrl.alert()}\">\n                    <md-icon\n                        aria-label=\"Battery status: {{ ctrl.description() }}\"\n                        title=\"{{ ctrl.description() }}\"\n                        class=\"material-icons md-light md-24\">{{ ctrl.icon() }}</md-icon>\n                    <span class=\"battery-percent\" aria-hidden=\"true\">{{ ctrl.percent() }}%</span>\n                </div>\n            `,\n        };\n    },\n];\n","export default [\n    '$state',\n    function ($state) {\n        return {\n            restrict: 'EA',\n            scope: {},\n            bindToController: {\n                distributionListReceiver: '=eeeDistributionListReceiver',\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.click = () => {\n                        $state.go('messenger.home.conversation', {\n                            type: 'distributionList',\n                            id: this.distributionListReceiver.id,\n                            initParams: null,\n                        });\n                    };\n                }],\n            template: `\n                <div class=\"distribution-list-badge receiver-badge\" ng-click=\"ctrl.click()\">\n                    <section class=\"avatar-box\">\n                        <eee-avatar eee-receiver=\"ctrl.distributionListReceiver\"\n                                    eee-resolution=\"'low'\"></eee-avatar>\n                    </section>\n                    <div class=\"receiver-badge-name\"\n                        ng-bind-html=\"ctrl.distributionListReceiver.displayName | escapeHtml | emojify\">\n                    </div>\n\n                </div>\n            `,\n        };\n    },\n];\n","export default [\n    function () {\n        return {\n            restrict: 'EA',\n            scope: {\n                contact: '=eeeContact',\n                colored: '=eeeColored',\n            },\n            template: `\n                <span class=\"message-name\"\n                    ng-style=\"colored && {'color': contact.color}\"\n                       ng-bind-html=\"contact | displayName | escapeHtml | emojify\">\n                </span>\n            `,\n        };\n    },\n];\n","export default [\n    function () {\n        return {\n            restrict: 'EA',\n            scope: {\n                message: '=eeeMessage',\n            },\n            template: `\n                <span title=\"{{ message.date | unixToTimestring:true }}\">{{ message.date | unixToTimestring }}</span>\n            `,\n        };\n    },\n];\n","export default [\n    'WebClientService',\n    function (webClientService) {\n        return {\n            restrict: 'EA',\n            scope: {},\n            bindToController: {\n                quote: '=eeeQuote',\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.contact = () => webClientService.contacts.get(this.quote.identity);\n                }],\n            template: `\n                <div class=\"message-quote-content\" ng-style=\"{'border-color': ctrl.contact().color}\" role=\"blockquote\">\n                    <span class=\"message-name\" ng-style=\"{'color': ctrl.contact().color}\"\n                        ng-bind-html=\"ctrl.contact().displayName | escapeHtml | emojify\"></span>\n                    <span class=\"message-quote\" ng-bind-html=\"ctrl.quote.text | escapeHtml | markify | emojify | linkify | mentionify | nlToBr\"></span>\n                </div>\n            `,\n        };\n    },\n];\n","export default [\n    function () {\n        return {\n            restrict: 'EA',\n            scope: {\n                message: '=eeeMessage',\n            },\n            template: `\n                <i\n                    class=\"material-icons md-dark md-14 {{message.state}}\"\n                    title=\"{{ message | messageStateTitleText | translate }}\"\n                    aria-label=\"icon {{ message | messageStateTitleText | translate }}\"\n                >{{ message | messageStateIcon }}</i>\n            `,\n        };\n    },\n];\n","export default [\n    function () {\n        return {\n            restrict: 'EA',\n            scope: {},\n            bindToController: {\n                message: '=eeeMessage',\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.$onInit = function () {\n                        const voip = this.message.voip;\n                        const incoming = !this.message.isOutbox;\n                        switch (voip.status) {\n                            case 1:\n                                this.colorClass = 'color-status-error';\n                                this.icon = 'call_missed';\n                                this.msgString = 'voip.CALL_MISSED';\n                                break;\n                            case 2:\n                                this.colorClass = 'color-status-ok';\n                                if (incoming) {\n                                    this.icon = 'call_received';\n                                    this.msgString = 'voip.CALL_FINISHED_IN';\n                                }\n                                else {\n                                    this.icon = 'call_made';\n                                    this.msgString = 'voip.CALL_FINISHED_OUT';\n                                }\n                                break;\n                            case 3:\n                                if (incoming) {\n                                    this.icon = 'call_missed';\n                                    switch (voip.reason) {\n                                        case 1:\n                                            this.colorClass = 'color-status-error';\n                                            this.msgString = 'voip.CALL_MISSED_BUSY';\n                                            break;\n                                        case 3:\n                                            this.colorClass = 'color-status-warning';\n                                            this.msgString = 'voip.CALL_REJECTED';\n                                            break;\n                                        case 0:\n                                        case 2:\n                                        case 4:\n                                        default:\n                                            this.colorClass = 'color-status-error';\n                                            this.msgString = 'voip.CALL_MISSED';\n                                            break;\n                                    }\n                                }\n                                else {\n                                    this.icon = 'call_missed_outgoing';\n                                    this.colorClass = 'color-status-error';\n                                    switch (voip.reason) {\n                                        case 1:\n                                            this.msgString = 'voip.CALL_REJECTED_BUSY';\n                                            break;\n                                        case 2:\n                                            this.msgString = 'voip.CALL_REJECTED_UNAVAILABLE';\n                                            break;\n                                        case 4:\n                                            this.msgString = 'voip.CALL_REJECTED_DISABLED';\n                                            break;\n                                        case 3:\n                                        case 0:\n                                        default:\n                                            this.msgString = 'voip.CALL_REJECTED';\n                                            break;\n                                    }\n                                }\n                                break;\n                            case 4:\n                                this.colorClass = 'color-status-warning';\n                                this.icon = 'call_missed_outgoing';\n                                this.msgString = 'voip.CALL_ABORTED';\n                                break;\n                        }\n                    };\n                }],\n            template: `\n                 <p>\n                    <md-icon class=\"material-icons {{ ctrl.colorClass }}\">{{ ctrl.icon }}</md-icon>\n                    <span translate>{{ ctrl.msgString }}</span>\n                </p>\n            `,\n        };\n    },\n];\n","export default [\n    function () {\n        return {\n            require: 'ngInclude',\n            restrict: 'A',\n            link(scope, el, attrs) {\n                el.replaceWith(el.children());\n            },\n        };\n    },\n];\n","export default [\n    function () {\n        return {\n            restrict: 'E',\n            scope: {},\n            bindToController: {\n                location: '=',\n            },\n            controllerAs: 'ctrl',\n            controller: [function () { }],\n            template: `\n                <div class=\"location-message\">\n                    <div class=\"circle\">\n                        <i class=\"material-icons md-24\">location_on</i>\n                    </div>\n                    <div class=\"location-details\">\n                        <div class=\"description\">{{ ctrl.location.description }}</div>\n                        <div class=\"details\" ng-if=\"ctrl.location.address\">{{ ctrl.location.address }}</div>\n                        <div class=\"details\" ng-if=\"!ctrl.location.address\">{{ ctrl.location.lat }}, {{ ctrl.location.lon }}</div>\n                    </div>\n                </div>\n            `,\n        };\n    },\n];\n","export default [\n    function () {\n        return {\n            restrict: 'A',\n            scope: {\n                visible: '=searchboxFocus',\n            },\n            link($scope, $element, attrs) {\n                $scope.$watch('visible', (currentValue, previousValue) => {\n                    const input = $element.find('input');\n                    if (currentValue === true && previousValue === false) {\n                        $element.addClass('visible');\n                        input[0].focus();\n                    }\n                    else if (currentValue === false && previousValue === true) {\n                        $element.removeClass('visible');\n                        input.val('').triggerHandler('change');\n                    }\n                });\n            },\n        };\n    },\n];\n","export default [\n    '$window',\n    'TrustedKeyStore',\n    'StateService',\n    function ($window, trustedKeyStore, stateService) {\n        return {\n            restrict: 'E',\n            scope: {},\n            bindToController: {\n                active: '=',\n            },\n            controllerAs: 'ctrl',\n            controller: [function () {\n                    this.logout = () => {\n                        trustedKeyStore.clearTrustedKey();\n                        $window.location.reload();\n                    };\n                    this.stateService = stateService;\n                }],\n            template: `\n                <div id=\"expanded-status-bar\" ng-class=\"{'active': ctrl.active}\">\n                    <div ng-if=\"ctrl.active\">\n                        <div class=\"loading\"><span></span></div>\n                    </div>\n                    <div>\n                        <h1 translate>connecting.CONNECTION_PROBLEMS</h1>\n                        <p class=\"details\" ng-if=\"ctrl.stateService.progress < 100\">\n                            <span ng-if=\"ctrl.stateService.connectionBuildupState === 'new'\" translate>connecting.RECOVERING_CONNECTION</span>\n                            <span ng-if=\"ctrl.stateService.connectionBuildupState === 'push'\" translate>connecting.WAITING_FOR_APP</span>\n                            <span ng-if=\"ctrl.stateService.connectionBuildupState === 'manual_start'\" translate>connecting.WAITING_FOR_APP_MANUAL</span>\n                            <span ng-if=\"ctrl.stateService.connectionBuildupState === 'connecting'\" translate>connecting.CONNECTING_TO_SERVER</span>\n                            <span ng-if=\"ctrl.stateService.connectionBuildupState === 'waiting'\" translate>connecting.CONNECTING_TO_APP</span>\n                            <span ng-if=\"ctrl.stateService.connectionBuildupState === 'peer_handshake'\" translate>connecting.CONNECTING_TO_APP</span>\n                        </p>\n                        <p class=\"details\" ng-if=\"ctrl.stateService.progress === 100\" translate>connecting.RECOVERING_CONNECTION</p>\n                    </div>\n                    <div ng-show=\"ctrl.stateService.connectionBuildupState !== 'done'\">\n                        <span class=\"progress\">{{ ctrl.stateService.progress }}%</span>\n                    </div>\n                </div>\n            `,\n        };\n    },\n];\n","const markupChars = {\n    [2]: '*',\n    [3]: '_',\n    [4]: '~',\n};\nconst cssClasses = {\n    [2]: 'text-bold',\n    [3]: 'text-italic',\n    [4]: 'text-strike',\n};\nfunction isMarkupToken(tokenType) {\n    return markupChars.hasOwnProperty(tokenType);\n}\nfunction isBoundary(character) {\n    return character === undefined || /[\\s.,!?¡¿‽⸮;:&(){}\\[\\]⟨⟩‹›«»'\"‘’“”*~\\-_…⋯᠁]/.test(character);\n}\nfunction isUrlBoundary(character) {\n    return character === undefined || !/[a-zA-Z0-9\\-._~:/?#\\[\\]@!$&'()*+,;=%]/.test(character);\n}\nfunction isUrlStart(substring) {\n    return substring.match(/^[a-zA-Z]+:\\/\\//) != null;\n}\nexport function tokenize(text) {\n    const tokens = [];\n    let textBuf = '';\n    let matchingUrl = false;\n    const pushTextBufToken = () => {\n        if (textBuf.length > 0) {\n            tokens.push({ kind: 0, value: textBuf });\n            textBuf = '';\n        }\n    };\n    for (let i = 0; i < text.length; i++) {\n        const currentChar = text[i];\n        if (!matchingUrl) {\n            matchingUrl = isUrlStart(text.substring(i));\n        }\n        if (matchingUrl) {\n            textBuf += currentChar;\n            const nextIsUrlBoundary = isUrlBoundary(text[i + 1]);\n            if (nextIsUrlBoundary) {\n                pushTextBufToken();\n                matchingUrl = false;\n            }\n        }\n        else {\n            const prevIsBoundary = isBoundary(text[i - 1]);\n            const nextIsBoundary = isBoundary(text[i + 1]);\n            if (currentChar === '*' && (prevIsBoundary || nextIsBoundary)) {\n                pushTextBufToken();\n                tokens.push({ kind: 2 });\n            }\n            else if (currentChar === '_' && (prevIsBoundary || nextIsBoundary)) {\n                pushTextBufToken();\n                tokens.push({ kind: 3 });\n            }\n            else if (currentChar === '~' && (prevIsBoundary || nextIsBoundary)) {\n                pushTextBufToken();\n                tokens.push({ kind: 4 });\n            }\n            else if (currentChar === '\\n') {\n                pushTextBufToken();\n                tokens.push({ kind: 1 });\n            }\n            else {\n                textBuf += currentChar;\n            }\n        }\n    }\n    pushTextBufToken();\n    return tokens;\n}\nexport function parse(tokens) {\n    const stack = [];\n    const tokensPresent = {\n        [2]: false,\n        [3]: false,\n        [4]: false,\n    };\n    const hasToken = (token, value) => {\n        if (value === undefined) {\n            return tokensPresent[token];\n        }\n        tokensPresent[token] = value;\n    };\n    const consumeStack = () => {\n        let textBuf = '';\n        for (const token of stack) {\n            switch (token.kind) {\n                case 0:\n                    textBuf += token.value;\n                    break;\n                case 2:\n                case 3:\n                case 4:\n                    textBuf += markupChars[token.kind];\n                    break;\n                case 1:\n                    throw new Error('Unexpected newline token on stack');\n                default:\n                    throw new Error('Unknown token on stack: ' + token.kind);\n            }\n        }\n        stack.splice(0, stack.length);\n        return textBuf;\n    };\n    const popStack = () => {\n        const stackTop = stack.pop();\n        if (stackTop === undefined) {\n            throw new Error('Stack is empty');\n        }\n        return stackTop;\n    };\n    const pushMarkup = (textParts, cssClass) => {\n        let html = `<span class=\"${cssClass}\">`;\n        for (let i = textParts.length - 1; i >= 0; i--) {\n            html += textParts[i];\n        }\n        html += '</span>';\n        stack.push({ kind: 0, value: html });\n    };\n    for (const token of tokens) {\n        switch (token.kind) {\n            case 0:\n                stack.push(token);\n                break;\n            case 2:\n            case 3:\n            case 4:\n                if (hasToken(token.kind)) {\n                    const textParts = [];\n                    while (true) {\n                        const stackTop = popStack();\n                        if (stackTop.kind === 0) {\n                            textParts.push(stackTop.value);\n                        }\n                        else if (stackTop.kind === token.kind) {\n                            if (textParts.length > 0) {\n                                pushMarkup(textParts, cssClasses[token.kind]);\n                            }\n                            else {\n                                const markupChar = markupChars[token.kind];\n                                stack.push({ kind: 0, value: markupChar + markupChar });\n                            }\n                            hasToken(token.kind, false);\n                            break;\n                        }\n                        else if (isMarkupToken(stackTop.kind)) {\n                            textParts.push(markupChars[stackTop.kind]);\n                        }\n                        else {\n                            throw new Error('Unknown token on stack: ' + token.kind);\n                        }\n                        hasToken(stackTop.kind, false);\n                    }\n                }\n                else {\n                    stack.push(token);\n                    hasToken(token.kind, true);\n                }\n                break;\n            case 1:\n                stack.push({ kind: 0, value: consumeStack() + '\\n' });\n                hasToken(2, false);\n                hasToken(3, false);\n                hasToken(4, false);\n                break;\n            default:\n                throw new Error('Invalid token kind: ' + token.kind);\n        }\n    }\n    return consumeStack();\n}\nexport function markify(text) {\n    return parse(tokenize(text));\n}\n","import Autolinker from 'autolinker';\nimport { escapeRegExp, filter, hasValue } from './helpers';\nimport { emojify } from './helpers/emoji';\nimport { markify } from './markup_parser';\nangular.module('3ema.filters', [])\n    .filter('escapeHtml', function () {\n    const map = {\n        '&': '&amp;',\n        '<': '&lt;',\n        '>': '&gt;',\n        '\"': '&quot;',\n        \"'\": '&#039;',\n    };\n    return (text) => {\n        if (text === undefined || text === null) {\n            text = '';\n        }\n        return text.replace(/[&<>\"']/g, (m) => map[m]);\n    };\n})\n    .filter('nlToBr', function () {\n    return (text, enabled) => {\n        if (enabled || enabled === undefined) {\n            text = text.replace(/\\n/g, '<br>');\n        }\n        return text;\n    };\n})\n    .filter('emptyToPlaceholder', function () {\n    return (text, placeholder = '-') => {\n        if (text === null || text === undefined || text.trim().length === 0) {\n            return placeholder;\n        }\n        return text;\n    };\n})\n    .filter('linkify', function () {\n    const autolinker = new Autolinker({\n        newWindow: true,\n        stripPrefix: false,\n        stripTrailingSlash: false,\n        truncate: 99999,\n        className: 'autolinked',\n        urls: true,\n        email: true,\n        phone: false,\n        mention: false,\n        hashtag: false,\n    });\n    return (text) => autolinker.link(text);\n})\n    .filter('emojify', () => emojify)\n    .filter('markify', () => markify)\n    .filter('mentionify', [\n    'WebClientService',\n    '$translate',\n    'escapeHtmlFilter',\n    function (webClientService, $translate, escapeHtmlFilter) {\n        return (text) => {\n            if (text !== null && text.length > 10) {\n                let result = text.match(/@\\[([\\*\\@a-zA-Z0-9][\\@a-zA-Z0-9]{7})\\]/g);\n                if (result !== null) {\n                    result = new Set(result);\n                    for (const possibleMention of result) {\n                        const identity = possibleMention.substr(2, 8);\n                        let mentionName;\n                        let cssClass;\n                        if (identity === '@@@@@@@@') {\n                            mentionName = $translate.instant('messenger.ALL');\n                            cssClass = 'all';\n                        }\n                        else if (identity === webClientService.me.id) {\n                            mentionName = webClientService.me.displayName;\n                            cssClass = 'me';\n                        }\n                        else {\n                            const contact = webClientService.contacts.get(possibleMention.substr(2, 8));\n                            if (contact !== null && contact !== undefined) {\n                                cssClass = 'id ' + identity;\n                                mentionName = contact.displayName;\n                            }\n                        }\n                        if (mentionName !== undefined) {\n                            text = text.replace(new RegExp(escapeRegExp(possibleMention), 'g'), '<span class=\"mention ' + cssClass + '\"'\n                                + ' text=\"@[' + identity + ']\">' + escapeHtmlFilter(mentionName) + '</span>');\n                        }\n                    }\n                }\n            }\n            return text;\n        };\n    },\n])\n    .filter('reverse', function () {\n    return (list) => list.slice().reverse();\n})\n    .filter('hasData', function () {\n    return function (obj, receivers) {\n        const valid = (receiver) => receivers.get(receiver.type).has(receiver.id);\n        return filter(obj, valid);\n    };\n})\n    .filter('hasContact', function () {\n    return function (obj, contacts) {\n        const valid = (item) => contacts.has(item.id);\n        return filter(obj, valid);\n    };\n})\n    .filter('duration', function () {\n    return function (seconds) {\n        const left = Math.floor(seconds / 60);\n        const right = seconds % 60;\n        const padLeft = left < 10 ? '0' : '';\n        const padRight = right < 10 ? '0' : '';\n        return padLeft + left + ':' + padRight + right;\n    };\n})\n    .filter('mapLink', function () {\n    return function (location) {\n        return 'https://www.openstreetmap.org/?mlat='\n            + location.lat + '&mlon='\n            + location.lon;\n    };\n})\n    .filter('messageStateIcon', function () {\n    return (message) => {\n        if (!message) {\n            return '';\n        }\n        if (!message.isOutbox) {\n            switch (message.state) {\n                case 'user-ack':\n                    return 'thumb_up';\n                case 'user-dec':\n                    return 'thumb_down';\n                default:\n                    return 'reply';\n            }\n        }\n        switch (message.state) {\n            case 'pending':\n            case 'sending':\n                return 'file_upload';\n            case 'sent':\n                return 'email';\n            case 'delivered':\n                return 'move_to_inbox';\n            case 'read':\n                return 'visibility';\n            case 'send-failed':\n                return 'report_problem';\n            case 'user-ack':\n                return 'thumb_up';\n            case 'user-dec':\n                return 'thumb_down';\n            default:\n                return '';\n        }\n    };\n})\n    .filter('messageStateTitleText', ['$translate', function ($translate) {\n        return (message) => {\n            if (!message) {\n                return null;\n            }\n            if (!message.isOutbox) {\n                switch (message.state) {\n                    case 'user-ack':\n                        return 'messageStates.WE_ACK';\n                    case 'user-dec':\n                        return 'messageStates.WE_DEC';\n                    default:\n                        return 'messageStates.UNKNOWN';\n                }\n            }\n            switch (message.state) {\n                case 'pending':\n                    return 'messageStates.PENDING';\n                case 'sending':\n                    return 'messageStates.SENDING';\n                case 'sent':\n                    return 'messageStates.SENT';\n                case 'delivered':\n                    return 'messageStates.DELIVERED';\n                case 'read':\n                    return 'messageStates.READ';\n                case 'send-failed':\n                    return 'messageStates.FAILED';\n                case 'user-ack':\n                    return 'messageStates.USER_ACK';\n                case 'user-dec':\n                    return 'messageStates.USER_DEC';\n                default:\n                    return 'messageStates.UNKNOWN';\n            }\n        };\n    }])\n    .filter('fileSize', function () {\n    return (size) => {\n        if (!size) {\n            return '';\n        }\n        const i = Math.floor(Math.log(size) / Math.log(1024));\n        const x = (size / Math.pow(1024, i)).toFixed(2);\n        return (x + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i]);\n    };\n})\n    .filter('mimeTypeLabel', ['MimeService', function (mimeService) {\n        return (mimeType) => mimeService.getLabel(mimeType);\n    }])\n    .filter('mimeTypeIcon', ['MimeService', function (mimeService) {\n        return (mimeType) => mimeService.getIconUrl(mimeType);\n    }])\n    .filter('idsToNames', ['WebClientService', '$filter', function (webClientService, $filter) {\n        return (ids) => {\n            const names = [];\n            for (const id of ids) {\n                const contactReceiver = webClientService.contacts.get(id);\n                if (hasValue(contactReceiver)) {\n                    names.push($filter('displayName')(contactReceiver));\n                }\n                else {\n                    names.push('Unknown');\n                }\n            }\n            return names.join(', ');\n        };\n    }])\n    .filter('unixToTimestring', ['$translate', function ($translate) {\n        function formatTime(date) {\n            return ('00' + date.getHours()).slice(-2) + ':' +\n                ('00' + date.getMinutes()).slice(-2);\n        }\n        function formatMonth(num) {\n            switch (num) {\n                case 0x0:\n                    return 'date.month_short.JAN';\n                case 0x1:\n                    return 'date.month_short.FEB';\n                case 0x2:\n                    return 'date.month_short.MAR';\n                case 0x3:\n                    return 'date.month_short.APR';\n                case 0x4:\n                    return 'date.month_short.MAY';\n                case 0x5:\n                    return 'date.month_short.JUN';\n                case 0x6:\n                    return 'date.month_short.JUL';\n                case 0x7:\n                    return 'date.month_short.AUG';\n                case 0x8:\n                    return 'date.month_short.SEP';\n                case 0x9:\n                    return 'date.month_short.OCT';\n                case 0xa:\n                    return 'date.month_short.NOV';\n                case 0xb:\n                    return 'date.month_short.DEC';\n            }\n        }\n        function isSameDay(date1, date2) {\n            return date1.getFullYear() === date2.getFullYear()\n                && date1.getMonth() === date2.getMonth()\n                && date1.getDate() === date2.getDate();\n        }\n        return (timestamp, forceFull = false) => {\n            const date = new Date(timestamp * 1000);\n            const now = new Date();\n            if (!forceFull && isSameDay(date, now)) {\n                return formatTime(date);\n            }\n            const yesterday = new Date(now.getTime() - 1000 * 60 * 60 * 24);\n            if (!forceFull && isSameDay(date, yesterday)) {\n                return $translate.instant('date.YESTERDAY') + ', ' + formatTime(date);\n            }\n            let year = '';\n            if (forceFull || date.getFullYear() !== now.getFullYear()) {\n                year = ' ' + date.getFullYear();\n            }\n            return date.getDate() + '. '\n                + $translate.instant(formatMonth(date.getMonth()))\n                + year + ', '\n                + formatTime(date);\n        };\n    }])\n    .filter('unsafeResUrl', ['$sce', function ($sce) {\n        return $sce.trustAsResourceUrl;\n    }])\n    .filter('displayName', ['WebClientService', '$translate',\n    function (webClientService, $translate) {\n        return function (contact) {\n            if (contact.id === webClientService.me.id) {\n                return $translate.instant('messenger.ME');\n            }\n            else {\n                return contact.displayName;\n            }\n        };\n    }])\n    .filter('strengthToColor', [function () {\n        return function (strength) {\n            switch (strength) {\n                case \"strong\":\n                    return '#05a63f';\n                case \"good\":\n                    return '#cddc39';\n                case \"weak\":\n                    return '#ff9800';\n                case \"bad\":\n                default:\n                    return '#f44336';\n            }\n        };\n    }]);\n","import { DialogController } from '../controllers/dialog';\nimport { scorePassword } from '../helpers/password_strength';\nclass WelcomeController {\n    constructor($scope, $state, $window, $mdDialog, $translate, logService, webClientService, trustedKeyStore, stateService, pushService, browserService, versionService, settingsService, timeoutService, controllerService, minVersions, config) {\n        this.name = 'welcome';\n        this.password = '';\n        this.passwordStrength = { score: 0, strength: \"bad\" };\n        this.formLocked = false;\n        this.pleaseUpdateAppMsg = null;\n        this.browserWarningShown = false;\n        controllerService.setControllerName('welcome');\n        this.$scope = $scope;\n        this.$state = $state;\n        this.$window = $window;\n        this.$mdDialog = $mdDialog;\n        this.$translate = $translate;\n        this.webClientService = webClientService;\n        this.trustedKeyStore = trustedKeyStore;\n        this.stateService = stateService;\n        this.pushService = pushService;\n        this.settingsService = settingsService;\n        this.timeoutService = timeoutService;\n        this.config = config;\n        this.log = logService.getLogger('Welcome-C');\n        this.browser = browserService.getBrowser();\n        const version = this.browser.version;\n        this.log.info('Detected browser:', this.browser.description());\n        if (!this.browser.wasDetermined()) {\n            this.log.warn('Could not determine browser version');\n            this.showBrowserWarning();\n        }\n        else if (this.browser.name === \"chrome\") {\n            if (version < minVersions.CHROME) {\n                this.log.warn('Chrome is too old (' + version + ' < ' + minVersions.CHROME + ')');\n                this.showBrowserWarning();\n            }\n        }\n        else if (this.browser.name === \"firefox\") {\n            if (version < minVersions.FF) {\n                this.log.warn('Firefox is too old (' + version + ' < ' + minVersions.FF + ')');\n                this.showBrowserWarning();\n            }\n        }\n        else if (this.browser.name === \"opera\") {\n            if (version < minVersions.OPERA) {\n                this.log.warn('Opera is too old (' + version + ' < ' + minVersions.OPERA + ')');\n                this.showBrowserWarning();\n            }\n        }\n        else if (this.browser.name === \"safari\") {\n            if (version < minVersions.SAFARI) {\n                this.log.warn('Safari is too old (' + version + ' < ' + minVersions.SAFARI + ')');\n                this.showBrowserWarning();\n            }\n        }\n        else if (this.browser.name === \"edge\") {\n            if (version < minVersions.EDGE) {\n                this.log.warn('Edge is too old (' + version + ' < ' + minVersions.EDGE + ')');\n                this.showBrowserWarning();\n            }\n        }\n        else {\n            this.log.warn('Non-supported browser, please use Chrome, Firefox, Edge or Opera');\n            this.showBrowserWarning();\n        }\n        if (this.trustedKeyStore.blocked === true) {\n            this.log.error('Cannot access local storage. Is it being blocked by a browser add-on?');\n            this.showLocalStorageWarning();\n        }\n        versionService.initVersion();\n        if (this.config.PREV_PROTOCOL_LAST_VERSION !== null) {\n            this.pleaseUpdateAppMsg = this.$translate.instant('troubleshooting.PLEASE_UPDATE_APP');\n            if (!this.config.SELF_HOSTED) {\n                this.pleaseUpdateAppMsg += ' ' + this.$translate.instant('troubleshooting.USE_ARCHIVE_VERSION', {\n                    archiveUrl: `https://web.threema.ch/archive/${this.config.PREV_PROTOCOL_LAST_VERSION}/`,\n                });\n            }\n        }\n        this.webClientService.clearCache();\n        let hasTrustedKey = null;\n        try {\n            hasTrustedKey = this.trustedKeyStore.hasTrustedKey();\n        }\n        catch (e) {\n            this.log.error('Exception while accessing local storage:', e);\n            this.showLocalStorageException(e);\n        }\n        if (hasTrustedKey) {\n            this.mode = 'unlock';\n            this.unlock();\n        }\n        else {\n            this.mode = 'scan';\n            this.scan();\n        }\n    }\n    get showLoadingIndicator() {\n        switch (this.stateService.connectionBuildupState) {\n            case 'push':\n            case 'peer_handshake':\n            case 'loading':\n            case 'done':\n                return true;\n            default:\n                return false;\n        }\n    }\n    get state() {\n        return this.stateService.connectionBuildupState;\n    }\n    get progress() {\n        return this.stateService.progress;\n    }\n    get slowConnect() {\n        return this.stateService.slowConnect;\n    }\n    get showWebrtcTroubleshooting() {\n        return this.webClientService.chosenTask === \"webrtc\";\n    }\n    scan(stopArguments) {\n        this.log.info('Initialize session by scanning QR code...');\n        this.webClientService.stop(stopArguments !== undefined ? stopArguments : {\n            reason: \"stop\",\n            send: false,\n            close: 'welcome',\n            connectionBuildupState: this.stateService.connectionBuildupState,\n        });\n        this.webClientService.init({\n            resume: false,\n        });\n        this.$scope.$watch(() => this.password, () => {\n            const payload = this.webClientService.buildQrCodePayload(this.password.length > 0);\n            this.qrCode = this.buildQrCode(payload);\n            this.passwordStrength = scorePassword(this.password);\n        });\n        this.setupBroadcastChannel(this.webClientService.salty.keyStore.publicKeyHex, 0)\n            .then((result) => {\n            this.$scope.$apply(() => {\n                switch (result) {\n                    case 'already_open':\n                        this.log.warn('Session already connected in another tab or window');\n                        break;\n                    case 'no_answer':\n                        this.start();\n                        break;\n                }\n            });\n        })\n            .catch((error) => {\n            this.$scope.$apply(() => {\n                this.log.warn('Unable to set up broadcast channel:', error);\n                this.start();\n            });\n        });\n    }\n    unlock() {\n        this.stateService.reset('new');\n        this.log.info('Initialize session by unlocking trusted key...');\n    }\n    unlockConfirm() {\n        this.formLocked = true;\n        const decrypted = this.trustedKeyStore.retrieveTrustedKey(this.password);\n        if (decrypted === null) {\n            this.formLocked = false;\n            return this.showDecryptionFailed();\n        }\n        const keyStore = new saltyrtcClient.KeyStore(decrypted.ownSecretKey);\n        this.setupBroadcastChannel(keyStore.publicKeyHex, WelcomeController.BROADCAST_DELAY)\n            .then((result) => {\n            this.$scope.$apply(() => {\n                switch (result) {\n                    case 'already_open':\n                        this.log.warn('Session already connected in another tab or window');\n                        break;\n                    case 'no_answer':\n                        this.log.debug('No broadcast received indicating that a session is already open');\n                        this.reconnect(keyStore, decrypted);\n                        break;\n                }\n            });\n        })\n            .catch((error) => {\n            this.$scope.$apply(() => {\n                this.log.warn('Unable to set up broadcast channel:', error);\n                this.reconnect(keyStore, decrypted);\n            });\n        });\n    }\n    setupBroadcastChannel(publicKeyHex, delayMs) {\n        const future = new Future();\n        if (!('BroadcastChannel' in this.$window)) {\n            future.reject('BroadcastChannel not supported in this browser');\n            return future;\n        }\n        const CHANNEL_NAME = 'session-check';\n        const TYPE_PUBLIC_KEY = 'public-key';\n        const TYPE_ALREADY_OPEN = 'already-open';\n        const channel = new BroadcastChannel(CHANNEL_NAME);\n        channel.onmessage = (event) => {\n            const message = JSON.parse(event.data);\n            switch (message.type) {\n                case TYPE_PUBLIC_KEY:\n                    if (message.key === publicKeyHex\n                        && (this.stateService.connectionBuildupState === 'loading'\n                            || this.stateService.connectionBuildupState === 'done')) {\n                        this.log.debug('Another tab is trying to connect to our session. Respond with a broadcast.');\n                        channel.postMessage(JSON.stringify({\n                            type: TYPE_ALREADY_OPEN,\n                            key: publicKeyHex,\n                        }));\n                    }\n                    break;\n                case TYPE_ALREADY_OPEN:\n                    if (message.key === publicKeyHex && this.stateService.connectionBuildupState !== 'done') {\n                        future.resolve('already_open');\n                        this.timeoutService.register(() => {\n                            this.stateService.updateConnectionBuildupState('already_connected');\n                            this.stateService.state = \"error\";\n                        }, 500, true, 'alreadyConnected');\n                    }\n                    break;\n                default:\n                    this.log.warn('Unknown broadcast message type:', message.type);\n                    break;\n            }\n        };\n        this.log.debug('Checking if the session is already open in another tab or window');\n        channel.postMessage(JSON.stringify({\n            type: TYPE_PUBLIC_KEY,\n            key: publicKeyHex,\n        }));\n        setTimeout(() => future.resolve('no_answer'), delayMs);\n        return future;\n    }\n    reconnect(keyStore, decrypted) {\n        this.webClientService.stop({\n            reason: \"stop\",\n            send: false,\n            close: 'welcome',\n            connectionBuildupState: this.stateService.connectionBuildupState,\n        });\n        if (decrypted.pushToken !== null && decrypted.pushTokenType !== null) {\n            this.webClientService.updatePushToken(decrypted.pushToken, decrypted.pushTokenType);\n            this.pushService.init(decrypted.pushToken, decrypted.pushTokenType);\n        }\n        this.webClientService.init({\n            keyStore: keyStore,\n            peerTrustedKey: decrypted.peerPublicKey,\n            resume: false,\n        });\n        this.start();\n    }\n    showBrowserWarning() {\n        this.browserWarningShown = true;\n        this.$translate.onReady().then(() => {\n            const confirm = this.$mdDialog.confirm()\n                .title(this.$translate.instant('welcome.BROWSER_NOT_SUPPORTED'))\n                .htmlContent(this.$translate.instant('welcome.BROWSER_NOT_SUPPORTED_DETAILS', {\n                firefoxLink: '<a href=\"https://www.mozilla.org/firefox/\" target=\"_blank\" rel=\"noopener noreferrer\">Firefox</a>',\n                chromeLink: '<a href=\"https://www.google.com/chrome/browser/desktop/\" target=\"_blank\" rel=\"noopener noreferrer\">Chrome</a>',\n                operaLink: '<a href=\"https://www.opera.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Opera</a>',\n                edgeLink: '<a href=\"https://www.microsoft.com/edge\" target=\"_blank\" rel=\"noopener noreferrer\">Edge</a>',\n                safariLink: '<a href=\"https://www.apple.com/safari/\" target=\"_blank\" rel=\"noopener noreferrer\">Safari</a>',\n            }))\n                .ok(this.$translate.instant('welcome.CONTINUE_ANYWAY'))\n                .cancel(this.$translate.instant('welcome.ABORT'));\n            this.$mdDialog.show(confirm).then(() => {\n            }, () => {\n                window.location.replace('https://threema.ch/threema-web');\n            });\n        });\n    }\n    showLocalStorageWarning() {\n        this.$translate.onReady().then(() => {\n            const confirm = this.$mdDialog.alert()\n                .title(this.$translate.instant('common.ERROR'))\n                .htmlContent(this.$translate.instant('welcome.LOCAL_STORAGE_MISSING_DETAILS'))\n                .ok(this.$translate.instant('common.OK'));\n            this.$mdDialog.show(confirm);\n        });\n    }\n    showLocalStorageException(e) {\n        this.$translate.onReady().then(() => {\n            const confirm = this.$mdDialog.alert()\n                .title(this.$translate.instant('common.ERROR'))\n                .htmlContent(this.$translate.instant('welcome.LOCAL_STORAGE_EXCEPTION_DETAILS', {\n                errorMsg: e.name,\n            }))\n                .ok(this.$translate.instant('common.OK'));\n            this.$mdDialog.show(confirm);\n        });\n    }\n    showDecryptionFailed() {\n        this.$mdDialog.show({\n            controller: DialogController,\n            controllerAs: 'ctrl',\n            templateUrl: 'partials/dialog.unlockfailed.html',\n            parent: angular.element(document.body),\n            clickOutsideToClose: true,\n            fullscreen: true,\n        });\n    }\n    showAlreadyConnected() {\n        this.$translate.onReady().then(() => {\n            const confirm = this.$mdDialog.alert()\n                .title(this.$translate.instant('welcome.ALREADY_CONNECTED'))\n                .htmlContent(this.$translate.instant('welcome.ALREADY_CONNECTED_DETAILS'))\n                .ok(this.$translate.instant('common.OK'));\n            this.$mdDialog.show(confirm);\n        });\n    }\n    deleteSession(ev) {\n        const confirm = this.$mdDialog.confirm()\n            .title(this.$translate.instant('common.SESSION_DELETE'))\n            .textContent(this.$translate.instant('common.CONFIRM_DELETE_BODY'))\n            .targetEvent(ev)\n            .ok(this.$translate.instant('common.YES'))\n            .cancel(this.$translate.instant('common.CANCEL'));\n        this.$mdDialog.show(confirm).then(() => {\n            this.mode = 'scan';\n            this.clearPassword();\n            this.formLocked = false;\n            this.scan({\n                reason: \"delete\",\n                send: true,\n                close: 'welcome',\n            });\n        }, () => {\n        });\n    }\n    buildQrCode(payload) {\n        const len = payload.length;\n        let version;\n        if (len <= 134) {\n            version = 6;\n        }\n        else if (len <= 154) {\n            version = 7;\n        }\n        else if (len <= 192) {\n            version = 8;\n        }\n        else if (len <= 230) {\n            version = 9;\n        }\n        else if (len <= 271) {\n            version = 10;\n        }\n        else if (len <= 321) {\n            version = 11;\n        }\n        else if (len <= 367) {\n            version = 12;\n        }\n        else if (len <= 425) {\n            version = 13;\n        }\n        else if (len <= 458) {\n            version = 14;\n        }\n        else if (len <= 520) {\n            version = 15;\n        }\n        else if (len <= 586) {\n            version = 16;\n        }\n        else {\n            this.log.error('QR Code payload too large: Is your SaltyRTC host string huge?');\n            version = 40;\n        }\n        return {\n            version: version,\n            errorCorrectionLevel: 'L',\n            size: 384,\n            data: payload,\n        };\n    }\n    clearPassword() {\n        this.password = '';\n        this.passwordStrength = { score: 0, strength: \"bad\" };\n    }\n    start() {\n        this.webClientService.start().then(() => {\n            this.webClientService.setPassword(this.password);\n            this.clearPassword();\n            this.formLocked = false;\n            this.timeoutService.register(() => this.$state.go('messenger.home'), WelcomeController.REDIRECT_DELAY, true, 'redirectToHome');\n        }, (error) => {\n            this.log.error('Error state:', error);\n        }, (progress) => { });\n    }\n    reload() {\n        this.$window.location.reload();\n    }\n}\nWelcomeController.BROADCAST_DELAY = 100;\nWelcomeController.REDIRECT_DELAY = 500;\nWelcomeController.$inject = [\n    '$scope', '$state', '$window', '$mdDialog', '$translate',\n    'LogService', 'WebClientService', 'TrustedKeyStore', 'StateService', 'PushService', 'BrowserService',\n    'VersionService', 'SettingsService', 'TimeoutService', 'ControllerService',\n    'BROWSER_MIN_VERSIONS', 'CONFIG',\n];\nangular.module('3ema.welcome', [])\n    .config(['$stateProvider', ($stateProvider) => {\n        $stateProvider\n            .state('welcome', {\n            url: '/welcome',\n            templateUrl: 'partials/welcome.html',\n            controller: 'WelcomeController',\n            controllerAs: 'ctrl',\n            params: { initParams: null },\n        });\n    }])\n    .controller('WelcomeController', WelcomeController);\n","export function scorePassword(password) {\n    let score = 0;\n    if (password.length === 0) {\n        return { score: score, strength: \"bad\" };\n    }\n    const letterCount = {};\n    for (const character of password) {\n        letterCount[character] = (letterCount[character] || 0) + 1;\n        score += 5.0 / letterCount[character];\n    }\n    const categories = {\n        digits: /\\d/.test(password),\n        lower: /[a-z]/.test(password),\n        upper: /[A-Z]/.test(password),\n        nonWords: /\\W/.test(password),\n    };\n    const categoryCount = Object\n        .values(categories)\n        .reduce((total, x) => x ? total + 1 : total, 0);\n    score += (categoryCount - 1) * 10;\n    score = Math.trunc(score);\n    let strength;\n    if (score > 80) {\n        strength = \"strong\";\n    }\n    else if (score > 60) {\n        strength = \"good\";\n    }\n    else if (score > 40) {\n        strength = \"weak\";\n    }\n    else {\n        strength = \"bad\";\n    }\n    return {\n        score: score,\n        strength: strength,\n    };\n}\n","export class BatteryStatusService {\n    constructor($translate, logService, notificationService) {\n        this.batteryStatus = null;\n        this.alertedLow = false;\n        this.alertedCritical = false;\n        this.$translate = $translate;\n        this.notificationService = notificationService;\n        this.log = logService.getLogger('BatteryStatus-S');\n    }\n    setStatus(batteryStatus) {\n        this.log.debug('Status:', batteryStatus);\n        if (batteryStatus.percent === null) {\n            this.clearStatus();\n            return;\n        }\n        this.batteryStatus = batteryStatus;\n        if (!batteryStatus.isCharging) {\n            if (!this.alertedCritical && batteryStatus.percent < BatteryStatusService.PERCENT_CRITICAL) {\n                this.notifyLevel('critical');\n                this.alertedCritical = true;\n            }\n            else if (!this.alertedLow && batteryStatus.percent < BatteryStatusService.PERCENT_LOW) {\n                this.notifyLevel('low');\n                this.alertedLow = true;\n            }\n        }\n        if (this.alertedLow && batteryStatus.isCharging) {\n            this.alertedLow = false;\n            this.notificationService.hideNotification('battery-low');\n        }\n        if (this.alertedCritical && batteryStatus.isCharging) {\n            this.alertedCritical = false;\n            this.notificationService.hideNotification('battery-critical');\n        }\n        const hysteresis = 3;\n        if (this.alertedLow && batteryStatus.percent > BatteryStatusService.PERCENT_LOW + hysteresis) {\n            this.alertedLow = false;\n            this.notificationService.hideNotification('battery-low');\n        }\n        if (this.alertedCritical && batteryStatus.percent > BatteryStatusService.PERCENT_CRITICAL + hysteresis) {\n            this.alertedCritical = false;\n            this.notificationService.hideNotification('battery-critical');\n        }\n    }\n    clearStatus() {\n        this.batteryStatus = null;\n    }\n    get dataAvailable() {\n        return this.batteryStatus !== null;\n    }\n    get percent() {\n        return this.batteryStatus.percent;\n    }\n    get isCharging() {\n        return this.batteryStatus.isCharging;\n    }\n    get isLow() {\n        return this.batteryStatus.percent < BatteryStatusService.PERCENT_LOW;\n    }\n    get isCritical() {\n        return this.batteryStatus.percent < BatteryStatusService.PERCENT_CRITICAL;\n    }\n    notifyLevel(level) {\n        if (!this.notificationService.getWantsNotifications()) {\n            return;\n        }\n        const title = this.$translate.instant('common.WARNING');\n        const picture = 'img/ic_battery_alert-64x64.png';\n        let tag;\n        let body;\n        if (level === 'low') {\n            tag = 'battery-low';\n            body = this.$translate.instant('battery.LEVEL_LOW', { percent: this.percent });\n            this.notificationService.hideNotification('battery-critical');\n        }\n        else if (level === 'critical') {\n            tag = 'battery-critical';\n            body = this.$translate.instant('battery.LEVEL_CRITICAL', { percent: this.percent });\n            this.notificationService.hideNotification('battery-low');\n        }\n        this.notificationService.showNotification(tag, title, body, picture, undefined, true, true);\n    }\n    toString() {\n        if (this.batteryStatus === null) {\n            return 'No data';\n        }\n        return this.percent + '%, ' + (this.isCharging ? 'charging' : 'discharging');\n    }\n}\nBatteryStatusService.PERCENT_LOW = 20;\nBatteryStatusService.PERCENT_CRITICAL = 5;\nBatteryStatusService.$inject = ['$translate', 'LogService', 'NotificationService'];\n","export class BrowserInfo {\n    constructor(userAgent, name, version, mobile = false) {\n        this.userAgent = userAgent;\n        this.name = name;\n        this.version = version;\n        this.mobile = mobile;\n    }\n    wasDetermined() {\n        return this.name !== null && this.version !== null;\n    }\n    description(separator = ' ') {\n        if (this.name === null) {\n            return 'Unknown';\n        }\n        let description = '';\n        switch (this.name) {\n            case \"chrome\":\n                description = 'Chrome ' + this.version;\n                break;\n            case \"chromeIos\":\n                description = 'Chrome (iOS) ' + this.version;\n                break;\n            case \"firefox\":\n                description = 'Firefox ' + this.version;\n                break;\n            case \"firefoxIos\":\n                description = 'Firefox (iOS) ' + this.version;\n                break;\n            case \"edge\":\n                description = 'Edge ' + this.version;\n                break;\n            case \"ie\":\n                description = 'Internet Explorer ' + this.version;\n                break;\n            case \"opera\":\n                description = 'Opera ' + this.version;\n                break;\n            case \"safari\":\n                description = 'Safari ' + this.version;\n                break;\n        }\n        if (this.mobile) {\n            description += ' [Mobile]';\n        }\n        return description.split(' ').join(separator);\n    }\n    supportsWebrtcTask() {\n        switch (this.name) {\n            case \"safari\":\n            case \"firefoxIos\":\n            case \"chromeIos\":\n                return false;\n            default:\n                return true;\n        }\n    }\n    isFirefox(requireVersion = false) {\n        return this.name === \"firefox\" && (!requireVersion || this.version !== null);\n    }\n    isSafari(requireVersion = false) {\n        return this.name === \"safari\" && (!requireVersion || this.version !== null);\n    }\n}\n","import { BrowserInfo } from '../helpers/browser_info';\nexport class BrowserService {\n    constructor($window, logService) {\n        this.$window = $window;\n        this.log = logService.getLogger('Browser-S');\n    }\n    getBrowser() {\n        if (this.browser === undefined) {\n            const browser = {\n                chrome: false,\n                chromeIos: false,\n                firefox: false,\n                firefoxIos: false,\n                ie: false,\n                edge: false,\n                opera: false,\n                safari: false,\n            };\n            const uagent = this.$window.navigator.userAgent.toLowerCase();\n            browser.chrome = /webkit/.test(uagent) && /chrome/.test(uagent) && !/edg/.test(uagent);\n            browser.chromeIos = /mozilla/.test(uagent) && /crios/.test(uagent);\n            browser.firefox = /mozilla/.test(uagent) && /firefox/.test(uagent);\n            browser.firefoxIos = /mozilla/.test(uagent) && /fxios/.test(uagent);\n            browser.ie = (/msie/.test(uagent) || /trident/.test(uagent)) && !/edge/.test(uagent);\n            browser.edge = /edg/.test(uagent);\n            browser.safari = /safari/.test(uagent) && /applewebkit/.test(uagent)\n                && !/chrome/.test(uagent) && !/fxios/.test(uagent) && !/crios/.test(uagent);\n            browser.opera = /mozilla/.test(uagent) && /applewebkit/.test(uagent)\n                && /chrome/.test(uagent) && /safari/.test(uagent) && /opr/.test(uagent);\n            if (browser.opera && browser.chrome) {\n                browser.chrome = false;\n            }\n            let version = null;\n            for (const x in browser) {\n                if (browser[x]) {\n                    let b;\n                    if (x === 'ie') {\n                        b = 'msie';\n                    }\n                    else if (x === 'edge') {\n                        b = 'edge?';\n                    }\n                    else if (x === 'opera') {\n                        b = 'opr';\n                    }\n                    else if (x === 'firefoxIos') {\n                        b = 'fxios';\n                    }\n                    else if (x === 'chromeIos') {\n                        b = 'crios';\n                    }\n                    else if (x === 'safari') {\n                        b = 'version';\n                    }\n                    else {\n                        b = x;\n                    }\n                    let match = uagent.match(new RegExp('(' + b + ')( |\\/)([0-9]+)'));\n                    let versionString;\n                    if (match) {\n                        versionString = match[3];\n                    }\n                    else {\n                        match = uagent.match(new RegExp('rv:([0-9]+)'));\n                        versionString = match ? match[1] : '';\n                    }\n                    const versionInt = parseInt(versionString, 10);\n                    version = isNaN(versionInt) ? undefined : versionInt;\n                    break;\n                }\n            }\n            if (browser.chrome) {\n                this.browser = new BrowserInfo(uagent, \"chrome\", version);\n            }\n            if (browser.chromeIos) {\n                this.browser = new BrowserInfo(uagent, \"chromeIos\", version, true);\n            }\n            if (browser.firefox) {\n                this.browser = new BrowserInfo(uagent, \"firefox\", version);\n            }\n            if (browser.firefoxIos) {\n                this.browser = new BrowserInfo(uagent, \"firefoxIos\", version, true);\n            }\n            if (browser.ie) {\n                this.browser = new BrowserInfo(uagent, \"ie\", version);\n            }\n            if (browser.edge) {\n                this.browser = new BrowserInfo(uagent, \"edge\", version);\n            }\n            if (browser.safari) {\n                const mobile = /mobile/.test(uagent);\n                this.browser = new BrowserInfo(uagent, \"safari\", version, mobile);\n            }\n            if (browser.opera) {\n                this.browser = new BrowserInfo(uagent, \"opera\", version);\n            }\n        }\n        return this.browser;\n    }\n    supportsWebrtcTask() {\n        if (this.browser === undefined) {\n            this.getBrowser();\n        }\n        return this.browser.supportsWebrtcTask();\n    }\n    supportsExtendedLocaleCompare() {\n        if (this.supportsExtendedLocaleCompareCache !== undefined) {\n            return this.supportsExtendedLocaleCompareCache;\n        }\n        function getSupport() {\n            try {\n                'foo'.localeCompare('bar', 'i');\n            }\n            catch (e) {\n                return e.name === 'RangeError';\n            }\n            return false;\n        }\n        const support = getSupport();\n        this.supportsExtendedLocaleCompareCache = support;\n        this.log.debug(`Browser ${support ? 'supports' : 'does not support'} extended locale compare options`);\n        return support;\n    }\n}\nBrowserService.$inject = ['$window', 'LogService'];\n","export class ContactService {\n    constructor(webClientService) {\n        this.webClientService = webClientService;\n    }\n    requiredDetails(contactReceiver) {\n        return new Promise((resolve, reject) => {\n            if (contactReceiver.systemContact === undefined) {\n                this.webClientService.requestContactDetail(contactReceiver)\n                    .then((data) => resolve(data))\n                    .catch((data) => reject(data));\n            }\n            else {\n                resolve(contactReceiver);\n            }\n        });\n    }\n}\nContactService.$inject = ['WebClientService'];\n","import { hasValue } from '../helpers';\nexport class AvatarControllerModel {\n    constructor(logService, webClientService, receiver) {\n        this.avatar = null;\n        this._avatarChanged = false;\n        const log = logService.getLogger('Avatar-CM');\n        this.loadAvatar = new Promise((resolve, reject) => {\n            if (!hasValue(receiver)) {\n                log.debug('No receiver defined, no avatar');\n                resolve(null);\n                return;\n            }\n            else if (!hasValue(receiver.avatar) || !hasValue(receiver.avatar.high)) {\n                log.debug('Requesting high res avatar from app');\n                webClientService.requestAvatar(receiver, true)\n                    .then((data) => resolve(data))\n                    .catch((error) => reject(error));\n            }\n            else {\n                log.debug('Returning cached avatar');\n                resolve(receiver.avatar.high);\n            }\n        });\n        this.onChangeAvatar = (image) => {\n            this.avatar = image;\n            this._avatarChanged = true;\n        };\n    }\n    getAvatar() {\n        return this.avatar;\n    }\n    get avatarChanged() {\n        return this._avatarChanged;\n    }\n}\n","import { AvatarControllerModel } from './avatar';\nexport class ContactControllerModel {\n    constructor($translate, $mdDialog, logService, webClientService, mode, contact) {\n        this.receiverType = 'contact';\n        this.isLoading = false;\n        this.mode = \"new\";\n        this.$translate = $translate;\n        this.$mdDialog = $mdDialog;\n        this.log = logService.getLogger('Contact-CM');\n        if (contact === undefined) {\n            if (mode !== \"new\") {\n                throw new Error('ContactControllerModel: Contact may not be undefined for mode ' + mode);\n            }\n        }\n        else {\n            this.contact = contact;\n        }\n        this.webClientService = webClientService;\n        this.mode = mode;\n        switch (this.getMode()) {\n            case \"edit\":\n                this.subject = $translate.instant('messenger.EDIT_RECEIVER');\n                this.firstName = this.contact.firstName;\n                this.lastName = this.contact.lastName;\n                this.avatarController = new AvatarControllerModel(logService, this.webClientService, this.contact);\n                this.access = this.contact.access;\n                this.firstNameLabel = this.access.canChangeLastName ?\n                    $translate.instant('messenger.FIRST_NAME') :\n                    $translate.instant('messenger.NAME');\n                break;\n            case \"view\":\n            case \"chat\":\n                this.subject = this.contact.displayName;\n                this.access = this.contact.access;\n                break;\n            case \"new\":\n                this.subject = $translate.instant('messenger.ADD_CONTACT');\n                break;\n            default:\n                this.log.error('Invalid controller model mode: ', this.getMode());\n        }\n    }\n    setOnRemoved(callback) {\n        this.onRemovedCallback = callback;\n    }\n    getMode() {\n        return this.mode;\n    }\n    isValid() {\n        if (this.getMode() === \"edit\") {\n            return true;\n        }\n        return this.identity !== undefined && this.identity.length === 8;\n    }\n    canChat() {\n        return this.contact !== null && this.contact.id !== this.webClientService.me.id;\n    }\n    canEdit() {\n        return this.access !== undefined && (this.access.canChangeAvatar === true\n            || this.access.canChangeFirstName === true\n            || this.access.canChangeLastName === true);\n    }\n    canClean() {\n        return this.canChat();\n    }\n    clean(ev) {\n        const confirm = this.$mdDialog.confirm()\n            .title(this.$translate.instant('messenger.DELETE_THREAD'))\n            .textContent(this.$translate.instant('messenger.DELETE_THREAD_MESSAGE', { count: 1 }))\n            .targetEvent(ev)\n            .ok(this.$translate.instant('common.YES'))\n            .cancel(this.$translate.instant('common.NO'));\n        this.$mdDialog.show(confirm).then(() => {\n            this.reallyClean();\n        }, () => {\n            this.log.debug('Clean cancelled');\n        });\n    }\n    reallyClean() {\n        if (!this.contact) {\n            this.log.error('reallyClean: Contact is null');\n            return;\n        }\n        if (!this.canClean()) {\n            this.log.error('Not allowed to clean this contact');\n            return;\n        }\n        this.isLoading = true;\n        this.webClientService.cleanReceiverConversation(this.contact)\n            .then(() => {\n            this.isLoading = false;\n        })\n            .catch((error) => {\n            this.log.error(`Cleaning receiver conversation failed: ${error}`);\n            this.isLoading = false;\n        });\n    }\n    canShowQr() {\n        return false;\n    }\n    save() {\n        switch (this.getMode()) {\n            case \"edit\":\n                return this.webClientService.modifyContact(this.contact.id, this.firstName, this.lastName, this.avatarController.avatarChanged ? this.avatarController.getAvatar() : undefined);\n            case \"new\":\n                return this.webClientService.addContact(this.identity);\n            default:\n                this.log.error('Cannot save contact, invalid mode');\n                return Promise.reject('Cannot save contact, invalid mode');\n        }\n    }\n}\n","export class DistributionListControllerModel {\n    constructor($translate, $mdDialog, logService, webClientService, mode, distributionList) {\n        this.receiverType = 'distributionList';\n        this.isLoading = false;\n        this.requiredMemberFeatureMask = 0;\n        this.$translate = $translate;\n        this.$mdDialog = $mdDialog;\n        this.log = logService.getLogger('DistributionList-CM');\n        if (distributionList === undefined) {\n            if (mode !== \"new\") {\n                throw new Error('DistributionListControllerModel: Distribution list ' +\n                    'may not be undefined for mode ' + mode);\n            }\n        }\n        else {\n            this.distributionList = distributionList;\n        }\n        this.mode = mode;\n        this.webClientService = webClientService;\n        this.addContactPlaceholder = $translate.instant('messenger.DISTRIBUTION_LIST_SELECT_MEMBERS');\n        switch (this.getMode()) {\n            case \"edit\":\n                this.subject = $translate.instant('messenger.EDIT_RECEIVER');\n                this.name = this.distributionList.displayName;\n                this.members = this.distributionList.members;\n                break;\n            case \"view\":\n            case \"chat\":\n                this.subject = this.distributionList.displayName;\n                this.members = this.distributionList.members;\n                break;\n            case \"new\":\n                this.subject = $translate.instant('messenger.CREATE_DISTRIBUTION_LIST');\n                this.members = [];\n                break;\n            default:\n                this.log.error('Invalid controller model mode: ', this.getMode());\n        }\n    }\n    setOnRemoved(callback) {\n        this.onRemovedCallback = callback;\n    }\n    getMode() {\n        return this.mode;\n    }\n    isValid() {\n        return this.members.filter((identity) => {\n            return identity !== this.webClientService.me.id;\n        }).length > 0;\n    }\n    canChat() {\n        return true;\n    }\n    canEdit() {\n        return true;\n    }\n    canClean() {\n        return true;\n    }\n    clean(ev) {\n        const confirm = this.$mdDialog.confirm()\n            .title(this.$translate.instant('messenger.DELETE_THREAD'))\n            .textContent(this.$translate.instant('messenger.DELETE_THREAD_MESSAGE', { count: 1 }))\n            .targetEvent(ev)\n            .ok(this.$translate.instant('common.YES'))\n            .cancel(this.$translate.instant('common.CANCEL'));\n        this.$mdDialog.show(confirm).then(() => {\n            this.reallyClean();\n        }, () => {\n            this.log.debug('Clean cancelled');\n        });\n    }\n    reallyClean() {\n        if (!this.distributionList) {\n            this.log.error('reallyClean: Distribution list is null');\n            return;\n        }\n        if (!this.canClean()) {\n            this.log.error('Not allowed to clean this distribution list');\n            return;\n        }\n        this.isLoading = true;\n        this.webClientService.cleanReceiverConversation(this.distributionList)\n            .then(() => {\n            this.isLoading = false;\n        })\n            .catch((error) => {\n            this.log.error(`Cleaning receiver conversation failed: ${error}`);\n            this.isLoading = false;\n        });\n    }\n    canShowQr() {\n        return false;\n    }\n    delete(ev) {\n        const confirm = this.$mdDialog.confirm()\n            .title(this.$translate.instant('messenger.DISTRIBUTION_LIST_DELETE'))\n            .textContent(this.$translate.instant('messenger.DISTRIBUTION_LIST_DELETE_REALLY'))\n            .targetEvent(ev)\n            .ok(this.$translate.instant('common.OK'))\n            .cancel(this.$translate.instant('common.CANCEL'));\n        this.$mdDialog.show(confirm).then(() => {\n            this.reallyDelete();\n        }, () => {\n            this.log.debug('Delete cancelled');\n        });\n    }\n    reallyDelete() {\n        if (!this.distributionList) {\n            this.log.error('reallyDelete: Distribution list is null');\n            return;\n        }\n        if (!this.distributionList.access.canDelete) {\n            this.log.error('Not allowed to delete this distribution list');\n            return;\n        }\n        this.isLoading = true;\n        this.webClientService.deleteDistributionList(this.distributionList).then(() => {\n            this.isLoading = false;\n            if (this.onRemovedCallback && this.distributionList !== null) {\n                this.onRemovedCallback(this.distributionList.id);\n            }\n        }).catch((error) => {\n            this.log.error(`Deleting distribution list failed: ${error}`);\n            this.isLoading = false;\n        });\n    }\n    save() {\n        switch (this.getMode()) {\n            case \"edit\":\n                return this.webClientService.modifyDistributionList(this.distributionList.id, this.members, this.name);\n            case \"new\":\n                return this.webClientService.createDistributionList(this.members, this.name);\n            default:\n                this.log.error('Cannot save distribution list, invalid mode');\n                return Promise.reject('Cannot save distribution list, invalid mode');\n        }\n    }\n    onChangeMembers(identities) {\n        this.members = identities;\n    }\n    getMembers() {\n        return this.members;\n    }\n}\n","import { AvatarControllerModel } from './avatar';\nexport class GroupControllerModel {\n    constructor($translate, $mdDialog, logService, webClientService, mode, group) {\n        this.receiverType = 'group';\n        this.isLoading = false;\n        this.requiredMemberFeatureMask = 2;\n        this.$translate = $translate;\n        this.$mdDialog = $mdDialog;\n        this.log = logService.getLogger('Group-CM');\n        if (group === undefined) {\n            if (mode !== \"new\") {\n                throw new Error('GroupControllerModel: Group may not be undefined for mode ' + mode);\n            }\n        }\n        else {\n            this.group = group;\n        }\n        this.mode = mode;\n        this.webClientService = webClientService;\n        this.addContactPlaceholder = $translate.instant('messenger.GROUP_SELECT_CONTACTS');\n        switch (this.getMode()) {\n            case \"edit\":\n                this.subject = $translate.instant('messenger.EDIT_RECEIVER');\n                this.name = this.group.displayName;\n                this.members = this.group.members;\n                this.avatarController = new AvatarControllerModel(logService, this.webClientService, this.group);\n                this.access = this.group.access;\n                break;\n            case \"view\":\n            case \"chat\":\n                this.subject = this.group.displayName;\n                this.members = this.group.members;\n                this.access = this.group.access;\n                break;\n            case \"new\":\n                this.subject = $translate.instant('messenger.CREATE_GROUP');\n                this.members = [];\n                this.avatarController = new AvatarControllerModel(logService, this.webClientService, null);\n                break;\n            default:\n                this.log.error('Invalid controller model mode: ', this.getMode());\n        }\n    }\n    getMaxMemberSize() {\n        return this.webClientService.getMaxGroupMemberSize();\n    }\n    setOnRemoved(callback) {\n        this.onRemovedCallback = callback;\n    }\n    getMode() {\n        return this.mode;\n    }\n    isValid() {\n        return this.members.filter((identity) => {\n            return identity !== this.webClientService.me.id;\n        }).length > 0;\n    }\n    canChat() {\n        return true;\n    }\n    canEdit() {\n        return this.access !== undefined && (this.access.canChangeAvatar === true\n            || this.access.canChangeName === true\n            || this.access.canChangeMembers === true);\n    }\n    canClean() {\n        return this.canChat();\n    }\n    clean(ev) {\n        const confirm = this.$mdDialog.confirm()\n            .title(this.$translate.instant('messenger.DELETE_THREAD'))\n            .textContent(this.$translate.instant('messenger.DELETE_THREAD_MESSAGE', { count: 1 }))\n            .targetEvent(ev)\n            .ok(this.$translate.instant('common.YES'))\n            .cancel(this.$translate.instant('common.CANCEL'));\n        this.$mdDialog.show(confirm).then(() => {\n            this.reallyClean();\n        }, () => {\n            this.log.debug('Clean cancelled');\n        });\n    }\n    reallyClean() {\n        if (!this.group) {\n            this.log.error('reallyClean: Group is null');\n            return;\n        }\n        if (!this.canClean()) {\n            this.log.error('Not allowed to clean this group');\n            return;\n        }\n        this.isLoading = true;\n        this.webClientService.cleanReceiverConversation(this.group)\n            .then(() => {\n            this.isLoading = false;\n        })\n            .catch((error) => {\n            this.log.error(`Cleaning receiver conversation failed: ${error}`);\n            this.isLoading = false;\n        });\n    }\n    canShowQr() {\n        return false;\n    }\n    leave(ev) {\n        if (!this.group) {\n            this.log.error('leave: Group is null');\n            return;\n        }\n        const confirm = this.$mdDialog.confirm()\n            .title(this.$translate.instant('messenger.GROUP_LEAVE'))\n            .textContent(this.$translate.instant(this.group.administrator === this.webClientService.me.id\n            ? 'messenger.GROUP_REALLY_LEAVE_ADMIN'\n            : 'messenger.GROUP_REALLY_LEAVE'))\n            .targetEvent(ev)\n            .ok(this.$translate.instant('common.OK'))\n            .cancel(this.$translate.instant('common.CANCEL'));\n        this.$mdDialog.show(confirm).then(() => {\n            this.reallyLeave(this.group);\n        }, () => {\n            this.log.debug('Leave cancelled');\n        });\n    }\n    reallyLeave(group) {\n        if (!group.access.canLeave) {\n            this.log.error('Cannot leave group');\n            return;\n        }\n        this.isLoading = true;\n        this.webClientService.leaveGroup(group)\n            .then(() => {\n            this.isLoading = false;\n        })\n            .catch((error) => {\n            this.log.error(`Leaving group failed: ${error}`);\n            this.isLoading = false;\n        });\n    }\n    delete(ev) {\n        if (!this.group) {\n            this.log.error('delete: Group is null');\n            return;\n        }\n        const confirm = this.$mdDialog.confirm()\n            .title(this.$translate.instant('messenger.GROUP_DELETE'))\n            .textContent(this.$translate.instant('messenger.GROUP_DELETE_REALLY'))\n            .targetEvent(ev)\n            .ok(this.$translate.instant('common.OK'))\n            .cancel(this.$translate.instant('common.CANCEL'));\n        this.$mdDialog.show(confirm).then(() => {\n            this.reallyDelete(this.group);\n        }, () => {\n            this.log.debug('Delete cancelled');\n        });\n    }\n    reallyDelete(group) {\n        if (!this.access.canDelete) {\n            this.log.error('Can not delete group');\n            return;\n        }\n        this.isLoading = true;\n        this.webClientService.deleteGroup(group)\n            .then(() => {\n            this.isLoading = false;\n            if (this.onRemovedCallback) {\n                this.onRemovedCallback(group.id);\n            }\n        })\n            .catch((error) => {\n            this.log.error(`Deleting group failed: ${error}`);\n            this.isLoading = false;\n        });\n    }\n    sync(ev) {\n        if (!this.group) {\n            this.log.error('sync: Group is null');\n            return;\n        }\n        if (!this.access.canSync) {\n            this.log.error('Cannot sync group');\n            return;\n        }\n        this.isLoading = true;\n        this.webClientService.syncGroup(this.group)\n            .then(() => {\n            this.isLoading = false;\n        })\n            .catch((errorCode) => {\n            this.isLoading = false;\n            this.showError(errorCode);\n        });\n    }\n    save() {\n        switch (this.getMode()) {\n            case \"edit\":\n                return this.webClientService.modifyGroup(this.group.id, this.members, this.name, this.avatarController.avatarChanged ? this.avatarController.getAvatar() : undefined);\n            case \"new\":\n                return this.webClientService.createGroup(this.members, (this.name && this.name.length > 0) ? this.name : undefined, this.avatarController.avatarChanged ? this.avatarController.getAvatar() : undefined);\n            default:\n                this.log.error('Cannot save group, invalid mode');\n                return Promise.reject('Cannot save group, invalid mode');\n        }\n    }\n    onChangeMembers(identities) {\n        this.members = identities;\n    }\n    getMembers() {\n        return this.members;\n    }\n    showError(errorCode) {\n        if (errorCode === undefined) {\n            errorCode = 'unknown';\n        }\n        this.$mdDialog.show(this.$mdDialog.alert()\n            .clickOutsideToClose(true)\n            .title(this.group ? this.group.displayName : 'Error')\n            .textContent(this.$translate.instant('validationError.modifyReceiver.' + errorCode))\n            .ok(this.$translate.instant('common.OK')));\n    }\n}\n","import { hasValue } from '../helpers';\nimport { AvatarControllerModel } from './avatar';\nexport class MeControllerModel {\n    constructor($translate, $mdDialog, logService, webClientService, mode, me) {\n        this.receiverType = 'me';\n        this.isLoading = false;\n        this.mode = \"view\";\n        this.log = logService.getLogger('Me-CM');\n        this.$translate = $translate;\n        this.$mdDialog = $mdDialog;\n        this.me = me;\n        this.webClientService = webClientService;\n        this.mode = mode;\n        this.nickname = webClientService.me.publicNickname || '';\n        switch (mode) {\n            case \"edit\":\n                this.subject = $translate.instant('messenger.EDIT_RECEIVER');\n                this.avatarController = new AvatarControllerModel(logService, this.webClientService, this.me);\n                break;\n            case \"view\":\n                this.subject = $translate.instant('messenger.MY_THREEMA_ID');\n                break;\n            default:\n                this.log.error('Invalid controller model mode: ', this.getMode());\n        }\n    }\n    setOnRemoved(callback) {\n    }\n    getMode() {\n        return this.mode;\n    }\n    canClean() {\n        return false;\n    }\n    clean(ev) {\n    }\n    isValid() {\n        return (this.me !== null\n            && this.me !== undefined\n            && this.me.id === this.webClientService.me.id);\n    }\n    canChat() {\n        return false;\n    }\n    canEdit() {\n        const mdm = this.webClientService.appCapabilities.mdm;\n        return mdm === undefined || !mdm.readonlyProfile;\n    }\n    canShowQr() {\n        return true;\n    }\n    save() {\n        switch (this.getMode()) {\n            case \"edit\":\n                return this.webClientService.modifyProfile(this.nickname, this.avatarController.avatarChanged ? this.avatarController.getAvatar() : undefined).then(() => {\n                    this.webClientService.me.publicNickname = this.nickname;\n                    if (this.avatarController.avatarChanged) {\n                        const avatar = this.avatarController.getAvatar();\n                        if (avatar) {\n                            if (!hasValue(this.webClientService.me.avatar)) {\n                                this.webClientService.me.avatar = { high: avatar };\n                            }\n                            else {\n                                this.webClientService.me.avatar.high = avatar;\n                            }\n                        }\n                    }\n                    return this.me;\n                });\n            default:\n                this.log.error('Not allowed to save profile: Invalid mode');\n                return Promise.reject('unknown');\n        }\n    }\n}\n","import { ContactControllerModel } from '../controller_model/contact';\nimport { DistributionListControllerModel } from '../controller_model/distributionList';\nimport { GroupControllerModel } from '../controller_model/group';\nimport { MeControllerModel } from '../controller_model/me';\nexport class ControllerModelService {\n    constructor($translate, $mdDialog, logService, webClientService) {\n        this.$translate = $translate;\n        this.$mdDialog = $mdDialog;\n        this.logService = logService;\n        this.webClientService = webClientService;\n        this.log = logService.getLogger('ControllerModel-S');\n    }\n    me(receiver, mode) {\n        return new MeControllerModel(this.$translate, this.$mdDialog, this.logService, this.webClientService, mode, receiver);\n    }\n    contact(receiver, mode) {\n        return new ContactControllerModel(this.$translate, this.$mdDialog, this.logService, this.webClientService, mode, receiver);\n    }\n    group(receiver, mode) {\n        return new GroupControllerModel(this.$translate, this.$mdDialog, this.logService, this.webClientService, mode, receiver);\n    }\n    distributionList(receiver, mode) {\n        return new DistributionListControllerModel(this.$translate, this.$mdDialog, this.logService, this.webClientService, mode, receiver);\n    }\n}\nControllerModelService.$inject = ['$translate', '$mdDialog', 'LogService', 'WebClientService'];\n","import * as nacl from 'tweetnacl';\nimport { hexToU8a, u8aToHex } from '../helpers';\nimport { stringToUtf8a, utf8aToString } from '../helpers';\nexport class TrustedKeyStoreService {\n    constructor($window, logService) {\n        this.STORAGE_KEY = 'trusted';\n        this.storage = null;\n        this.blocked = false;\n        this.log = logService.getLogger('TrustedKeyStore-S', 'color: #fff; background-color: #666699');\n        try {\n            if ($window.localStorage === null) {\n                this.blocked = true;\n            }\n            this.storage = $window.localStorage;\n        }\n        catch (e) {\n            this.log.warn('LocalStorage blocked:', e);\n            this.blocked = true;\n        }\n    }\n    stringToBytes(str) {\n        const arr = [];\n        for (let i = 0; i < str.length; i++) {\n            arr.push(str.charCodeAt(i));\n        }\n        return new Uint8Array(arr);\n    }\n    pwToKey(password) {\n        const bytes = this.stringToBytes(password);\n        const hash = nacl.hash(bytes);\n        return hash.slice(0, nacl.secretbox.keyLength);\n    }\n    storeTrustedKey(ownPublicKey, ownSecretKey, peerPublicKey, pushToken, pushTokenType, password) {\n        const nonce = nacl.randomBytes(nacl.secretbox.nonceLength);\n        let pushTokenString = null;\n        if (pushToken !== null && pushTokenType !== null) {\n            switch (pushTokenType) {\n                case \"gcm\":\n                    pushTokenString = \"g\" + ':' + pushToken;\n                    break;\n                case \"apns\":\n                    pushTokenString = \"a\" + ':' + pushToken;\n                    break;\n            }\n        }\n        const token = (pushTokenString == null)\n            ? new Uint8Array(0)\n            : stringToUtf8a(pushTokenString);\n        const data = new Uint8Array(3 * 32 + token.byteLength);\n        data.set(ownPublicKey, 0);\n        data.set(ownSecretKey, 32);\n        data.set(peerPublicKey, 64);\n        data.set(token, 96);\n        const encrypted = nacl.secretbox(data, nonce, this.pwToKey(password));\n        this.log.debug('Storing trusted key');\n        this.storage.setItem(this.STORAGE_KEY, u8aToHex(nonce) + ':' + u8aToHex(encrypted));\n    }\n    hasTrustedKey() {\n        const item = this.storage.getItem(this.STORAGE_KEY);\n        return item !== null && item.length > 96 && item.indexOf(':') !== -1;\n    }\n    retrieveTrustedKey(password) {\n        const storedValue = this.storage.getItem(this.STORAGE_KEY);\n        if (storedValue === null) {\n            return null;\n        }\n        const parts = storedValue.split(':');\n        if (parts.length !== 2) {\n            return null;\n        }\n        const nonce = hexToU8a(parts[0]);\n        const encrypted = hexToU8a(parts[1]);\n        const decrypted = nacl.secretbox.open(encrypted, nonce, this.pwToKey(password));\n        if (!decrypted) {\n            return null;\n        }\n        const tokenBytes = decrypted.slice(96);\n        const tokenString = tokenBytes.byteLength > 0 ? utf8aToString(tokenBytes) : null;\n        let tokenType = null;\n        let token = null;\n        if (tokenString !== null && tokenString[1] === ':') {\n            switch (tokenString[0]) {\n                case \"g\":\n                    tokenType = \"gcm\";\n                    break;\n                case \"a\":\n                    tokenType = \"apns\";\n                    break;\n                default:\n                    this.log.error('Invalid push token type:', tokenString[0]);\n                    return null;\n            }\n            token = tokenString.slice(2);\n        }\n        else if (tokenString !== null) {\n            token = tokenString;\n            tokenType = \"gcm\";\n        }\n        return {\n            ownPublicKey: decrypted.slice(0, 32),\n            ownSecretKey: decrypted.slice(32, 64),\n            peerPublicKey: decrypted.slice(64, 96),\n            pushToken: token,\n            pushTokenType: tokenType,\n        };\n    }\n    clearTrustedKey() {\n        this.log.debug('Clearing trusted key');\n        this.storage.removeItem(this.STORAGE_KEY);\n    }\n}\nTrustedKeyStoreService.$inject = ['$window', 'LogService'];\n","import { BaseConfidential } from './confidential';\nconst LOG_TYPES = ['debug', 'trace', 'info', 'warn', 'error'];\nconst ALLOWED_TYPES = [Boolean, Number, String, Array];\nexport class TeeLogger {\n    constructor(loggers) {\n        this.loggers = loggers;\n        for (const type of LOG_TYPES) {\n            this[type] = this.forward.bind(this, type);\n        }\n    }\n    forward(type, message, ...args) {\n        for (const log of this.loggers) {\n            log[type](message, ...args);\n        }\n    }\n}\nexport class LevelLogger {\n    constructor(logger, level) {\n        this.debug = this.noop;\n        this.trace = this.noop;\n        this.info = this.noop;\n        this.warn = this.noop;\n        this.error = this.noop;\n        this.logger = logger;\n        this.level = level;\n        switch (level) {\n            case 'debug':\n                this.debug = this.logger.debug.bind(this.logger);\n                this.trace = this.logger.trace.bind(this.logger);\n            case 'info':\n                this.info = this.logger.info.bind(this.logger);\n            case 'warn':\n                this.warn = this.logger.warn.bind(this.warn);\n            case 'error':\n                this.error = this.logger.error.bind(this.error);\n            default:\n                break;\n        }\n    }\n    noop() {\n    }\n}\nexport class TagLogger {\n    constructor(logger, ...tag) {\n        this.logger = logger;\n        for (const type of LOG_TYPES) {\n            this[type] = logger[type].bind(logger, ...tag);\n        }\n    }\n}\nexport class UnveilLogger {\n    constructor(logger) {\n        this.logger = logger;\n        for (const type of LOG_TYPES) {\n            this[type] = this.unveil.bind(this, type);\n        }\n    }\n    unveil(type, ...args) {\n        args = args.map((item) => item instanceof BaseConfidential ? item.uncensored : item);\n        this.logger[type](...args);\n    }\n}\nexport class ConsoleLogger {\n    constructor() {\n        this.debug = console.debug;\n        this.trace = console.trace;\n        this.info = console.info;\n        this.warn = console.warn;\n        this.error = console.error;\n    }\n}\nexport class MemoryLogger {\n    constructor(limit = 0) {\n        this.records = [];\n        this.limit = 0;\n        this.limit = limit;\n        for (const type of LOG_TYPES) {\n            this[type] = this.append.bind(this, type);\n        }\n    }\n    append(type, message, ...args) {\n        if (this.limit > 0 && this.records.length >= this.limit) {\n            this.records.shift();\n        }\n        this.records.push([Date.now(), type, message, ...args]);\n    }\n    getRecords() {\n        return this.records.map(([date, type, message, ...args]) => {\n            if (message !== null && message !== undefined && message.constructor === String) {\n                message = message.trim();\n            }\n            return [date, type, message, ...args];\n        });\n    }\n    getReplacer(sanitize) {\n        return (key, value) => {\n            if (value === null || value === undefined) {\n                return value;\n            }\n            if (value instanceof BaseConfidential) {\n                value = sanitize ? value.censored() : value.uncensored;\n            }\n            for (const allowedType of ALLOWED_TYPES) {\n                if (value.constructor === allowedType) {\n                    return value;\n                }\n            }\n            if (value instanceof Error) {\n                return value.toString();\n            }\n            if (value instanceof ArrayBuffer) {\n                return `[ArrayBuffer: length=${value.byteLength}]`;\n            }\n            if (value instanceof Uint8Array) {\n                return `[Uint8Array: length=${value.byteLength}, offset=${value.byteOffset}]`;\n            }\n            if (value instanceof Blob) {\n                return `[Blob: length=${value.size}, type=${value.type}]`;\n            }\n            if (value.constructor === Object) {\n                return value;\n            }\n            return `[${value.constructor.name}]`;\n        };\n    }\n}\n","import { ConsoleLogger, LevelLogger, MemoryLogger, TagLogger, TeeLogger, UnveilLogger } from '../helpers/logger';\nexport class LogService {\n    constructor(config) {\n        this.config = config;\n        let logger;\n        const loggers = [];\n        logger = new ConsoleLogger();\n        logger = new UnveilLogger(logger);\n        if (config.CONSOLE_LOG_LEVEL !== 'debug') {\n            logger = new LevelLogger(logger, config.CONSOLE_LOG_LEVEL);\n        }\n        loggers.push(logger);\n        logger = this.memory = new MemoryLogger(config.REPORT_LOG_LIMIT);\n        if (config.REPORT_LOG_LEVEL !== 'debug') {\n            logger = new LevelLogger(logger, config.REPORT_LOG_LEVEL);\n        }\n        loggers.push(logger);\n        this.root = new TeeLogger(loggers);\n        this.setupUncaughtExceptionHandling();\n    }\n    getLogger(tag, style, level) {\n        let styledTag;\n        if (style !== undefined) {\n            styledTag = `%c[${tag}]`;\n        }\n        else {\n            styledTag = `[${tag}]`;\n        }\n        styledTag = styledTag.padStart(this.config.LOG_TAG_PADDING + styledTag.length - tag.length);\n        let logger;\n        if (style !== undefined) {\n            logger = new TagLogger(this.root, styledTag, style);\n        }\n        else {\n            logger = new TagLogger(this.root, styledTag);\n        }\n        if (level !== undefined) {\n            logger = new LevelLogger(logger, level);\n        }\n        return logger;\n    }\n    setupUncaughtExceptionHandling() {\n        const logger = this.getLogger('UncaughtException');\n        window.addEventListener('error', (e) => {\n            const data = [];\n            data.push(`Unhandled exception (w): ${e.message}\\n`);\n            data.push((e.error && e.error.stack) ? e.error.stack : e.error);\n            logger.error(...data);\n            e.stopPropagation();\n            e.preventDefault();\n            return true;\n        });\n        window.addEventListener('unhandledrejection', (e) => {\n            logger.error('Unhandled promise rejection:', (e.reason && e.reason.stack) ? e.reason.stack : e.reason);\n            e.stopPropagation();\n            e.preventDefault();\n            return true;\n        });\n    }\n}\nLogService.$inject = ['CONFIG'];\n","import { isContactReceiver } from '../typeguards';\nexport class MessageAccess {\n    constructor() {\n        this.quote = false;\n        this.ack = false;\n        this.dec = false;\n        this.delete = false;\n        this.download = false;\n        this.copy = false;\n    }\n}\nexport class MessageService {\n    constructor(receiverService, timeoutService) {\n        this.timeoutDelaySeconds = 30;\n        this.receiverService = receiverService;\n        this.timeoutService = timeoutService;\n    }\n    getAccess(message, receiver) {\n        const access = new MessageAccess();\n        if (message !== undefined) {\n            access.quote = (message.type === 'text')\n                || (message.type === 'location')\n                || (message.caption !== undefined && message.caption !== null && message.caption.length > 0);\n            access.copy = access.quote;\n            if (receiver !== undefined && message.temporaryId === undefined) {\n                if (message.isOutbox === false\n                    && isContactReceiver(receiver)\n                    && message.type !== 'voipStatus') {\n                    access.ack = message.state !== 'user-ack';\n                    access.dec = message.state !== 'user-dec';\n                }\n                switch (message.type) {\n                    case 'image':\n                    case 'video':\n                    case 'audio':\n                    case 'file':\n                        access.download = true;\n                        break;\n                    default:\n                        access.download = false;\n                }\n                access.delete = true;\n            }\n        }\n        return access;\n    }\n    getQuoteText(message) {\n        let quoteText = null;\n        if (message !== null && message !== undefined) {\n            switch (message.type) {\n                case 'text':\n                    quoteText = message.body;\n                    break;\n                case 'location':\n                    quoteText = message.location.description;\n                    break;\n                case 'file':\n                case 'image':\n                    quoteText = message.caption;\n                    break;\n                default:\n            }\n        }\n        return quoteText;\n    }\n    showStatusIcon(message, receiver) {\n        if (message !== null && receiver !== null) {\n            const messageState = message.state;\n            switch (receiver.type) {\n                case 'group':\n                    if (message.isOutbox && (message.temporaryId === undefined || message.temporaryId === null)) {\n                        return messageState === 'send-failed'\n                            || messageState === 'sending'\n                            || (messageState === 'pending' && message.type !== 'ballot');\n                    }\n                    return false;\n                case 'distributionList':\n                    return false;\n                case 'contact':\n                    if (!message.isOutbox) {\n                        return messageState === 'user-ack'\n                            || messageState === 'user-dec';\n                    }\n                    else if (this.receiverService.isBusinessContact(receiver)) {\n                        return messageState === 'send-failed'\n                            || messageState === 'sending'\n                            || messageState === 'pending';\n                    }\n                    return true;\n                default:\n                    return false;\n            }\n        }\n        return false;\n    }\n    getPreviewThumbnail(uri, preview) {\n        const image = new Image();\n        image.src = uri;\n        if (image.width > MessageService.MAX_THUMBNAIL_SIZE || image.height > MessageService.MAX_THUMBNAIL_SIZE) {\n            const scale = Math.min(MessageService.MAX_THUMBNAIL_SIZE / image.width, MessageService.MAX_THUMBNAIL_SIZE / image.height);\n            image.width = Math.round(scale * image.width);\n            image.height = Math.round(scale * image.height);\n        }\n        return {\n            previewDataUrl: uri,\n            preview: preview,\n            width: image.width,\n            height: image.height,\n        };\n    }\n    createTemporary(temporaryId, receiver, type, data, previewDataUrl) {\n        const timestampS = Math.floor(Date.now() / 1000);\n        const message = {\n            type: type,\n            id: undefined,\n            date: timestampS,\n            sortKey: undefined,\n            partnerId: receiver.id,\n            isOutbox: true,\n            isStatus: false,\n            state: 'pending',\n            quote: data.quote,\n            temporaryId: temporaryId,\n        };\n        switch (type) {\n            case 'text':\n                const textData = data;\n                message.body = textData.text;\n                break;\n            case 'image': {\n                const fileData = data;\n                message.caption = fileData.caption;\n                if (previewDataUrl !== undefined) {\n                    message.thumbnail = this.getPreviewThumbnail(previewDataUrl, fileData.data);\n                }\n                break;\n            }\n            case 'video': {\n                const fileData = data;\n                message.video = {\n                    duration: null,\n                    size: fileData.size,\n                };\n                break;\n            }\n            case 'audio':\n                break;\n            case 'file': {\n                const fileData = data;\n                message.caption = fileData.caption;\n                message.file = {\n                    name: fileData.name,\n                    size: fileData.size,\n                    type: fileData.fileType,\n                    inApp: false,\n                };\n                if (previewDataUrl !== undefined) {\n                    message.thumbnail = this.getPreviewThumbnail(previewDataUrl, fileData.data);\n                }\n                break;\n            }\n            default:\n                throw new Error(`Cannot create temporary message for type: ${type}`);\n        }\n        return message;\n    }\n    isSentOrSendingFailed(message) {\n        switch (message.state) {\n            case 'pending':\n            case 'sending':\n                return false;\n            default:\n                return true;\n        }\n    }\n}\nMessageService.MAX_THUMBNAIL_SIZE = 350;\nMessageService.$inject = ['ReceiverService', 'TimeoutService'];\n","import { hasValue } from '../helpers';\nexport class MimeService {\n    constructor($translate) {\n        this.imageMimeTypes = ['image/png', 'image/jpg', 'image/jpeg'];\n        this.audioMimeTypesAndroid = ['audio/ogg'];\n        this.audioMimeTypesIos = ['audio/m4a', 'audio/x-m4a', 'audio/mp4'];\n        this.videoMimeTypes = ['video/mp4', 'video/mpg', 'video/mpeg'];\n        this.$translate = $translate;\n    }\n    isImage(mimeType) {\n        return this.is(mimeType, this.imageMimeTypes);\n    }\n    isAudio(mimeType, os) {\n        switch (os) {\n            case \"android\":\n                return this.is(mimeType, this.audioMimeTypesAndroid);\n            case \"ios\":\n                return this.is(mimeType, this.audioMimeTypesIos);\n        }\n        return false;\n    }\n    isVideo(mimeType) {\n        return this.is(mimeType, this.videoMimeTypes);\n    }\n    getLabel(mimeType) {\n        const key = this.getKey(mimeType);\n        if (key !== null) {\n            return this.$translate.instant('mimeTypes.' + key);\n        }\n        return mimeType;\n    }\n    getIconUrl(mimeType) {\n        let key = this.getKey(mimeType);\n        if (!hasValue(key) || key.length === 0) {\n            key = 'generic';\n        }\n        return 'img/mime/ic_doc_' + key + '.png';\n    }\n    getKey(mimeType) {\n        if (!hasValue(mimeType)) {\n            return null;\n        }\n        if (mimeType.startsWith('audio/')) {\n            return 'audio';\n        }\n        if (mimeType.startsWith('video/')) {\n            return 'video';\n        }\n        switch (mimeType) {\n            case 'application/vnd.android.package-archive':\n                return 'apk';\n            case 'application/ogg':\n            case 'application/x-flac':\n            case 'application/mpeg3':\n            case 'application/x-mpeg-3':\n                return 'audio';\n            case 'application/pgp-keys':\n            case 'application/pgp-signature':\n            case 'application/x-pkcs12':\n            case 'application/x-pkcs7-certreqresp':\n            case 'application/x-pkcs7-crl':\n            case 'application/x-x509-ca-cert':\n            case 'application/x-x509-user-cert':\n            case 'application/x-pkcs7-certificates':\n            case 'application/x-pkcs7-mime':\n            case 'application/x-pkcs7-signature':\n                return 'certificate';\n            case 'application/rdf+xml':\n            case 'application/rss+xml':\n            case 'application/x-object':\n            case 'application/xhtml+xml':\n            case 'text/css':\n            case 'text/html':\n            case 'text/xml':\n            case 'text/x-c++hdr':\n            case 'text/x-c++src':\n            case 'text/x-chdr':\n            case 'text/x-csrc':\n            case 'text/x-dsrc':\n            case 'text/x-csh':\n            case 'text/x-haskell':\n            case 'text/x-java':\n            case 'text/x-literate-haskell':\n            case 'text/x-pascal':\n            case 'text/x-tcl':\n            case 'text/x-tex':\n            case 'application/x-latex':\n            case 'application/x-texinfo':\n            case 'application/atom+xml':\n            case 'application/ecmascript':\n            case 'application/json':\n            case 'application/javascript':\n            case 'application/xml':\n            case 'text/javascript':\n            case 'application/x-javascript':\n                return 'codes';\n            case 'application/mac-binhex40':\n            case 'application/rar':\n            case 'application/zip':\n            case 'application/x-apple-diskimage':\n            case 'application/x-debian-package':\n            case 'application/x-gtar':\n            case 'application/x-iso9660-image':\n            case 'application/x-lha':\n            case 'application/x-lzh':\n            case 'application/x-lzx':\n            case 'application/x-stuffit':\n            case 'application/x-tar':\n            case 'application/x-webarchive':\n            case 'application/x-webarchive-xml':\n            case 'application/gzip':\n            case 'application/x-7z-compressed':\n            case 'application/x-deb':\n            case 'application/x-rar-compressed':\n                return 'compressed';\n            case 'text/x-vcard':\n            case 'text/vcard':\n                return 'contact';\n            case 'text/calendar':\n            case 'text/x-vcalendar':\n                return 'event';\n            case 'application/x-font':\n            case 'application/font-woff':\n            case 'application/x-font-woff':\n            case 'application/x-font-ttf':\n                return 'font';\n            case 'application/vnd.oasis.opendocument.graphics':\n            case 'application/vnd.oasis.opendocument.graphics-template':\n            case 'application/vnd.oasis.opendocument.image':\n            case 'application/vnd.stardivision.draw':\n            case 'application/vnd.sun.xml.draw':\n            case 'application/vnd.sun.xml.draw.template':\n            case 'image/jpg':\n            case 'image/jpeg':\n            case 'image/png':\n            case 'image/gif':\n                return 'image';\n            case 'application/pdf':\n                return 'pdf';\n            case 'application/vnd.ms-powerpoint':\n            case 'application/vnd.oasis.opendocument.presentation':\n            case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':\n            case 'application/vnd.openxmlformats-officedocument.presentationml.slideshow':\n            case 'application/vnd.openxmlformats-officedocument.presentationml.template':\n            case 'application/vnd.stardivision.impress':\n            case 'application/vnd.sun.xml.impress':\n            case 'application/vnd.sun.xml.impress.template':\n            case 'application/x-kpresenter':\n                return 'presentation';\n            case 'application/vnd.oasis.opendocument.spreadsheet':\n            case 'application/vnd.oasis.opendocument.spreadsheet-template':\n            case 'application/vnd.stardivision.calc':\n            case 'application/vnd.sun.xml.calc':\n            case 'application/vnd.sun.xml.calc.template':\n            case 'application/x-kspread':\n            case 'application/vnd.ms-excel':\n            case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':\n            case 'application/vnd.openxmlformats-officedocument.spreadsheetml.template':\n                return 'spreadsheet';\n            case 'application/vnd.oasis.opendocument.text':\n            case 'application/vnd.oasis.opendocument.text-master':\n            case 'application/vnd.oasis.opendocument.text-template':\n            case 'application/vnd.oasis.opendocument.text-web':\n            case 'application/vnd.stardivision.writer':\n            case 'application/vnd.stardivision.writer-global':\n            case 'application/vnd.sun.xml.writer':\n            case 'application/vnd.sun.xml.writer.global':\n            case 'application/vnd.sun.xml.writer.template':\n            case 'application/x-abiword':\n            case 'application/x-kword':\n                return 'text';\n            case 'application/x-quicktimeplayer':\n            case 'application/x-shockwave-flash':\n                return 'video';\n            case 'application/msword':\n            case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':\n            case 'application/vnd.openxmlformats-officedocument.wordprocessingml.template':\n                return 'word';\n            default:\n                return null;\n        }\n    }\n    is(mimeType, possibleTypes) {\n        return mimeType !== undefined\n            && possibleTypes.indexOf(mimeType) !== -1;\n    }\n}\nMimeService.$inject = ['$translate'];\n","export class NotificationService {\n    constructor($window, $state, logService, settingsService) {\n        this.notificationPermission = null;\n        this.desktopNotifications = null;\n        this.notificationAPIAvailable = null;\n        this.notificationPreview = null;\n        this.notificationSound = null;\n        this.notificationCache = {};\n        this.$window = $window;\n        this.$state = $state;\n        this.settingsService = settingsService;\n        this.log = logService.getLogger('Notification-S');\n    }\n    init() {\n        this.checkNotificationAPI();\n        this.fetchSettings();\n    }\n    requestNotificationPermission() {\n        if (this.notificationAPIAvailable) {\n            const Notification = this.$window.Notification;\n            this.log.debug('Requesting notification permission...');\n            Notification.requestPermission((result) => {\n                switch (result) {\n                    case 'denied':\n                        this.notificationPermission = false;\n                        break;\n                    case 'granted':\n                        this.notificationPermission = true;\n                        this.desktopNotifications = true;\n                        this.storeSetting(NotificationService.SETTINGS_NOTIFICATIONS, 'true');\n                        break;\n                    case 'default':\n                        this.desktopNotifications = false;\n                        this.notificationPermission = null;\n                        break;\n                    default:\n                        this.notificationPermission = false;\n                        break;\n                }\n                this.log.debug('Notification permission', this.notificationPermission);\n            });\n        }\n    }\n    checkNotificationAPI() {\n        this.notificationAPIAvailable = ('Notification' in this.$window);\n        this.log.debug('Notification API available:', this.notificationAPIAvailable);\n        if (this.notificationAPIAvailable) {\n            const Notification = this.$window.Notification;\n            switch (Notification.permission) {\n                case 'denied':\n                    this.notificationPermission = false;\n                    break;\n                case 'granted':\n                    this.notificationPermission = true;\n                    break;\n                case 'default':\n                    this.notificationPermission = null;\n                    break;\n                default:\n                    this.notificationPermission = false;\n                    break;\n            }\n        }\n        this.log.debug('Initial notificationPermission', this.notificationPermission);\n    }\n    fetchSettings() {\n        this.log.debug('Fetching settings...');\n        const notifications = this.retrieveSetting(NotificationService.SETTINGS_NOTIFICATIONS);\n        const preview = this.retrieveSetting(NotificationService.SETTINGS_NOTIFICATION_PREVIEW);\n        const sound = this.retrieveSetting(NotificationService.SETTINGS_NOTIFICATION_SOUND);\n        if (notifications === 'true') {\n            this.log.debug('Desktop notifications:', notifications);\n            this.desktopNotifications = true;\n            this.requestNotificationPermission();\n        }\n        else if (notifications === 'false') {\n            this.log.debug('Desktop notifications:', notifications);\n            this.desktopNotifications = false;\n        }\n        else {\n            this.log.debug('Desktop notifications:', notifications, 'Asking user...');\n            this.requestNotificationPermission();\n        }\n        if (preview === 'false') {\n            this.log.debug('Notification preview:', preview);\n            this.notificationPreview = false;\n        }\n        else {\n            this.log.debug('Notification preview:', preview, 'Using default value (true)');\n            this.notificationPreview = true;\n            this.storeSetting(NotificationService.SETTINGS_NOTIFICATION_PREVIEW, 'true');\n        }\n        if (sound === 'true') {\n            this.log.debug('Notification sound:', sound);\n            this.notificationSound = true;\n        }\n        else {\n            this.log.debug('Notification sound:', sound, 'Using default value (false)');\n            this.notificationSound = false;\n            this.storeSetting(NotificationService.SETTINGS_NOTIFICATION_SOUND, 'false');\n        }\n    }\n    getNotificationPermission() {\n        return this.notificationPermission;\n    }\n    getWantsNotifications() {\n        return this.desktopNotifications;\n    }\n    getWantsPreview() {\n        return this.notificationPreview;\n    }\n    getWantsSound() {\n        return this.notificationSound;\n    }\n    isNotificationApiAvailable() {\n        return this.notificationAPIAvailable;\n    }\n    setWantsNotifications(wantsNotifications) {\n        this.log.debug('Requesting notification preference change to', wantsNotifications);\n        if (wantsNotifications) {\n            this.requestNotificationPermission();\n        }\n        else {\n            this.desktopNotifications = false;\n            this.storeSetting(NotificationService.SETTINGS_NOTIFICATIONS, 'false');\n        }\n    }\n    setWantsPreview(wantsPreview) {\n        this.log.debug('Requesting preview preference change to', wantsPreview);\n        this.notificationPreview = wantsPreview;\n        this.storeSetting(NotificationService.SETTINGS_NOTIFICATION_PREVIEW, wantsPreview ? 'true' : 'false');\n    }\n    setWantsSound(wantsSound) {\n        this.log.debug('Requesting sound preference change to', wantsSound);\n        this.notificationSound = wantsSound;\n        this.storeSetting(NotificationService.SETTINGS_NOTIFICATION_SOUND, wantsSound ? 'true' : 'false');\n    }\n    storeSetting(key, value) {\n        this.settingsService.storeUntrustedKeyValuePair(key, value);\n    }\n    retrieveSetting(key) {\n        return this.settingsService.retrieveUntrustedKeyValuePair(key);\n    }\n    getAppNotificationSettings(conversation) {\n        if (!conversation.notifications) {\n            return {\n                sound: { muted: false },\n                dnd: { enabled: false, mentionOnly: false },\n            };\n        }\n        const sound = conversation.notifications.sound;\n        const dnd = conversation.notifications.dnd;\n        const simpleSound = {\n            muted: !(sound.mode === \"default\"),\n        };\n        const simpleDnd = {\n            enabled: dnd.mode === \"on\",\n            mentionOnly: (dnd.mentionOnly === undefined || dnd.mentionOnly === null) ? false : dnd.mentionOnly,\n        };\n        if (dnd.mode === \"until\") {\n            if (!dnd.until || dnd.until <= 0) {\n                simpleDnd.enabled = false;\n            }\n            else {\n                const until = new Date(dnd.until);\n                const now = new Date();\n                simpleDnd.enabled = until > now;\n            }\n        }\n        if (!simpleDnd.enabled) {\n            simpleDnd.mentionOnly = false;\n        }\n        return {\n            sound: simpleSound,\n            dnd: simpleDnd,\n        };\n    }\n    getDndModeSimplified(conversation) {\n        const simplified = this.getAppNotificationSettings(conversation);\n        if (simplified.dnd.enabled) {\n            return simplified.dnd.mentionOnly ? 'mention' : 'on';\n        }\n        return 'off';\n    }\n    showNotification(tag, title, body, avatar = '/img/threema-64x64.png', clickCallback, forceShowBody = false, overwriteOlder = false, forceMute = false) {\n        if (this.notificationSound && !forceMute) {\n            const audio = new Audio(NotificationService.NOTIFICATION_SOUND);\n            audio.play();\n        }\n        if (this.notificationPermission !== true || this.desktopNotifications !== true) {\n            return false;\n        }\n        if (!this.notificationPreview && !forceShowBody) {\n            body = '';\n            if (this.notificationCache[tag]) {\n                this.clearCache(tag);\n            }\n        }\n        if (overwriteOlder === true) {\n            this.clearCache(tag);\n        }\n        if (this.notificationCache[tag]) {\n            body = `${this.notificationCache[tag].body}\\n${body}`;\n        }\n        this.log.debug('Showing notification', tag);\n        const notification = new this.$window.Notification(title, {\n            icon: avatar,\n            body: body.trim(),\n            tag: tag,\n        });\n        notification.onclick = () => {\n            this.$window.focus();\n            if (clickCallback !== undefined) {\n                clickCallback();\n            }\n            this.log.debug('Hiding notification', tag, 'on click');\n            notification.close();\n            this.clearCache(tag);\n        };\n        this.notificationCache[tag] = notification;\n        return true;\n    }\n    hideNotification(tag) {\n        const notification = this.notificationCache[tag];\n        if (notification !== undefined) {\n            this.log.debug('Hiding notification', tag);\n            notification.close();\n            this.clearCache(tag);\n            return true;\n        }\n        else {\n            return false;\n        }\n    }\n    clearCache(tag) {\n        delete this.notificationCache[tag];\n    }\n}\nNotificationService.SETTINGS_NOTIFICATIONS = 'notifications';\nNotificationService.SETTINGS_NOTIFICATION_PREVIEW = 'notificationPreview';\nNotificationService.SETTINGS_NOTIFICATION_SOUND = 'notificationSound';\nNotificationService.NOTIFICATION_SOUND = 'sounds/notification.mp3';\nNotificationService.$inject = ['$window', '$state', 'LogService', 'SettingsService'];\n","import { stringToUtf8a, u8aToBase64 } from '../helpers';\nexport class QrCodeService {\n    constructor(CONFIG, PROTOCOL_VERSION) {\n        this.config = CONFIG;\n        this.protocolVersion = PROTOCOL_VERSION;\n    }\n    buildQrCodePayload(initiatorKey, authToken, serverKey, host, port, persistent) {\n        const saltyRtcHostBytes = stringToUtf8a(host);\n        const buf = new ArrayBuffer(2 + 1 + 32 + 32 + 32 + 2 + saltyRtcHostBytes.byteLength);\n        let options = 0;\n        options |= (this.config.SELF_HOSTED === true ? 1 : 0) << 0;\n        options |= (persistent ? 1 : 0) << 1;\n        const dataView = new DataView(buf);\n        dataView.setUint16(0, this.protocolVersion);\n        dataView.setUint8(2, options);\n        const u8Array = new Uint8Array(buf);\n        u8Array.set(initiatorKey, 3);\n        u8Array.set(authToken, 35);\n        if (serverKey === null) {\n            u8Array.set(new Uint8Array(32), 67);\n        }\n        else {\n            u8Array.set(serverKey, 67);\n        }\n        dataView.setUint16(99, port);\n        u8Array.set(saltyRtcHostBytes, 101);\n        return u8aToBase64(new Uint8Array(buf));\n    }\n}\nQrCodeService.$inject = ['CONFIG', 'PROTOCOL_VERSION'];\n","export class SettingsService {\n    constructor($window, logService) {\n        this.log = logService.getLogger('Settings-S');\n        this.storage = $window.localStorage;\n    }\n    storeUntrustedKeyValuePair(key, value) {\n        this.log.debug('Storing settings key:', key);\n        this.storage.setItem(SettingsService.STORAGE_KEY_PREFIX + key, value);\n    }\n    retrieveUntrustedKeyValuePair(key, alwaysCreate = true) {\n        this.log.debug('Retrieving settings key:', key);\n        if (this.hasUntrustedKeyValuePair(key)) {\n            return this.storage.getItem(SettingsService.STORAGE_KEY_PREFIX + key);\n        }\n        else {\n            if (alwaysCreate) {\n                this.storeUntrustedKeyValuePair(key, '');\n            }\n            return '';\n        }\n    }\n    removeUntrustedKeyValuePair(key) {\n        this.log.debug('Removing settings key:', key);\n        this.storage.removeItem(SettingsService.STORAGE_KEY_PREFIX + key);\n    }\n    hasUntrustedKeyValuePair(key) {\n        const item = this.storage.getItem(SettingsService.STORAGE_KEY_PREFIX + key);\n        return item !== null;\n    }\n}\nSettingsService.STORAGE_KEY_PREFIX = 'settings-';\nSettingsService.$inject = ['$window', 'LogService'];\n","import { AsyncEvent } from 'ts-events';\nexport class StateService {\n    constructor($interval, logService) {\n        this.evtConnectionBuildupStateChange = new AsyncEvent();\n        this.evtGlobalConnectionStateChange = new AsyncEvent();\n        this.evtUnreadCountChange = new AsyncEvent();\n        this.progress = 0;\n        this.progressInterval = null;\n        this.slowConnect = false;\n        this.attempt = 0;\n        this._unreadCount = 0;\n        this.$interval = $interval;\n        this.log = logService.getLogger('State-S', 'color: #fff; background-color: #cc9900');\n        this.reset();\n    }\n    get state() {\n        return this._state;\n    }\n    set state(state) {\n        const prevState = this._state;\n        if (prevState === state) {\n            return;\n        }\n        this._state = state;\n        this.evtGlobalConnectionStateChange.post({ state: state, prevState: prevState });\n    }\n    updateSignalingConnectionState(state, chosenTask, handoverDone) {\n        const prevState = this.signalingConnectionState;\n        this.signalingConnectionState = state;\n        if (!handoverDone) {\n            this.log.debug('Signaling connection state:', prevState, '=>', state);\n            switch (state) {\n                case 'new':\n                case 'ws-connecting':\n                case 'server-handshake':\n                case 'peer-handshake':\n                    this.state = \"warning\";\n                    break;\n                case 'task':\n                    this.stage = 1;\n                    if (chosenTask === \"relayed-data\") {\n                        this.updateTaskConnectionState(\"connected\");\n                    }\n                    else {\n                        this.state = \"warning\";\n                    }\n                    break;\n                case 'closing':\n                case 'closed':\n                    this.state = \"error\";\n                    break;\n                default:\n                    this.log.warn(`Unknown signaling connection state: ${state}`);\n            }\n        }\n        else {\n            this.log.debug('Ignored signaling connection state to \"' + state + '\"');\n        }\n    }\n    updateTaskConnectionState(state) {\n        const prevState = this.taskConnectionState;\n        this.taskConnectionState = state;\n        if (this.stage === 1) {\n            this.log.debug('Task connection state:', prevState, '=>', state);\n            switch (state) {\n                case \"new\":\n                case \"connecting\":\n                case \"reconnecting\":\n                    this.state = \"warning\";\n                    break;\n                case \"connected\":\n                    this.state = \"ok\";\n                    this.attempt = 0;\n                    break;\n                case \"disconnected\":\n                    this.state = \"error\";\n                    break;\n                default:\n                    this.log.warn('Ignored task connection state change to \"' + state + '\"');\n            }\n        }\n        else {\n            this.log.debug('Ignored task connection state change to \"' + state + '\"');\n        }\n    }\n    updateConnectionBuildupState(state) {\n        if (this.connectionBuildupState === state) {\n            return;\n        }\n        const prevState = this.connectionBuildupState;\n        this.log.debug('Connection buildup state:', prevState, '=>', state);\n        this.connectionBuildupState = state;\n        this.evtConnectionBuildupStateChange.post({ state: state, prevState: prevState });\n        if (this.progressInterval !== null) {\n            this.$interval.cancel(this.progressInterval);\n            this.progressInterval = null;\n        }\n        this.slowConnect = false;\n        switch (state) {\n            case 'new':\n                this.progress = 0;\n                break;\n            case 'push':\n                this.progress = 0;\n                this.progressInterval = this.$interval(() => {\n                    if (this.progress < 12) {\n                        this.progress += 1;\n                    }\n                    else {\n                        this.slowConnect = true;\n                    }\n                }, 800);\n                break;\n            case 'manual_start':\n                this.progress = 0;\n                break;\n            case 'connecting':\n                this.progress = 13;\n                break;\n            case 'waiting':\n                this.progress = 14;\n                break;\n            case 'peer_handshake':\n                this.progress = 15;\n                this.progressInterval = this.$interval(() => {\n                    if (this.progress < 40) {\n                        this.progress += 5;\n                    }\n                    else if (this.progress < 55) {\n                        this.progress += 3;\n                    }\n                    else if (this.progress < 60) {\n                        this.progress += 1;\n                    }\n                    else {\n                        this.slowConnect = true;\n                    }\n                }, 500);\n                break;\n            case 'loading':\n                this.progress = 60;\n                this.progressInterval = this.$interval(() => {\n                    if (this.progress < 80) {\n                        this.progress += 4;\n                    }\n                    else if (this.progress < 90) {\n                        this.progress += 2;\n                    }\n                    else if (this.progress < 99) {\n                        this.progress += 1;\n                    }\n                    else {\n                        this.slowConnect = true;\n                    }\n                }, 600);\n                break;\n            case 'done':\n                this.progress = 100;\n                break;\n            default:\n                this.progress = 0;\n                break;\n        }\n    }\n    readyToSubmit(chosenTask, startupDone) {\n        switch (chosenTask) {\n            case \"relayed-data\":\n                return true;\n            case \"webrtc\":\n            default:\n                return this.state === \"ok\" && startupDone;\n        }\n    }\n    get unreadCount() {\n        return this._unreadCount;\n    }\n    set unreadCount(count) {\n        if (this._unreadCount === count) {\n            return;\n        }\n        this._unreadCount = count;\n        this.evtUnreadCountChange.post(count);\n    }\n    reset(connectionBuildupState = 'new') {\n        this.log.debug('Reset states');\n        this.signalingConnectionState = 'new';\n        this.taskConnectionState = \"new\";\n        this.stage = 0;\n        this.state = \"error\";\n        this.connectionBuildupState = connectionBuildupState;\n        this.progress = 0;\n        this.unreadCount = 0;\n    }\n}\nStateService.$inject = ['$interval', 'LogService'];\n","import { AsyncEvent } from 'ts-events';\nexport class ThemeService {\n    constructor($interval, logService) {\n        this.evtThemeChange = new AsyncEvent();\n        this._theme = \"threema\";\n        this.$interval = $interval;\n        this.log = logService.getLogger('Theme-S', 'color: #fff; background-color: #cc9900');\n        this.log.debug(`Initializing with theme ${this.theme}`);\n    }\n    get theme() {\n        return this._theme;\n    }\n    changeTheme(theme) {\n        this._theme = theme;\n        this.evtThemeChange.post(theme);\n    }\n}\nThemeService.$inject = ['$interval', 'LogService'];\n","export class TimeoutService {\n    constructor(config, $timeout, logService) {\n        this.timeouts = new Set();\n        this.config = config;\n        this.$timeout = $timeout;\n        this.log = logService.getLogger('Timeout-S', 'color: #fff; background-color: #669900', this.config.TIMER_LOG_LEVEL);\n    }\n    register(fn, delay, invokeApply, name) {\n        this.log.debug(`Registering timeout${name === undefined ? '' : ` (${name})`}`);\n        const timeout = this.$timeout(fn, delay, invokeApply);\n        timeout\n            .then(() => this.timeouts.delete(timeout))\n            .catch((reason) => {\n            if (reason !== 'canceled') {\n                this.log.error('Registered timeout promise rejected:', reason);\n            }\n        });\n        timeout['_timeout_name'] = name;\n        this.timeouts.add(timeout);\n        return timeout;\n    }\n    cancel(timeout) {\n        const name = timeout['_timeout_name'];\n        this.log.debug(`Cancelling timeout${name === undefined ? '' : ` (${name})`}`);\n        const cancelled = this.$timeout.cancel(timeout);\n        this.timeouts.delete(timeout);\n        return cancelled;\n    }\n    cancelAll() {\n        this.log.debug('Cancelling ' + this.timeouts.size + ' timeouts');\n        for (const timeout of this.timeouts) {\n            this.$timeout.cancel(timeout);\n        }\n        this.timeouts.clear();\n    }\n}\nTimeoutService.$inject = ['CONFIG', '$timeout', 'LogService'];\n","export class TitleService {\n    constructor($document, stateService) {\n        this.DEFAULT_TITLE = 'Threema Web';\n        this.unreadCount = 0;\n        this.$document = $document;\n        this.stateService = stateService;\n        this.stateService.evtUnreadCountChange.attach((count) => {\n            this.unreadCount = count;\n            this.update();\n        });\n        this.update();\n    }\n    update() {\n        if (this.unreadCount > 0) {\n            this.title = `(${this.unreadCount}) ${this.DEFAULT_TITLE}`;\n        }\n        else {\n            this.title = this.DEFAULT_TITLE;\n        }\n        this.$document[0].title = this.title;\n    }\n}\nTitleService.$inject = ['$document', 'StateService'];\n","export class VersionService {\n    constructor($http, $mdDialog, $translate, $window, CONFIG, logService) {\n        this.dialogShowing = false;\n        this.$http = $http;\n        this.$mdDialog = $mdDialog;\n        this.$translate = $translate;\n        this.$window = $window;\n        this.config = CONFIG;\n        this.log = logService.getLogger('Version-S');\n    }\n    initVersion() {\n        if (this.version !== undefined) {\n            this.checkForUpdate();\n            return;\n        }\n        this.fetchVersion()\n            .then((version) => {\n            this.version = version;\n            this.log.info('Using Threema Web version', this.version);\n        })\n            .catch((error) => {\n            this.log.error('Could not fetch version.txt:', error);\n        });\n    }\n    fetchVersion() {\n        return new Promise((resolve, reject) => {\n            const cacheBust = Math.floor(Math.random() * 1000000000);\n            this.$http({\n                method: 'GET',\n                url: 'version.txt?' + cacheBust,\n                cache: false,\n                responseType: 'text',\n                transformResponse: (data, headersGetter, statusCode) => {\n                    if (statusCode !== 200) {\n                        return reject('HTTP ' + statusCode);\n                    }\n                    return data.trim();\n                },\n            }).then((successResponse) => {\n                return resolve(successResponse.data);\n            }, (error) => {\n                return reject(error);\n            });\n        });\n    }\n    checkForUpdate() {\n        this.log.debug('Checking for version update...');\n        if (this.version === undefined) {\n            this.log.error('Cannot check for update, version is not initialized');\n            return;\n        }\n        this.fetchVersion()\n            .then((version) => {\n            if (version !== this.version) {\n                this.log.warn('A new version of Threema Web is available:', this.version, '->', version);\n                this.notifyNewVersion(version);\n            }\n        })\n            .catch((error) => {\n            this.log.error('Could not fetch version.txt:', error);\n        });\n    }\n    notifyNewVersion(version) {\n        if (this.dialogShowing === true) {\n            return;\n        }\n        const changelogUrl = 'https://github.com/threema-ch/threema-web/blob/'\n            + this.config.GIT_BRANCH\n            + '/CHANGELOG.md';\n        const changelogLink = '<a href=\"' + changelogUrl + '\" target=\"_blank\" rel=\"noopener noreferrer\">Changelog</a>';\n        const confirm = this.$mdDialog.alert()\n            .title(this.$translate.instant('version.NEW_VERSION'))\n            .htmlContent(this.$translate.instant('version.NEW_VERSION_BODY', {\n            version: version,\n            changelog: changelogLink,\n        }))\n            .ok(this.$translate.instant('common.OK'));\n        this.dialogShowing = true;\n        this.$mdDialog.show(confirm).then(() => {\n            this.$window.location.reload();\n        }, () => {\n            this.$window.location.reload();\n        });\n    }\n}\nVersionService.$inject = ['$http', '$mdDialog', '$translate', '$window', 'CONFIG', 'LogService'];\n","export function isFirstUnreadStatusMessage(message) {\n    return message.type === 'status' && message.statusType === 'firstUnreadMessage';\n}\n","import { copyShallow, randomString } from '../helpers';\nimport { ConfidentialArray, ConfidentialObjectValues } from '../helpers/confidential';\nimport { isFirstUnreadStatusMessage } from '../message_helpers';\nfunction setDefault(obj, key, defaultValue) {\n    if (obj[key] === undefined) {\n        obj[key] = defaultValue;\n    }\n}\nexport class StringHashSet {\n    constructor() {\n        this.setObj = {};\n        this.val = {};\n    }\n    add(str) {\n        this.setObj[str] = this.val;\n    }\n    contains(str) {\n        return this.setObj[str] === this.val;\n    }\n    remove(str) {\n        delete this.setObj[str];\n    }\n    values() {\n        const values = [];\n        for (const i in this.setObj) {\n            if (this.setObj[i] === this.val) {\n                values.push(i);\n            }\n        }\n        return values;\n    }\n    clearAll() {\n        for (const element in this.setObj) {\n            if (this.setObj.hasOwnProperty(element)) {\n                this.remove(element);\n            }\n        }\n    }\n}\nclass Receivers {\n    constructor() {\n        this.me = null;\n        this.contacts = new Map();\n        this.groups = new Map();\n        this.distributionLists = new Map();\n    }\n    get(receiverType) {\n        switch (receiverType) {\n            case 'me':\n                return this.me;\n            case 'contact':\n                return this.contacts;\n            case 'group':\n                return this.groups;\n            case 'distributionList':\n                return this.distributionLists;\n            default:\n                throw new Error('Unknown or invalid receiver type: ' + receiverType);\n        }\n    }\n    getData(receiver) {\n        if (receiver.type === 'me') {\n            return this.me.id === receiver.id ? this.me : undefined;\n        }\n        else {\n            const receivers = this.get(receiver.type);\n            return receivers.get(receiver.id);\n        }\n    }\n    set(data) {\n        this.setContacts(data['contact']);\n        this.setGroups(data['group']);\n        this.setDistributionLists(data['distributionList']);\n    }\n    setMe(data) {\n        data.type = 'me';\n        this.me = data;\n    }\n    setContacts(data) {\n        this.contacts = new Map(data.map((c) => {\n            c.type = 'contact';\n            setDefault(c, 'color', '#f0f0f0');\n            return [c.id, c];\n        }));\n        if (this.me !== undefined) {\n            this.contacts.set(this.me.id, this.me);\n        }\n    }\n    setGroups(data) {\n        this.groups = new Map(data.map((g) => {\n            g.type = 'group';\n            setDefault(g, 'disabled', false);\n            setDefault(g, 'locked', false);\n            setDefault(g, 'visible', true);\n            return [g.id, g];\n        }));\n    }\n    setDistributionLists(data) {\n        this.distributionLists = new Map(data.map((d) => {\n            d.type = 'distributionList';\n            return [d.id, d];\n        }));\n    }\n    extend(receiverType, data) {\n        switch (receiverType) {\n            case 'me':\n                return this.extendMe(data);\n            case 'contact':\n                return this.extendContact(data);\n            case 'group':\n                return this.extendGroup(data);\n            case 'distributionList':\n                return this.extendDistributionList(data);\n            default:\n                throw new Error('Unknown or invalid receiver type: ' + receiverType);\n        }\n    }\n    extendDistributionList(data) {\n        let distributionListReceiver = this.distributionLists.get(data.id);\n        if (distributionListReceiver === undefined) {\n            data.type = 'distributionList';\n            this.distributionLists.set(data.id, data);\n            return data;\n        }\n        distributionListReceiver = angular.extend(distributionListReceiver, data);\n        return distributionListReceiver;\n    }\n    extendGroup(data) {\n        setDefault(data, 'disabled', false);\n        setDefault(data, 'locked', false);\n        setDefault(data, 'visible', true);\n        let groupReceiver = this.groups.get(data.id);\n        if (groupReceiver === undefined) {\n            data.type = 'group';\n            this.groups.set(data.id, data);\n            return data;\n        }\n        groupReceiver = angular.extend(groupReceiver, data);\n        return groupReceiver;\n    }\n    extendMe(data) {\n        if (this.me === undefined) {\n            data.type = 'me';\n            this.me = data;\n            return data;\n        }\n        this.me = angular.extend(this.me, data);\n        return this.me;\n    }\n    extendContact(data) {\n        let contactReceiver = this.contacts.get(data.id);\n        if (contactReceiver === undefined) {\n            data.type = 'contact';\n            setDefault(data, 'color', '#f0f0f0');\n            this.contacts.set(data.id, data);\n            return data;\n        }\n        contactReceiver = angular.extend(contactReceiver, data);\n        return contactReceiver;\n    }\n}\nexport class Conversations {\n    constructor(receiverService) {\n        this.conversations = [];\n        this.filter = null;\n        this.converter = null;\n        this.receiverService = receiverService;\n    }\n    get() {\n        let conversations = this.conversations;\n        if (this.filter != null) {\n            conversations = this.filter(conversations);\n        }\n        if (this.converter != null) {\n            conversations = conversations.map(this.converter);\n        }\n        return conversations;\n    }\n    set(data) {\n        for (const conversation of data) {\n            if (conversation.position !== undefined) {\n                delete conversation.position;\n            }\n            setDefault(conversation, 'isStarred', false);\n        }\n        this.conversations = data;\n    }\n    find(pattern) {\n        for (const conversation of this.get()) {\n            const a = pattern;\n            const b = conversation;\n            if (a !== undefined && b !== undefined && a.type === b.type && a.id === b.id) {\n                return conversation;\n            }\n        }\n        return null;\n    }\n    add(conversation) {\n        this.conversations.splice(conversation.position, 0, conversation);\n    }\n    updateOrAdd(conversation, returnOld = false) {\n        for (const i of this.conversations.keys()) {\n            if (this.receiverService.compare(this.conversations[i], conversation)) {\n                let previousConversation = null;\n                if (returnOld) {\n                    previousConversation = copyShallow(this.conversations[i]);\n                }\n                setDefault(conversation, 'isStarred', false);\n                Object.assign(this.conversations[i], conversation);\n                if (conversation.latestMessage === undefined\n                    && this.conversations[i].latestMessage !== undefined) {\n                    delete this.conversations[i].latestMessage;\n                }\n                if (this.conversations[i].position !== i) {\n                    const tmp = this.conversations.splice(i, 1)[0];\n                    this.conversations.splice(conversation.position, 0, tmp);\n                }\n                return previousConversation;\n            }\n        }\n        this.add(conversation);\n        return null;\n    }\n    remove(conversation) {\n        for (const i of this.conversations.keys()) {\n            if (this.receiverService.compare(this.conversations[i], conversation)) {\n                this.conversations.splice(i, 1);\n                return;\n            }\n        }\n    }\n    setFilter(filter) {\n        this.filter = filter;\n    }\n    setConverter(converter) {\n        this.converter = converter;\n    }\n}\nclass ReceiverMessages {\n    constructor() {\n        this.referenceMsgId = null;\n        this.requested = false;\n        this.more = true;\n        this.list = [];\n    }\n}\nclass Messages {\n    constructor(logService) {\n        this.messages = new Map();\n        this.converter = null;\n        this.log = logService.getLogger('MessagesContainer');\n    }\n    lazyCreate(receiver) {\n        if (!this.messages.has(receiver.type)) {\n            this.messages.set(receiver.type, new Map());\n        }\n        const typeMap = this.messages.get(receiver.type);\n        if (!typeMap.has(receiver.id)) {\n            typeMap.set(receiver.id, new ReceiverMessages());\n        }\n    }\n    getReceiverMessages(receiver) {\n        this.lazyCreate(receiver);\n        return this.messages.get(receiver.type).get(receiver.id);\n    }\n    getList(receiver) {\n        return this.getReceiverMessages(receiver).list;\n    }\n    clear($scope) {\n        this.messages.forEach((messageMap, receiverType) => {\n            messageMap.forEach((messages, id) => {\n                messages.requested = false;\n                messages.referenceMsgId = null;\n                messages.more = true;\n                messages.list = [];\n                this.notify({\n                    id: id,\n                    type: receiverType,\n                }, $scope);\n            });\n        });\n    }\n    clearReceiverMessages(receiver) {\n        let cachedMessageCount = 0;\n        if (this.messages.has(receiver.type)) {\n            const typeMessages = this.messages.get(receiver.type);\n            if (typeMessages.has(receiver.id)) {\n                cachedMessageCount = typeMessages.get(receiver.id).list.length;\n                typeMessages.delete(receiver.id);\n            }\n        }\n        return cachedMessageCount;\n    }\n    contains(receiver) {\n        return this.messages.has(receiver.type) &&\n            this.messages.get(receiver.type).has(receiver.id);\n    }\n    hasMore(receiver) {\n        return this.getReceiverMessages(receiver).more;\n    }\n    setMore(receiver, more) {\n        this.getReceiverMessages(receiver).more = more;\n    }\n    getReferenceMsgId(receiver) {\n        return this.getReceiverMessages(receiver).referenceMsgId;\n    }\n    isRequested(receiver) {\n        return this.getReceiverMessages(receiver).requested;\n    }\n    setRequested(receiver) {\n        const messages = this.getReceiverMessages(receiver);\n        if (messages.requested) {\n            throw new Error('Message request for receiver ' + receiver.id + ' still pending');\n        }\n        messages.requested = true;\n    }\n    clearRequested(receiver) {\n        const messages = this.getReceiverMessages(receiver);\n        messages.requested = false;\n    }\n    addNewer(receiver, messages) {\n        if (messages.length === 0) {\n            return;\n        }\n        const receiverMessages = this.getReceiverMessages(receiver);\n        if (receiverMessages.list.length === 0) {\n            receiverMessages.referenceMsgId = messages[0].id;\n        }\n        for (const message of messages) {\n            if (message.sortKey === undefined) {\n                message.sortKey = receiverMessages.list.length > 0\n                    ? receiverMessages.list[receiverMessages.list.length - 1].sortKey\n                    : 0;\n            }\n            receiverMessages.list.push(message);\n        }\n    }\n    addOlder(receiver, messages) {\n        if (messages.length === 0) {\n            return;\n        }\n        const receiverMessages = this.getReceiverMessages(receiver);\n        const firstId = messages[0].id;\n        const lastId = messages[messages.length - 1].id;\n        const predicate = (msg) => msg.id === firstId || msg.id === lastId;\n        if (receiverMessages.list.findIndex(predicate, receiverMessages.list) !== -1) {\n            this.log.warn('Messages to be prepended intersect with existing messages:', new ConfidentialArray(messages.map((message) => new ConfidentialObjectValues(message))));\n            return;\n        }\n        receiverMessages.referenceMsgId = messages[0].id;\n        receiverMessages.list.unshift.apply(receiverMessages.list, messages);\n    }\n    addStatusMessage(receiver, text) {\n        const receiverMessages = this.getReceiverMessages(receiver);\n        receiverMessages.list.push({\n            type: 'status',\n            id: randomString(6),\n            body: '',\n            caption: text,\n            sortKey: undefined,\n            partnerId: receiver.id,\n            isOutbox: false,\n            isStatus: true,\n            statusType: 'text',\n        });\n    }\n    update(receiver, message) {\n        const list = this.getList(receiver);\n        for (let i = 0; i < list.length; i++) {\n            if (list[i].id === message.id) {\n                if (message.thumbnail === undefined) {\n                    message.thumbnail = list[i].thumbnail;\n                }\n                list[i] = message;\n                return true;\n            }\n        }\n        return false;\n    }\n    setThumbnail(receiver, messageId, thumbnailImage) {\n        const list = this.getList(receiver);\n        for (const message of list) {\n            if (message.id === messageId) {\n                if (message.thumbnail === undefined) {\n                    message.thumbnail = { img: thumbnailImage };\n                }\n                else {\n                    message.thumbnail.img = thumbnailImage;\n                }\n                return true;\n            }\n        }\n        return false;\n    }\n    remove(receiver, messageId) {\n        const list = this.getList(receiver);\n        for (let i = 0; i < list.length; i++) {\n            if (list[i].id === messageId) {\n                list.splice(i, 1);\n                return true;\n            }\n        }\n        return false;\n    }\n    removeTemporary(receiver, temporaryMessageId) {\n        const list = this.getList(receiver);\n        for (let i = 0; i < list.length; i++) {\n            if (list[i].temporaryId === temporaryMessageId) {\n                list.splice(i, 1);\n                return true;\n            }\n        }\n        return false;\n    }\n    bindTemporaryToMessageId(receiver, temporaryId, messageId) {\n        const list = this.getList(receiver);\n        for (const message of list) {\n            if (message.temporaryId === temporaryId) {\n                if (message.id !== undefined) {\n                    return message;\n                }\n                message.temporaryId = null;\n                message.id = messageId;\n                return message;\n            }\n        }\n        return null;\n    }\n    notify(receiver, $scope) {\n        $scope.$broadcast('threema.receiver.' + receiver.type + '.' + receiver.id + '.messages', this.getList(receiver), this.hasMore(receiver));\n    }\n    register(receiver, $scope, callback) {\n        $scope.$on('threema.receiver.' + receiver.type + '.' + receiver.id + '.messages', callback);\n        return this.getList(receiver);\n    }\n    updateFirstUnreadMessage(receiver) {\n        const receiverMessages = this.getReceiverMessages(receiver);\n        if (receiverMessages !== undefined && receiverMessages.list.length > 0) {\n            let firstUnreadMessageIndex;\n            for (let i = receiverMessages.list.length - 1; i >= 0; i--) {\n                const message = receiverMessages.list[i];\n                if (isFirstUnreadStatusMessage(message)) {\n                    receiverMessages.list.splice(i, 1);\n                    if (firstUnreadMessageIndex !== undefined) {\n                        firstUnreadMessageIndex -= 1;\n                    }\n                }\n                else if (!message.isOutbox && message.unread) {\n                    firstUnreadMessageIndex = i;\n                }\n            }\n            if (firstUnreadMessageIndex !== undefined) {\n                receiverMessages.list.splice(firstUnreadMessageIndex, 0, {\n                    type: 'status',\n                    isStatus: true,\n                    statusType: 'firstUnreadMessage',\n                });\n            }\n        }\n    }\n}\nclass Converter {\n    static addReceiverToConversation(receivers) {\n        return (conversation) => {\n            conversation.receiver = receivers.getData({\n                type: conversation.type,\n                id: conversation.id,\n            });\n            return conversation;\n        };\n    }\n}\nclass Typing {\n    constructor() {\n        this.set = new StringHashSet();\n    }\n    getReceiverUid(receiver) {\n        return receiver.type + '-' + receiver.id;\n    }\n    setTyping(receiver) {\n        this.set.add(this.getReceiverUid(receiver));\n    }\n    unsetTyping(receiver) {\n        this.set.remove(this.getReceiverUid(receiver));\n    }\n    clearAll() {\n        this.set.clearAll();\n    }\n    isTyping(receiver) {\n        return this.set.contains(this.getReceiverUid(receiver));\n    }\n}\nclass Drafts {\n    constructor() {\n        this.quotes = new Map();\n        this.texts = new Map();\n    }\n    getReceiverUid(receiver) {\n        return receiver.id;\n    }\n    setQuote(receiver, quote) {\n        this.quotes.set(this.getReceiverUid(receiver), quote);\n    }\n    removeQuote(receiver) {\n        this.quotes.delete(this.getReceiverUid(receiver));\n    }\n    getQuote(receiver) {\n        return this.quotes.get(this.getReceiverUid(receiver));\n    }\n    setText(receiver, draftMessage) {\n        this.texts.set(this.getReceiverUid(receiver), draftMessage);\n    }\n    removeText(receiver) {\n        this.texts.delete(this.getReceiverUid(receiver));\n    }\n    getText(receiver) {\n        return this.texts.get(this.getReceiverUid(receiver));\n    }\n}\nangular.module('3ema.container', [])\n    .factory('Container', ['$filter', 'LogService', 'ReceiverService',\n    function ($filter, logService, receiverService) {\n        class Filters {\n            static hasData(receivers) {\n                return (obj) => $filter('hasData')(obj, receivers);\n            }\n            static hasContact(contacts) {\n                return (obj) => $filter('hasContact')(obj, contacts);\n            }\n            static isValidMessage(contacts) {\n                return (obj) => $filter('isValidMessage')(obj, contacts);\n            }\n        }\n        return {\n            Converter: Converter,\n            Filters: Filters,\n            createReceivers: () => new Receivers(),\n            createConversations: () => new Conversations(receiverService),\n            createMessages: () => new Messages(logService),\n            createTyping: () => new Typing(),\n            createDrafts: () => new Drafts(),\n        };\n    },\n]);\n","import { BatteryStatusService } from './services/battery';\nimport { BrowserService } from './services/browser';\nimport { ContactService } from './services/contact';\nimport { ControllerService } from './services/controller';\nimport { ControllerModelService } from './services/controller_model';\nimport { FingerPrintService } from './services/fingerprint';\nimport { TrustedKeyStoreService } from './services/keystore';\nimport { LogService } from './services/log';\nimport { MediaboxService } from './services/mediabox';\nimport { MessageService } from './services/message';\nimport { MimeService } from './services/mime';\nimport { NotificationService } from './services/notification';\nimport { PushService } from './services/push';\nimport { QrCodeService } from './services/qrcode';\nimport { ReceiverService } from './services/receiver';\nimport { SettingsService } from './services/settings';\nimport { StateService } from './services/state';\nimport { StringService } from './services/string';\nimport { ThemeService } from './services/theme';\nimport { TimeoutService } from './services/timeout';\nimport { TitleService } from './services/title';\nimport { UriService } from './services/uri';\nimport { VersionService } from './services/version';\nimport { WebClientService } from './services/webclient';\nangular.module('3ema.services', [])\n    .service('LogService', LogService)\n    .service('BatteryStatusService', BatteryStatusService)\n    .service('ContactService', ContactService)\n    .service('ControllerModelService', ControllerModelService)\n    .service('FingerPrintService', FingerPrintService)\n    .service('MessageService', MessageService)\n    .service('NotificationService', NotificationService)\n    .service('PushService', PushService)\n    .service('QrCodeService', QrCodeService)\n    .service('ReceiverService', ReceiverService)\n    .service('StateService', StateService)\n    .service('ThemeService', ThemeService)\n    .service('TimeoutService', TimeoutService)\n    .service('TitleService', TitleService)\n    .service('TrustedKeyStore', TrustedKeyStoreService)\n    .service('WebClientService', WebClientService)\n    .service('MimeService', MimeService)\n    .service('BrowserService', BrowserService)\n    .service('ControllerService', ControllerService)\n    .service('StringService', StringService)\n    .service('SettingsService', SettingsService)\n    .service('MediaboxService', MediaboxService)\n    .service('UriService', UriService)\n    .service('VersionService', VersionService);\n","import { sha256 } from '../helpers/crypto';\nexport class FingerPrintService {\n    async generate(publicKey) {\n        if (publicKey !== undefined && publicKey.byteLength === 32) {\n            const sha256PublicKey = await sha256(publicKey);\n            if (sha256PublicKey !== undefined) {\n                return sha256PublicKey.toLowerCase().substr(0, 32);\n            }\n        }\n        return 'undefined/failed';\n    }\n}\n","import { hasValue } from '../helpers';\nimport { isContactReceiver } from '../typeguards';\nexport class ReceiverService {\n    setActive(activeReceiver) {\n        this.activeReceiver = activeReceiver;\n    }\n    getActive() {\n        return this.activeReceiver;\n    }\n    isConversationActive(conversation) {\n        if (!this.activeReceiver) {\n            return false;\n        }\n        return this.compare(conversation, this.activeReceiver);\n    }\n    compare(a, b) {\n        return a !== undefined\n            && b !== undefined\n            && a.type === b.type\n            && a.id === b.id;\n    }\n    isBusinessContact(receiver) {\n        return isContactReceiver(receiver)\n            && receiver.id.substr(0, 1) === '*';\n    }\n    isBlocked(receiver) {\n        if (!hasValue(receiver)) {\n            return false;\n        }\n        if (isContactReceiver(receiver) && hasValue(receiver.isBlocked)) {\n            return receiver.isBlocked;\n        }\n        else {\n            return false;\n        }\n    }\n}\n","export class ControllerService {\n    setControllerName(name) {\n        this.currentController = name;\n    }\n    getControllerName() {\n        return this.currentController;\n    }\n}\n","import { AsyncEvent } from 'ts-events';\nexport class MediaboxService {\n    constructor() {\n        this.evtMediaChanged = new AsyncEvent();\n        this.data = null;\n        this.caption = '';\n        this.filename = '';\n        this.mimetype = '';\n    }\n    setMedia(data, filename, mimetype, caption) {\n        this.data = data;\n        this.filename = filename;\n        this.mimetype = mimetype;\n        this.caption = caption;\n        this.evtMediaChanged.post(data !== null);\n    }\n    clearMedia() {\n        this.data = null;\n        this.filename = '';\n        this.mimetype = '';\n        this.caption = '';\n        this.evtMediaChanged.post(false);\n    }\n}\n","export class UriService {\n    parseQueryParams(query) {\n        if (query.length === 0) {\n            return {};\n        }\n        const objStr = '{\"' + decodeURI(query).replace(/\"/g, '\\\\\"').replace(/&/g, '\",\"').replace(/=/g, '\":\"') + '\"}';\n        return JSON.parse(objStr);\n    }\n}\n","import { AsyncEvent } from 'ts-events';\nimport './components';\nimport config from './config';\nimport './controllers';\nimport './directives';\nimport './filters';\nimport { hasValue } from './helpers';\nimport './partials/messenger';\nimport './partials/welcome';\nimport './services';\nimport './threema/container';\nAsyncEvent.setScheduler(function (callback) {\n    setTimeout(callback, 0);\n});\nangular.module('3ema', [\n    'ngAnimate',\n    'ngSanitize',\n    'ngAria',\n    'ui.router',\n    'angular-inview',\n    'monospaced.qrcode',\n    'luegg.directives',\n    'pascalprecht.translate',\n    'ngMaterial',\n    '3ema.filters',\n    '3ema.components',\n    '3ema.directives',\n    '3ema.container',\n    '3ema.services',\n    '3ema.controllers',\n    '3ema.welcome',\n    '3ema.messenger',\n])\n    .value('VERSION', config.VERSION)\n    .value('PROTOCOL_VERSION', 2)\n    .constant('CONFIG', config)\n    .constant('CACHE_BUST', `v=${config.VERSION}`)\n    .constant('BROWSER_MIN_VERSIONS', {\n    FF: 60,\n    CHROME: 65,\n    OPERA: 52,\n    SAFARI: 11,\n    EDGE: 79,\n})\n    .config(['$urlRouterProvider', ($urlRouterProvider) => {\n        $urlRouterProvider.otherwise('/welcome');\n    }])\n    .config(['$translateProvider', ($translateProvider) => {\n        $translateProvider.useSanitizeValueStrategy('sanitizeParameters');\n        $translateProvider.useMessageFormatInterpolation();\n        $translateProvider\n            .useStaticFilesLoader({\n            prefix: 'i18n/',\n            suffix: '.json',\n        })\n            .uniformLanguageTag('java')\n            .registerAvailableLanguageKeys(['cs', 'de', 'en', 'es', 'fr', 'nl', 'pl', 'sk', 'uk', 'zh'], {\n            'cs_*': 'cs',\n            'de_*': 'de',\n            'en_*': 'en',\n            'es_*': 'es',\n            'fr_*': 'fr',\n            'nl_*': 'nl',\n            'pl_*': 'pl',\n            'sk_*': 'sk',\n            'uk_*': 'uk',\n            'zh_*': 'zh',\n        })\n            .determinePreferredLanguage()\n            .fallbackLanguage('en');\n    }])\n    .config(['$mdThemingProvider', ($mdThemingProvider) => {\n        $mdThemingProvider.definePalette('threema', {\n            50: 'f2faf5',\n            100: 'e6f6eb',\n            200: 'cdedd9',\n            300: 'b4e4c5',\n            400: '9bdbb2',\n            500: '82d29f',\n            600: '69ca8c',\n            700: '50c078',\n            800: '37b865',\n            900: '1eae52',\n            A100: '05a63f',\n            A200: '048432',\n            A400: '03732b',\n            A700: '036325',\n            contrastDefaultColor: 'light',\n            contrastDarkColors: ['50', '100', '200', '300', '400', '500', '600'],\n        });\n        $mdThemingProvider.definePalette('threemawork', {\n            50: '#f2f9ff',\n            100: 'e5f4ff',\n            200: 'cceaff',\n            300: 'b2dfff',\n            400: '99d5ff',\n            500: '7fcaff',\n            600: '66c0ff',\n            700: '4cb5ff',\n            800: '33abff',\n            900: '19a0ff',\n            A100: '0096ff',\n            A200: '0086e5',\n            A400: '0068b2',\n            A700: '004a7f',\n            contrastDefaultColor: 'light',\n            contrastDarkColors: ['50', '100', '200', '300', '400', '500', '600'],\n        });\n        $mdThemingProvider.theme('threema')\n            .primaryPalette('grey', { default: '800' })\n            .accentPalette('threema', { default: 'A100' });\n        $mdThemingProvider.theme('threemawork')\n            .primaryPalette('grey', { default: '800' })\n            .accentPalette('threemawork', { default: 'A100' });\n        $mdThemingProvider.alwaysWatchTheme(true);\n    }])\n    .config(['$compileProvider', ($compileProvider) => {\n    }])\n    .config(['$httpProvider', ($httpProvider) => {\n        $httpProvider.interceptors.push(['CACHE_BUST', (CACHE_BUST) => {\n                return {\n                    request: (conf) => {\n                        if (conf.url.indexOf('partials/') !== -1 ||\n                            conf.url.indexOf('directives/') !== -1 ||\n                            conf.url.indexOf('components/') !== -1 ||\n                            conf.url.indexOf('i18n/') !== -1) {\n                            const separator = conf.url.indexOf('?') === -1 ? '?' : '&';\n                            conf.url = conf.url + separator + CACHE_BUST;\n                        }\n                        return conf;\n                    },\n                };\n            }]);\n    }])\n    .factory('$exceptionHandler', ['LogService', function (logService) {\n        const logger = logService.getLogger('UncaughtException');\n        return function myExceptionHandler(e, cause) {\n            if (!hasValue(e)) {\n                logger.error(`Unhandled exception (ng): ${e}`);\n                return;\n            }\n            const data = [];\n            data.push('Unhandled exception (ng):');\n            if (e.message && e.name) {\n                data.push(e.message.includes(e.name) ? `${e.message}\\n` : `${e.name}: ${e.message}\\n`);\n            }\n            data.push(e.stack ? e.stack : e);\n            if (cause) {\n                data.push('\\nCaused by:\\n');\n                data.push(cause.stack ? cause.stack : cause);\n            }\n            logger.error(...data);\n        };\n    }]);\n","export class StringService {\n    byteChunk(str, byteLength, offset = null) {\n        const chars = Array.from(str);\n        const chunks = [''];\n        let currentChunkSize = 0;\n        let chunkIndex = 0;\n        const offsetChars = [' ', '\\r', '\\n', '\\t', '.'];\n        let lastSeparator = -1;\n        chars.forEach((charString) => {\n            const length = Buffer.byteLength(charString, 'utf8');\n            if (offset !== null) {\n                if (offsetChars.indexOf(charString) > -1) {\n                    lastSeparator = currentChunkSize + 1;\n                }\n            }\n            if (currentChunkSize + length > byteLength) {\n                let appendNewChunk = true;\n                if (lastSeparator > -1) {\n                    if (currentChunkSize - lastSeparator <= offset\n                        && chunks.length >= 1) {\n                        chunks.push(chunks[chunkIndex].substr(lastSeparator).trim());\n                        chunks[chunkIndex] = chunks[chunkIndex].substr(0, lastSeparator).trim();\n                        appendNewChunk = false;\n                        currentChunkSize -= lastSeparator;\n                        chunkIndex++;\n                        lastSeparator = -1;\n                    }\n                }\n                if (appendNewChunk) {\n                    chunkIndex++;\n                    currentChunkSize = 0;\n                    chunks.push('');\n                }\n            }\n            chunks[chunkIndex] = (chunks[chunkIndex] + charString);\n            currentChunkSize += length;\n        });\n        return chunks;\n    }\n}\n"],"sourceRoot":""}