{"version":3,"names":["isScheduler","value","schedule","subscribeToArray","array","subscriber","i","len","length","closed","next","complete","scheduleArray","input","scheduler","Observable","sub","Subscription","add","this","fromArray","OuterSubscriber","Subscriber","notifyNext","outerValue","innerValue","outerIndex","innerIndex","innerSub","destination","notifyError","error","notifyComplete","InnerSubscriber","constructor","parent","super","index","_next","_error","unsubscribe","_complete","subscribeToPromise","promise","then","err","hostReportError","getSymbolIterator","Symbol","iterator","subscribeToIterable","iterable","Symbol_iterator","item","done","return","subscribeToObservable","obj","obs","Symbol_observable","subscribe","TypeError","isArrayLike","x","isPromise","subscribeTo","result","isObject","msg","subscribeToResult","outerSubscriber","innerSubscriber","undefined","NONE","combineLatest","observables","resultSelector","pop","isArray","lift","CombineLatestOperator","call","source","CombineLatestSubscriber","active","values","observable","push","toRespond","unused","_outerValue","oldVal","_tryResultSelector","slice","apply","chars","InvalidCharacterError","message","prototype","Error","name","polyfill","str","String","replace","bc","bs","buffer","idx","output","charAt","fromCharCode","indexOf","atob","window","bind","b64DecodeUnicode","decodeURIComponent","m","p","code","charCodeAt","toString","toUpperCase","base64_url_decode","InvalidTokenError","lib","token","options","pos","header","JSON","parse","split","e","InvalidTokenError_1","AuthenticationChangedEvent","portal","tokens","jwt","authenticated","access_token","id_token","token_type","user_info","oidcError","static","crypto","encode","buf","ArrayBuffer","bufView8","Uint8Array","strLen","sha256","async","data","encoded","hash","subtle","digest","hexString","hexCodes","byte","padStart","sha256HexStr","hashBuffer","hashHex","toLowerCase","OAuth2Client","config","base64encode","bufferArray","btoa","redirectUri","extraQueryParams","stateValue","generateRandomValue","codeVerifier","digestedBuffer","challenge","console","warn","authorizationEndpoint","getWellKnownConfiguration","stsServer","authorization_endpoint","url","clientId","scope","audience","getRandomValues","finishAuthorizationCodeFlow","authorizationCode","verifier","getToken","grant_type","client_id","code_verifier","redirect_uri","renewRefreshToken","refreshToken","refresh_token","body","wellKnownConfig","tokenEndpoint","token_endpoint","bodyData","Object","keys","map","key","encodeURIComponent","join","fetch","method","headers","response","json","getUserInfoEndpoint","userinfo_endpoint","getCheckSessionIFrame","check_session_iframe","getEndSessionEndpoint","end_session_endpoint","_wellKnownConfig","REFRESH_BEFORE_EXPIRATION_MS","SILENT_RENEW_TIMEOUT_MS","SingleSignOnListener","iframe","generateUrl","processAuthenticationResponse","getAttribute","triggerSilentRenew","contentWindow","debug","silentRenewTimeoutHandler","setTimeout","error_description","src","processMessage","origin","location","handled","type","info","clearTimeout","scheduleRefresh","expires","afterMs","Math","max","Date","now","scheduledSilentRenewHandler","AuthenticationState","verifierKey","tokensKey","stateDeterminedKey","sessionStorage","setItem","stringify","peek","getItem","removeItem","clear","pushVerifier","peekVerifier","popVerifier","clearVerifier","pushTokens","peekTokens","clearTokens","setStateDetermined","getStateDetermined","BaseAuthenticationService","state","client","authenticationDetermined","oidcErrorDetected","stateDetermined","checkSingleSignOn","extraParams","getDescription","request","createAuthorizationUrl","params","swapTokens","clearState","createAuthorizationTokens","session_state","userInfo","getUserInfo","accessToken","userInfoEndpoint","Authorization","getTokens","endpoint","postLogoutRedirectUri","SalesForceAuthenticationService","normalRedirectUrl","silentRedirectUrl","iframeSso","handleAuthenticationDetermined","singleSignOnListener","createSilentLoginUrl","createLoginUrl","locale","URLSearchParams","append","check","createRegistrationUrl","_","widgetsRoot","WidgetUtil","rootUrl","exp","jwt_decode","getAuthenticationParameters","search","has","get","cleanAuthenticationParameters","href","history","replaceState","document","title","UserMenuConstants","BUSINESSPORTAL","CONSUMER","LOGIN","LOGOUT","BP_LANDING","BP_SWITCH","BP_LOGIN","CONSUMER_LANDING","CONSUMER_SWITCH","CONSUMER_LOGIN","CREATE_CONSUMER_ACCOUNT","pnlBusinessUserMenuCss","PnlBusinessUserMenu","language","systemIdentifier","canHover","matchMedia","matches","loginNotAvailable","onReady","emit","setupAuthenticationService","handlePendingAuthenticationCodeFlow","authenticationService","onLoginRequested","onLogoutRequested","createLogoutUrl","refreshUserInfo","peekAuthenticationState","openMenu","open","closeMenu","handleFocusOut","event","relatedTarget","Node","component","contains","_b","_a","handleResize","menuElement","shadowRoot","querySelector","adjustIfOutOfBounds","oidcConfig","silentRenewPage","finished","loginDetermined","loggedIn","onSpecificAuthenticationChange","createNotAuthorized","idToken","createAuthorized","createError","element","rect","getBoundingClientRect","style","right","innerWidth","shiftLeft","left","offsetLeft","classList","determineMenuOptions","menu","userMenuItems","filter","identifier","system","concat","usermenuState","portalItems","toggleMenu","loginButtonText","find","menuItem","text","renderMenu","activePortal","menuStyle","renderMinimalMenu","renderNormalMenu","h","id","class","loggedOut","onClick","login","innerHTML","images","arrow_up","menuItems","onMenuItemSelected","onMenuItemClicked","detail","renderLoginInProgress","render","hidden","ref","el","RefreshTokenRefresher","swapRefreshToken","scheduledRefreshHandler","AkamaiAuthenticationService","prepareForLogin","onSameDomain","refreshTokenRefresher","sameTLD","tld","stsHost","URL","hostname","currentHost","endsWith","addClaims","redirectUrl","email","hashed_email","accountId","hashed_sub","hashed_account_id","Promise","resolve","endSessionEndpoint","SingleSignOutListener","getSessionState","triggerLogout","firstCheck","checkSessionIFrame","clearInterval","checkSessionTimeoutHandler","interval","setInterval","checkSession","sessionState","postMessage","IdentityAuthenticationService","iframeCheckSession","singleSignOutListener","start","pnlConsumerUserMenuCss","PnlConsumerUserMenu","systemIdentifiers","windowWidth","focusIn","stsType","includes","logout","startRegistration","xmlns","width","height","color","d","stroke","fill","silentRenewScript","pnlLanguageSelectorCss","LanguageSelector","stopImmediatePropagation","renderLanguageItem","chooseLocale","toLanguage","onLocaleChanged","htmlLang","setAttribute","locales","availableLocales","UserMenuState","pnlUserMenuCss","PnlUserMenu","consumerPortalConfigured","businessPortalConfigured","activePortal$","Subject","consumerLogin$","businessportalLogin$","languageChanged$","createEmpty","domain","fetchUserMenu","bpStsServer","consumerAuth","businessPortalAuth","determinePortalItems","emitAuthenticationChange","loadMenu","addEventListener","stateIFrameOrigin","showUserMenu","subMenuActive","handleAuthenticationChange","stopPropagation","handleMenuItemSelected","dispatchEvent","CustomEvent","switchActivePortal","handleLoginRequested","onAuthenticationChange","bpAuth","getPortalItems","primaryAuth","secondaryAuth","portalType","items","authIdentifier","authButton","isConfigured","secondaryAuthIdentifier","getSecondaryAuthIdentifier","secondaryAuthButton","registrationButton","authentication","activePortalIFrame","renderStateUnknown","renderConsumerUserMenu","renderBusinessPortalUserMenu","bpClientId","stateIFrameUrl","pnlUserMenuItemListCss","Menu","renderMenuItem","renderItem","isButton","renderButtonItem","renderLinkItem","alignCenter","description","menuItemSelected","icon","isSecondary"],"sources":["./node_modules/rxjs/_esm2015/internal/util/isScheduler.js","./node_modules/rxjs/_esm2015/internal/util/subscribeToArray.js","./node_modules/rxjs/_esm2015/internal/scheduled/scheduleArray.js","./node_modules/rxjs/_esm2015/internal/observable/fromArray.js","./node_modules/rxjs/_esm2015/internal/OuterSubscriber.js","./node_modules/rxjs/_esm2015/internal/InnerSubscriber.js","./node_modules/rxjs/_esm2015/internal/util/subscribeToPromise.js","./node_modules/rxjs/_esm2015/internal/symbol/iterator.js","./node_modules/rxjs/_esm2015/internal/util/subscribeToIterable.js","./node_modules/rxjs/_esm2015/internal/util/subscribeToObservable.js","./node_modules/rxjs/_esm2015/internal/util/isArrayLike.js","./node_modules/rxjs/_esm2015/internal/util/isPromise.js","./node_modules/rxjs/_esm2015/internal/util/subscribeTo.js","./node_modules/rxjs/_esm2015/internal/util/subscribeToResult.js","./node_modules/rxjs/_esm2015/internal/observable/combineLatest.js","./node_modules/jwt-decode/lib/atob.js","./node_modules/jwt-decode/lib/base64_url_decode.js","./node_modules/jwt-decode/lib/index.js","./src/services/authentication/authenticationchanged.event.ts","./src/services/authentication/crypto.ts","./src/services/authentication/clients/OAuth2client.ts","./src/services/singleSignOn/singleSignOnListener.ts","./src/services/authentication/authentication.state.ts","./src/services/authentication/services/base-authentication.service.ts","./src/services/authentication/services/salesforce-authentication.service.ts","./src/services/singleSignOn/authParams.ts","./src/components/pnl-user-menu/utility/user-menu-actions.ts","./src/components/pnl-business-user-menu/pnl-business-user-menu.scss?tag=pnl-business-user-menu&encapsulation=shadow","./src/components/pnl-business-user-menu/pnl-business-user-menu.tsx","./src/services/singleSignOn/refreshTokenRefresher.ts","./src/services/authentication/services/akamai-authentication.service.ts","./src/services/singleSignOn/singleSignOutListener.ts","./src/services/authentication/services/identity-authentication.service.ts","./src/components/pnl-consumer-user-menu/pnl-consumer-user-menu.scss?tag=pnl-consumer-user-menu&encapsulation=shadow","./src/components/pnl-consumer-user-menu/pnl-consumer-user-menu.tsx","./src/components/pnl-header/pnl-language-selector/pnl-language-selector.scss?tag=pnl-language-selector","./src/components/pnl-header/pnl-language-selector/pnl-language-selector.tsx","./src/components/user-menu.models.ts","./src/components/pnl-user-menu/pnl-user-menu.scss?tag=pnl-user-menu&encapsulation=shadow","./src/components/pnl-user-menu/pnl-user-menu.tsx","./src/components/pnl-user-menu/pnl-user-menu-item/pnl-user-menu-item-list.scss?tag=pnl-user-menu-item-list","./src/components/pnl-user-menu/pnl-user-menu-item/pnl-user-menu-item-list.tsx"],"sourcesContent":["export function isScheduler(value) {\n return value && typeof value.schedule === 'function';\n}\n//# sourceMappingURL=isScheduler.js.map","export const subscribeToArray = (array) => (subscriber) => {\n for (let i = 0, len = array.length; i < len && !subscriber.closed; i++) {\n subscriber.next(array[i]);\n }\n subscriber.complete();\n};\n//# sourceMappingURL=subscribeToArray.js.map","import { Observable } from '../Observable';\nimport { Subscription } from '../Subscription';\nexport function scheduleArray(input, scheduler) {\n return new Observable(subscriber => {\n const sub = new Subscription();\n let i = 0;\n sub.add(scheduler.schedule(function () {\n if (i === input.length) {\n subscriber.complete();\n return;\n }\n subscriber.next(input[i++]);\n if (!subscriber.closed) {\n sub.add(this.schedule());\n }\n }));\n return sub;\n });\n}\n//# sourceMappingURL=scheduleArray.js.map","import { Observable } from '../Observable';\nimport { subscribeToArray } from '../util/subscribeToArray';\nimport { scheduleArray } from '../scheduled/scheduleArray';\nexport function fromArray(input, scheduler) {\n if (!scheduler) {\n return new Observable(subscribeToArray(input));\n }\n else {\n return scheduleArray(input, scheduler);\n }\n}\n//# sourceMappingURL=fromArray.js.map","import { Subscriber } from './Subscriber';\nexport class OuterSubscriber extends Subscriber {\n notifyNext(outerValue, innerValue, outerIndex, innerIndex, innerSub) {\n this.destination.next(innerValue);\n }\n notifyError(error, innerSub) {\n this.destination.error(error);\n }\n notifyComplete(innerSub) {\n this.destination.complete();\n }\n}\n//# sourceMappingURL=OuterSubscriber.js.map","import { Subscriber } from './Subscriber';\nexport class InnerSubscriber extends Subscriber {\n constructor(parent, outerValue, outerIndex) {\n super();\n this.parent = parent;\n this.outerValue = outerValue;\n this.outerIndex = outerIndex;\n this.index = 0;\n }\n _next(value) {\n this.parent.notifyNext(this.outerValue, value, this.outerIndex, this.index++, this);\n }\n _error(error) {\n this.parent.notifyError(error, this);\n this.unsubscribe();\n }\n _complete() {\n this.parent.notifyComplete(this);\n this.unsubscribe();\n }\n}\n//# sourceMappingURL=InnerSubscriber.js.map","import { hostReportError } from './hostReportError';\nexport const subscribeToPromise = (promise) => (subscriber) => {\n promise.then((value) => {\n if (!subscriber.closed) {\n subscriber.next(value);\n subscriber.complete();\n }\n }, (err) => subscriber.error(err))\n .then(null, hostReportError);\n return subscriber;\n};\n//# sourceMappingURL=subscribeToPromise.js.map","export function getSymbolIterator() {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator';\n }\n return Symbol.iterator;\n}\nexport const iterator = getSymbolIterator();\nexport const $$iterator = iterator;\n//# sourceMappingURL=iterator.js.map","import { iterator as Symbol_iterator } from '../symbol/iterator';\nexport const subscribeToIterable = (iterable) => (subscriber) => {\n const iterator = iterable[Symbol_iterator]();\n do {\n let item;\n try {\n item = iterator.next();\n }\n catch (err) {\n subscriber.error(err);\n return subscriber;\n }\n if (item.done) {\n subscriber.complete();\n break;\n }\n subscriber.next(item.value);\n if (subscriber.closed) {\n break;\n }\n } while (true);\n if (typeof iterator.return === 'function') {\n subscriber.add(() => {\n if (iterator.return) {\n iterator.return();\n }\n });\n }\n return subscriber;\n};\n//# sourceMappingURL=subscribeToIterable.js.map","import { observable as Symbol_observable } from '../symbol/observable';\nexport const subscribeToObservable = (obj) => (subscriber) => {\n const obs = obj[Symbol_observable]();\n if (typeof obs.subscribe !== 'function') {\n throw new TypeError('Provided object does not correctly implement Symbol.observable');\n }\n else {\n return obs.subscribe(subscriber);\n }\n};\n//# sourceMappingURL=subscribeToObservable.js.map","export const isArrayLike = ((x) => x && typeof x.length === 'number' && typeof x !== 'function');\n//# sourceMappingURL=isArrayLike.js.map","export function isPromise(value) {\n return !!value && typeof value.subscribe !== 'function' && typeof value.then === 'function';\n}\n//# sourceMappingURL=isPromise.js.map","import { subscribeToArray } from './subscribeToArray';\nimport { subscribeToPromise } from './subscribeToPromise';\nimport { subscribeToIterable } from './subscribeToIterable';\nimport { subscribeToObservable } from './subscribeToObservable';\nimport { isArrayLike } from './isArrayLike';\nimport { isPromise } from './isPromise';\nimport { isObject } from './isObject';\nimport { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { observable as Symbol_observable } from '../symbol/observable';\nexport const subscribeTo = (result) => {\n if (!!result && typeof result[Symbol_observable] === 'function') {\n return subscribeToObservable(result);\n }\n else if (isArrayLike(result)) {\n return subscribeToArray(result);\n }\n else if (isPromise(result)) {\n return subscribeToPromise(result);\n }\n else if (!!result && typeof result[Symbol_iterator] === 'function') {\n return subscribeToIterable(result);\n }\n else {\n const value = isObject(result) ? 'an invalid object' : `'${result}'`;\n const msg = `You provided ${value} where a stream was expected.`\n + ' You can provide an Observable, Promise, Array, or Iterable.';\n throw new TypeError(msg);\n }\n};\n//# sourceMappingURL=subscribeTo.js.map","import { InnerSubscriber } from '../InnerSubscriber';\nimport { subscribeTo } from './subscribeTo';\nimport { Observable } from '../Observable';\nexport function subscribeToResult(outerSubscriber, result, outerValue, outerIndex, innerSubscriber = new InnerSubscriber(outerSubscriber, outerValue, outerIndex)) {\n if (innerSubscriber.closed) {\n return undefined;\n }\n if (result instanceof Observable) {\n return result.subscribe(innerSubscriber);\n }\n return subscribeTo(result)(innerSubscriber);\n}\n//# sourceMappingURL=subscribeToResult.js.map","import { isScheduler } from '../util/isScheduler';\nimport { isArray } from '../util/isArray';\nimport { OuterSubscriber } from '../OuterSubscriber';\nimport { subscribeToResult } from '../util/subscribeToResult';\nimport { fromArray } from './fromArray';\nconst NONE = {};\nexport function combineLatest(...observables) {\n let resultSelector = undefined;\n let scheduler = undefined;\n if (isScheduler(observables[observables.length - 1])) {\n scheduler = observables.pop();\n }\n if (typeof observables[observables.length - 1] === 'function') {\n resultSelector = observables.pop();\n }\n if (observables.length === 1 && isArray(observables[0])) {\n observables = observables[0];\n }\n return fromArray(observables, scheduler).lift(new CombineLatestOperator(resultSelector));\n}\nexport class CombineLatestOperator {\n constructor(resultSelector) {\n this.resultSelector = resultSelector;\n }\n call(subscriber, source) {\n return source.subscribe(new CombineLatestSubscriber(subscriber, this.resultSelector));\n }\n}\nexport class CombineLatestSubscriber extends OuterSubscriber {\n constructor(destination, resultSelector) {\n super(destination);\n this.resultSelector = resultSelector;\n this.active = 0;\n this.values = [];\n this.observables = [];\n }\n _next(observable) {\n this.values.push(NONE);\n this.observables.push(observable);\n }\n _complete() {\n const observables = this.observables;\n const len = observables.length;\n if (len === 0) {\n this.destination.complete();\n }\n else {\n this.active = len;\n this.toRespond = len;\n for (let i = 0; i < len; i++) {\n const observable = observables[i];\n this.add(subscribeToResult(this, observable, undefined, i));\n }\n }\n }\n notifyComplete(unused) {\n if ((this.active -= 1) === 0) {\n this.destination.complete();\n }\n }\n notifyNext(_outerValue, innerValue, outerIndex) {\n const values = this.values;\n const oldVal = values[outerIndex];\n const toRespond = !this.toRespond\n ? 0\n : oldVal === NONE ? --this.toRespond : this.toRespond;\n values[outerIndex] = innerValue;\n if (toRespond === 0) {\n if (this.resultSelector) {\n this._tryResultSelector(values);\n }\n else {\n this.destination.next(values.slice());\n }\n }\n }\n _tryResultSelector(values) {\n let result;\n try {\n result = this.resultSelector.apply(this, values);\n }\n catch (err) {\n this.destination.error(err);\n return;\n }\n this.destination.next(result);\n }\n}\n//# sourceMappingURL=combineLatest.js.map","/**\n * The code was extracted from:\n * https://github.com/davidchambers/Base64.js\n */\n\nvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\n\nfunction InvalidCharacterError(message) {\n this.message = message;\n}\n\nInvalidCharacterError.prototype = new Error();\nInvalidCharacterError.prototype.name = 'InvalidCharacterError';\n\nfunction polyfill (input) {\n var str = String(input).replace(/=+$/, '');\n if (str.length % 4 == 1) {\n throw new InvalidCharacterError(\"'atob' failed: The string to be decoded is not correctly encoded.\");\n }\n for (\n // initialize result and counters\n var bc = 0, bs, buffer, idx = 0, output = '';\n // get next character\n buffer = str.charAt(idx++);\n // character found in table? initialize bit storage and add its ascii value;\n ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,\n // and if not first of each 4 characters,\n // convert the first 8 bits to one ascii character\n bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0\n ) {\n // try to find character in table (0-63, not found => -1)\n buffer = chars.indexOf(buffer);\n }\n return output;\n}\n\n\nmodule.exports = typeof window !== 'undefined' && window.atob && window.atob.bind(window) || polyfill;\n","var atob = require('./atob');\n\nfunction b64DecodeUnicode(str) {\n return decodeURIComponent(atob(str).replace(/(.)/g, function (m, p) {\n var code = p.charCodeAt(0).toString(16).toUpperCase();\n if (code.length < 2) {\n code = '0' + code;\n }\n return '%' + code;\n }));\n}\n\nmodule.exports = function(str) {\n var output = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n switch (output.length % 4) {\n case 0:\n break;\n case 2:\n output += \"==\";\n break;\n case 3:\n output += \"=\";\n break;\n default:\n throw \"Illegal base64url string!\";\n }\n\n try{\n return b64DecodeUnicode(output);\n } catch (err) {\n return atob(output);\n }\n};\n","'use strict';\n\nvar base64_url_decode = require('./base64_url_decode');\n\nfunction InvalidTokenError(message) {\n this.message = message;\n}\n\nInvalidTokenError.prototype = new Error();\nInvalidTokenError.prototype.name = 'InvalidTokenError';\n\nmodule.exports = function (token,options) {\n if (typeof token !== 'string') {\n throw new InvalidTokenError('Invalid token specified');\n }\n\n options = options || {};\n var pos = options.header === true ? 0 : 1;\n try {\n return JSON.parse(base64_url_decode(token.split('.')[pos]));\n } catch (e) {\n throw new InvalidTokenError('Invalid token specified: ' + e.message);\n }\n};\n\nmodule.exports.InvalidTokenError = InvalidTokenError;\n","import { AuthorizationTokens, OidcError } from './authentication.models';\n\nexport class AuthenticationChangedEvent {\n readonly portal: string;\n\n readonly access_token: string;\n readonly id_token: string;\n readonly token_type: string;\n readonly user_info: any;\n readonly name: string;\n\n readonly authenticated: boolean;\n\n readonly jwt: any;\n\n readonly oidcError: OidcError;\n\n private constructor(portal: string, tokens: AuthorizationTokens, jwt: any, error: OidcError) {\n this.portal = portal;\n if (tokens != null && jwt != null) {\n this.authenticated = true;\n this.access_token = tokens.access_token;\n this.id_token = tokens.id_token;\n this.token_type = tokens.token_type;\n this.user_info = tokens.user_info;\n\n this.jwt = jwt;\n }\n else {\n this.authenticated = false;\n this.oidcError = error;\n }\n }\n\n static createAuthorized(portal: string, tokens: AuthorizationTokens, jwt: any) {\n return new AuthenticationChangedEvent(portal, tokens, jwt, null);\n }\n\n static createNotAuthorized(portal: string) {\n return new AuthenticationChangedEvent(portal, null, null, null);\n }\n\n static createError(portal: string, error: OidcError) {\n return new AuthenticationChangedEvent(portal, null, null, error);\n }\n}\n","export const crypto = window.crypto || window['msCrypto']; // For IE11\n\n// IE Edge don't implement TextEncoder; so use a 'polyfill'\nexport const encode = (value: string) => {\n const buf = new ArrayBuffer(value.length);\n const bufView8 = new Uint8Array(buf);\n for (let i = 0, strLen = value.length; i < strLen; i++) {\n bufView8[i] = value.charCodeAt(i);\n }\n return bufView8;\n}\n\nexport const sha256 = async (data: string) => {\n const encoded = encode(data);\n const hash = await crypto.subtle.digest('SHA-256', encoded);\n return hash;\n}\n\n// For any smarties who think they can use map() here...\n// Microsoft Edge doesn't agree with you. That approach 'drops' random bytes\n// from the buffer which will sometimes result in a key that's too small.\nexport const hexString = (buffer: Uint8Array) => {\n let hexCodes = '';\n for (let byte of buffer) {\n hexCodes += byte.toString(16).padStart(2, '0');\n }\n return hexCodes;\n}\n\nexport const sha256HexStr = async (data: string) => {\n const hashBuffer = await sha256(data);\n const hashHex = hexString(new Uint8Array(hashBuffer));\n return hashHex?.toLowerCase();\n}\n","import { hexString, sha256 } from '../crypto';\nimport { OidcConfig } from '../oidcconfig.model';\n\ninterface AuthorizationRequest {\n url: string;\n codeVerifier: string;\n redirectUri: string;\n stateValue: string;\n}\n\nexport interface TokenResponse {\n error: string;\n\n access_token: string;\n refresh_token?: string;\n id_token: string;\n token_type: string;\n expires_in: number;\n}\n\nexport class OAuth2Client {\n constructor(\n public readonly config: OidcConfig\n ) { }\n\n async createAuthorizationUrl(redirectUri: string, extraQueryParams: URLSearchParams | undefined) {\n const stateValue = this.generateRandomValue();\n const codeVerifier = this.generateRandomValue();\n\n const buffer = await sha256(codeVerifier);\n const digestedBuffer = buffer.result || buffer;\n const challenge = this.base64encode(digestedBuffer);\n\n if (!challenge) {\n console.warn('Could not generate secure code challenge. Login not available.');\n return;\n }\n\n const authorizationEndpoint = await this.getWellKnownConfiguration(this.config.stsServer)\n .then(config => config.authorization_endpoint as string);\n\n var url = `${authorizationEndpoint}` +\n `?client_id=${this.config.clientId}` +\n `&scope=${this.config.scope}` +\n `&response_type=code` +\n `&code_challenge_method=S256` +\n `&code_challenge=${challenge}` +\n `&state=${stateValue}` +\n `&redirect_uri=${redirectUri}`;\n\n if (this.config.audience) {\n url += `&audience=${this.config.audience}`;\n }\n\n if (extraQueryParams) {\n url += `&${extraQueryParams}`;\n }\n\n return {\n url,\n codeVerifier,\n redirectUri,\n stateValue\n } as AuthorizationRequest;\n }\n\n private generateRandomValue() {\n const length = 64;\n var array = new Uint8Array((length) / 2);\n crypto.getRandomValues(array);\n return hexString(array);\n }\n\n private base64encode = (buffer: ArrayBuffer) => {\n let data = '';\n const bufferArray = new Uint8Array(buffer);\n for (let byte of bufferArray) {\n data += String.fromCharCode(byte);\n }\n\n return btoa(data)\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n }\n\n finishAuthorizationCodeFlow(authorizationCode: string, verifier: string, redirectUri: string): Promise {\n return this.getToken({\n 'grant_type': 'authorization_code',\n 'client_id': this.config.clientId,\n 'code': authorizationCode,\n 'code_verifier': verifier,\n 'redirect_uri': redirectUri\n });\n }\n\n renewRefreshToken(refreshToken: string): Promise {\n return this.getToken({\n 'grant_type': 'refresh_token',\n 'client_id': this.config.clientId,\n 'refresh_token': refreshToken\n });\n }\n\n private async getToken(body: any): Promise {\n const wellKnownConfig = await this.getWellKnownConfiguration(this.config.stsServer);\n const tokenEndpoint = wellKnownConfig.token_endpoint;\n\n const bodyData = Object\n .keys(body)\n .map(key => { return encodeURIComponent(key) + '=' + encodeURIComponent(body[key]) })\n .join('&');\n\n const tokens = await fetch(tokenEndpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n body: bodyData\n })\n .then(response => response.json())\n .then(tokens => tokens as TokenResponse);\n\n return tokens;\n }\n\n getUserInfoEndpoint(): Promise {\n return this.getWellKnownConfiguration(this.config.stsServer).then(config => config.userinfo_endpoint as string);\n }\n\n getCheckSessionIFrame(): Promise {\n return this.getWellKnownConfiguration(this.config.stsServer).then(config => config.check_session_iframe as string);\n }\n\n getEndSessionEndpoint(): Promise {\n return this.getWellKnownConfiguration(this.config.stsServer).then(config => config.end_session_endpoint as string);\n }\n\n private _wellKnownConfig: Promise;\n protected async getWellKnownConfiguration(stsServer: string) {\n if (!this._wellKnownConfig) {\n const response = await fetch(stsServer + '/.well-known/openid-configuration');\n this._wellKnownConfig = response.json();\n }\n\n return this._wellKnownConfig;\n }\n}\n","import { AuthenticationResponse } from './authParams';\n\nconst REFRESH_BEFORE_EXPIRATION_MS = 1000;\nconst SILENT_RENEW_TIMEOUT_MS = 2000;\n\nexport class SingleSignOnListener {\n\n private silentRenewTimeoutHandler: any;\n private scheduledSilentRenewHandler: any;\n private portal: string;\n\n constructor(\n private readonly iframe: HTMLIFrameElement,\n private readonly generateUrl: () => Promise,\n private readonly processAuthenticationResponse: (response: AuthenticationResponse) => void\n ) {\n this.portal = this.iframe.getAttribute('data-portal');\n }\n\n async check() {\n await this.triggerSilentRenew();\n }\n\n private async triggerSilentRenew() {\n if (!this.iframe || !this.iframe.contentWindow) {\n console.warn('No silent renew iframe available. Silent renew will NOT be available.');\n return;\n }\n\n const url = await this.generateUrl();\n if (url) {\n console.debug(`Request silent renew with iframe using ${url}`);\n\n this.silentRenewTimeoutHandler = setTimeout(() => {\n console.warn(`Did not receive message from ${this.portal} on time. Assume user is not logged in`);\n this.processAuthenticationResponse({\n error: 'silent-renew-timeout',\n error_description: 'Silent renew iframe did not respond in a timely manner.'\n });\n }, SILENT_RENEW_TIMEOUT_MS);\n\n this.iframe.src = url;\n }\n }\n\n processMessage(message: MessageEvent): void {\n if (!message.data || message.origin != window.location.origin) {\n return;\n }\n\n let handled = false;\n switch (message.data.type) {\n case `postnl:${this.portal}:received-authorization-code`:\n console.info(`Received message with authorization code from ${this.portal}`);\n try {\n this.processAuthenticationResponse(message.data);\n handled = true;\n } catch (error) {\n handled = true;\n }\n break;\n case `postnl:${this.portal}:received-error`:\n console.warn(`Received message with error response from ${this.portal}`, message.data);\n this.processAuthenticationResponse(message.data);\n handled = true;\n break;\n }\n\n if (handled) clearTimeout(this.silentRenewTimeoutHandler);\n }\n\n scheduleRefresh(expires: number) {\n const afterMs = Math.max(expires * REFRESH_BEFORE_EXPIRATION_MS - Date.now() - 60000, 0); // Refresh one minute before it expires (or immediately if it's already expired)\n console.info(`Schedule silent renew for ${new Date(Date.now() + afterMs)} (in ${afterMs / REFRESH_BEFORE_EXPIRATION_MS}s.)`);\n\n clearTimeout(this.scheduledSilentRenewHandler);\n this.scheduledSilentRenewHandler = setTimeout(async () => {\n await this.triggerSilentRenew();\n }, afterMs);\n }\n}\n","import { AuthorizationTokens, Verifier } from './authentication.models';\n\nexport class AuthenticationState {\n\n public readonly portal: string;\n\n private verifierKey: string;\n private tokensKey: string;\n private stateDeterminedKey: string;\n\n constructor(portal: string, clientId: string) {\n this.portal = portal;\n this.verifierKey = `${portal}:${clientId}:oidc-verifier`;\n this.tokensKey = `${portal}:${clientId}:oidc-tokens`;\n this.stateDeterminedKey = `${portal}:${clientId}:oidc-state-determined`;\n }\n\n private push(key: string, value: T): void {\n sessionStorage.setItem(key, JSON.stringify(value));\n }\n\n private peek(key: string): T {\n return JSON.parse(sessionStorage.getItem(key)) as T;\n }\n\n private pop(key: string): T {\n const value = sessionStorage.getItem(key);\n if (value) {\n sessionStorage.removeItem(key);\n }\n\n return JSON.parse(value) as T;\n }\n\n private clear(key: string): void {\n sessionStorage.removeItem(key);\n }\n\n pushVerifier(verifier: Verifier): void {\n this.push(this.verifierKey, verifier);\n }\n\n peekVerifier(): Verifier {\n return this.peek(this.verifierKey);\n }\n\n popVerifier(): Verifier {\n return this.pop(this.verifierKey);\n }\n\n clearVerifier(): void {\n this.clear(this.verifierKey);\n }\n\n pushTokens(tokens: AuthorizationTokens): void {\n this.push(this.tokensKey, tokens);\n }\n\n peekTokens(): AuthorizationTokens | null {\n return this.peek(this.tokensKey);\n }\n\n clearTokens() {\n this.clear(this.tokensKey);\n }\n\n setStateDetermined() {\n this.push(this.stateDeterminedKey, true);\n }\n\n getStateDetermined(): boolean {\n return this.peek(this.stateDeterminedKey);\n }\n}\n","import { AuthenticationResponse } from '../../singleSignOn/authParams';\nimport { AuthorizationTokens, Verifier } from '../authentication.models';\nimport { AuthenticationState } from '../authentication.state';\nimport { OAuth2Client, TokenResponse } from '../clients/OAuth2client';\nimport { AuthenticationDetermined, OidcErrorDetected } from './authenticationservice.interface';\n\nexport abstract class BaseAuthenticationService {\n\n protected constructor(\n protected readonly state: AuthenticationState,\n protected readonly client: OAuth2Client,\n protected readonly authenticationDetermined: AuthenticationDetermined,\n protected readonly oidcErrorDetected: OidcErrorDetected\n ) {}\n\n abstract getDescription(): string;\n\n async check(): Promise {\n const stateDetermined = this.state.getStateDetermined();\n\n if (stateDetermined) {\n const tokens = this.state.peekTokens();\n this.authenticationDetermined(tokens);\n } else {\n await this.checkSingleSignOn();\n }\n }\n\n abstract checkSingleSignOn(): Promise;\n\n protected async createAuthorizationUrl(redirectUri: string, extraParams: URLSearchParams | undefined): Promise {\n console.debug(`Prepare authorization code flow for ${this.getDescription()}`);\n const request = await this.client.createAuthorizationUrl(redirectUri, extraParams);\n const verifier: Verifier = {\n codeVerifier: request.codeVerifier,\n redirectUri: request.redirectUri,\n stateValue: request.stateValue\n };\n this.state.pushVerifier(verifier);\n\n console.debug(`Stored verifier state for ${this.state.portal}`);\n\n return request.url;\n }\n\n async finishAuthorizationCodeFlow(params: AuthenticationResponse): Promise {\n const verifier = this.state.popVerifier();\n if (!verifier) {\n // No verifier code available, this authentication code flow is not for this service.\n return false;\n }\n\n this.state.setStateDetermined();\n\n if (params.error) {\n this.oidcErrorDetected({ error: params.error, error_description: params.error_description });\n return false;\n } else {\n const tokens = await this.swapTokens(params, verifier);\n this.authenticationDetermined(tokens);\n return true;\n }\n }\n\n private async swapTokens(params: AuthenticationResponse, verifier: Verifier): Promise {\n console.info(`${this.getDescription()}: Trying to swapping authorization code for access token...`);\n\n if (params.error) {\n this.clearState();\n return null;\n }\n\n if (!params.state || !verifier.stateValue || verifier.stateValue !== params.state) {\n this.clearState();\n console.debug(`State parameter for does not match. This response is not intended for ${this.getDescription()}.`);\n return null;\n }\n\n const response = await this.client.finishAuthorizationCodeFlow(params.code, verifier.codeVerifier, verifier.redirectUri);\n if (response.error) {\n this.clearState();\n throw new Error(`${this.getDescription()}: Received error from sts server while swapping authentication code for access token: ${response.error}`);\n }\n\n return this.createAuthorizationTokens(response, params.session_state);\n }\n\n async renewRefreshToken(refreshToken: string): Promise {\n console.info(`${this.getDescription()}: Trying to swap refresh token for access token...`);\n\n const response = await this.client.renewRefreshToken(refreshToken);\n if (response.error) {\n this.clearState();\n throw new Error(`${this.getDescription()}: Received error from sts server while swapping refresh token for access token: ${response.error}`);\n }\n\n const tokens = await this.createAuthorizationTokens(response);\n this.authenticationDetermined(tokens);\n }\n\n protected async createAuthorizationTokens(response: TokenResponse, session_state?: string) {\n const userInfo = await this.getUserInfo(response.access_token);\n\n const tokens: AuthorizationTokens = {\n access_token: response.access_token,\n refresh_token: response.refresh_token,\n id_token: response.id_token,\n token_type: response.token_type,\n session_state,\n user_info: userInfo\n };\n\n this.state.pushTokens(tokens);\n return tokens;\n }\n\n async refreshUserInfo(): Promise {\n const tokens = this.state.peekTokens();\n if (!tokens) {\n return null;\n }\n\n tokens.user_info = await this.getUserInfo(tokens.access_token);\n this.state.pushTokens(tokens);\n return tokens;\n }\n\n protected async getUserInfo(accessToken: string): Promise {\n const userInfoEndpoint = await this.client.getUserInfoEndpoint();\n const userInfo = await fetch(userInfoEndpoint, {\n headers: { 'Authorization': `Bearer ${accessToken}` }\n })\n .then(response => response.json());\n\n return userInfo;\n }\n\n getTokens() {\n return this.state.peekTokens();\n }\n\n async createLogoutUrl(): Promise {\n const tokens = this.state.peekTokens();\n if (!tokens) return;\n\n this.clearState();\n const endpoint = await this.client.getEndSessionEndpoint();\n\n return endpoint +\n `?id_token_hint=${tokens.id_token}` +\n `&post_logout_redirect_uri=${this.client.config.postLogoutRedirectUri}`;\n }\n\n clearState() {\n this.state.clearTokens();\n this.state.clearVerifier();\n }\n}\n","import jwt_decode from 'jwt-decode';\nimport { SingleSignOnListener } from '../../singleSignOn/singleSignOnListener';\nimport { WidgetUtil } from '../../widgets.util';\nimport { AuthorizationTokens } from '../authentication.models';\nimport { AuthenticationState } from '../authentication.state';\nimport { OAuth2Client } from '../clients/OAuth2client';\nimport { AuthenticationDetermined, IAuthenticationService, OidcErrorDetected } from './authenticationservice.interface';\nimport { BaseAuthenticationService } from './base-authentication.service';\n\nexport class SalesForceAuthenticationService extends BaseAuthenticationService implements IAuthenticationService {\n private singleSignOnListener: SingleSignOnListener;\n\n constructor(\n protected readonly client: OAuth2Client,\n protected readonly normalRedirectUrl: string,\n protected readonly silentRedirectUrl: string,\n protected readonly iframeSso: HTMLIFrameElement,\n authenticationDetermined: AuthenticationDetermined,\n oidcErrorDetected: OidcErrorDetected\n ) {\n super(new AuthenticationState('businessportal', client.config.clientId), client,\n (tokens) => this.handleAuthenticationDetermined(tokens, authenticationDetermined),\n oidcErrorDetected);\n\n this.singleSignOnListener = new SingleSignOnListener(iframeSso,\n () => this.createSilentLoginUrl(),\n (response) => this.finishAuthorizationCodeFlow(response));\n }\n\n getDescription() {\n return 'PostNL BusinessPortal';\n }\n\n createLoginUrl(locale: string): Promise {\n const extraParams = new URLSearchParams();\n extraParams.append('ui_locales', locale);\n return this.createAuthorizationUrl(this.normalRedirectUrl, extraParams);\n }\n\n async checkSingleSignOn(): Promise {\n this.singleSignOnListener.check();\n }\n\n createSilentLoginUrl(): Promise {\n const extraParams = new URLSearchParams();\n return this.createAuthorizationUrl(this.silentRedirectUrl, extraParams);\n }\n\n createRegistrationUrl(_: string): Promise {\n throw new Error('SalesForce does not support registration.');\n }\n\n processMessage(message: MessageEvent): void {\n this.singleSignOnListener.processMessage(message);\n }\n\n protected async getUserInfo(accessToken: string): Promise {\n // SalesForce does not support CORS on the user_info endpoint, so we reference a proxy here that does.\n const widgetsRoot = WidgetUtil.rootUrl();\n const userInfoEndpoint = `${widgetsRoot}/proxy/salesforce/services/oauth2/userinfo`;\n const userInfo = await fetch(userInfoEndpoint, {\n headers: { 'Authorization': `Bearer ${accessToken}` }\n })\n .then(response => response.json());\n\n return userInfo;\n }\n\n private handleAuthenticationDetermined(tokens: AuthorizationTokens | null, authenticationDetermined: AuthenticationDetermined) {\n if (tokens) {\n const exp = jwt_decode(tokens.id_token)['exp'];\n this.singleSignOnListener.scheduleRefresh(exp);\n } else {\n this.clearState();\n }\n\n authenticationDetermined(tokens);\n }\n}\n","export interface AuthenticationResponse {\n code?: string;\n state?: string;\n session_state?: string;\n\n error?: string;\n error_description?: string;\n}\n\nexport function getAuthenticationParameters(location: Location): AuthenticationResponse | undefined {\n const params = new URLSearchParams(location.search);\n if (params.has('code') && params.has('state')) {\n // This is an authentication code flow\n return {\n code: params.get('code'),\n state: params.get('state'),\n session_state: params.get('session_state')\n };\n } else if (params.has('error')) {\n return {\n error: params.get('error'),\n error_description: params.get('error_description')\n }\n }\n\n return undefined;\n}\n\nexport function cleanAuthenticationParameters(location: Location) {\n if (getAuthenticationParameters(location)) {\n let url = location.href.split('?')[0];\n window.history.replaceState({}, document.title, url);\n }\n}\n","export type PortalType = 'identity' | 'businessportal';\n\nexport class UserMenuConstants {\n public static readonly BUSINESSPORTAL: PortalType = 'businessportal';\n public static readonly CONSUMER: PortalType = 'identity';\n\n public static readonly LOGIN = 'login';\n public static readonly LOGOUT = 'logout';\n\n public static readonly BP_LANDING = 'bp-landing';\n public static readonly BP_SWITCH = 'bp-switch';\n public static readonly BP_LOGIN = 'bp-login';\n\n public static readonly CONSUMER_LANDING = 'consumer-landing';\n public static readonly CONSUMER_SWITCH = 'consumer-switch';\n public static readonly CONSUMER_LOGIN = 'consumer-login';\n\n public static readonly CREATE_CONSUMER_ACCOUNT = 'create-consumer-account';\n}\n","@import '../../assets/styles/variables';\n@import '../../assets/styles//typography';\n@import '../../assets/styles/components/component.button';\n@import '../../../node_modules/@postnl/pci/postnl-styles/settings';\n@import '../../../node_modules/@postnl/pci/postnl-styles/components/flyout';\n\n:host(*) {\n all: initial;\n font-family: $font-stack;\n font-size: 16px;\n}\n\n// This styling makes the global flyout menu suitable for the user menu.\n.pci-flyout__list {\n .pnl-user-menu & {\n right: 0;\n left: unset;\n top: 10px;\n z-index: 1000000;\n box-sizing: border-box;\n box-shadow: none;\n border: 1px solid $color-border-default;\n border-radius: 0.25em;\n max-inline-size: 350px;\n inline-size: calc(100vw - 1.5rem);\n padding: 1em 1em 1.5em !important;\n\n @media (min-width: 30em) {\n width: calc(100vw - 2rem);\n }\n\n @media (min-width: 42.5em) {\n width: calc(100vw - 3rem);\n }\n\n @media (min-width: 48em) {\n width: auto;\n min-width: 260px;\n }\n }\n\n &::before {\n display: none;\n }\n}\n\n.pnl-user-menu {\n @media (min-width: 48em) {\n width: 200px;\n\n &::after {\n width: 100%;\n height: 25px;\n z-index: 1;\n content: '';\n display: block;\n position: absolute;\n }\n }\n}\n\n.pci-flyout__list-item {\n position: relative;\n flex-direction: column;\n}\n\n.pci-flyout__icon {\n display: flex;\n margin-inline-end: 0.5em;\n color: $color-text-button-secondary-default;\n\n .pci-flyout__trigger & {\n color: $color-text-button-secondary-default;\n transition: none;\n }\n\n .pci-align-menu-item & {\n margin-inline-end: 0;\n\n > svg {\n width: unset;\n }\n }\n}\n\n.pci-button {\n .pci-flyout__list-item & {\n width: 100%;\n }\n\n &.pci-flyout__trigger {\n margin-left: auto;\n min-width: unset;\n font-weight: 500;\n background-color: transparent;\n }\n}\n\n.pci-button__register {\n color: $color-text-button-secondary-default;\n font-weight: 400;\n}\n\n.pci-flyout__link {\n display: flex;\n align-items: center;\n color: $color-text-button-secondary-default !important;\n border: none;\n transition: none;\n cursor: pointer;\n\n span {\n padding-inline-end: 0.125rem;\n border-bottom: 1px solid transparent;\n }\n\n &:hover {\n span {\n border-bottom-color: $color-text-button-secondary-default;\n }\n }\n\n &:focus:not(:focus-visible) {\n outline: none;\n border: none;\n }\n\n &:focus-visible {\n outline: solid 2px $color-text-button-secondary-default;\n outline-offset: 2px;\n border-radius: 0.125em;\n border-bottom: none;\n }\n}\n\n// Center link without icon within menu\n.pci-align-menu-item {\n flex-direction: row-reverse; // Icon and text needs to be switched\n margin: 0px auto;\n padding-inline-start: 0.25em;\n}\n\n.pnl-user-menu__simpleloginbutton {\n position: relative;\n height: 40px;\n min-width: unset;\n font-family: $font-family-bodytext, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n font-feature-settings: 'ss03' on, 'ss01' on;\n font-size: 1rem;\n border: none;\n border-radius: 0.25rem;\n color: $color-text-button-secondary-default;\n transition: none;\n\n &:focus:not(:focus-visible) {\n outline: none;\n }\n\n &:focus-visible {\n outline: solid 2px $color-border-focus-outline;\n outline-offset: 2px;\n }\n\n &.pci-flyout__trigger {\n margin-left: auto;\n min-width: unset;\n font-weight: 500;\n background-color: transparent;\n }\n\n &[aria-expanded='true'] {\n &::before {\n content: '';\n width: 0.875rem;\n height: 0.875rem;\n top: 50px;\n right: 2px;\n position: absolute;\n z-index: 2000000;\n background: #fff;\n pointer-events: none;\n border-top: 1px solid $color-border-default;\n border-left: 1px solid $color-border-default;\n -webkit-transform: rotate(45deg) translateX(-0.625rem);\n transform: rotate(45deg) translateX(-0.625rem);\n }\n }\n}\n\n// Show or hide menu\n.is-hidden {\n position: relative;\n visibility: hidden;\n z-index: -1;\n}\n\n.is-visible {\n visibility: visible;\n position: relative;\n z-index: 1000001;\n}\n","import {\n Component,\n Element,\n Event,\n EventEmitter,\n Listen,\n Prop,\n State,\n h,\n} from '@stencil/core';\nimport jwt_decode from 'jwt-decode';\nimport { images } from '../../helpers/inline-images.service';\nimport {\n AuthorizationTokens,\n OidcError,\n} from '../../services/authentication/authentication.models';\nimport { AuthenticationChangedEvent } from '../../services/authentication/authenticationchanged.event';\nimport { OAuth2Client } from '../../services/authentication/clients/OAuth2client';\nimport { OidcConfig } from '../../services/authentication/oidcconfig.model';\nimport { IAuthenticationService } from '../../services/authentication/services/authenticationservice.interface';\nimport { SalesForceAuthenticationService } from '../../services/authentication/services/salesforce-authentication.service';\nimport {\n cleanAuthenticationParameters,\n getAuthenticationParameters,\n} from '../../services/singleSignOn/authParams';\nimport { UserMenuConstants } from '../pnl-user-menu/utility/user-menu-actions';\nimport { MenuItemModel, UserMenu, UserMenuState } from '../user-menu.models';\n\n@Component({\n tag: 'pnl-business-user-menu',\n shadow: true,\n styleUrl: 'pnl-business-user-menu.scss',\n})\nexport class PnlBusinessUserMenu {\n private authenticationService: IAuthenticationService;\n\n private loggedIn: boolean;\n\n private iframeSso: HTMLIFrameElement;\n\n private language = 'nl_NL';\n private systemIdentifier = 'bp';\n\n @Element() component: HTMLElement;\n\n @State() loginNotAvailable: boolean = false;\n @State() loginDetermined: boolean;\n @State() name: string;\n @State() open: boolean = false;\n\n @Prop() menu: UserMenu;\n @Prop() usermenuState: UserMenuState;\n\n /** The Security Token service to connect to. e.g. https://mijn.postnl.nl/ */\n @Prop() stsServer: string;\n\n /** The client id to use when requested a token */\n @Prop() clientId: string;\n\n /** The absolute URI to the silent-redirect.html that hosts the silent redirect script. */\n @Prop() silentRenewPage: string;\n\n /** (optional) the URI to redirect users to after authenication is finished. Defaults to the root of the current origin */\n @Prop() redirectUri: string = location.origin;\n\n /** (optional) the url to which the sts will redirect after logout. Defaults to the root of the current origin */\n @Prop() postLogoutRedirectUri: string = location.origin;\n\n /** (optional) The style to render the user menu in. 'normal' (default) will show the full user menu. 'minimal' will show only the name and a login option of not logged in. */\n @Prop() menuStyle: 'normal' | 'minimal' = 'normal';\n\n /** This event will fire before the user will be redirected to the login screen. Use this to store state, and/or the URL the user should return to after logging in */\n @Event() onLoginRequested: EventEmitter;\n\n /** This event will fire before the user will be logged out. Use this to store state, and/or the URL the user should return to after logging out */\n @Event() onLogoutRequested: EventEmitter;\n\n /** This event will fire when an access token is acquired. Note that this event will also fire after a silent renew */\n @Event()\n onSpecificAuthenticationChange: EventEmitter;\n\n /** Internal event for usermenu state changes */\n @Event() onMenuItemClicked: EventEmitter;\n\n /** This event will fire when the component has loaded, but not yet initialized. You can use this to perform some extra actions in your client application before\n * the component is initialized.\n */\n @Event() onReady: EventEmitter;\n\n async componentWillLoad() {\n try {\n if (!this.stsServer) {\n throw new Error(\n 'No businessportal sts-server specified in pnl-user-menu'\n );\n }\n if (!this.clientId) {\n throw new Error(\n 'No businessportal client-id specified in pnl-user-menu'\n );\n }\n } catch (error) {\n this.loginNotAvailable = true;\n throw error;\n }\n }\n\n async componentDidLoad() {\n this.onReady.emit();\n\n this.setupAuthenticationService();\n\n if (!(await this.handlePendingAuthenticationCodeFlow())) {\n this.authenticationService.check();\n }\n }\n\n /**\n * Dispatch a 'postnl:businessportal:login' event to trigger a manual login.\n * The user will be redirected to the Business Portal.\n */\n @Listen('postnl:businessportal:login', { target: 'window' })\n async login() {\n this.onLoginRequested.emit(UserMenuConstants.BUSINESSPORTAL);\n window.location.href = await this.authenticationService.createLoginUrl(\n this.language\n );\n }\n\n /**\n * Dispatch a 'postnl:businessportal:logout' event to trigger a manual logout.\n */\n @Listen('postnl:businessportal:logout', { target: 'window' })\n async logout() {\n this.onLogoutRequested.emit();\n window.location.href =\n await this.authenticationService.createLogoutUrl();\n }\n\n /**\n *Dispatch a 'postnl:businessportal:refreshuserinformation' to trigger a refresh of the user_info\n */\n @Listen('postnl:businessportal:refreshuserinformation', {\n target: 'window',\n })\n async updateUserInformation() {\n const tokens = await this.authenticationService.refreshUserInfo();\n this.authenticationDetermined(tokens);\n }\n\n /** Triggers an onAuthenticationChanged event with the current authentication state.\n */\n @Listen('postnl:businessportal:peekauthenticationstate', {\n target: 'window',\n })\n peekAuthenticationState() {\n const tokens = this.authenticationService.getTokens();\n this.authenticationDetermined(tokens);\n }\n\n private canHover = window.matchMedia('(hover: hover)').matches;\n\n @Listen('mouseenter')\n openMenu() {\n if (this.canHover) {\n this.open = true;\n }\n }\n\n @Listen('mouseleave')\n closeMenu() {\n if (this.canHover) {\n this.open = false;\n }\n }\n\n @Listen('focusout')\n handleFocusOut(event: FocusEvent) {\n if (\n event.relatedTarget instanceof Node &&\n this.component.contains(event.relatedTarget)\n ) {\n return;\n }\n this.open = false;\n }\n\n @Listen('message', { target: 'window' })\n async handleMessage(message: MessageEvent) {\n if (\n message.data?.type?.indexOf(\n `postnl:${UserMenuConstants.BUSINESSPORTAL}`\n ) > -1\n ) {\n this.authenticationService.processMessage(message);\n }\n }\n\n @Listen('resize', { target: 'window' })\n handleResize() {\n const menuElement = this.component.shadowRoot?.querySelector(\n '#pnl-user-menu-container'\n );\n\n if (menuElement) {\n this.adjustIfOutOfBounds(menuElement as HTMLElement);\n }\n }\n\n private setupAuthenticationService() {\n const oidcConfig: OidcConfig = {\n stsServer: this.stsServer,\n clientId: this.clientId,\n scope: 'openid profile email',\n postLogoutRedirectUri: this.postLogoutRedirectUri,\n };\n\n const client = new OAuth2Client(oidcConfig);\n this.authenticationService = new SalesForceAuthenticationService(\n client,\n this.redirectUri,\n this.silentRenewPage,\n this.iframeSso,\n (tokens) => this.authenticationDetermined(tokens),\n (error) => this.oidcErrorDetected(error)\n );\n }\n\n private async handlePendingAuthenticationCodeFlow(): Promise {\n const params = getAuthenticationParameters(window.location);\n if (!params) {\n console.debug('No authentication parameters present.');\n return false;\n }\n\n const finished =\n await this.authenticationService.finishAuthorizationCodeFlow(\n params\n );\n\n cleanAuthenticationParameters(window.location);\n\n return finished;\n }\n\n private authenticationDetermined(tokens: AuthorizationTokens | null): void {\n this.loginDetermined = true;\n if (tokens == null) {\n console.debug('Business user logged out');\n\n this.loggedIn = false;\n this.name = undefined;\n\n this.onSpecificAuthenticationChange.emit(\n AuthenticationChangedEvent.createNotAuthorized(\n UserMenuConstants.BUSINESSPORTAL\n )\n );\n } else {\n console.debug('Business user logged in');\n\n this.loggedIn = true;\n this.name = tokens.user_info['given_name'];\n\n const idToken = jwt_decode(tokens.id_token);\n this.onSpecificAuthenticationChange.emit(\n AuthenticationChangedEvent.createAuthorized(\n UserMenuConstants.BUSINESSPORTAL,\n tokens,\n idToken\n )\n );\n }\n }\n\n private oidcErrorDetected(oidcError: OidcError) {\n console.debug('Business portal login error detected:', oidcError);\n\n this.loginDetermined = true;\n this.loggedIn = false;\n this.name = undefined;\n\n this.onSpecificAuthenticationChange.emit(\n AuthenticationChangedEvent.createError(\n UserMenuConstants.BUSINESSPORTAL,\n oidcError\n )\n );\n }\n\n private adjustIfOutOfBounds(element: HTMLElement): void {\n if (!element) {\n return;\n }\n\n const rect = element.getBoundingClientRect();\n const style = element.style;\n\n if (rect.right > window.innerWidth) {\n const shiftLeft = rect.right - window.innerWidth;\n style.left = `(${element.offsetLeft - shiftLeft}px`;\n }\n\n if (rect.left < 0) {\n style.left = `${element.offsetLeft + 8 - rect.left}px`;\n\n element.classList.add('is-leftside');\n }\n }\n\n private determineMenuOptions(): MenuItemModel[] {\n // Get all non-javascript items for the specified system\n // And add the portal-specific items to it.\n const menu = this.menu.userMenuItems\n .filter((item) => !item.identifier)\n .filter((item) => item.system === this.systemIdentifier)\n .concat(this.usermenuState.portalItems);\n\n return menu;\n }\n\n private toggleMenu() {\n this.open = !this.open;\n\n if (this.open) {\n const menuElement = this.component.shadowRoot?.querySelector(\n '#pnl-user-menu-container'\n );\n if (menuElement) {\n this.adjustIfOutOfBounds(menuElement as HTMLElement);\n }\n }\n }\n\n private loginButtonText() {\n return this.loggedIn && this.name !== null\n ? this.name\n : this.menu.userMenuItems.find(\n (menuItem) => menuItem.identifier === 'login'\n ).text;\n }\n\n private renderMenu() {\n if (\n this.usermenuState.activePortal !== UserMenuConstants.BUSINESSPORTAL\n ) {\n return;\n }\n\n return this.menuStyle === 'minimal'\n ? this.renderMinimalMenu()\n : this.renderNormalMenu();\n }\n\n private renderMinimalMenu() {\n const loggedIn = (\n \n );\n\n const loggedOut = (\n \n );\n\n return this.loggedIn ? loggedIn : loggedOut;\n }\n\n private renderNormalMenu() {\n return (\n \n );\n }\n\n private renderLoginInProgress() {\n if (\n this.usermenuState.activePortal !== UserMenuConstants.BUSINESSPORTAL\n ) {\n return
;\n }\n return
...
;\n }\n\n render() {\n if (this.loginNotAvailable) {\n return;\n }\n return (\n
\n {!this.loginDetermined\n ? this.renderLoginInProgress()\n : this.renderMenu()}\n (this.iframeSso = el)}\n >\n
\n );\n }\n}\n","export class RefreshTokenRefresher {\n private scheduledRefreshHandler: any;\n\n constructor(\n private readonly swapRefreshToken: () => void\n ) {}\n\n scheduleRefresh(expires: number) {\n const afterMs = Math.max(expires * 1000 - Date.now() - 60000, 0); // Refresh one minute before it expires (or immediately if it's already expired)\n\n console.info(`Schedule refresh token renew for ${new Date(Date.now() + afterMs)} (in ${afterMs / 1000}s.)`);\n\n clearTimeout(this.scheduledRefreshHandler);\n this.scheduledRefreshHandler = setTimeout(async () => {\n await this.swapRefreshToken();\n }, afterMs);\n }\n}\n","import jwt_decode from 'jwt-decode';\nimport { RefreshTokenRefresher } from '../../singleSignOn/refreshTokenRefresher';\nimport { SingleSignOnListener } from '../../singleSignOn/singleSignOnListener';\nimport { AuthorizationTokens } from '../authentication.models';\nimport { AuthenticationState } from '../authentication.state';\nimport { OAuth2Client } from '../clients/OAuth2client';\nimport { AuthenticationDetermined, IAuthenticationService, OidcErrorDetected, PrepareForLogin } from './authenticationservice.interface';\nimport { BaseAuthenticationService } from './base-authentication.service';\nimport { sha256HexStr } from '../crypto';\n\nexport class AkamaiAuthenticationService extends BaseAuthenticationService implements IAuthenticationService {\n private singleSignOnListener: SingleSignOnListener;\n private refreshTokenRefresher: RefreshTokenRefresher | undefined;\n\n constructor(\n protected readonly client: OAuth2Client,\n protected readonly normalRedirectUrl: string,\n protected readonly prepareForLogin: PrepareForLogin,\n protected readonly silentRedirectUrl: string | undefined,\n protected readonly iframeSso: HTMLIFrameElement,\n authenticationDetermined: AuthenticationDetermined,\n oidcErrorDetected: OidcErrorDetected\n ) {\n super(new AuthenticationState('akamai', client.config.clientId), client,\n (tokens) => this.handleAuthenticationDetermined(tokens, authenticationDetermined),\n oidcErrorDetected);\n\n if (this.iframeSso) {\n this.singleSignOnListener = new SingleSignOnListener(iframeSso,\n () => this.createSilentLoginUrl(),\n (response) => this.finishAuthorizationCodeFlow(response));\n }\n\n if (!this.onSameDomain()) {\n console.info('Use refresh tokens for refreshing user sessions.');\n this.refreshTokenRefresher = new RefreshTokenRefresher(() => this.swapRefreshToken());\n } else {\n console.info('Use silent renew iframe for refreshing user sessions.');\n }\n }\n\n private onSameDomain() {\n const sameTLD = (tld: string) => {\n var stsHost = new URL(this.client.config.stsServer).hostname;\n var currentHost = window.location.hostname;\n return stsHost.endsWith(tld) && currentHost.endsWith(tld);\n };\n\n return sameTLD('.postnl.nl') || sameTLD('.postnl.be');\n }\n\n getDescription() {\n return 'Akamai Cloud Identity Provider';\n }\n\n createLoginUrl(locale: string): Promise {\n const extraParams = new URLSearchParams();\n extraParams.append('ui_locales', locale.replace('_', '-')); // Convert old to new locale format\n this.addClaims(extraParams);\n\n return this.createAuthorizationUrl(this.normalRedirectUrl, extraParams);\n }\n\n async checkSingleSignOn(): Promise {\n if (this.singleSignOnListener) {\n // Use SSO iframe\n this.singleSignOnListener.check();\n } else {\n // No SSO iframe configured, we redirect the user to a silent login page\n this.prepareForLogin();\n\n const url = await this.createSilentLoginUrl();\n window.location.href = url;\n }\n }\n\n createSilentLoginUrl(): Promise {\n const extraParams = new URLSearchParams();\n extraParams.append('prompt', 'none');\n this.addClaims(extraParams);\n\n const redirectUrl = this.singleSignOnListener ? this.silentRedirectUrl : this.normalRedirectUrl;\n\n return this.createAuthorizationUrl(redirectUrl, extraParams);\n }\n\n createRegistrationUrl(locale: string): Promise {\n const extraParams = new URLSearchParams();\n extraParams.append('ui_locales', locale.replace('_', '-')); // Convert old to new locale format\n extraParams.append('prompt', 'create');\n this.addClaims(extraParams);\n\n return this.createAuthorizationUrl(this.normalRedirectUrl, extraParams);\n }\n\n private addClaims(params: URLSearchParams): void {\n // This way, Akamai includes the account_id in the Access Token\n params.append('claims', '{\"userinfo\":{\"account_id\":null}}');\n }\n\n processMessage(message: MessageEvent): void {\n this.singleSignOnListener.processMessage(message);\n }\n\n private async swapRefreshToken() {\n const refreshToken = this.state.peekTokens()?.refresh_token;\n if (!refreshToken) {\n console.warn('No refresh token available for swapping.');\n return;\n }\n\n this.renewRefreshToken(refreshToken);\n }\n\n protected async getUserInfo(accessToken: string): Promise {\n const userInfo = await super.getUserInfo(accessToken);\n\n if (userInfo.email) {\n userInfo.hashed_email = await sha256HexStr(userInfo.email);\n }\n\n /**\n * Since migrating to Akamai, the 'sub' is no longer the AccountId. Instead, a new field 'account_id'\n * is added. For backwards compatibility, we hash either account_id or it not present, sub.\n *\n * Old versions of the UDL still pass sub to Analytics. We'll change this so sub will also contain\n * the hashed account_id. New versions of the UDL will use the more specific account_id field.\n */\n const accountId = userInfo['account_id'] || userInfo.sub;\n if (accountId) {\n const hash = await sha256HexStr(accountId);\n userInfo.hashed_sub = hash; // TODO: Deprecated! Removed when all data-layers are updated to @cpt/universal-database@1.0.6+\n userInfo.hashed_account_id = hash;\n }\n\n return userInfo;\n }\n\n async createLogoutUrl(): Promise {\n super.createLogoutUrl();\n\n // Akamai does not implement an end_session endpoint, so we create the custom one here\n return new Promise((resolve, _) => {\n const endSessionEndpoint = this.client.config.stsServer.replace(/login([^login]*$)/, 'auth-ui/logout$1') +\n `?client_id=${this.client.config.clientId}` +\n `&redirect_uri=${this.client.config.postLogoutRedirectUri}`;\n resolve(endSessionEndpoint);\n });\n }\n\n private handleAuthenticationDetermined(tokens: AuthorizationTokens | null, authenticationDetermined: AuthenticationDetermined) {\n if (tokens?.refresh_token) {\n const exp = jwt_decode(tokens.access_token)['exp'];\n\n if (this.refreshTokenRefresher) {\n this.refreshTokenRefresher.scheduleRefresh(exp);\n } else {\n this.singleSignOnListener.scheduleRefresh(exp);\n }\n } else if (!tokens) {\n this.clearState();\n }\n\n authenticationDetermined(tokens);\n }\n}\n","import { OAuth2Client } from '../authentication/clients/OAuth2client';\n\nexport class SingleSignOutListener {\n\n private checkSessionTimeoutHandler: any;\n private firstCheck: boolean = true;\n\n constructor(\n private readonly iframe: HTMLIFrameElement,\n private readonly client: OAuth2Client,\n private readonly getSessionState: () => string,\n private readonly triggerLogout: () => void\n ) { }\n\n async start() {\n if (!this.triggerLogout) return;\n\n const checkSessionIFrame = await this.client.getCheckSessionIFrame();\n if (!checkSessionIFrame) {\n console.error('No single sign out iframe available. Disabling single sign out.');\n return;\n }\n\n clearInterval(this.checkSessionTimeoutHandler);\n this.iframe.src = checkSessionIFrame;\n this.firstCheck = true;\n\n const interval = 2000;\n console.debug(`Session check enabled. Checking every ${interval}ms`);\n this.checkSessionTimeoutHandler = setInterval(() => this.checkSession(), interval);\n }\n\n private checkSession() {\n const sessionState = this.getSessionState();\n if (!sessionState) {\n return;\n }\n\n const message = `${this.client.config.clientId} ${sessionState}`;\n this.iframe.contentWindow?.postMessage(message, this.client.config.stsServer);\n }\n\n processMessage(message: MessageEvent): void {\n if (!message.data || message.origin != new URL(this.client.config.stsServer).origin) {\n return;\n }\n\n if (message.data === 'changed') {\n clearInterval(this.checkSessionTimeoutHandler);\n\n if (this.firstCheck) {\n /// If the very first check (which happens right after a login) indicates the session ended, then the browser\n /// is most likely blocking 3rd party cookies. This happens when the browser is in incognito mode, or when using Safari.\n /// In this case, single sign-out is disabled. Otherwise the user is logged out again.\n console.warn('Check_session indicates a logout on the very first try after a login. Your browser most likely blocks (3rd party) cookies. Single signout not available.');\n } else {\n console.debug('Check_session indicates the user session has changed. Logging out user');\n this.triggerLogout();\n }\n }\n\n this.firstCheck = false;\n }\n}\n","import jwt_decode from 'jwt-decode';\nimport { SingleSignOnListener } from '../../singleSignOn/singleSignOnListener';\nimport { SingleSignOutListener } from '../../singleSignOn/singleSignOutListener';\nimport { AuthorizationTokens } from '../authentication.models';\nimport { AuthenticationState } from '../authentication.state';\nimport { OAuth2Client } from '../clients/OAuth2client';\nimport { AuthenticationDetermined, IAuthenticationService, OidcErrorDetected } from './authenticationservice.interface';\nimport { BaseAuthenticationService } from './base-authentication.service';\n\nexport class IdentityAuthenticationService extends BaseAuthenticationService implements IAuthenticationService {\n private singleSignOnListener: SingleSignOnListener;\n private singleSignOutListener: SingleSignOutListener;\n\n constructor(\n protected readonly client: OAuth2Client,\n protected readonly normalRedirectUrl: string,\n protected readonly silentRedirectUrl: string,\n protected readonly iframeSso: HTMLIFrameElement,\n protected readonly iframeCheckSession: HTMLIFrameElement,\n authenticationDetermined: AuthenticationDetermined,\n oidcErrorDetected: OidcErrorDetected\n ) {\n super(new AuthenticationState('identity', client.config.clientId), client,\n (tokens) => this.handleAuthenticationDetermined(tokens, authenticationDetermined),\n oidcErrorDetected);\n\n this.singleSignOnListener = new SingleSignOnListener(iframeSso,\n () => this.createSilentLoginUrl(),\n (response) => this.finishAuthorizationCodeFlow(response));\n\n this.singleSignOutListener = new SingleSignOutListener(this.iframeCheckSession, client, () => this.getSessionState(), () => this.authenticationDetermined(null));\n }\n\n private getSessionState(): string | undefined {\n return this.state.peekTokens()?.session_state;\n }\n\n getDescription() {\n return 'PostNL Identity';\n }\n\n createLoginUrl(locale: string): Promise {\n const extraParams = new URLSearchParams();\n extraParams.append('ui_locale', locale);\n\n return this.createAuthorizationUrl(this.normalRedirectUrl, extraParams);\n }\n\n async checkSingleSignOn() : Promise {\n this.singleSignOnListener.check();\n }\n\n createSilentLoginUrl(): Promise {\n const extraParams = new URLSearchParams();\n extraParams.append('prompt', 'none');\n return this.createAuthorizationUrl(this.silentRedirectUrl, extraParams);\n }\n\n createRegistrationUrl(_: string): Promise {\n throw new Error('PostNL Identity does not support registration. Redirect the user to /account/nieuw-account instead.');\n }\n\n processMessage(message: MessageEvent): void {\n this.singleSignOnListener.processMessage(message);\n this.singleSignOutListener.processMessage(message);\n }\n\n private handleAuthenticationDetermined(tokens: AuthorizationTokens | null, authenticationDetermined: AuthenticationDetermined) {\n if (tokens) {\n const exp = jwt_decode(tokens.access_token)['exp'];\n this.singleSignOnListener.scheduleRefresh(exp);\n this.singleSignOutListener.start();\n } else {\n this.clearState();\n }\n\n authenticationDetermined(tokens);\n }\n}\n","@import '../../assets/styles/variables';\n@import '../../assets/styles//typography';\n@import '../../assets/styles/components/component.button';\n@import '../../../node_modules/@postnl/pci/postnl-styles/settings';\n@import '../../../node_modules/@postnl/pci/postnl-styles/components/flyout';\n@import '../../../node_modules/@postnl/pci-foundation/src/index.scss';\n\n:host(*) {\n all: initial;\n font-family: $font-stack;\n font-size: 16px;\n}\n\n// This styling makes the global flyout menu suitable for the user menu.\n.pci-flyout__list {\n .pnl-user-menu & {\n right: 0;\n left: unset;\n top: 10px;\n z-index: 1000000;\n box-sizing: border-box;\n box-shadow: none;\n border: 1px solid $color-border-default;\n border-radius: 0.25em;\n inline-size: calc(100vw - 1.5rem);\n max-inline-size: 350px;\n padding: 1em 1em 1.5em !important;\n\n @media (min-width: 30em) {\n width: calc(100vw - 2rem);\n }\n\n @media (min-width: 42.5em) {\n width: calc(100vw - 3rem);\n }\n\n @media (min-width: 48em) {\n width: auto;\n min-width: 260px;\n }\n }\n\n &::before {\n display: none;\n }\n}\n\n.pnl-user-menu {\n @media (min-width: 48em) {\n width: 200px;\n\n &:after {\n width: 100%;\n height: 25px;\n z-index: 1;\n content: '';\n display: block;\n position: absolute;\n }\n }\n\n &__login {\n .pci-flyout__icon {\n margin: 0 0.5rem;\n }\n\n .pci-flyout__list {\n right: -66px !important;\n\n @media (min-width: 48em) {\n right: -32% !important;\n }\n\n &:before {\n right: 72px !important;\n }\n }\n }\n\n &__positioning {\n @media (max-width: 48em) {\n .pci-flyout__list {\n right: -66px;\n }\n }\n }\n}\n\n.pci-flyout__list-item {\n position: relative;\n flex-direction: column;\n}\n\n.pci-flyout__icon {\n display: flex;\n margin-inline-end: 0.5em;\n color: $color-text-button-secondary-default;\n\n .pci-flyout__trigger & {\n color: $color-text-button-secondary-default;\n transition: none;\n }\n\n .pci-align-menu-item & {\n margin-inline-end: 0;\n\n > svg {\n width: unset;\n }\n }\n}\n\n.pci-flyout__link {\n display: flex;\n align-items: center;\n color: $color-text-button-secondary-default !important;\n border: none;\n border-radius: 0.25rem;\n transition: none;\n cursor: pointer;\n\n span {\n padding-inline-end: 0.125rem;\n border-bottom: 1px solid transparent;\n }\n\n &:hover {\n span {\n border-bottom-color: $color-text-button-secondary-default;\n }\n }\n\n &:focus:not(:focus-visible) {\n outline: none;\n border: none;\n }\n\n &:focus-visible {\n outline: solid 2px $color-border-focus-outline;\n outline-offset: 2px;\n border-bottom: none;\n }\n}\n\n// Center link without icon within menu\n.pci-align-menu-item {\n flex-direction: row-reverse; // Icon and text needs to be switched\n margin: 0px auto;\n padding-inline-start: 0.25em;\n}\n\n.pci-button {\n .pci-flyout__list-item & {\n width: 100%;\n text-wrap: balance;\n }\n}\n\n.pci-button__register {\n color: $color-text-button-secondary-default;\n font-weight: 400;\n}\n\n.pnl-user-menu__name {\n color: $color-text-button-secondary-default;\n font-weight: 500 !important;\n text-transform: capitalize;\n}\n\n.pnl-user-menu__simpleloginbutton {\n position: relative;\n height: 40px;\n min-width: unset;\n font-family: $font-family-bodytext, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n font-feature-settings: 'ss03' on, 'ss01' on;\n font-size: 1rem;\n border: none;\n border-radius: 0.25rem;\n color: $color-text-button-secondary-default;\n transition: none;\n\n &:focus:not(:focus-visible) {\n outline: none;\n }\n\n &:focus-visible {\n outline: solid 2px $color-border-focus-outline;\n outline-offset: 2px;\n }\n\n &::after {\n content: '';\n position: absolute;\n inset: 0;\n z-index: -1;\n transform: scale(1.5);\n }\n\n &[aria-expanded='true'] {\n &::before {\n content: '';\n width: 0.875rem;\n height: 0.875rem;\n top: 50px;\n right: 2px;\n position: absolute;\n z-index: 2000000;\n background: #fff;\n pointer-events: none;\n border-top: 1px solid $color-border-default;\n border-left: 1px solid $color-border-default;\n -webkit-transform: rotate(45deg) translateX(-0.625rem);\n transform: rotate(45deg) translateX(-0.625rem);\n }\n }\n\n &:hover {\n cursor: pointer;\n }\n\n &.pci-flyout__trigger {\n margin-left: auto;\n min-width: unset;\n font-weight: 500;\n background-color: transparent;\n }\n}\n\n// Show or hide menu\n.is-hidden {\n position: relative;\n visibility: hidden;\n z-index: -1;\n}\n\n.is-visible {\n visibility: visible;\n position: relative;\n z-index: 1000001;\n}\n","import {\n Component,\n Element,\n Event,\n EventEmitter,\n Listen,\n Prop,\n State,\n h,\n} from '@stencil/core';\nimport jwt_decode from 'jwt-decode';\nimport { images } from '../../helpers/inline-images.service';\nimport {\n AuthorizationTokens,\n OidcError,\n StsType,\n} from '../../services/authentication/authentication.models';\nimport { AuthenticationChangedEvent } from '../../services/authentication/authenticationchanged.event';\nimport { OAuth2Client } from '../../services/authentication/clients/OAuth2client';\nimport { OidcConfig } from '../../services/authentication/oidcconfig.model';\nimport { AkamaiAuthenticationService } from '../../services/authentication/services/akamai-authentication.service';\nimport { IAuthenticationService } from '../../services/authentication/services/authenticationservice.interface';\nimport { IdentityAuthenticationService } from '../../services/authentication/services/identity-authentication.service';\nimport {\n cleanAuthenticationParameters,\n getAuthenticationParameters,\n} from '../../services/singleSignOn/authParams';\nimport { UserMenuConstants } from '../pnl-user-menu/utility/user-menu-actions';\nimport { MenuItemModel, UserMenu, UserMenuState } from '../user-menu.models';\n\n@Component({\n tag: 'pnl-consumer-user-menu',\n shadow: true,\n styleUrl: './pnl-consumer-user-menu.scss',\n})\nexport class PnlConsumerUserMenu {\n private authenticationService: IAuthenticationService;\n\n private loggedIn: boolean;\n\n private iframeSso: HTMLIFrameElement;\n private iframeCheckSession: HTMLIFrameElement;\n\n private readonly systemIdentifiers = ['poa', 'shop'];\n\n @Element() component: HTMLElement;\n\n @State() loginNotAvailable: boolean = false;\n @State() loginDetermined: boolean;\n @State() name: string;\n\n @State() open: boolean = false;\n\n @Prop() menu: UserMenu;\n @Prop() usermenuState: UserMenuState;\n\n /** The language to show render the user menu in (en_GB, nl_NL, nl_BE and fr_BE) */\n @Prop() language: string;\n\n /** The domain of the client application. This is used to display the correct menu items. Currently, 'postnl.nl' and 'postnl.be' are supported. */\n @Prop() domain: string;\n\n /** (optional) set the type of security token service. Supported values: 'identity' or 'akamai'. Defaults to 'identity'. */\n @Prop() stsType: StsType = 'identity';\n\n /** The Security Token service to connect to. e.g. https://jouw.postnl.nl/identity */\n @Prop() stsServer: string;\n\n /** The client id to use when requested a token */\n @Prop() clientId: string;\n\n /** (optional) extra audience(s) for which to request access. This will be added to the JWT token's audience, next to the default 'poa-profiles-api' */\n @Prop() audience: string;\n\n /** (optional) extra scope(s) to request access for. This will be added to the default OpenID scopes 'openid' and 'profile', and the scope 'poa-profiles-api' */\n @Prop() scope: string;\n\n /** The absolute URI to the silent-redirect.html that hosts the silent redirect script. */\n @Prop() silentRenewPage: string;\n\n /** (optional) this property will be added to the first element in the iframe, as 'data-silent-renew-script' attribute, so that the silentRenewPage can use that to configure which script to load. */\n @Prop() silentRenewScript: string;\n\n /** (optional) the URI to redirect users to after authenication is finished. Defaults to the root of the current origin */\n @Prop() redirectUri: string = location.origin;\n\n /** (optional) the url to which the sts will redirect after logout. Defaults to the root of the current origin */\n @Prop() postLogoutRedirectUri: string = location.origin;\n\n /** (optional) The style to render the user menu in. 'normal' (default) will show the full user menu. 'minimal' will show only the name and a login option of not logged in. */\n @Prop() menuStyle: 'normal' | 'minimal' = 'normal';\n\n /** This event will fire before the user will be redirected to the login screen. Use this to store state, and/or the URL the user should return to after logging in */\n @Event() onLoginRequested: EventEmitter;\n\n /** This event will fire before the user will be logged out. Use this to store state, and/or the URL the user should return to after logging out */\n @Event() onLogoutRequested: EventEmitter;\n\n /** This event will fire when an access token is acquired. Note that this event will also fire after a silent renew */\n @Event()\n onSpecificAuthenticationChange: EventEmitter;\n\n /** Internal event for usermenu state changes */\n @Event() onMenuItemClicked: EventEmitter;\n\n /** This event will fire when the component has loaded, but not yet initialized. You can use this to perform some extra actions in your client application before\n * the component is initialized.\n */\n @Event() onReady: EventEmitter;\n\n async componentWillLoad() {\n try {\n if (!this.stsServer) {\n throw new Error('No sts-server specified in pnl-user-menu');\n }\n if (!this.clientId) {\n throw new Error('No client-id specified in pnl-user-menu');\n }\n } catch (error) {\n this.loginNotAvailable = true;\n throw error;\n }\n }\n\n async componentDidLoad() {\n this.onReady.emit();\n\n this.setupAuthenticationService();\n\n if (!(await this.handlePendingAuthenticationCodeFlow())) {\n this.authenticationService.check();\n }\n }\n\n @Listen('focusout')\n handleFocusOut(event: FocusEvent) {\n if (\n event.relatedTarget instanceof Node &&\n this.component.contains(event.relatedTarget)\n ) {\n return;\n }\n this.open = false;\n }\n\n @Listen('message', { target: 'window' })\n async handleMessage(message: MessageEvent) {\n if (\n message.data?.type?.indexOf(\n `postnl:${UserMenuConstants.CONSUMER}`\n ) > -1\n ) {\n this.authenticationService.processMessage(message);\n }\n }\n\n /** Triggers a manual login. The user will be redirected to the identity provider after caing this method.\n */\n @Listen('postnl:identity:login', { target: 'window' })\n async login() {\n this.onLoginRequested.emit(UserMenuConstants.CONSUMER);\n window.location.href = await this.authenticationService.createLoginUrl(\n this.language\n );\n }\n\n /** Triggers the user registration process in Akamai. The user will be redirected to the identity provider after dispatching this event.\n */\n @Listen('postnl:identity:startregistration', { target: 'window' })\n async startRegistration() {\n this.onLoginRequested.emit(UserMenuConstants.CONSUMER);\n window.location.href =\n await this.authenticationService.createRegistrationUrl(\n this.language\n );\n }\n\n /** Reset the user widget's state. This will clear the currently logged in user and reinitialize the widget.\n */\n @Listen('postnl:identity:resetstate', { target: 'window' })\n async resetState() {\n this.authenticationService.clearState();\n }\n\n /** Triggers a manuel logout.\n */\n @Listen('postnl:identity:logout', { target: 'window' })\n async logout() {\n this.onLogoutRequested.emit();\n window.location.href =\n await this.authenticationService.createLogoutUrl();\n }\n\n /** Triggers a refresh of the user's information.\n */\n @Listen('postnl:identity:refreshuserinformation', { target: 'window' })\n async updateUserInformation() {\n const tokens = await this.authenticationService.refreshUserInfo();\n this.authenticationDetermined(tokens);\n }\n\n /** Triggers an onAuthenticationChanged event with the current authentication state.\n */\n @Listen('postnl:identity:peekauthenticationstate', { target: 'window' })\n peekAuthenticationState() {\n const tokens = this.authenticationService.getTokens();\n this.authenticationDetermined(tokens);\n }\n\n private canHover = window.matchMedia('(hover: hover)').matches;\n private windowWidth = window.innerWidth;\n\n @Listen('mouseenter')\n openMenu() {\n if (this.windowWidth > 912 && this.canHover) {\n this.open = true;\n }\n }\n\n @Listen('mouseleave')\n closeMenu() {\n if (this.windowWidth > 912 && this.canHover) {\n this.open = false;\n }\n }\n\n @Listen('focusin')\n focusIn(event: FocusEvent) {\n if (\n event.relatedTarget instanceof Node &&\n this.component.contains(event.relatedTarget)\n ) {\n return;\n }\n\n if (this.open && !this.canHover) {\n this.toggleMenu();\n }\n }\n\n @Listen('resize', { target: 'window' })\n handleResize() {\n const menuElement = this.component.shadowRoot?.querySelector(\n '#pnl-user-menu-container'\n );\n\n if (menuElement) {\n this.adjustIfOutOfBounds(menuElement as HTMLElement);\n }\n }\n\n private setupAuthenticationService(): void {\n const oidcConfig: OidcConfig = {\n stsServer: this.stsServer,\n clientId: this.clientId,\n audience:\n 'poa-profiles-api' + (this.audience ? ` ${this.audience}` : ''),\n scope:\n 'openid profile email poa-profiles-api' +\n (this.scope ? ` ${this.scope}` : ''),\n postLogoutRedirectUri: this.postLogoutRedirectUri,\n };\n const client = new OAuth2Client(oidcConfig);\n\n this.authenticationService =\n this.stsType === 'identity'\n ? new IdentityAuthenticationService(\n client,\n this.redirectUri,\n this.silentRenewPage,\n this.iframeSso,\n this.iframeCheckSession,\n (tokens) => this.authenticationDetermined(tokens),\n (error) => this.oidcErrorDetected(error)\n )\n : new AkamaiAuthenticationService(\n client,\n this.redirectUri,\n () =>\n this.onLoginRequested.emit(\n UserMenuConstants.CONSUMER\n ),\n this.silentRenewPage,\n this.iframeSso,\n (tokens) => this.authenticationDetermined(tokens),\n (error) => this.oidcErrorDetected(error)\n );\n }\n\n private async handlePendingAuthenticationCodeFlow(): Promise {\n const params = getAuthenticationParameters(window.location);\n if (!params) {\n console.debug('No authentication parameters present.');\n return false;\n }\n\n const finished =\n await this.authenticationService.finishAuthorizationCodeFlow(\n params\n );\n\n cleanAuthenticationParameters(window.location);\n\n return finished;\n }\n\n private authenticationDetermined(tokens: AuthorizationTokens | null): void {\n this.loginDetermined = true;\n if (tokens == null) {\n console.debug('Consumer logged out');\n\n this.loggedIn = false;\n this.name = undefined;\n\n this.onSpecificAuthenticationChange.emit(\n AuthenticationChangedEvent.createNotAuthorized(\n UserMenuConstants.CONSUMER\n )\n );\n } else {\n console.debug('Consumer logged in');\n\n this.loggedIn = true;\n this.name = tokens.user_info['given_name'];\n\n const accessToken = jwt_decode(tokens.access_token);\n this.onSpecificAuthenticationChange.emit(\n AuthenticationChangedEvent.createAuthorized(\n UserMenuConstants.CONSUMER,\n tokens,\n accessToken\n )\n );\n }\n }\n\n private oidcErrorDetected(oidcError: OidcError): void {\n console.debug('Consumer login error detected', oidcError);\n\n this.loginDetermined = true;\n this.loggedIn = false;\n this.name = undefined;\n\n this.onSpecificAuthenticationChange.emit(\n AuthenticationChangedEvent.createError(\n UserMenuConstants.CONSUMER,\n oidcError\n )\n );\n }\n\n private adjustIfOutOfBounds(element: HTMLElement): void {\n if (!element) {\n return;\n }\n\n const rect = element.getBoundingClientRect();\n const style = element.style;\n\n if (rect.right > window.innerWidth) {\n const shiftLeft = rect.right - window.innerWidth;\n style.left = `(${element.offsetLeft - shiftLeft}px`;\n }\n\n if (rect.left < 0) {\n style.left = `${element.offsetLeft + 8 - rect.left}px`;\n }\n }\n\n private determineMenuOptions(): MenuItemModel[] {\n // Get all non-javascript items for the specified systems\n // And add the portal-specific items to it.\n let menu = this.menu.userMenuItems\n .filter((item) => !item.identifier)\n .filter((item) => this.systemIdentifiers.includes(item.system))\n .concat(this.usermenuState.portalItems);\n return menu;\n }\n\n private toggleMenu() {\n this.open = !this.open;\n\n if (this.open) {\n const menuElement = this.component.shadowRoot?.querySelector(\n '#pnl-user-menu-container'\n );\n\n if (menuElement) {\n this.adjustIfOutOfBounds(menuElement as HTMLElement);\n }\n }\n }\n\n private loginButtonText() {\n return this.loggedIn && this.name !== null\n ? this.name\n : this.menu.userMenuItems.find(\n (menuItem) => menuItem.identifier === UserMenuConstants.LOGIN\n ).text;\n }\n\n private renderMenu() {\n if (this.usermenuState.activePortal !== UserMenuConstants.CONSUMER) {\n return;\n }\n\n return this.menuStyle === 'minimal'\n ? this.renderMinimalMenu()\n : this.renderNormalMenu();\n }\n\n private renderMinimalMenu() {\n const loggedIn = (\n \n this.toggleMenu()}\n aria-controls=\"pnl-user-menu-section\"\n aria-expanded={this.open ? 'true' : 'false'}\n >\n {this.loginButtonText()}\n \n \n
\n
    \n
  • \n this.logout()}\n >\n Uitloggen\n \n
  • \n
\n
\n \n );\n\n const loggedOut = (\n \n this.toggleMenu()}\n aria-expanded={this.open ? 'true' : 'false'}\n class=\"pci-flyout__trigger pnl-user-menu__simpleloginbutton\"\n >\n {this.loginButtonText()}\n \n \n
\n
    \n
  • \n this.login()}\n >\n Inloggen\n \n
  • \n
  • \n this.startRegistration()}\n >\n Account aanmaken\n \n \n \n \n
  • \n
\n
\n \n );\n\n return this.loggedIn ? loggedIn : loggedOut;\n }\n\n private renderNormalMenu() {\n return (\n \n );\n }\n\n private renderLoginInProgress() {\n if (this.usermenuState.activePortal !== UserMenuConstants.CONSUMER) {\n return
;\n }\n return
...
;\n }\n\n render() {\n if (this.loginNotAvailable) {\n return;\n }\n\n return (\n
\n {!this.loginDetermined\n ? this.renderLoginInProgress()\n : this.renderMenu()}\n {this.silentRenewPage && (\n (this.iframeSso = el)}\n >\n )}\n (this.iframeCheckSession = el)}\n >\n
\n );\n }\n}\n","@import '../../../assets/styles/variables';\n@import '../../../assets/styles/components/component.button';\n@import '../../../../node_modules/@postnl/pci/postnl-styles/settings';\n@import '../../../../node_modules/@postnl/pci/postnl-styles/components/flyout';\n\n:host(*) {\n all: initial;\n font-size: 16px;\n font-family: $font-stack;\n}\n\n.pnl-language-selector__list {\n margin-left: auto;\n display: flex;\n\n > li {\n padding: 0 1.5em;\n\n &:not(:last-child) {\n border-right: 1px solid $light-grey;\n }\n\n &:last-child {\n padding-right: 0;\n }\n\n .pnl-navigation-container & {\n margin-top: unset !important;\n }\n }\n}\n\n// This styling makes the global flyout menu suitable for the language selector.\n.pci-flyout__trigger,\n.pci-button--text {\n .pnl-language-selector & {\n padding: 0;\n font-size: unset;\n text-transform: uppercase;\n }\n}\n\n.pci-flyout__list {\n .pnl-language-selector & {\n transform: none;\n\n @media (max-width: $bp-nav) {\n left: unset;\n }\n }\n}\n\n.pci-flyout__list-item {\n .pnl-language-selector & {\n display: flex;\n align-items: center;\n justify-content: center;\n text-transform: uppercase;\n }\n}\n\n// Specific styles for current mobile menu\n.pnl-language-selector {\n .pnl-navigation-container & {\n display: flex;\n justify-content: flex-end;\n margin-top: auto;\n }\n\n .pci-flyout__trigger {\n width: unset;\n min-width: unset;\n font-size: unset;\n font-weight: 500;\n background-color: unset;\n\n &:active {\n background-color: unset;\n }\n\n &:focus:not(:focus-visible) {\n outline: none;\n }\n\n &:focus-visible {\n outline: 2px solid $color-border-focus-outline;\n outline-offset: 2px;\n border-radius: 0.25rem;\n }\n }\n}\n\n.pnl-language-selector {\n .pci-flyout__list {\n .pnl-navigation-container & {\n padding: 1rem;\n z-index: 9999;\n }\n }\n}\n\n.pci-flyout__icon {\n margin-right: 0.5em;\n color: $color-text-button-secondary-default;\n\n .pnl-language-selector & {\n color: $color-text-button-secondary-default !important;\n }\n}\n\n.pci-button__text,\n.pci-flyout__link {\n .pnl-language-selector & {\n color: $color-text-button-secondary-default !important;\n\n &:hover {\n text-decoration: underline;\n }\n\n &:focus:not(:focus-visible) {\n outline: none;\n }\n\n &:focus-visible {\n outline: 2px solid $color-border-focus-outline;\n outline-offset: 2px;\n border-radius: 0.25rem;\n }\n }\n}\n\n.pci-button {\n .pci-flyout__list-item & {\n height: unset;\n width: unset;\n min-width: unset;\n }\n}\n","import {\n Component,\n Element,\n Event,\n EventEmitter,\n Listen,\n Prop,\n State,\n h,\n} from '@stencil/core';\nimport { images } from '../../../helpers/inline-images.service';\n\n@Component({\n tag: 'pnl-language-selector',\n styleUrl: 'pnl-language-selector.scss',\n})\nexport class LanguageSelector {\n toggleMenu = (event: MouseEvent) => {\n this.open = !this.open;\n event.stopImmediatePropagation();\n };\n\n renderLanguageItem = (locale: string) => (\n
  • \n this.chooseLocale(locale)}\n >\n {this.toLanguage(locale)}\n \n
  • \n );\n\n toLanguage = (locale: string) => locale.split('_')[0];\n\n @Element() component: HTMLElement;\n\n @State() open: boolean;\n\n @Prop() availableLocales: string;\n @Prop() locale: string;\n\n /** Fires when the user changes the locale. */\n @Event() onLocaleChanged: EventEmitter;\n\n @Listen('focusout')\n handleFocusOut(event: FocusEvent) {\n if (\n event.relatedTarget instanceof Node &&\n this.component.contains(event.relatedTarget)\n ) {\n return;\n }\n this.open = false;\n }\n\n chooseLocale(locale: string) {\n this.onLocaleChanged.emit(locale);\n\n const htmlLang = locale.replace('_', '-');\n document.querySelector('html').setAttribute('lang', htmlLang);\n\n this.open = false;\n }\n\n render() {\n const locales = this.availableLocales.split(',');\n if (locales.length <= 1) {\n return;\n }\n\n return (\n
    \n \n {this.toLanguage(this.locale)}\n\n
    \n \n \n \n );\n }\n}\n","export interface UserMenu {\n userMenuItems: MenuItemModel[];\n}\n\nexport interface MenuItemModel {\n identifier?: string;\n url?: string;\n text?: string;\n description?: string;\n icon?: string;\n system?: string;\n isButton?: boolean;\n isSecondary?: boolean;\n alignCenter?: boolean;\n}\n\nexport class UserMenuState {\n constructor(\n public readonly activePortal: string,\n public readonly portalItems: MenuItemModel[]) { }\n\n static createEmpty() {\n return new UserMenuState(undefined, []);\n }\n}\n","@import '../../assets/styles/variables';\n@import '../../../node_modules/@postnl/pci/postnl-styles/settings';\n@import '../../../node_modules/@postnl/pci/postnl-styles/components/button';\n@import '../../../node_modules/@postnl/pci/postnl-styles/components/flyout';\n@import '../../../node_modules/@postnl/pci-foundation/src/index.scss';\n\n:host(*) {\n all: initial;\n font-family: $font-stack;\n font-size: 16px;\n}\n\n// Hide user menu when sub menu is open\n.is-hidden {\n @media (max-width: $bp-nav) {\n display: none;\n }\n}\n","import {\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Listen,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\nimport { combineLatest, Subject } from 'rxjs';\nimport { StsType } from '../../services/authentication/authentication.models';\nimport { AuthenticationChangedEvent } from '../../services/authentication/authenticationchanged.event';\nimport { WidgetUtil } from '../../services/widgets.util';\nimport { fetchUserMenu } from '../menu-service';\nimport { MenuItemModel, UserMenu, UserMenuState } from '../user-menu.models';\nimport { PortalType, UserMenuConstants } from './utility/user-menu-actions';\n\n@Component({\n tag: 'pnl-user-menu',\n shadow: true,\n styleUrl: './pnl-user-menu.scss',\n})\nexport class PnlUserMenu {\n private consumerPortalConfigured: boolean = false;\n private businessPortalConfigured: boolean = false;\n\n private activePortal$ = new Subject();\n private consumerLogin$ = new Subject();\n private businessportalLogin$ = new Subject();\n private languageChanged$ = new Subject();\n private activePortalIFrame: HTMLIFrameElement;\n\n @Element() component: HTMLElement;\n\n @State() loginNotAvailable: boolean = false;\n @State() stateDetermined: boolean;\n @State() menu: UserMenu;\n @State() subMenuActive: boolean = false;\n @State() usermenuState: UserMenuState = UserMenuState.createEmpty();\n\n /** The language to show render the user menu in (en_GB, nl_NL, nl_BE and fr_BE) */\n @Prop() language: string;\n\n /** The domain of the client application. This is used to display the correct menu items. Currently, 'postnl.nl' and 'postnl.be' are supported. */\n @Prop() domain: string;\n\n /** (optional) set the type of the consumer security token service. Supported values: 'identity' or 'akamai'. */\n @Prop() stsType: StsType;\n\n /** (optional) The Security Token service for the consumer portal to connect to. */\n @Prop() stsServer: string;\n\n /** (optional) The client id for the consumer portal to use when requested a token */\n @Prop() clientId: string;\n\n /** (optional) extra audience(s) for which to request access. This will be added to the JWT token's audience, next to the default 'poa-profiles-api' */\n @Prop() audience: string;\n\n /** (optional) extra scope(s) to request access for. This will be added to the default OpenID scopes 'openid' and 'profile', and the scope 'poa-profiles-api' */\n @Prop() scope: string;\n\n /** The absolute URI to the silent-redirect.html that hosts the silent redirect script. */\n @Prop() silentRenewPage: string;\n\n /** (optional) this property will be added to the first element in the iframe, as 'data-silent-renew-script' attribute, so that the silentRenewPage can use that to configure which script to load. */\n @Prop() silentRenewScript: string;\n\n /** (optional) the URI to redirect users to after authenication is finished. Defaults to the root of the current origin */\n @Prop() redirectUri: string = location.origin;\n\n /** (optional) the url to which the sts will redirect after logout. Defaults to the root of the current origin */\n @Prop() postLogoutRedirectUri: string = location.origin;\n\n /** (optional) The Security Token service for the businessportal to connect to. */\n @Prop() bpStsServer: string;\n\n /** (optional) The client id for the businessportal to use when requested a token */\n @Prop() bpClientId: string;\n\n /** (optional) The style to render the user menu in. 'normal' (default) will show the full user menu. 'minimal' will show only the name and a login option of not logged in. */\n @Prop() menuStyle: 'normal' | 'minimal' = 'normal';\n\n @Watch('language')\n @Watch('domain')\n async loadMenu() {\n if (this.domain && this.language) {\n this.menu = await fetchUserMenu(this.domain, this.language);\n }\n this.languageChanged$.next();\n }\n\n /** This event will fire before the user will be redirected to the login screen. Use this to store state, and/or the URL the user should return to after logging in */\n @Event() onLoginRequested: EventEmitter;\n\n /** This event will fire before the user will be logged out. Use this to store state, and/or the URL the user should return to after logging out */\n @Event() onLogoutRequested: EventEmitter;\n\n /** This event will fire when an access token is acquired. Note that this event will also fire after a silent renew */\n @Event() onAuthenticationChange: EventEmitter;\n\n /** This event will fire when the component has loaded, but not yet initialized. You can use this to perform some extra actions in your client application before\n * the component is initialized.\n */\n @Event() onReady: EventEmitter;\n async componentWillLoad() {\n try {\n if (!this.stsServer && !this.bpStsServer)\n throw new Error(\n 'Please configure an sts-server or a bp-sts-server (or both).'\n );\n\n this.consumerPortalConfigured = this.stsServer !== undefined;\n this.businessPortalConfigured = this.bpStsServer !== undefined;\n\n combineLatest([\n this.activePortal$,\n this.consumerLogin$,\n this.businessportalLogin$,\n this.languageChanged$,\n ]).subscribe((values) => {\n const activePortal =\n values[0] !== 'unknown'\n ? (values[0] as PortalType)\n : UserMenuConstants.CONSUMER;\n const consumerAuth = values[1];\n const businessPortalAuth = values[2];\n\n const portalItems = this.determinePortalItems(\n activePortal,\n consumerAuth,\n businessPortalAuth\n );\n this.usermenuState = new UserMenuState(\n activePortal,\n portalItems\n );\n\n if (\n this.usermenuState.activePortal ===\n UserMenuConstants.CONSUMER\n ) {\n this.emitAuthenticationChange(consumerAuth);\n }\n if (\n this.usermenuState.activePortal ===\n UserMenuConstants.BUSINESSPORTAL\n ) {\n this.emitAuthenticationChange(businessPortalAuth);\n }\n });\n\n await this.loadMenu();\n\n if (!this.consumerPortalConfigured) {\n this.consumerLogin$.next(\n AuthenticationChangedEvent.createNotAuthorized(\n UserMenuConstants.CONSUMER\n )\n );\n this.activePortal$.next(UserMenuConstants.BUSINESSPORTAL);\n }\n\n if (!this.businessPortalConfigured) {\n this.businessportalLogin$.next(\n AuthenticationChangedEvent.createNotAuthorized(\n UserMenuConstants.BUSINESSPORTAL\n )\n );\n this.activePortal$.next(UserMenuConstants.CONSUMER);\n }\n\n // Listen to messages from the activePortal state iframe\n window.addEventListener('message', (message) => {\n if (message.origin !== WidgetUtil.stateIFrameOrigin()) {\n // check origin to make sure our IFrame posted the message\n return;\n }\n if (message.data.type === 'activePortal') {\n this.activePortal$.next(message.data.value);\n }\n });\n } catch (error) {\n this.loginNotAvailable = true;\n throw error;\n }\n }\n\n async componentDidLoad() {\n this.onReady.emit();\n }\n\n @Listen('onSubMenuToggle', { target: 'document' })\n showUserMenu(event: CustomEvent) {\n this.subMenuActive = event.detail;\n }\n\n @Listen('onSpecificAuthenticationChange')\n handleAuthenticationChange(event: CustomEvent) {\n event.stopPropagation();\n if (event.detail.portal === UserMenuConstants.CONSUMER) {\n this.consumerLogin$.next(event.detail);\n } else if (event.detail.portal === UserMenuConstants.BUSINESSPORTAL) {\n this.businessportalLogin$.next(event.detail);\n }\n }\n\n @Listen('onMenuItemClicked')\n handleMenuItemSelected(event: CustomEvent) {\n switch (event.detail) {\n case UserMenuConstants.LOGIN: {\n window.dispatchEvent(\n new CustomEvent(\n `postnl:${this.usermenuState.activePortal}:login`\n )\n );\n break;\n }\n case UserMenuConstants.LOGOUT: {\n window.dispatchEvent(\n new CustomEvent(\n `postnl:${this.usermenuState.activePortal}:logout`\n )\n );\n break;\n }\n case UserMenuConstants.BP_SWITCH: {\n this.switchActivePortal(UserMenuConstants.BUSINESSPORTAL);\n window.dispatchEvent(\n new CustomEvent(\n 'postnl:businessportal:refreshuserinformation'\n )\n );\n break;\n }\n case UserMenuConstants.BP_LOGIN: {\n window.dispatchEvent(\n new CustomEvent('postnl:businessportal:login')\n );\n break;\n }\n case UserMenuConstants.CREATE_CONSUMER_ACCOUNT: {\n window.dispatchEvent(\n new CustomEvent('postnl:identity:startregistration')\n );\n break;\n }\n case UserMenuConstants.CONSUMER_SWITCH: {\n this.switchActivePortal(UserMenuConstants.CONSUMER);\n window.dispatchEvent(\n new CustomEvent('postnl:identity:refreshuserinformation')\n );\n break;\n }\n case UserMenuConstants.CONSUMER_LOGIN: {\n window.dispatchEvent(new CustomEvent('postnl:identity:login'));\n break;\n }\n }\n }\n\n @Listen('onLoginRequested')\n handleLoginRequested(event: CustomEvent) {\n if (!this.businessPortalConfigured) {\n return;\n }\n\n if (event.detail === UserMenuConstants.BUSINESSPORTAL) {\n this.switchActivePortal(UserMenuConstants.BUSINESSPORTAL);\n } else {\n this.switchActivePortal(UserMenuConstants.CONSUMER);\n }\n }\n\n /** Triggers a manual login. The user will be redirected to the identity provider after calling this method.\n */\n async login() {\n window.dispatchEvent(new CustomEvent(`postnl:identity:login`));\n }\n\n /** Triggers a manuel logout.\n */\n async logout() {\n window.dispatchEvent(new CustomEvent(`postnl:identity:logout`));\n }\n\n /** Triggers an onAuthenticationChanged event with the current authentication state.\n */\n @Listen('postnl:peekauthenticationstate', { target: 'window' })\n peekAuthenticationState() {\n window.dispatchEvent(\n new CustomEvent(\n `postnl:${this.usermenuState.activePortal}:peekauthenticationstate`\n )\n );\n }\n\n private emitAuthenticationChange(event: AuthenticationChangedEvent) {\n console.debug('Emitting authenticationChange', event);\n this.onAuthenticationChange.emit(event);\n }\n\n private determinePortalItems(\n activePortal: PortalType,\n consumerAuth: AuthenticationChangedEvent,\n bpAuth: AuthenticationChangedEvent\n ): MenuItemModel[] {\n return activePortal == UserMenuConstants.CONSUMER\n ? this.getPortalItems(consumerAuth, bpAuth, activePortal)\n : this.getPortalItems(bpAuth, consumerAuth, activePortal);\n }\n\n private getPortalItems(\n primaryAuth: AuthenticationChangedEvent,\n secondaryAuth: AuthenticationChangedEvent,\n portalType: PortalType\n ): MenuItemModel[] {\n const items: MenuItemModel[] = [];\n\n // Determine the login/logout button based on primary authentication state\n const authIdentifier = primaryAuth.authenticated\n ? UserMenuConstants.LOGOUT\n : UserMenuConstants.LOGIN;\n const authButton = this.menu.userMenuItems.find(\n (item) => item.identifier === authIdentifier\n );\n if (authButton) items.push(authButton);\n\n // Determine the secondary portal button (switch, login or landing)\n const isConfigured =\n portalType === UserMenuConstants.CONSUMER\n ? this.businessPortalConfigured\n : this.consumerPortalConfigured;\n const secondaryAuthIdentifier = this.getSecondaryAuthIdentifier(\n portalType,\n isConfigured,\n secondaryAuth\n );\n const secondaryAuthButton = this.menu.userMenuItems.find(\n (item) => item.identifier === secondaryAuthIdentifier\n );\n\n if (secondaryAuthButton) {\n // Check if we can use the user's name to the secondary auth button\n if (\n secondaryAuth.authenticated &&\n secondaryAuth.user_info['given_name']\n ) {\n secondaryAuthButton.text =\n secondaryAuth.user_info['given_name'];\n }\n items.push(secondaryAuthButton);\n }\n\n // Add registration button for unauthenticated consumers\n if (\n !primaryAuth.authenticated &&\n portalType === UserMenuConstants.CONSUMER\n ) {\n const registrationButton = this.menu.userMenuItems.find(\n (item) =>\n item.identifier ===\n UserMenuConstants.CREATE_CONSUMER_ACCOUNT\n );\n if (registrationButton) items.push(registrationButton);\n }\n\n return items;\n }\n\n private getSecondaryAuthIdentifier(\n portalType: PortalType,\n isConfigured: boolean,\n authentication: AuthenticationChangedEvent\n ): string {\n if (portalType === UserMenuConstants.CONSUMER) {\n if (!isConfigured) return UserMenuConstants.BP_LANDING;\n return authentication.authenticated\n ? UserMenuConstants.BP_SWITCH\n : UserMenuConstants.BP_LOGIN;\n } else {\n if (!isConfigured) return UserMenuConstants.CONSUMER_LANDING;\n return authentication.authenticated\n ? UserMenuConstants.CONSUMER_SWITCH\n : UserMenuConstants.CONSUMER_LOGIN;\n }\n }\n\n private switchActivePortal(activePortal: string) {\n this.activePortalIFrame.contentWindow.postMessage(\n activePortal,\n WidgetUtil.stateIFrameOrigin()\n );\n this.activePortal$.next(activePortal);\n }\n\n private renderStateUnknown() {\n return
    ...
    ;\n }\n\n private renderConsumerUserMenu() {\n return (\n \n );\n }\n\n private renderBusinessPortalUserMenu() {\n return (\n \n );\n }\n\n render() {\n if (this.loginNotAvailable) {\n return;\n }\n return (\n
    \n {this.consumerPortalConfigured &&\n this.businessPortalConfigured && (\n (this.activePortalIFrame = el)}\n >\n )}\n {!this.usermenuState && this.renderStateUnknown()}\n\n {this.consumerPortalConfigured && this.renderConsumerUserMenu()}\n {this.businessPortalConfigured &&\n this.renderBusinessPortalUserMenu()}\n
    \n );\n }\n}\n","@import '../../../assets/styles/variables';\n@import '../../../assets/styles//typography';\n\n// Show or hide menu\n.is-hidden {\n position: relative;\n visibility: hidden;\n z-index: -1;\n}\n\n.is-visible {\n visibility: visible;\n position: relative;\n z-index: 1000001;\n}\n","import { Component, Event, EventEmitter, h, Prop } from '@stencil/core';\nimport { images } from '../../../helpers/inline-images.service';\nimport { MenuItemModel } from '../../user-menu.models';\n\n@Component({\n tag: 'pnl-user-menu-item-list',\n styleUrl: './pnl-user-menu-item-list.scss',\n})\nexport class Menu {\n /// The menu items to render\n @Prop() menuItems: MenuItemModel[];\n\n /// Whether or not this menu items should be visible\n @Prop() open: boolean;\n\n /// Emits with the 'identifier' value of the selected menu item, unless it also has an url. In that case, user is redirect to that page.\n @Event() menuItemSelected: EventEmitter;\n\n renderMenuItem(menuItem: MenuItemModel) {\n // TODO: display logic is intertwined with the url property. Should be split:\n // - isButton renders as a button if there is a url, otherwise \n );\n }\n\n render() {\n if (!this.menuItems) {\n return;\n }\n\n return (\n
    \n
      \n {this.menuItems.map((item) => this.renderMenuItem(item))}\n
    \n
    \n );\n }\n}\n"],"mappings":"qPAAO,SAASA,EAAYC,GACxB,OAAOA,UAAgBA,EAAMC,WAAa,UAC9C,CCFO,MAAMC,EAAoBC,GAAWC,IACxC,IAAK,IAAIC,EAAI,EAAGC,EAAMH,EAAMI,OAAQF,EAAIC,IAAQF,EAAWI,OAAQH,IAAK,CACpED,EAAWK,KAAKN,EAAME,GAC9B,CACID,EAAWM,UAAU,ECFlB,SAASC,EAAcC,EAAOC,GACjC,OAAO,IAAIC,GAAWV,IAClB,MAAMW,EAAM,IAAIC,EAChB,IAAIX,EAAI,EACRU,EAAIE,IAAIJ,EAAUZ,UAAS,WACvB,GAAII,IAAMO,EAAML,OAAQ,CACpBH,EAAWM,WACX,MAChB,CACYN,EAAWK,KAAKG,EAAMP,MACtB,IAAKD,EAAWI,OAAQ,CACpBO,EAAIE,IAAIC,KAAKjB,WAC7B,CACA,KACQ,OAAOc,CAAG,GAElB,CCfO,SAASI,EAAUP,EAAOC,GAC7B,IAAKA,EAAW,CACZ,OAAO,IAAIC,EAAWZ,EAAiBU,GAC/C,KACS,CACD,OAAOD,EAAcC,EAAOC,EACpC,CACA,CCTO,MAAMO,UAAwBC,EACjCC,WAAWC,EAAYC,EAAYC,EAAYC,EAAYC,GACvDT,KAAKU,YAAYnB,KAAKe,EAC9B,CACIK,YAAYC,EAAOH,GACfT,KAAKU,YAAYE,MAAMA,EAC/B,CACIC,eAAeJ,GACXT,KAAKU,YAAYlB,UACzB,ECTO,MAAMsB,UAAwBX,EACjCY,YAAYC,EAAQX,EAAYE,GAC5BU,QACAjB,KAAKgB,OAASA,EACdhB,KAAKK,WAAaA,EAClBL,KAAKO,WAAaA,EAClBP,KAAKkB,MAAQ,CACrB,CACIC,MAAMrC,GACFkB,KAAKgB,OAAOZ,WAAWJ,KAAKK,WAAYvB,EAAOkB,KAAKO,WAAYP,KAAKkB,QAASlB,KACtF,CACIoB,OAAOR,GACHZ,KAAKgB,OAAOL,YAAYC,EAAOZ,MAC/BA,KAAKqB,aACb,CACIC,YACItB,KAAKgB,OAAOH,eAAeb,MAC3BA,KAAKqB,aACb,EClBO,MAAME,EAAsBC,GAAatC,IAC5CsC,EAAQC,MAAM3C,IACV,IAAKI,EAAWI,OAAQ,CACpBJ,EAAWK,KAAKT,GAChBI,EAAWM,UACvB,KACQkC,GAAQxC,EAAW0B,MAAMc,KACxBD,KAAK,KAAME,GAChB,OAAOzC,CAAU,ECTd,SAAS0C,IACZ,UAAWC,SAAW,aAAeA,OAAOC,SAAU,CAClD,MAAO,YACf,CACI,OAAOD,OAAOC,QAClB,CACO,MAAMA,EAAWF,ICLjB,MAAMG,EAAuBC,GAAc9C,IAC9C,MAAM4C,EAAWE,EAASC,KAC1B,EAAG,CACC,IAAIC,EACJ,IACIA,EAAOJ,EAASvC,MAK5B,CAHQ,MAAOmC,GACHxC,EAAW0B,MAAMc,GACjB,OAAOxC,CACnB,CACQ,GAAIgD,EAAKC,KAAM,CACXjD,EAAWM,WACX,KACZ,CACQN,EAAWK,KAAK2C,EAAKpD,OACrB,GAAII,EAAWI,OAAQ,CACnB,KACZ,CACA,OAAa,MACT,UAAWwC,EAASM,SAAW,WAAY,CACvClD,EAAWa,KAAI,KACX,GAAI+B,EAASM,OAAQ,CACjBN,EAASM,QACzB,IAEA,CACI,OAAOlD,CAAU,EC3Bd,MAAMmD,EAAyBC,GAASpD,IAC3C,MAAMqD,EAAMD,EAAIE,KAChB,UAAWD,EAAIE,YAAc,WAAY,CACrC,MAAM,IAAIC,UAAU,iEAC5B,KACS,CACD,OAAOH,EAAIE,UAAUvD,EAC7B,GCRO,MAAMyD,EAAgBC,GAAMA,UAAYA,EAAEvD,SAAW,iBAAmBuD,IAAM,WCA9E,SAASC,EAAU/D,GACtB,QAASA,UAAgBA,EAAM2D,YAAc,mBAAqB3D,EAAM2C,OAAS,UACrF,CCOO,MAAMqB,EAAeC,IACxB,KAAMA,UAAiBA,EAAOP,KAAuB,WAAY,CAC7D,OAAOH,EAAsBU,EACrC,MACS,GAAIJ,EAAYI,GAAS,CAC1B,OAAO/D,EAAiB+D,EAChC,MACS,GAAIF,EAAUE,GAAS,CACxB,OAAOxB,EAAmBwB,EAClC,MACS,KAAMA,UAAiBA,EAAOd,KAAqB,WAAY,CAChE,OAAOF,EAAoBgB,EACnC,KACS,CACD,MAAMjE,EAAQkE,EAASD,GAAU,oBAAsB,IAAIA,KAC3D,MAAME,EAAM,gBAAgBnE,iCACtB,+DACN,MAAM,IAAI4D,UAAUO,EAC5B,GCxBO,SAASC,EAAkBC,EAAiBJ,EAAQ1C,EAAYE,EAAY6C,EAAkB,IAAItC,EAAgBqC,EAAiB9C,EAAYE,IAClJ,GAAI6C,EAAgB9D,OAAQ,CACxB,OAAO+D,SACf,CACI,GAAIN,aAAkBnD,EAAY,CAC9B,OAAOmD,EAAON,UAAUW,EAChC,CACI,OAAON,EAAYC,EAAZD,CAAoBM,EAC/B,CCNA,MAAME,EAAO,GACN,SAASC,KAAiBC,GAC7B,IAAIC,EAAiBJ,UACrB,IAAI1D,EAAY0D,UAChB,GAAIxE,EAAY2E,EAAYA,EAAYnE,OAAS,IAAK,CAClDM,EAAY6D,EAAYE,KAChC,CACI,UAAWF,EAAYA,EAAYnE,OAAS,KAAO,WAAY,CAC3DoE,EAAiBD,EAAYE,KACrC,CACI,GAAIF,EAAYnE,SAAW,GAAKsE,EAAQH,EAAY,IAAK,CACrDA,EAAcA,EAAY,EAClC,CACI,OAAOvD,EAAUuD,EAAa7D,GAAWiE,KAAK,IAAIC,EAAsBJ,GAC5E,CACO,MAAMI,EACT9C,YAAY0C,GACRzD,KAAKyD,eAAiBA,CAC9B,CACIK,KAAK5E,EAAY6E,GACb,OAAOA,EAAOtB,UAAU,IAAIuB,EAAwB9E,EAAYc,KAAKyD,gBAC7E,EAEO,MAAMO,UAAgC9D,EACzCa,YAAYL,EAAa+C,GACrBxC,MAAMP,GACNV,KAAKyD,eAAiBA,EACtBzD,KAAKiE,OAAS,EACdjE,KAAKkE,OAAS,GACdlE,KAAKwD,YAAc,EAC3B,CACIrC,MAAMgD,GACFnE,KAAKkE,OAAOE,KAAKd,GACjBtD,KAAKwD,YAAYY,KAAKD,EAC9B,CACI7C,YACI,MAAMkC,EAAcxD,KAAKwD,YACzB,MAAMpE,EAAMoE,EAAYnE,OACxB,GAAID,IAAQ,EAAG,CACXY,KAAKU,YAAYlB,UAC7B,KACa,CACDQ,KAAKiE,OAAS7E,EACdY,KAAKqE,UAAYjF,EACjB,IAAK,IAAID,EAAI,EAAGA,EAAIC,EAAKD,IAAK,CAC1B,MAAMgF,EAAaX,EAAYrE,GAC/Ba,KAAKD,IAAImD,EAAkBlD,KAAMmE,EAAYd,UAAWlE,GACxE,CACA,CACA,CACI0B,eAAeyD,GACX,IAAKtE,KAAKiE,QAAU,KAAO,EAAG,CAC1BjE,KAAKU,YAAYlB,UAC7B,CACA,CACIY,WAAWmE,EAAajE,EAAYC,GAChC,MAAM2D,EAASlE,KAAKkE,OACpB,MAAMM,EAASN,EAAO3D,GACtB,MAAM8D,GAAarE,KAAKqE,UAClB,EACAG,IAAWlB,IAAStD,KAAKqE,UAAYrE,KAAKqE,UAChDH,EAAO3D,GAAcD,EACrB,GAAI+D,IAAc,EAAG,CACjB,GAAIrE,KAAKyD,eAAgB,CACrBzD,KAAKyE,mBAAmBP,EACxC,KACiB,CACDlE,KAAKU,YAAYnB,KAAK2E,EAAOQ,QAC7C,CACA,CACA,CACID,mBAAmBP,GACf,IAAInB,EACJ,IACIA,EAAS/C,KAAKyD,eAAekB,MAAM3E,KAAMkE,EAKrD,CAHQ,MAAOxC,GACH1B,KAAKU,YAAYE,MAAMc,GACvB,MACZ,CACQ1B,KAAKU,YAAYnB,KAAKwD,EAC9B,ECjFA,IAAI6B,EAAQ,oEAEZ,SAASC,EAAsBC,GAC7B9E,KAAK8E,QAAUA,CACjB,CAEAD,EAAsBE,UAAY,IAAIC,MACtCH,EAAsBE,UAAUE,KAAO,wBAEvC,SAASC,EAAUxF,GACjB,IAAIyF,EAAMC,OAAO1F,GAAO2F,QAAQ,MAAO,IACvC,GAAIF,EAAI9F,OAAS,GAAK,EAAG,CACvB,MAAM,IAAIwF,EAAsB,oEACpC,CACE,IAEE,IAAIS,EAAK,EAAGC,EAAIC,EAAQC,EAAM,EAAGC,EAAS,GAE1CF,EAASL,EAAIQ,OAAOF,MAEnBD,IAAWD,EAAKD,EAAK,EAAIC,EAAK,GAAKC,EAASA,EAG3CF,IAAO,GAAKI,GAAUN,OAAOQ,aAAa,IAAML,KAAQ,EAAID,EAAK,IAAM,EACzE,CAEAE,EAASZ,EAAMiB,QAAQL,EAC3B,CACE,OAAOE,CACT,CAGA,IAAAI,SAAwBC,SAAW,aAAeA,OAAOD,MAAQC,OAAOD,KAAKE,KAAKD,SAAWb,ECnC7F,SAASe,EAAiBd,GACxB,OAAOe,mBAAmBJ,EAAKX,GAAKE,QAAQ,QAAQ,SAAUc,EAAGC,GAC/D,IAAIC,EAAOD,EAAEE,WAAW,GAAGC,SAAS,IAAIC,cACxC,GAAIH,EAAKhH,OAAS,EAAG,CACnBgH,EAAO,IAAMA,CACnB,CACI,MAAO,IAAMA,CACjB,IACA,CAEA,IAAAI,EAAiB,SAAStB,GACxB,IAAIO,EAASP,EAAIE,QAAQ,KAAM,KAAKA,QAAQ,KAAM,KAClD,OAAQK,EAAOrG,OAAS,GACtB,KAAK,EACH,MACF,KAAK,EACHqG,GAAU,KACV,MACF,KAAK,EACHA,GAAU,IACV,MACF,QACE,KAAM,4BAGV,IACE,OAAOO,EAAiBP,EAG5B,CAFI,MAAOhE,GACP,OAAOoE,EAAKJ,EAChB,CACA,EC5BA,SAASgB,EAAkB5B,GACzB9E,KAAK8E,QAAUA,CACjB,CAEA4B,EAAkB3B,UAAY,IAAIC,MAClC0B,EAAkB3B,UAAUE,KAAO,oBAEnC,IAAA0B,EAAiB,SAAUC,EAAMC,GAC/B,UAAWD,IAAU,SAAU,CAC7B,MAAM,IAAIF,EAAkB,0BAChC,CAEEG,EAAUA,GAAW,GACrB,IAAIC,EAAMD,EAAQE,SAAW,KAAO,EAAI,EACxC,IACE,OAAOC,KAAKC,MAAMR,EAAkBG,EAAMM,MAAM,KAAKJ,IAGzD,CAFI,MAAOK,GACP,MAAM,IAAIT,EAAkB,4BAA8BS,EAAErC,QAChE,CACA,EAEA,IAAAsC,EAAmCV,E,4BCvBtBW,EAeTtG,YAAoBuG,EAAgBC,EAA6BC,EAAU5G,GACvEZ,KAAKsH,OAASA,EACd,GAAIC,GAAU,MAAQC,GAAO,KAAM,CAC/BxH,KAAKyH,cAAgB,KACrBzH,KAAK0H,aAAeH,EAAOG,aAC3B1H,KAAK2H,SAAWJ,EAAOI,SACvB3H,KAAK4H,WAAaL,EAAOK,WACzB5H,KAAK6H,UAAYN,EAAOM,UAExB7H,KAAKwH,IAAMA,C,KAEV,CACDxH,KAAKyH,cAAgB,MACrBzH,KAAK8H,UAAYlH,C,EAIzBmH,wBAAwBT,EAAgBC,EAA6BC,GACjE,OAAO,IAAIH,EAA2BC,EAAQC,EAAQC,EAAK,K,CAG/DO,2BAA2BT,GACvB,OAAO,IAAID,EAA2BC,EAAQ,KAAM,KAAM,K,CAG9DS,mBAAmBT,EAAgB1G,GAC/B,OAAO,IAAIyG,EAA2BC,EAAQ,KAAM,KAAM1G,E,EC3C3D,MAAMoH,EAASjC,OAAOiC,QAAUjC,OAAO,YAGvC,MAAMkC,EAAUnJ,IACnB,MAAMoJ,EAAM,IAAIC,YAAYrJ,EAAMO,QAClC,MAAM+I,EAAW,IAAIC,WAAWH,GAChC,IAAK,IAAI/I,EAAI,EAAGmJ,EAASxJ,EAAMO,OAAQF,EAAImJ,EAAQnJ,IAAK,CACpDiJ,EAASjJ,GAAKL,EAAMwH,WAAWnH,E,CAEnC,OAAOiJ,CAAQ,EAGZ,MAAMG,EAASC,MAAOC,IACzB,MAAMC,EAAUT,EAAOQ,GACvB,MAAME,QAAaX,EAAOY,OAAOC,OAAO,UAAWH,GACnD,OAAOC,CAAI,EAMR,MAAMG,EAAatD,IACtB,IAAIuD,EAAW,GACf,IAAK,IAAIC,KAAQxD,EAAQ,CACrBuD,GAAYC,EAAKzC,SAAS,IAAI0C,SAAS,EAAG,I,CAE9C,OAAOF,CAAQ,EAGZ,MAAMG,EAAeV,MAAOC,IAC/B,MAAMU,QAAmBZ,EAAOE,GAChC,MAAMW,EAAUN,EAAU,IAAIT,WAAWc,IACzC,OAAOC,IAAO,MAAPA,SAAO,SAAPA,EAASC,aAAa,E,MCZpBC,EACTvI,YACoBwI,GAAAvJ,KAAAuJ,SAmDZvJ,KAAAwJ,aAAgBhE,IACpB,IAAIiD,EAAO,GACX,MAAMgB,EAAc,IAAIpB,WAAW7C,GACnC,IAAK,IAAIwD,KAAQS,EAAa,CAC1BhB,GAAQrD,OAAOQ,aAAaoD,E,CAGhC,OAAOU,KAAKjB,GACPpD,QAAQ,MAAO,KACfA,QAAQ,MAAO,KACfA,QAAQ,KAAM,GAAG,C,CA1D1BmD,6BAA6BmB,EAAqBC,GAC9C,MAAMC,EAAa7J,KAAK8J,sBACxB,MAAMC,EAAe/J,KAAK8J,sBAE1B,MAAMtE,QAAe+C,EAAOwB,GAC5B,MAAMC,EAAiBxE,EAAOzC,QAAUyC,EACxC,MAAMyE,EAAYjK,KAAKwJ,aAAaQ,GAEpC,IAAKC,EAAW,CACZC,QAAQC,KAAK,kEACb,M,CAGJ,MAAMC,QAA8BpK,KAAKqK,0BAA0BrK,KAAKuJ,OAAOe,WAC1E7I,MAAK8H,GAAUA,EAAOgB,yBAE3B,IAAIC,EAAM,GAAGJ,IACT,cAAcpK,KAAKuJ,OAAOkB,WAC1B,UAAUzK,KAAKuJ,OAAOmB,QACtB,sBACA,8BACA,mBAAmBT,IACnB,UAAUJ,IACV,iBAAiBF,IAErB,GAAI3J,KAAKuJ,OAAOoB,SAAU,CACtBH,GAAO,aAAaxK,KAAKuJ,OAAOoB,U,CAGpC,GAAIf,EAAkB,CAClBY,GAAO,IAAIZ,G,CAGf,MAAO,CACHY,MACAT,eACAJ,cACAE,a,CAIAC,sBACJ,MAAMzK,EAAS,GACf,IAAIJ,EAAQ,IAAIoJ,WAAW,EAAW,GACtCL,OAAO4C,gBAAgB3L,GACvB,OAAO6J,EAAU7J,E,CAgBrB4L,4BAA4BC,EAA2BC,EAAkBpB,GACrE,OAAO3J,KAAKgL,SAAS,CACjBC,WAAc,qBACdC,UAAalL,KAAKuJ,OAAOkB,SACzBpE,KAAQyE,EACRK,cAAiBJ,EACjBK,aAAgBzB,G,CAIxB0B,kBAAkBC,GACd,OAAOtL,KAAKgL,SAAS,CACjBC,WAAc,gBACdC,UAAalL,KAAKuJ,OAAOkB,SACzBc,cAAiBD,G,CAIjB9C,eAAegD,GACnB,MAAMC,QAAwBzL,KAAKqK,0BAA0BrK,KAAKuJ,OAAOe,WACzE,MAAMoB,EAAgBD,EAAgBE,eAEtC,MAAMC,EAAWC,OACZC,KAAKN,GACLO,KAAIC,GAAgBC,mBAAmBD,GAAO,IAAMC,mBAAmBT,EAAKQ,MAC5EE,KAAK,KAEV,MAAM3E,QAAe4E,MAAMT,EAAe,CACtCU,OAAQ,OACRC,QAAS,CAAE,eAAgB,qCAC3Bb,KAAMI,IAETnK,MAAK6K,GAAYA,EAASC,SAC1B9K,MAAK8F,GAAUA,IAEhB,OAAOA,C,CAGXiF,sBACI,OAAOxM,KAAKqK,0BAA0BrK,KAAKuJ,OAAOe,WAAW7I,MAAK8H,GAAUA,EAAOkD,mB,CAGvFC,wBACI,OAAO1M,KAAKqK,0BAA0BrK,KAAKuJ,OAAOe,WAAW7I,MAAK8H,GAAUA,EAAOoD,sB,CAGvFC,wBACI,OAAO5M,KAAKqK,0BAA0BrK,KAAKuJ,OAAOe,WAAW7I,MAAK8H,GAAUA,EAAOsD,sB,CAI7ErE,gCAAgC8B,GACtC,IAAKtK,KAAK8M,iBAAkB,CACxB,MAAMR,QAAiBH,MAAM7B,EAAY,qCACzCtK,KAAK8M,iBAAmBR,EAASC,M,CAGrC,OAAOvM,KAAK8M,gB,EC7IpB,MAAMC,EAA+B,IACrC,MAAMC,EAA0B,I,MAEnBC,EAMTlM,YACqBmM,EACAC,EACAC,GAFApN,KAAAkN,SACAlN,KAAAmN,cACAnN,KAAAoN,gCAEjBpN,KAAKsH,OAAStH,KAAKkN,OAAOG,aAAa,c,CAG3C7E,oBACUxI,KAAKsN,oB,CAGP9E,2BACJ,IAAKxI,KAAKkN,SAAWlN,KAAKkN,OAAOK,cAAe,CAC5CrD,QAAQC,KAAK,yEACb,M,CAGJ,MAAMK,QAAYxK,KAAKmN,cACvB,GAAI3C,EAAK,CACLN,QAAQsD,MAAM,0CAA0ChD,KAExDxK,KAAKyN,0BAA4BC,YAAW,KACxCxD,QAAQC,KAAK,gCAAgCnK,KAAKsH,gDAClDtH,KAAKoN,8BAA8B,CAC/BxM,MAAO,uBACP+M,kBAAmB,2DACrB,GACHX,GAEHhN,KAAKkN,OAAOU,IAAMpD,C,EAI1BqD,eAAe/I,GACX,IAAKA,EAAQ2D,MAAQ3D,EAAQgJ,QAAU/H,OAAOgI,SAASD,OAAQ,CAC3D,M,CAGJ,IAAIE,EAAU,MACd,OAAQlJ,EAAQ2D,KAAKwF,MACjB,IAAK,UAAUjO,KAAKsH,qCAChB4C,QAAQgE,KAAK,iDAAiDlO,KAAKsH,UACnE,IACItH,KAAKoN,8BAA8BtI,EAAQ2D,MAC3CuF,EAAU,I,CACZ,MAAOpN,GACLoN,EAAU,I,CAEd,MACJ,IAAK,UAAUhO,KAAKsH,wBAChB4C,QAAQC,KAAK,6CAA6CnK,KAAKsH,SAAUxC,EAAQ2D,MACjFzI,KAAKoN,8BAA8BtI,EAAQ2D,MAC3CuF,EAAU,KACV,MAGR,GAAIA,EAASG,aAAanO,KAAKyN,0B,CAGnCW,gBAAgBC,GACZ,MAAMC,EAAUC,KAAKC,IAAIH,EAAUtB,EAA+B0B,KAAKC,MAAQ,IAAO,GACtFxE,QAAQgE,KAAK,6BAA6B,IAAIO,KAAKA,KAAKC,MAAQJ,UAAgBA,EAAUvB,QAE1FoB,aAAanO,KAAK2O,6BAClB3O,KAAK2O,4BAA8BjB,YAAWlF,gBACpCxI,KAAKsN,oBAAoB,GAChCgB,E,QC5EEM,EAQT7N,YAAYuG,EAAgBmD,GACxBzK,KAAKsH,OAASA,EACdtH,KAAK6O,YAAc,GAAGvH,KAAUmD,kBAChCzK,KAAK8O,UAAY,GAAGxH,KAAUmD,gBAC9BzK,KAAK+O,mBAAqB,GAAGzH,KAAUmD,yB,CAGnCrG,KAAQ4H,EAAalN,GACzBkQ,eAAeC,QAAQjD,EAAKhF,KAAKkI,UAAUpQ,G,CAGvCqQ,KAAQnD,GACZ,OAAOhF,KAAKC,MAAM+H,eAAeI,QAAQpD,G,CAGrCtI,IAAOsI,GACX,MAAMlN,EAAQkQ,eAAeI,QAAQpD,GACrC,GAAIlN,EAAO,CACPkQ,eAAeK,WAAWrD,E,CAG9B,OAAOhF,KAAKC,MAAMnI,E,CAGdwQ,MAAMtD,GACVgD,eAAeK,WAAWrD,E,CAG9BuD,aAAaxE,GACT/K,KAAKoE,KAAKpE,KAAK6O,YAAa9D,E,CAGhCyE,eACI,OAAOxP,KAAKmP,KAAKnP,KAAK6O,Y,CAG1BY,cACI,OAAOzP,KAAK0D,IAAc1D,KAAK6O,Y,CAGnCa,gBACI1P,KAAKsP,MAAMtP,KAAK6O,Y,CAGpBc,WAAWpI,GACPvH,KAAKoE,KAAKpE,KAAK8O,UAAWvH,E,CAG9BqI,aACI,OAAO5P,KAAKmP,KAA0BnP,KAAK8O,U,CAG/Ce,cACI7P,KAAKsP,MAAMtP,KAAK8O,U,CAGpBgB,qBACI9P,KAAKoE,KAAKpE,KAAK+O,mBAAoB,K,CAGvCgB,qBACI,OAAO/P,KAAKmP,KAAcnP,KAAK+O,mB,QCjEjBiB,GAElBjP,YACuBkP,EACAC,EACAC,EACAC,GAHApQ,KAAAiQ,QACAjQ,KAAAkQ,SACAlQ,KAAAmQ,2BACAnQ,KAAAoQ,mB,CAKvB5H,cACI,MAAM6H,EAAkBrQ,KAAKiQ,MAAMF,qBAEnC,GAAIM,EAAiB,CACjB,MAAM9I,EAASvH,KAAKiQ,MAAML,aAC1B5P,KAAKmQ,yBAAyB5I,E,KAC3B,OACGvH,KAAKsQ,mB,EAMT9H,6BAA6BmB,EAAqB4G,GACxDrG,QAAQsD,MAAM,uCAAuCxN,KAAKwQ,oBAC1D,MAAMC,QAAgBzQ,KAAKkQ,OAAOQ,uBAAuB/G,EAAa4G,GACtE,MAAMxF,EAAqB,CACvBhB,aAAc0G,EAAQ1G,aACtBJ,YAAa8G,EAAQ9G,YACrBE,WAAY4G,EAAQ5G,YAExB7J,KAAKiQ,MAAMV,aAAaxE,GAExBb,QAAQsD,MAAM,6BAA6BxN,KAAKiQ,MAAM3I,UAEtD,OAAOmJ,EAAQjG,G,CAGnBhC,kCAAkCmI,GAC9B,MAAM5F,EAAW/K,KAAKiQ,MAAMR,cAC5B,IAAK1E,EAAU,CAEX,OAAO,K,CAGX/K,KAAKiQ,MAAMH,qBAEX,GAAIa,EAAO/P,MAAO,CACdZ,KAAKoQ,kBAAkB,CAAExP,MAAO+P,EAAO/P,MAAO+M,kBAAmBgD,EAAOhD,oBACxE,OAAO,K,KACJ,CACH,MAAMpG,QAAevH,KAAK4Q,WAAWD,EAAQ5F,GAC7C/K,KAAKmQ,yBAAyB5I,GAC9B,OAAO,I,EAIPiB,iBAAiBmI,EAAgC5F,GACrDb,QAAQgE,KAAK,GAAGlO,KAAKwQ,+EAErB,GAAIG,EAAO/P,MAAO,CACdZ,KAAK6Q,aACL,OAAO,I,CAGX,IAAKF,EAAOV,QAAUlF,EAASlB,YAAckB,EAASlB,aAAe8G,EAAOV,MAAO,CAC/EjQ,KAAK6Q,aACL3G,QAAQsD,MAAM,yEAAyExN,KAAKwQ,qBAC5F,OAAO,I,CAGX,MAAMlE,QAAiBtM,KAAKkQ,OAAOrF,4BAA4B8F,EAAOtK,KAAM0E,EAAShB,aAAcgB,EAASpB,aAC5G,GAAI2C,EAAS1L,MAAO,CAChBZ,KAAK6Q,aACL,MAAM,IAAI7L,MAAM,GAAGhF,KAAKwQ,yGAAyGlE,EAAS1L,Q,CAG9I,OAAOZ,KAAK8Q,0BAA0BxE,EAAUqE,EAAOI,c,CAG3DvI,wBAAwB8C,GACpBpB,QAAQgE,KAAK,GAAGlO,KAAKwQ,sEAErB,MAAMlE,QAAiBtM,KAAKkQ,OAAO7E,kBAAkBC,GACrD,GAAIgB,EAAS1L,MAAO,CAChBZ,KAAK6Q,aACL,MAAM,IAAI7L,MAAM,GAAGhF,KAAKwQ,mGAAmGlE,EAAS1L,Q,CAGxI,MAAM2G,QAAevH,KAAK8Q,0BAA0BxE,GACpDtM,KAAKmQ,yBAAyB5I,E,CAGxBiB,gCAAgC8D,EAAyByE,GAC/D,MAAMC,QAAiBhR,KAAKiR,YAAY3E,EAAS5E,cAEjD,MAAMH,EAA8B,CAChCG,aAAc4E,EAAS5E,aACvB6D,cAAee,EAASf,cACxB5D,SAAU2E,EAAS3E,SACnBC,WAAY0E,EAAS1E,WACrBmJ,gBACAlJ,UAAWmJ,GAGfhR,KAAKiQ,MAAMN,WAAWpI,GACtB,OAAOA,C,CAGXiB,wBACI,MAAMjB,EAASvH,KAAKiQ,MAAML,aAC1B,IAAKrI,EAAQ,CACT,OAAO,I,CAGXA,EAAOM,gBAAkB7H,KAAKiR,YAAY1J,EAAOG,cACjD1H,KAAKiQ,MAAMN,WAAWpI,GACtB,OAAOA,C,CAGDiB,kBAAkB0I,GACxB,MAAMC,QAAyBnR,KAAKkQ,OAAO1D,sBAC3C,MAAMwE,QAAiB7E,MAAMgF,EAAkB,CACvC9E,QAAS,CAAE+E,cAAiB,UAAUF,OAEzCzP,MAAK6K,GAAYA,EAASC,SAE/B,OAAOyE,C,CAGXK,YACI,OAAOrR,KAAKiQ,MAAML,Y,CAGtBpH,wBACI,MAAMjB,EAASvH,KAAKiQ,MAAML,aAC1B,IAAKrI,EAAQ,OAEbvH,KAAK6Q,aACL,MAAMS,QAAiBtR,KAAKkQ,OAAOtD,wBAEnC,OAAO0E,EACH,kBAAkB/J,EAAOI,WACzB,6BAA6B3H,KAAKkQ,OAAO3G,OAAOgI,uB,CAGxDV,aACI7Q,KAAKiQ,MAAMJ,cACX7P,KAAKiQ,MAAMP,e,QClJN8B,WAAwCxB,GAGjDjP,YACuBmP,EACAuB,EACAC,EACAC,EACnBxB,EACAC,GAEAnP,MAAM,IAAI2N,EAAoB,iBAAkBsB,EAAO3G,OAAOkB,UAAWyF,GACpE3I,GAAWvH,KAAK4R,+BAA+BrK,EAAQ4I,IACxDC,GATepQ,KAAAkQ,SACAlQ,KAAAyR,oBACAzR,KAAA0R,oBACA1R,KAAA2R,YAQnB3R,KAAK6R,qBAAuB,IAAI5E,EAAqB0E,GACjD,IAAM3R,KAAK8R,yBACVxF,GAAatM,KAAK6K,4BAA4ByB,I,CAGvDkE,iBACI,MAAO,uB,CAGXuB,eAAeC,GACX,MAAMzB,EAAc,IAAI0B,gBACxB1B,EAAY2B,OAAO,aAAcF,GACjC,OAAOhS,KAAK0Q,uBAAuB1Q,KAAKyR,kBAAmBlB,E,CAG/D/H,0BACIxI,KAAK6R,qBAAqBM,O,CAG9BL,uBACI,MAAMvB,EAAc,IAAI0B,gBACxB,OAAOjS,KAAK0Q,uBAAuB1Q,KAAK0R,kBAAmBnB,E,CAG/D6B,sBAAsBC,GAClB,MAAM,IAAIrN,MAAM,4C,CAGpB6I,eAAe/I,GACX9E,KAAK6R,qBAAqBhE,eAAe/I,E,CAGnC0D,kBAAkB0I,GAExB,MAAMoB,EAAcC,EAAWC,UAC/B,MAAMrB,EAAmB,GAAGmB,8CAC5B,MAAMtB,QAAiB7E,MAAMgF,EAAkB,CACvC9E,QAAS,CAAE+E,cAAiB,UAAUF,OAEzCzP,MAAK6K,GAAYA,EAASC,SAE/B,OAAOyE,C,CAGHY,+BAA+BrK,EAAoC4I,GACvE,GAAI5I,EAAQ,CACR,MAAMkL,EAAMC,EAAWnL,EAAOI,UAAU,OACxC3H,KAAK6R,qBAAqBzD,gBAAgBqE,E,KACvC,CACHzS,KAAK6Q,Y,CAGTV,EAAyB5I,E,WCnEjBoL,GAA4B5E,GACxC,MAAM4C,EAAS,IAAIsB,gBAAgBlE,EAAS6E,QAC5C,GAAIjC,EAAOkC,IAAI,SAAWlC,EAAOkC,IAAI,SAAU,CAE3C,MAAO,CACHxM,KAAMsK,EAAOmC,IAAI,QACjB7C,MAAOU,EAAOmC,IAAI,SAClB/B,cAAeJ,EAAOmC,IAAI,iB,MAE3B,GAAInC,EAAOkC,IAAI,SAAU,CAC5B,MAAO,CACHjS,MAAO+P,EAAOmC,IAAI,SAClBnF,kBAAmBgD,EAAOmC,IAAI,qB,CAItC,OAAOzP,SACX,C,SAEgB0P,GAA8BhF,GAC1C,GAAI4E,GAA4B5E,GAAW,CACvC,IAAIvD,EAAMuD,EAASiF,KAAK9L,MAAM,KAAK,GACnCnB,OAAOkN,QAAQC,aAAa,GAAIC,SAASC,MAAO5I,E,CAExD,C,MC/Ba6I,IACcA,GAAAC,eAA6B,iBAC7BD,GAAAE,SAAuB,WAEvBF,GAAAG,MAAQ,QACRH,GAAAI,OAAS,SAETJ,GAAAK,WAAa,aACbL,GAAAM,UAAY,YACZN,GAAAO,SAAW,WAEXP,GAAAQ,iBAAmB,mBACnBR,GAAAS,gBAAkB,kBAClBT,GAAAU,eAAiB,iBAEjBV,GAAAW,wBAA0B,0BCjBrD,MAAMC,GAAyB,2+R,MCiClBC,GAAmB,M,sSAOpBlU,KAAAmU,SAAW,QACXnU,KAAAoU,iBAAmB,KAuHnBpU,KAAAqU,SAAWtO,OAAOuO,WAAW,kBAAkBC,Q,uBAnHjB,M,6DAGb,M,kJAeKxG,SAASD,O,2BAGCC,SAASD,O,eAGP,Q,CAoB1CtF,0BACI,IACI,IAAKxI,KAAKsK,UAAW,CACjB,MAAM,IAAItF,MACN,0D,CAGR,IAAKhF,KAAKyK,SAAU,CAChB,MAAM,IAAIzF,MACN,yD,EAGV,MAAOpE,GACLZ,KAAKwU,kBAAoB,KACzB,MAAM5T,C,EAId4H,yBACIxI,KAAKyU,QAAQC,OAEb1U,KAAK2U,6BAEL,UAAY3U,KAAK4U,sCAAwC,CACrD5U,KAAK6U,sBAAsB1C,O,EASnC3J,cACIxI,KAAK8U,iBAAiBJ,KAAKrB,GAAkBC,gBAC7CvN,OAAOgI,SAASiF,WAAahT,KAAK6U,sBAAsB9C,eACpD/R,KAAKmU,S,CAQb3L,eACIxI,KAAK+U,kBAAkBL,OACvB3O,OAAOgI,SAASiF,WACNhT,KAAK6U,sBAAsBG,iB,CASzCxM,8BACI,MAAMjB,QAAevH,KAAK6U,sBAAsBI,kBAChDjV,KAAKmQ,yBAAyB5I,E,CAQlC2N,0BACI,MAAM3N,EAASvH,KAAK6U,sBAAsBxD,YAC1CrR,KAAKmQ,yBAAyB5I,E,CAMlC4N,WACI,GAAInV,KAAKqU,SAAU,CACfrU,KAAKoV,KAAO,I,EAKpBC,YACI,GAAIrV,KAAKqU,SAAU,CACfrU,KAAKoV,KAAO,K,EAKpBE,eAAeC,GACX,GACIA,EAAMC,yBAAyBC,MAC/BzV,KAAK0V,UAAUC,SAASJ,EAAMC,eAChC,CACE,M,CAEJxV,KAAKoV,KAAO,K,CAIhB5M,oBAAoB1D,G,QAChB,KACI8Q,GAAAC,EAAA/Q,EAAQ2D,QAAI,MAAAoN,SAAA,SAAAA,EAAE5H,QAAI,MAAA2H,SAAA,SAAAA,EAAE/P,QAChB,UAAUwN,GAAkBC,oBAC3B,EACP,CACEtT,KAAK6U,sBAAsBhH,eAAe/I,E,EAKlDgR,e,MACI,MAAMC,GAAcF,EAAA7V,KAAK0V,UAAUM,cAAU,MAAAH,SAAA,SAAAA,EAAEI,cAC3C,4BAGJ,GAAIF,EAAa,CACb/V,KAAKkW,oBAAoBH,E,EAIzBpB,6BACJ,MAAMwB,EAAyB,CAC3B7L,UAAWtK,KAAKsK,UAChBG,SAAUzK,KAAKyK,SACfC,MAAO,uBACP6G,sBAAuBvR,KAAKuR,uBAGhC,MAAMrB,EAAS,IAAI5G,EAAa6M,GAChCnW,KAAK6U,sBAAwB,IAAIrD,GAC7BtB,EACAlQ,KAAK2J,YACL3J,KAAKoW,gBACLpW,KAAK2R,WACJpK,GAAWvH,KAAKmQ,yBAAyB5I,KACzC3G,GAAUZ,KAAKoQ,kBAAkBxP,I,CAIlC4H,4CACJ,MAAMmI,EAASgC,GAA4B5M,OAAOgI,UAClD,IAAK4C,EAAQ,CACTzG,QAAQsD,MAAM,yCACd,OAAO,K,CAGX,MAAM6I,QACIrW,KAAK6U,sBAAsBhK,4BAC7B8F,GAGRoC,GAA8BhN,OAAOgI,UAErC,OAAOsI,C,CAGHlG,yBAAyB5I,GAC7BvH,KAAKsW,gBAAkB,KACvB,GAAI/O,GAAU,KAAM,CAChB2C,QAAQsD,MAAM,4BAEdxN,KAAKuW,SAAW,MAChBvW,KAAKiF,KAAO5B,UAEZrD,KAAKwW,+BAA+B9B,KAChCrN,EAA2BoP,oBACvBpD,GAAkBC,gB,KAGvB,CACHpJ,QAAQsD,MAAM,2BAEdxN,KAAKuW,SAAW,KAChBvW,KAAKiF,KAAOsC,EAAOM,UAAU,cAE7B,MAAM6O,EAAUhE,EAAWnL,EAAOI,UAClC3H,KAAKwW,+BAA+B9B,KAChCrN,EAA2BsP,iBACvBtD,GAAkBC,eAClB/L,EACAmP,G,EAMRtG,kBAAkBtI,GACtBoC,QAAQsD,MAAM,wCAAyC1F,GAEvD9H,KAAKsW,gBAAkB,KACvBtW,KAAKuW,SAAW,MAChBvW,KAAKiF,KAAO5B,UAEZrD,KAAKwW,+BAA+B9B,KAChCrN,EAA2BuP,YACvBvD,GAAkBC,eAClBxL,G,CAKJoO,oBAAoBW,GACxB,IAAKA,EAAS,CACV,M,CAGJ,MAAMC,EAAOD,EAAQE,wBACrB,MAAMC,EAAQH,EAAQG,MAEtB,GAAIF,EAAKG,MAAQlR,OAAOmR,WAAY,CAChC,MAAMC,EAAYL,EAAKG,MAAQlR,OAAOmR,WACtCF,EAAMI,KAAO,IAAIP,EAAQQ,WAAaF,K,CAG1C,GAAIL,EAAKM,KAAO,EAAG,CACfJ,EAAMI,KAAO,GAAGP,EAAQQ,WAAa,EAAIP,EAAKM,SAE9CP,EAAQS,UAAUvX,IAAI,c,EAItBwX,uBAGJ,MAAMC,EAAOxX,KAAKwX,KAAKC,cAClBC,QAAQxV,IAAUA,EAAKyV,aACvBD,QAAQxV,GAASA,EAAK0V,SAAW5X,KAAKoU,mBACtCyD,OAAO7X,KAAK8X,cAAcC,aAE/B,OAAOP,C,CAGHQ,a,MACJhY,KAAKoV,MAAQpV,KAAKoV,KAElB,GAAIpV,KAAKoV,KAAM,CACX,MAAMW,GAAcF,EAAA7V,KAAK0V,UAAUM,cAAU,MAAAH,SAAA,SAAAA,EAAEI,cAC3C,4BAEJ,GAAIF,EAAa,CACb/V,KAAKkW,oBAAoBH,E,GAK7BkC,kBACJ,OAAOjY,KAAKuW,UAAYvW,KAAKiF,OAAS,KAChCjF,KAAKiF,KACLjF,KAAKwX,KAAKC,cAAcS,MACnBC,GAAaA,EAASR,aAAe,UACxCS,I,CAGJC,aACJ,GACIrY,KAAK8X,cAAcQ,eAAiBjF,GAAkBC,eACxD,CACE,M,CAGJ,OAAOtT,KAAKuY,YAAc,UACpBvY,KAAKwY,oBACLxY,KAAKyY,kB,CAGPD,oBACJ,MAAMjC,EACFmC,EAAA,OAAKC,GAAG,wBAAwBC,MAAM,iBAClCF,EAAA,QAAME,MAAM,uBACP5Y,KAAKiY,oBAKlB,MAAMY,EACFH,EAAA,OAAKC,GAAG,wBAAwBC,MAAM,iBAClCF,EAAA,UACIzK,KAAK,SACL6K,QAAS,IAAM9Y,KAAK+Y,QACpBH,MAAM,oEAENF,EAAA,QAAME,MAAM,kCACP5Y,KAAKiY,qBAMtB,OAAOjY,KAAKuW,SAAWA,EAAWsC,C,CAG9BJ,mBACJ,OACIC,EAAA,OAAKC,GAAG,wBAAwBC,MAAM,4BAClCF,EAAA,UACIzK,KAAK,SACL2K,MAAM,uDACNE,QAAS,IAAM9Y,KAAKgY,aAAY,gBAClB,0BAAyB,gBACxBhY,KAAKoV,KAAO,OAAS,SAEpCsD,EAAA,QAAME,MAAM,oBACP5Y,KAAKiY,mBAEVS,EAAA,KAAGE,MAAM,mBAAmBI,UAAWC,EAAOC,YAElDR,EAAA,2BACIS,UAAWnZ,KAAKuX,uBAChBnC,KAAMpV,KAAKoV,KACXgE,mBAAqB7D,GACjBvV,KAAKqZ,kBAAkB3E,KAAKa,EAAM+D,U,CAO9CC,wBACJ,GACIvZ,KAAK8X,cAAcQ,eAAiBjF,GAAkBC,eACxD,CACE,OAAOoF,EAAA,W,CAEX,OAAOA,EAAA,iB,CAGXc,SACI,GAAIxZ,KAAKwU,kBAAmB,CACxB,M,CAEJ,OACIkE,EAAA,YACM1Y,KAAKsW,gBACDtW,KAAKuZ,wBACLvZ,KAAKqY,aACXK,EAAA,UACIe,OAAM,KACNrG,MAAM,qBACNxF,IAAK5N,KAAKoW,gBAAe,cACZ/C,GAAkBC,eAC/BoG,IAAMC,GAAQ3Z,KAAK2R,UAAYgI,I,oDC7atCC,GAGT7Y,YACqB8Y,GAAA7Z,KAAA6Z,kB,CAGrBzL,gBAAgBC,GACZ,MAAMC,EAAUC,KAAKC,IAAIH,EAAU,IAAOI,KAAKC,MAAQ,IAAO,GAE9DxE,QAAQgE,KAAK,oCAAoC,IAAIO,KAAKA,KAAKC,MAAQJ,UAAgBA,EAAU,UAEjGH,aAAanO,KAAK8Z,yBAClB9Z,KAAK8Z,wBAA0BpM,YAAWlF,gBAChCxI,KAAK6Z,kBAAkB,GAC9BvL,E,QCLEyL,WAAoC/J,GAI7CjP,YACuBmP,EACAuB,EACAuI,EACAtI,EACAC,EACnBxB,EACAC,GAEAnP,MAAM,IAAI2N,EAAoB,SAAUsB,EAAO3G,OAAOkB,UAAWyF,GAC5D3I,GAAWvH,KAAK4R,+BAA+BrK,EAAQ4I,IACxDC,GAVepQ,KAAAkQ,SACAlQ,KAAAyR,oBACAzR,KAAAga,kBACAha,KAAA0R,oBACA1R,KAAA2R,YAQnB,GAAI3R,KAAK2R,UAAW,CAChB3R,KAAK6R,qBAAuB,IAAI5E,EAAqB0E,GACjD,IAAM3R,KAAK8R,yBACVxF,GAAatM,KAAK6K,4BAA4ByB,I,CAGvD,IAAKtM,KAAKia,eAAgB,CACtB/P,QAAQgE,KAAK,oDACblO,KAAKka,sBAAwB,IAAIN,IAAsB,IAAM5Z,KAAK6Z,oB,KAC/D,CACH3P,QAAQgE,KAAK,wD,EAIb+L,eACJ,MAAME,EAAWC,IACb,IAAIC,EAAU,IAAIC,IAAIta,KAAKkQ,OAAO3G,OAAOe,WAAWiQ,SACpD,IAAIC,EAAczU,OAAOgI,SAASwM,SAClC,OAAOF,EAAQI,SAASL,IAAQI,EAAYC,SAASL,EAAI,EAG7D,OAAOD,EAAQ,eAAiBA,EAAQ,a,CAG5C3J,iBACI,MAAO,gC,CAGXuB,eAAeC,GACX,MAAMzB,EAAc,IAAI0B,gBACxB1B,EAAY2B,OAAO,aAAcF,EAAO3M,QAAQ,IAAK,MACrDrF,KAAK0a,UAAUnK,GAEf,OAAOvQ,KAAK0Q,uBAAuB1Q,KAAKyR,kBAAmBlB,E,CAG/D/H,0BACI,GAAIxI,KAAK6R,qBAAsB,CAE3B7R,KAAK6R,qBAAqBM,O,KACvB,CAEHnS,KAAKga,kBAEL,MAAMxP,QAAYxK,KAAK8R,uBACvB/L,OAAOgI,SAASiF,KAAOxI,C,EAI/BsH,uBACI,MAAMvB,EAAc,IAAI0B,gBACxB1B,EAAY2B,OAAO,SAAU,QAC7BlS,KAAK0a,UAAUnK,GAEf,MAAMoK,EAAc3a,KAAK6R,qBAAuB7R,KAAK0R,kBAAoB1R,KAAKyR,kBAE9E,OAAOzR,KAAK0Q,uBAAuBiK,EAAapK,E,CAGpD6B,sBAAsBJ,GAClB,MAAMzB,EAAc,IAAI0B,gBACxB1B,EAAY2B,OAAO,aAAcF,EAAO3M,QAAQ,IAAK,MACrDkL,EAAY2B,OAAO,SAAU,UAC7BlS,KAAK0a,UAAUnK,GAEf,OAAOvQ,KAAK0Q,uBAAuB1Q,KAAKyR,kBAAmBlB,E,CAGvDmK,UAAU/J,GAEdA,EAAOuB,OAAO,SAAU,mC,CAG5BrE,eAAe/I,GACX9E,KAAK6R,qBAAqBhE,eAAe/I,E,CAGrC0D,yB,MACJ,MAAM8C,GAAeuK,EAAA7V,KAAKiQ,MAAML,gBAAY,MAAAiG,SAAA,SAAAA,EAAEtK,cAC9C,IAAKD,EAAc,CACfpB,QAAQC,KAAK,4CACb,M,CAGJnK,KAAKqL,kBAAkBC,E,CAGjB9C,kBAAkB0I,GACxB,MAAMF,QAAiB/P,MAAMgQ,YAAYC,GAEzC,GAAIF,EAAS4J,MAAO,CAChB5J,EAAS6J,mBAAqB3R,EAAa8H,EAAS4J,M,CAUxD,MAAME,EAAY9J,EAAS,eAAiBA,EAASnR,IACrD,GAAIib,EAAW,CACX,MAAMnS,QAAaO,EAAa4R,GAChC9J,EAAS+J,WAAapS,EACtBqI,EAASgK,kBAAoBrS,C,CAGjC,OAAOqI,C,CAGXxI,wBACIvH,MAAM+T,kBAGN,OAAO,IAAIiG,SAAgB,CAACC,EAAS7I,KACjC,MAAM8I,EAAqBnb,KAAKkQ,OAAO3G,OAAOe,UAAUjF,QAAQ,oBAAqB,oBACjF,cAAcrF,KAAKkQ,OAAO3G,OAAOkB,WACjC,iBAAiBzK,KAAKkQ,OAAO3G,OAAOgI,wBACxC2J,EAAQC,EAAmB,G,CAI3BvJ,+BAA+BrK,EAAoC4I,GACvE,GAAI5I,IAAM,MAANA,SAAM,SAANA,EAAQgE,cAAe,CACvB,MAAMkH,EAAMC,EAAWnL,EAAOG,cAAc,OAE5C,GAAI1H,KAAKka,sBAAuB,CAC5Bla,KAAKka,sBAAsB9L,gBAAgBqE,E,KACxC,CACHzS,KAAK6R,qBAAqBzD,gBAAgBqE,E,OAE3C,IAAKlL,EAAQ,CAChBvH,KAAK6Q,Y,CAGTV,EAAyB5I,E,QCjKpB6T,GAKTra,YACqBmM,EACAgD,EACAmL,EACAC,GAHAtb,KAAAkN,SACAlN,KAAAkQ,SACAlQ,KAAAqb,kBACArb,KAAAsb,gBANbtb,KAAAub,WAAsB,I,CAS9B/S,cACI,IAAKxI,KAAKsb,cAAe,OAEzB,MAAME,QAA2Bxb,KAAKkQ,OAAOxD,wBAC7C,IAAK8O,EAAoB,CACrBtR,QAAQtJ,MAAM,mEACd,M,CAGJ6a,cAAczb,KAAK0b,4BACnB1b,KAAKkN,OAAOU,IAAM4N,EAClBxb,KAAKub,WAAa,KAElB,MAAMI,EAAW,IACjBzR,QAAQsD,MAAM,yCAAyCmO,OACvD3b,KAAK0b,2BAA6BE,aAAY,IAAM5b,KAAK6b,gBAAgBF,E,CAGrEE,e,MACJ,MAAMC,EAAe9b,KAAKqb,kBAC1B,IAAKS,EAAc,CACf,M,CAGJ,MAAMhX,EAAU,GAAG9E,KAAKkQ,OAAO3G,OAAOkB,YAAYqR,KAClDjG,EAAA7V,KAAKkN,OAAOK,iBAAa,MAAAsI,SAAA,SAAAA,EAAEkG,YAAYjX,EAAS9E,KAAKkQ,OAAO3G,OAAOe,U,CAGvEuD,eAAe/I,GACX,IAAKA,EAAQ2D,MAAQ3D,EAAQgJ,QAAU,IAAIwM,IAAIta,KAAKkQ,OAAO3G,OAAOe,WAAWwD,OAAQ,CACjF,M,CAGJ,GAAIhJ,EAAQ2D,OAAS,UAAW,CAC5BgT,cAAczb,KAAK0b,4BAEnB,GAAI1b,KAAKub,WAAY,CAIjBrR,QAAQC,KAAK,2J,KACV,CACHD,QAAQsD,MAAM,0EACdxN,KAAKsb,e,EAIbtb,KAAKub,WAAa,K,QCpDbS,WAAsChM,GAI/CjP,YACuBmP,EACAuB,EACAC,EACAC,EACAsK,EACnB9L,EACAC,GAEAnP,MAAM,IAAI2N,EAAoB,WAAYsB,EAAO3G,OAAOkB,UAAWyF,GAC9D3I,GAAWvH,KAAK4R,+BAA+BrK,EAAQ4I,IACxDC,GAVepQ,KAAAkQ,SACAlQ,KAAAyR,oBACAzR,KAAA0R,oBACA1R,KAAA2R,YACA3R,KAAAic,qBAQnBjc,KAAK6R,qBAAuB,IAAI5E,EAAqB0E,GACjD,IAAM3R,KAAK8R,yBACVxF,GAAatM,KAAK6K,4BAA4ByB,KAEnDtM,KAAKkc,sBAAwB,IAAId,GAAsBpb,KAAKic,mBAAoB/L,GAAQ,IAAMlQ,KAAKqb,oBAAmB,IAAMrb,KAAKmQ,yBAAyB,O,CAGtJkL,kB,MACJ,OAAOxF,EAAA7V,KAAKiQ,MAAML,gBAAY,MAAAiG,SAAA,SAAAA,EAAE9E,a,CAGpCP,iBACI,MAAO,iB,CAGXuB,eAAeC,GACX,MAAMzB,EAAc,IAAI0B,gBACxB1B,EAAY2B,OAAO,YAAaF,GAEhC,OAAOhS,KAAK0Q,uBAAuB1Q,KAAKyR,kBAAmBlB,E,CAG/D/H,0BACIxI,KAAK6R,qBAAqBM,O,CAG9BL,uBACI,MAAMvB,EAAc,IAAI0B,gBACxB1B,EAAY2B,OAAO,SAAU,QAC7B,OAAOlS,KAAK0Q,uBAAuB1Q,KAAK0R,kBAAmBnB,E,CAG/D6B,sBAAsBC,GAClB,MAAM,IAAIrN,MAAM,sG,CAGpB6I,eAAe/I,GACX9E,KAAK6R,qBAAqBhE,eAAe/I,GACzC9E,KAAKkc,sBAAsBrO,eAAe/I,E,CAGtC8M,+BAA+BrK,EAAoC4I,GACvE,GAAI5I,EAAQ,CACR,MAAMkL,EAAMC,EAAWnL,EAAOG,cAAc,OAC5C1H,KAAK6R,qBAAqBzD,gBAAgBqE,GAC1CzS,KAAKkc,sBAAsBC,O,KACxB,CACHnc,KAAK6Q,Y,CAGTV,EAAyB5I,E,EC5EjC,MAAM6U,GAAyB,2vV,MCmClBC,GAAmB,M,sSAQXrc,KAAAsc,kBAAoB,CAAC,MAAO,QAsKrCtc,KAAAqU,SAAWtO,OAAOuO,WAAW,kBAAkBC,QAC/CvU,KAAAuc,YAAcxW,OAAOmR,W,uBAnKS,M,6DAIb,M,4GAYE,W,+KAqBGnJ,SAASD,O,2BAGCC,SAASD,O,eAGP,Q,CAoB1CtF,0BACI,IACI,IAAKxI,KAAKsK,UAAW,CACjB,MAAM,IAAItF,MAAM,2C,CAEpB,IAAKhF,KAAKyK,SAAU,CAChB,MAAM,IAAIzF,MAAM,0C,EAEtB,MAAOpE,GACLZ,KAAKwU,kBAAoB,KACzB,MAAM5T,C,EAId4H,yBACIxI,KAAKyU,QAAQC,OAEb1U,KAAK2U,6BAEL,UAAY3U,KAAK4U,sCAAwC,CACrD5U,KAAK6U,sBAAsB1C,O,EAKnCmD,eAAeC,GACX,GACIA,EAAMC,yBAAyBC,MAC/BzV,KAAK0V,UAAUC,SAASJ,EAAMC,eAChC,CACE,M,CAEJxV,KAAKoV,KAAO,K,CAIhB5M,oBAAoB1D,G,QAChB,KACI8Q,GAAAC,EAAA/Q,EAAQ2D,QAAI,MAAAoN,SAAA,SAAAA,EAAE5H,QAAI,MAAA2H,SAAA,SAAAA,EAAE/P,QAChB,UAAUwN,GAAkBE,cAC3B,EACP,CACEvT,KAAK6U,sBAAsBhH,eAAe/I,E,EAOlD0D,cACIxI,KAAK8U,iBAAiBJ,KAAKrB,GAAkBE,UAC7CxN,OAAOgI,SAASiF,WAAahT,KAAK6U,sBAAsB9C,eACpD/R,KAAKmU,S,CAOb3L,0BACIxI,KAAK8U,iBAAiBJ,KAAKrB,GAAkBE,UAC7CxN,OAAOgI,SAASiF,WACNhT,KAAK6U,sBAAsBzC,sBAC7BpS,KAAKmU,S,CAOjB3L,mBACIxI,KAAK6U,sBAAsBhE,Y,CAM/BrI,eACIxI,KAAK+U,kBAAkBL,OACvB3O,OAAOgI,SAASiF,WACNhT,KAAK6U,sBAAsBG,iB,CAMzCxM,8BACI,MAAMjB,QAAevH,KAAK6U,sBAAsBI,kBAChDjV,KAAKmQ,yBAAyB5I,E,CAMlC2N,0BACI,MAAM3N,EAASvH,KAAK6U,sBAAsBxD,YAC1CrR,KAAKmQ,yBAAyB5I,E,CAOlC4N,WACI,GAAInV,KAAKuc,YAAc,KAAOvc,KAAKqU,SAAU,CACzCrU,KAAKoV,KAAO,I,EAKpBC,YACI,GAAIrV,KAAKuc,YAAc,KAAOvc,KAAKqU,SAAU,CACzCrU,KAAKoV,KAAO,K,EAKpBoH,QAAQjH,GACJ,GACIA,EAAMC,yBAAyBC,MAC/BzV,KAAK0V,UAAUC,SAASJ,EAAMC,eAChC,CACE,M,CAGJ,GAAIxV,KAAKoV,OAASpV,KAAKqU,SAAU,CAC7BrU,KAAKgY,Y,EAKblC,e,MACI,MAAMC,GAAcF,EAAA7V,KAAK0V,UAAUM,cAAU,MAAAH,SAAA,SAAAA,EAAEI,cAC3C,4BAGJ,GAAIF,EAAa,CACb/V,KAAKkW,oBAAoBH,E,EAIzBpB,6BACJ,MAAMwB,EAAyB,CAC3B7L,UAAWtK,KAAKsK,UAChBG,SAAUzK,KAAKyK,SACfE,SACI,oBAAsB3K,KAAK2K,SAAW,IAAI3K,KAAK2K,WAAa,IAChED,MACI,yCACC1K,KAAK0K,MAAQ,IAAI1K,KAAK0K,QAAU,IACrC6G,sBAAuBvR,KAAKuR,uBAEhC,MAAMrB,EAAS,IAAI5G,EAAa6M,GAEhCnW,KAAK6U,sBACD7U,KAAKyc,UAAY,WACX,IAAIT,GACA9L,EACAlQ,KAAK2J,YACL3J,KAAKoW,gBACLpW,KAAK2R,UACL3R,KAAKic,oBACJ1U,GAAWvH,KAAKmQ,yBAAyB5I,KACzC3G,GAAUZ,KAAKoQ,kBAAkBxP,KAEtC,IAAImZ,GACA7J,EACAlQ,KAAK2J,aACL,IACI3J,KAAK8U,iBAAiBJ,KAClBrB,GAAkBE,WAE1BvT,KAAKoW,gBACLpW,KAAK2R,WACJpK,GAAWvH,KAAKmQ,yBAAyB5I,KACzC3G,GAAUZ,KAAKoQ,kBAAkBxP,I,CAI5C4H,4CACJ,MAAMmI,EAASgC,GAA4B5M,OAAOgI,UAClD,IAAK4C,EAAQ,CACTzG,QAAQsD,MAAM,yCACd,OAAO,K,CAGX,MAAM6I,QACIrW,KAAK6U,sBAAsBhK,4BAC7B8F,GAGRoC,GAA8BhN,OAAOgI,UAErC,OAAOsI,C,CAGHlG,yBAAyB5I,GAC7BvH,KAAKsW,gBAAkB,KACvB,GAAI/O,GAAU,KAAM,CAChB2C,QAAQsD,MAAM,uBAEdxN,KAAKuW,SAAW,MAChBvW,KAAKiF,KAAO5B,UAEZrD,KAAKwW,+BAA+B9B,KAChCrN,EAA2BoP,oBACvBpD,GAAkBE,U,KAGvB,CACHrJ,QAAQsD,MAAM,sBAEdxN,KAAKuW,SAAW,KAChBvW,KAAKiF,KAAOsC,EAAOM,UAAU,cAE7B,MAAMqJ,EAAcwB,EAAWnL,EAAOG,cACtC1H,KAAKwW,+BAA+B9B,KAChCrN,EAA2BsP,iBACvBtD,GAAkBE,SAClBhM,EACA2J,G,EAMRd,kBAAkBtI,GACtBoC,QAAQsD,MAAM,gCAAiC1F,GAE/C9H,KAAKsW,gBAAkB,KACvBtW,KAAKuW,SAAW,MAChBvW,KAAKiF,KAAO5B,UAEZrD,KAAKwW,+BAA+B9B,KAChCrN,EAA2BuP,YACvBvD,GAAkBE,SAClBzL,G,CAKJoO,oBAAoBW,GACxB,IAAKA,EAAS,CACV,M,CAGJ,MAAMC,EAAOD,EAAQE,wBACrB,MAAMC,EAAQH,EAAQG,MAEtB,GAAIF,EAAKG,MAAQlR,OAAOmR,WAAY,CAChC,MAAMC,EAAYL,EAAKG,MAAQlR,OAAOmR,WACtCF,EAAMI,KAAO,IAAIP,EAAQQ,WAAaF,K,CAG1C,GAAIL,EAAKM,KAAO,EAAG,CACfJ,EAAMI,KAAO,GAAGP,EAAQQ,WAAa,EAAIP,EAAKM,Q,EAI9CG,uBAGJ,IAAIC,EAAOxX,KAAKwX,KAAKC,cAChBC,QAAQxV,IAAUA,EAAKyV,aACvBD,QAAQxV,GAASlC,KAAKsc,kBAAkBI,SAASxa,EAAK0V,UACtDC,OAAO7X,KAAK8X,cAAcC,aAC/B,OAAOP,C,CAGHQ,a,MACJhY,KAAKoV,MAAQpV,KAAKoV,KAElB,GAAIpV,KAAKoV,KAAM,CACX,MAAMW,GAAcF,EAAA7V,KAAK0V,UAAUM,cAAU,MAAAH,SAAA,SAAAA,EAAEI,cAC3C,4BAGJ,GAAIF,EAAa,CACb/V,KAAKkW,oBAAoBH,E,GAK7BkC,kBACJ,OAAOjY,KAAKuW,UAAYvW,KAAKiF,OAAS,KAChCjF,KAAKiF,KACLjF,KAAKwX,KAAKC,cAAcS,MACnBC,GAAaA,EAASR,aAAetE,GAAkBG,QAC1D4E,I,CAGJC,aACJ,GAAIrY,KAAK8X,cAAcQ,eAAiBjF,GAAkBE,SAAU,CAChE,M,CAGJ,OAAOvT,KAAKuY,YAAc,UACpBvY,KAAKwY,oBACLxY,KAAKyY,kB,CAGPD,oBACJ,MAAMjC,EACFmC,EAAA,OACIC,GAAG,wBACHC,MAAM,uDAENF,EAAA,UACIzK,KAAK,SACL2K,MAAM,uDACNE,QAAS,IAAM9Y,KAAKgY,aAAY,gBAClB,wBAAuB,gBACtBhY,KAAKoV,KAAO,OAAS,SAEnCpV,KAAKiY,kBACNS,EAAA,KAAGE,MAAM,mBAAmBI,UAAWC,EAAOC,YAElDR,EAAA,OAAKE,OAAQ5Y,KAAKoV,KAAO,YAAc,cACnCsD,EAAA,MAAIC,GAAG,wBAAwBC,MAAM,oBACjCF,EAAA,MAAIE,MAAM,yBACNF,EAAA,UACIE,MAAM,aACNE,QAAS,IAAM9Y,KAAK2c,UAAQ,iBAUpD,MAAM9D,EACFH,EAAA,OACIC,GAAG,wBACHC,MAAM,iDAENF,EAAA,UACIzK,KAAK,SACL6K,QAAS,IAAM9Y,KAAKgY,aAAY,gBACjBhY,KAAKoV,KAAO,OAAS,QACpCwD,MAAM,wDAEL5Y,KAAKiY,kBACNS,EAAA,KAAGE,MAAM,mBAAmBI,UAAWC,EAAOC,YAElDR,EAAA,OAAKE,OAAQ5Y,KAAKoV,KAAO,YAAc,cACnCsD,EAAA,MAAIC,GAAG,wBAAwBC,MAAM,oBACjCF,EAAA,MAAIE,MAAM,yBACNF,EAAA,UACIE,MAAM,aACNE,QAAS,IAAM9Y,KAAK+Y,SAAO,aAKnCL,EAAA,MAAIE,MAAM,yBACNF,EAAA,UACIE,MAAM,kCACNE,QAAS,IAAM9Y,KAAK4c,qBAAmB,mBAGvClE,EAAA,OACImE,MAAM,6BACNC,MAAM,KACNC,OAAO,KACP/F,MAAO,CACHgG,MAAO,YAGXtE,EAAA,QACIuE,EAAE,4MACFjG,MAAO,CACHkG,OAAQ,OACR,YAAa,UACbC,KAAM,eACN,eAAgB,aAWpD,OAAOnd,KAAKuW,SAAWA,EAAWsC,C,CAG9BJ,mBACJ,OACIC,EAAA,OAAKC,GAAG,wBAAwBC,MAAM,4BAClCF,EAAA,UACIzK,KAAK,SACL2K,MAAM,uDACNE,QAAS,IAAM9Y,KAAKgY,aAAY,gBAClB,0BAAyB,gBACxBhY,KAAKoV,KAAO,OAAS,SAEnCpV,KAAKiY,kBACNS,EAAA,KAAGE,MAAM,mBAAmBI,UAAWC,EAAOC,YAElDR,EAAA,2BACIS,UAAWnZ,KAAKuX,uBAChBnC,KAAMpV,KAAKoV,KACXgE,mBAAqB7D,GACjBvV,KAAKqZ,kBAAkB3E,KAAKa,EAAM+D,U,CAO9CC,wBACJ,GAAIvZ,KAAK8X,cAAcQ,eAAiBjF,GAAkBE,SAAU,CAChE,OAAOmF,EAAA,W,CAEX,OAAOA,EAAA,iB,CAGXc,SACI,GAAIxZ,KAAKwU,kBAAmB,CACxB,M,CAGJ,OACIkE,EAAA,kCAA+B1Y,KAAKod,oBAC9Bpd,KAAKsW,gBACDtW,KAAKuZ,wBACLvZ,KAAKqY,aACVrY,KAAKoW,iBACFsC,EAAA,UACItF,MAAM,sBACNqG,OAAM,KACN7L,IAAK5N,KAAKoW,gBAAe,cACZ/C,GAAkBE,SAC/BmG,IAAMC,GAAQ3Z,KAAK2R,UAAYgI,IAGvCjB,EAAA,UACIe,OAAM,KACNrG,MAAM,gBACNsG,IAAMC,GAAQ3Z,KAAKic,mBAAqBtC,I,8CCziB5D,MAAM0D,GAAyB,orP,MCgBlBC,GAAgB,M,0EACzBtd,KAAAgY,WAAczC,IACVvV,KAAKoV,MAAQpV,KAAKoV,KAClBG,EAAMgI,0BAA0B,EAGpCvd,KAAAwd,mBAAsBxL,GAClB0G,EAAA,MAAIE,MAAM,yBACNF,EAAA,UACIzK,KAAK,SACL2K,MAAM,kCACNE,QAAS,IAAM9Y,KAAKyd,aAAazL,IAEhChS,KAAK0d,WAAW1L,KAK7BhS,KAAA0d,WAAc1L,GAAmBA,EAAO9K,MAAM,KAAK,G,0EAanDoO,eAAeC,GACX,GACIA,EAAMC,yBAAyBC,MAC/BzV,KAAK0V,UAAUC,SAASJ,EAAMC,eAChC,CACE,M,CAEJxV,KAAKoV,KAAO,K,CAGhBqI,aAAazL,GACThS,KAAK2d,gBAAgBjJ,KAAK1C,GAE1B,MAAM4L,EAAW5L,EAAO3M,QAAQ,IAAK,KACrC8N,SAAS8C,cAAc,QAAQ4H,aAAa,OAAQD,GAEpD5d,KAAKoV,KAAO,K,CAGhBoE,SACI,MAAMsE,EAAU9d,KAAK+d,iBAAiB7W,MAAM,KAC5C,GAAI4W,EAAQze,QAAU,EAAG,CACrB,M,CAGJ,OACIqZ,EAAA,OAAKE,MAAM,oCACPF,EAAA,UACIzK,KAAK,SACL2K,MAAM,sDACNE,QAAS9Y,KAAKgY,WAAU,gBACV,wBAAuB,gBACtBhY,KAAKoV,KAAO,OAAS,SAEnCpV,KAAK0d,WAAW1d,KAAKgS,QAEtB0G,EAAA,OACIE,MAAM,mBACNI,UAAWC,EAAOC,YAG1BR,EAAA,MAAIE,MAAM,mBAAmBa,QAASzZ,KAAKoV,MACtC0I,EAAQ/R,IAAI/L,KAAKwd,qB,oDCzEzBQ,GACTjd,YACoBuX,EACAP,GADA/X,KAAAsY,eACAtY,KAAA+X,a,CAEpBhQ,qBACI,OAAO,IAAIiW,GAAc3a,UAAW,G,ECtB5C,MAAM4a,GAAiB,0jN,MCwBVC,GAAW,M,iOACZle,KAAAme,yBAAoC,MACpCne,KAAAoe,yBAAoC,MAEpCpe,KAAAqe,cAAgB,IAAIC,EACpBte,KAAAue,eAAiB,IAAID,EACrBte,KAAAwe,qBAAuB,IAAIF,EAC3Bte,KAAAye,iBAAmB,IAAIH,E,uBAKO,M,sEAGJ,M,mBACMN,GAAcU,c,oPA8BxB3Q,SAASD,O,2BAGCC,SAASD,O,oEASP,Q,CAI1CtF,iBACI,GAAIxI,KAAK2e,QAAU3e,KAAKmU,SAAU,CAC9BnU,KAAKwX,WAAaoH,EAAc5e,KAAK2e,OAAQ3e,KAAKmU,S,CAEtDnU,KAAKye,iBAAiBlf,M,CAgB1BiJ,0BACI,IACI,IAAKxI,KAAKsK,YAActK,KAAK6e,YACzB,MAAM,IAAI7Z,MACN,gEAGRhF,KAAKme,yBAA2Bne,KAAKsK,YAAcjH,UACnDrD,KAAKoe,yBAA2Bpe,KAAK6e,cAAgBxb,UAErDE,EAAc,CACVvD,KAAKqe,cACLre,KAAKue,eACLve,KAAKwe,qBACLxe,KAAKye,mBACNhc,WAAWyB,IACV,MAAMoU,EACFpU,EAAO,KAAO,UACPA,EAAO,GACRmP,GAAkBE,SAC5B,MAAMuL,EAAe5a,EAAO,GAC5B,MAAM6a,EAAqB7a,EAAO,GAElC,MAAM6T,EAAc/X,KAAKgf,qBACrB1G,EACAwG,EACAC,GAEJ/e,KAAK8X,cAAgB,IAAIkG,GACrB1F,EACAP,GAGJ,GACI/X,KAAK8X,cAAcQ,eACnBjF,GAAkBE,SACpB,CACEvT,KAAKif,yBAAyBH,E,CAElC,GACI9e,KAAK8X,cAAcQ,eACnBjF,GAAkBC,eACpB,CACEtT,KAAKif,yBAAyBF,E,WAIhC/e,KAAKkf,WAEX,IAAKlf,KAAKme,yBAA0B,CAChCne,KAAKue,eAAehf,KAChB8H,EAA2BoP,oBACvBpD,GAAkBE,WAG1BvT,KAAKqe,cAAc9e,KAAK8T,GAAkBC,e,CAG9C,IAAKtT,KAAKoe,yBAA0B,CAChCpe,KAAKwe,qBAAqBjf,KACtB8H,EAA2BoP,oBACvBpD,GAAkBC,iBAG1BtT,KAAKqe,cAAc9e,KAAK8T,GAAkBE,S,CAI9CxN,OAAOoZ,iBAAiB,WAAYra,IAChC,GAAIA,EAAQgJ,SAAWyE,EAAW6M,oBAAqB,CAEnD,M,CAEJ,GAAIta,EAAQ2D,KAAKwF,OAAS,eAAgB,CACtCjO,KAAKqe,cAAc9e,KAAKuF,EAAQ2D,KAAK3J,M,KAG/C,MAAO8B,GACLZ,KAAKwU,kBAAoB,KACzB,MAAM5T,C,EAId4H,yBACIxI,KAAKyU,QAAQC,M,CAIjB2K,aAAa9J,GACTvV,KAAKsf,cAAgB/J,EAAM+D,M,CAI/BiG,2BAA2BhK,GACvBA,EAAMiK,kBACN,GAAIjK,EAAM+D,OAAOhS,SAAW+L,GAAkBE,SAAU,CACpDvT,KAAKue,eAAehf,KAAKgW,EAAM+D,O,MAC5B,GAAI/D,EAAM+D,OAAOhS,SAAW+L,GAAkBC,eAAgB,CACjEtT,KAAKwe,qBAAqBjf,KAAKgW,EAAM+D,O,EAK7CmG,uBAAuBlK,GACnB,OAAQA,EAAM+D,QACV,KAAKjG,GAAkBG,MAAO,CAC1BzN,OAAO2Z,cACH,IAAIC,YACA,UAAU3f,KAAK8X,cAAcQ,uBAGrC,K,CAEJ,KAAKjF,GAAkBI,OAAQ,CAC3B1N,OAAO2Z,cACH,IAAIC,YACA,UAAU3f,KAAK8X,cAAcQ,wBAGrC,K,CAEJ,KAAKjF,GAAkBM,UAAW,CAC9B3T,KAAK4f,mBAAmBvM,GAAkBC,gBAC1CvN,OAAO2Z,cACH,IAAIC,YACA,iDAGR,K,CAEJ,KAAKtM,GAAkBO,SAAU,CAC7B7N,OAAO2Z,cACH,IAAIC,YAAY,gCAEpB,K,CAEJ,KAAKtM,GAAkBW,wBAAyB,CAC5CjO,OAAO2Z,cACH,IAAIC,YAAY,sCAEpB,K,CAEJ,KAAKtM,GAAkBS,gBAAiB,CACpC9T,KAAK4f,mBAAmBvM,GAAkBE,UAC1CxN,OAAO2Z,cACH,IAAIC,YAAY,2CAEpB,K,CAEJ,KAAKtM,GAAkBU,eAAgB,CACnChO,OAAO2Z,cAAc,IAAIC,YAAY,0BACrC,K,GAMZE,qBAAqBtK,GACjB,IAAKvV,KAAKoe,yBAA0B,CAChC,M,CAGJ,GAAI7I,EAAM+D,SAAWjG,GAAkBC,eAAgB,CACnDtT,KAAK4f,mBAAmBvM,GAAkBC,e,KACvC,CACHtT,KAAK4f,mBAAmBvM,GAAkBE,S,EAMlD/K,cACIzC,OAAO2Z,cAAc,IAAIC,YAAY,yB,CAKzCnX,eACIzC,OAAO2Z,cAAc,IAAIC,YAAY,0B,CAMzCzK,0BACInP,OAAO2Z,cACH,IAAIC,YACA,UAAU3f,KAAK8X,cAAcQ,wC,CAKjC2G,yBAAyB1J,GAC7BrL,QAAQsD,MAAM,gCAAiC+H,GAC/CvV,KAAK8f,uBAAuBpL,KAAKa,E,CAG7ByJ,qBACJ1G,EACAwG,EACAiB,GAEA,OAAOzH,GAAgBjF,GAAkBE,SACnCvT,KAAKggB,eAAelB,EAAciB,EAAQzH,GAC1CtY,KAAKggB,eAAeD,EAAQjB,EAAcxG,E,CAG5C0H,eACJC,EACAC,EACAC,GAEA,MAAMC,EAAyB,GAG/B,MAAMC,EAAiBJ,EAAYxY,cAC7B4L,GAAkBI,OAClBJ,GAAkBG,MACxB,MAAM8M,EAAatgB,KAAKwX,KAAKC,cAAcS,MACtChW,GAASA,EAAKyV,aAAe0I,IAElC,GAAIC,EAAYF,EAAMhc,KAAKkc,GAG3B,MAAMC,EACFJ,IAAe9M,GAAkBE,SAC3BvT,KAAKoe,yBACLpe,KAAKme,yBACf,MAAMqC,EAA0BxgB,KAAKygB,2BACjCN,EACAI,EACAL,GAEJ,MAAMQ,EAAsB1gB,KAAKwX,KAAKC,cAAcS,MAC/ChW,GAASA,EAAKyV,aAAe6I,IAGlC,GAAIE,EAAqB,CAErB,GACIR,EAAczY,eACdyY,EAAcrY,UAAU,cAC1B,CACE6Y,EAAoBtI,KAChB8H,EAAcrY,UAAU,a,CAEhCuY,EAAMhc,KAAKsc,E,CAIf,IACKT,EAAYxY,eACb0Y,IAAe9M,GAAkBE,SACnC,CACE,MAAMoN,EAAqB3gB,KAAKwX,KAAKC,cAAcS,MAC9ChW,GACGA,EAAKyV,aACLtE,GAAkBW,0BAE1B,GAAI2M,EAAoBP,EAAMhc,KAAKuc,E,CAGvC,OAAOP,C,CAGHK,2BACJN,EACAI,EACAK,GAEA,GAAIT,IAAe9M,GAAkBE,SAAU,CAC3C,IAAKgN,EAAc,OAAOlN,GAAkBK,WAC5C,OAAOkN,EAAenZ,cAChB4L,GAAkBM,UAClBN,GAAkBO,Q,KACrB,CACH,IAAK2M,EAAc,OAAOlN,GAAkBQ,iBAC5C,OAAO+M,EAAenZ,cAChB4L,GAAkBS,gBAClBT,GAAkBU,c,EAIxB6L,mBAAmBtH,GACvBtY,KAAK6gB,mBAAmBtT,cAAcwO,YAClCzD,EACA/F,EAAW6M,qBAEfpf,KAAKqe,cAAc9e,KAAK+Y,E,CAGpBwI,qBACJ,OAAOpI,EAAA,iB,CAGHqI,yBACJ,OACIrI,EAAA,0BACIlB,KAAMxX,KAAKwX,KACXM,cAAe9X,KAAK8X,cACpB6G,OAAQ3e,KAAK2e,OAAM,WACT3e,KAAKyc,QAAO,aACVzc,KAAKsK,UAAS,YACftK,KAAKyK,SAAQ,oBACLzK,KAAKoW,gBACxBjC,SAAUnU,KAAKmU,SACfxK,YAAa3J,KAAK2J,YAClB4H,sBAAuBvR,KAAKuR,sBAC5B6L,kBAAmBpd,KAAKod,kBACxB1S,MAAO1K,KAAK0K,MAAK,aACL1K,KAAKuY,UACjBK,MAAO5Y,KAAKsf,cAAgB,YAAc,I,CAK9C0B,+BACJ,OACItI,EAAA,0BACIlB,KAAMxX,KAAKwX,KACXM,cAAe9X,KAAK8X,cAAa,aACrB9X,KAAK6e,YAAW,YACjB7e,KAAKihB,WAAU,oBACPjhB,KAAKoW,gBACxB7E,sBAAuBvR,KAAKuR,sBAC5B5H,YAAa3J,KAAK2J,YAAW,YAClB3J,KAAKuY,UAChBK,MAAO5Y,KAAKsf,cAAgB,YAAc,I,CAKtD9F,SACI,GAAIxZ,KAAKwU,kBAAmB,CACxB,M,CAEJ,OACIkE,EAAA,kCAA+B1Y,KAAKod,mBAC/Bpd,KAAKme,0BACFne,KAAKoe,0BACD1F,EAAA,UACItF,MAAM,uBACNuF,GAAG,sBACHc,OAAM,KACN7L,IAAK2E,EAAW2O,iBAChBxH,IAAMC,GAAQ3Z,KAAK6gB,mBAAqBlH,KAGlD3Z,KAAK8X,eAAiB9X,KAAK8gB,qBAE5B9gB,KAAKme,0BAA4Bne,KAAK+gB,yBACtC/gB,KAAKoe,0BACFpe,KAAKghB,+B,sHC1czB,MAAMG,GAAyB,wZ,MCQlBC,GAAI,M,yHAUbC,eAAelJ,GAKX,IAAImJ,EACJ,GAAInJ,EAAS3N,IAAK,CAEd8W,EAAanJ,EAASoJ,SAChBvhB,KAAKwhB,iBAAiBrJ,GACtBnY,KAAKyhB,eAAetJ,E,KACvB,CAEHmJ,EAAanJ,EAASuJ,YAChB1hB,KAAKyhB,eAAetJ,GACpBnY,KAAKwhB,iBAAiBrJ,E,CAGhC,OACIO,EAAA,MAAIE,MAAM,yBACLT,EAASwJ,aACNjJ,EAAA,QAAME,MAAM,qBACPT,EAASwJ,aAGjBL,E,CAKbG,eAAetJ,GACX,OACIO,EAAA,KACIE,MACI,qBACCT,EAASuJ,YAAc,sBAAwB,IAEpD1O,KAAMmF,EAAS3N,IAAM2N,EAAS3N,IAAM,IACpCsO,QACIX,EAAS3N,IACHnH,UACA,KACIrD,KAAK4hB,iBAAiBlN,KAAKyD,EAASR,WAAW,GAI5DQ,EAAS0J,MACNnJ,EAAA,KACIE,MAAM,mBACNI,UAAWC,EAAOd,EAAS0J,MAAK,cACpB,SAGpBnJ,EAAA,QAAME,MAAM,yBAAyBT,EAASC,M,CAK1DoJ,iBAAiBrJ,GACb,OACIO,EAAA,UACIE,MACI,eACCT,EAAS2J,YAAc,yBAA2B,MAClD3J,EAASuJ,YAAc,sBAAwB,IAEpD5I,QAAS,IACLX,EAAS3N,IACFzE,OAAOgI,SAASiF,KAAOmF,EAAS3N,IACjCxK,KAAK4hB,iBAAiBlN,KAAKyD,EAASR,aAG9Ce,EAAA,QAAME,MAAM,oBAAoBT,EAASC,M,CAKrDoB,SACI,IAAKxZ,KAAKmZ,UAAW,CACjB,M,CAGJ,OACIT,EAAA,OAAKE,OAAQ5Y,KAAKoV,KAAO,YAAc,cACnCsD,EAAA,MAAIC,GAAG,0BAA0BC,MAAM,oBAClC5Y,KAAKmZ,UAAUpN,KAAK7J,GAASlC,KAAKqhB,eAAenf,M"}