{"version":3,"sources":["../src/types.ts","../src/fab/index.css","../src/fab/components/view/logo.ts","../src/fab/components/common/html.ts","../src/fab/components/common/button/reconnect.ts","../src/fab/components/view/directory.ts","../src/fab/components/channel-picker/toolbar/button.ts","../src/fab/components/channel-picker/toolbar/index.ts","../src/fab/components/common/image.ts","../src/fab/components/channel-picker/channels.ts","../src/fab/components/channel-picker/index.ts","../src/fab/components/header/logo.ts","../src/fab/components/header/index.ts","../src/fab/components/resolver/header/dismiss.ts","../src/fab/components/resolver/header/logo.ts","../src/fab/components/common/title.ts","../src/fab/components/resolver/header/title.ts","../src/fab/components/resolver/header/index.ts","../src/fab/components/resolver/app-row/icon-container.ts","../src/fab/components/resolver/app-row/info/agent.ts","../src/fab/components/resolver/app-row/info/index.ts","../src/fab/components/resolver/app-row/title.ts","../src/fab/components/resolver/app-row/index.ts","../src/fab/components/resolver/group.ts","../src/fab/components/resolver/intent-row.ts","../src/fab/components/resolver/list.ts","../src/fab/components/resolver/index.ts","../src/fab/components/resolver-background.ts","../src/fab/components/toast/message.ts","../src/fab/components/toast/index.ts","../src/fab/components/container.ts","../src/fab/components/common/button/login.ts","../src/fab/window/logout.ts","../src/fab/authenticator.ts","../src/fab/components/common/button/open.ts","../src/fab/storage-access.ts","../src/fab/opener.ts","../src/fab/index.ts","../src/main.ts","../src/agent/channel.ts","../src/agent/api.ts","../src/agent/index.ts","../src/common/promise.ts","../../common/src/interop/subscriptions.ts","../src/agent/subscription.ts","../src/common/iframe.ts","../src/common/port.ts","../src/agent/iframe.ts","../src/agent/tunnel.ts","../../common/src/interop/envelope.ts","../src/agent/websocket.ts","../src/common/event-emitter.ts","../src/common/logger.ts","../../common/src/directories.ts","../src/agent/window-listener.ts","../src/agent/storage-access.ts","../src/common/app-id.ts","../src/agent/authentication.ts","../src/common/element.ts","../../common/src/types.ts"],"sourcesContent":["import type {\n  DownEventData,\n  DownEventTopic,\n  DownResponseData,\n  DownResponseTopic,\n} from '@/common/interop/down-messages';\nimport type { ConnectifiAppMetadata } from '@/common/types';\nimport type {\n  AppMetadata,\n  Context,\n  IntentMetadata,\n  DesktopAgent,\n  AppIntent,\n} from '@finos/fdc3';\nimport { AuthTargetType } from './agent/authentication';\n\nexport interface DirectoryIntent extends IntentMetadata {\n  contexts?: Array<string>;\n}\n\nexport enum ResolutionType {\n  Intent = 'intent-resolver',\n  Context = 'context-resolver',\n}\n\nexport type DownEventHandler<TTopic extends DownEventTopic> = (\n  data: DownEventData[TTopic],\n) => void;\nexport type DownEventHandlers = {\n  [K in keyof DownEventData]: DownEventHandler<K>;\n};\nexport type DownResponseHandler<TTopic extends DownResponseTopic> = (\n  data: DownResponseData[TTopic],\n) => void;\nexport type DownResponseHandlerMap = {\n  [K in keyof DownResponseData]: DownResponseHandler<K>;\n};\n\n/**\n * represents an FDC3 intent with a collection of related App Instances\n **/\n\nexport type AppIntentResult = {\n  intent: IntentMetadata;\n  apps: ConnectifiAppMetadata[];\n};\n\nexport interface IntentResolutionMessage {\n  resolutionType: ResolutionType;\n  context: Context;\n  data: AppIntentResult | AppIntentResult[];\n  bridgeData?: AppIntent | AppIntent[];\n  resultPendingId?: string;\n}\n\nexport interface ResolveCallbackProps {\n  selected: ConnectifiAppMetadata;\n  intent: string;\n  context: Context;\n  bridge?: boolean;\n  metadata?: any;\n}\n\nexport type ResolveCallback = (props: ResolveCallbackProps) => void;\n\nexport type CloseCallback = () => void;\n\nexport type AuthenticateConfig = {\n  /**\n   * Prompts the user to authenticate.\n   *\n   * By default, the current window will be redirected to login page.\n   * If redirect style is new window instead, the login page will be shown in a new browser window.\n   *\n   * Returns a promise that resolves when the user has successfully authenticated.\n   */\n  authenticate: (redirectStyle?: RedirectStyle) => Promise<void>;\n  getAuthenticationUrl: (targetType?: AuthTargetType) => string;\n} & DirectoryProps;\n\n/**\n * interface for any Agent\n * @deprecated\n */\nexport type FDC3Agent = {\n  connect: () => void;\n} & Pick<AuthenticateConfig, 'authenticate'>;\n\nexport type RequestStorageAccessConfig = {\n  /**\n   * A button for users to request storage access.\n   *\n   * This button is embedded within an iframe on the interop domain, as modern browsers require user interaction\n   * from the domain where third-party cookies reside. If a storage access request is initiated outside the interop\n   * domain, the browser will deny it. Custom implementations should append this button to a DOM element within their UI.\n   */\n  button: HTMLIFrameElement;\n\n  /**\n   * Waits for the user to grant or deny storage access.\n   *\n   * This method should be called after the storage access button has been appended to the UI.\n   *\n   * Returns a promise that resolves to a boolean, indicating whether the user granted or denied storage access.\n   */\n  waitForStorageAccess: () => Promise<boolean>;\n\n  /**\n   * Requests user consent for third-party cookie usage.\n   *\n   * This is necessary only if a storage access request fails, suggesting that third-party cookies may be blocked.\n   * By default, the current window is redirected to the consent page. If the redirect is set to new window,\n   * the consent page will open in a new browser window.\n   *\n   * Returns a promise that resolves to a boolean, indicating whether the user granted or denied consent.\n   */\n  requestConsent: (redirectStyle?: RedirectStyle) => Promise<boolean>;\n};\n\nexport interface AgentHandlers {\n  /**\n   * fdc3 api is ready for use\n   * @param fdc3\n   * @returns\n   */\n  onFDC3Ready?: (fdc3: DesktopAgent) => void;\n  /**\n   * directory session is established\n   * @param directory directory properties\n   * @param username if directory requires signin, the username is passed as well\n   * @returns\n   */\n  onSessionStarted?: (directory: DirectoryProps, username?: string) => void;\n  /**\n   * session error - timeout connecting to service, bad app id, etc.\n   * @param errorMessage\n   * @returns\n   */\n  onSessionError?: (errorMessage: string) => void;\n\n  /**\n   * signin/login is complete\n   * - applicable ONLY to directories with strict interop strategy\n   * @param username\n   * @returns\n   */\n  onSignedIn?: () => void;\n  /**\n   * signout/logout is complete\n   * - applicable ONLY to directories with strict interop strategy\n   * @returns\n   */\n  onSignedOut?: () => void;\n\n  /**\n   * channel joined - useful for setting any channel indicators\n   * @param channelId id of the channel that was joined\n   * @returns\n   */\n  onChannelJoined?: (channelId: string) => void;\n  /**\n   * channel left - useful for resetting any channel indicators\n   * @returns\n   */\n  onChannelLeft?: () => void;\n  /**\n   * interop service is connected (useful for clearing any disconnected state/indicators)\n   * @param initialConnect indicates if this is the initial connection to the service\n   * @returns\n   */\n  onConnected?: (initialConnect: boolean) => void;\n  /**\n   * interop service is disconnected, it will attempt to reconnect in  \"nextConnect\" seconds.\n   * useful for setting indicators/state like \"disconnected, reconnecting in ...\"\n   * @param nextConnect next reconnect attempt in seconds\n   * @returns\n   */\n  onDisconnected?: (nextConnect?: number) => void;\n  /**\n   * \"working\" or \"busy\" state of the agent\n   * typically used for a \"spinner\" or \"loading\" indicator/effect\n   * @param workInProgress\n   * @returns\n   */\n  onWorkingChanged?: (workInProgress: boolean) => void;\n\n  /**\n   * Called when agent is requesting the user to authenticate.\n   * @param directory the directory the user is authenticating against.\n   */\n  onSessionAuthRequired?: (directory: DirectoryProps) => void;\n\n  /**\n   * for implementing a custom intent resolver\n   * @param message\n   * @param callback\n   * @param closeCallback\n   * @returns\n   */\n  handleIntentResolution?: (\n    message: IntentResolutionMessage,\n    callback: ResolveCallback,\n    closeCallback: CloseCallback,\n  ) => void;\n\n  /**\n   * for overriding the default \"open\" implementation (window.open)\n   * @param message\n   * @returns\n   */\n  handleOpen?: (message: ConnectifiOpenMessage) => void;\n\n  /**\n   * for overriding the default FAB click operation\n   * @param message\n   * @returns\n   */\n  handleFABClicked?: (event: MouseEvent) => void;\n\n  /**\n   * Handles authenticating the user for directories that require authentication.\n   * Applicable ONLY to directories with strict interop strategy.\n   * @param directory directory properties\n   * @returns promise that resolves when authentication of the user is successful.\n   */\n  handleAuthenticate?: (config: AuthenticateConfig) => Promise<void>;\n\n  /**\n   * Overrides the default behavior for requesting storage access.\n   */\n  handleRequestStorageAccess?: (\n    config: RequestStorageAccessConfig,\n  ) => Promise<void>;\n}\n\nexport interface AgentConfig extends AgentHandlers {\n  props?: FabProps;\n  headless?: boolean;\n  logLevel?: LogLevel;\n  bridgeGlobal?: boolean;\n  // for overriding the default logging implementation (console.log)\n  logger?: (...params: any) => void;\n}\n\nexport interface AgentConfigInfo {\n  bridgeGlobal?: boolean;\n  headless?: boolean;\n  logLevel?: LogLevel;\n  props?: FabProps;\n  activeHandlers: AgentConfigHandlerInfo;\n}\n\nexport type AgentConfigHandlerInfo = { [P in keyof AgentHandlers]?: true };\n\nexport type LogLevel = 'debug' | 'info' | 'silent';\nexport interface Logger {\n  info: (...params: any) => void;\n  debug: (...params: any) => void;\n  error: (...params: any) => void;\n}\n\nexport type ValidPositions = 'tl' | 'ml' | 'bl' | 'tr' | 'mr' | 'br';\n\nexport type RedirectStyle = 'sameWindow' | 'newWindow';\n\nexport interface FabProps {\n  logoSrc?: string;\n  position?: ValidPositions;\n  loginStyle?: RedirectStyle;\n}\n\nexport interface DirectoryProps {\n  name: string;\n  interopStrategy: 'open' | 'openauth' | 'app' | 'strict';\n  icon?: string;\n}\n\nexport type FabToastType =\n  | 'success'\n  | 'error'\n  | 'login'\n  | 'reconnect'\n  | 'session'\n  | 'timeout';\n\n/**\n * interface for UI component binding to an Agent\n */\nexport interface AgentGUI {\n  agent: FDC3Agent | undefined;\n  connected: boolean;\n  logoSrc?: string;\n  bind: (agent: FDC3Agent) => void;\n\n  // allow override of the default click action\n  handleClick?: (event: MouseEvent) => void;\n\n  onConnected: (initialConnect: boolean) => void;\n  onDisconnected: (nextConnect?: number) => void;\n  onFDC3Ready: (fdc3: DesktopAgent) => void;\n  onSessionStarted: (directory: DirectoryProps, username?: string) => void;\n  onSessionError: (errorMessage: string) => void;\n  onSignedOut: () => void;\n  onWorkingChanged: (working: boolean) => void;\n  onChannelJoined: (channelId: string) => void;\n  onChannelLeft: () => void;\n  handleIntentResolution: (\n    message: IntentResolutionMessage,\n    callback: ResolveCallback,\n    closeCallback: CloseCallback,\n  ) => void;\n}\n\nexport interface ConnectifiMessageData {\n  target?: AppMetadata | string | undefined;\n  context?: Context;\n  intent?: string;\n  id?: string;\n  contextType?: string;\n  channelId?: string;\n  channel?: string;\n  name?: string | AppMetadata;\n  appId?: string;\n  src?: string;\n  title?: string;\n  stateId?: string;\n  url?: string;\n  pendingId?: string;\n  resultPendingId?: string;\n}\n\n/**\n * todo: change label \"fdc3Token\" to \"token\"\n */\nexport interface ConnectifiMessage {\n  topic: string;\n  appId: string;\n  eventId: string;\n  data:\n    | ConnectifiMessageData\n    | AppIntentResult\n    | AppIntentResult[]\n    | JoinChannelResult;\n  resultPendingId?: string;\n  context?: Context;\n}\n\nexport interface JoinChannelResult {\n  channel: string;\n}\n\nexport interface TopicDataPair {\n  topic: string;\n  data?: ConnectifiMessageData;\n}\n\nexport interface AgentState {\n  connected?: boolean;\n  owner?: string | null;\n  channel?: string | undefined;\n}\n\nexport enum ConnectionError {\n  NoConnectionAvailable = 'NoConnectionAvailable',\n}\n\nexport interface ConnectifiOpenMessage {\n  name?: string;\n  appId?: string;\n  url?: string;\n}\n","@keyframes throbber{0%{opacity:0}50%{opacity:.5}to{opacity:0}}@keyframes fadeInUp{0%{opacity:0;transform:translate3d(0,100%,0)}to{opacity:1;transform:translateZ(0)}}@keyframes fadeOutDown{0%{opacity:1}to{opacity:0;transform:translate3d(0,100%,0)}}@keyframes zoomIn{0%{opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomOut{0%{opacity:1}50%{opacity:0;transform:scale3d(.3,.3,.3)}to{opacity:0}}*{color:var(--text-color);font-family:Arial,Helvetica,sans-serif;line-height:1rem}img{height:1.2rem;width:1.2rem}button{align-items:center;background:transparent;border:none;border-radius:50%;display:flex;filter:var(--drop-shadow-sm);height:1.8rem;justify-content:center;margin:.2rem;padding:0;transition:var(--ease);width:1.8rem}button:hover{transform:scale(1.1)}button img{height:.7rem;width:.7rem}button:hover{transform:var(--grow)}.container{--text-color:#111;--shadow:#27272ac2;--drop-shadow:drop-shadow(5px 5px 10px var(--shadow));--drop-shadow-sm:drop-shadow(3px 3px 5px var(--shadow));--box-shadow:rgba(50,50,93,.2) 0px 13px 27px -5px,rgba(0,0,0,.25) 0px 8px 16px -8px;--border:1px solid var(--secondary-variant);--ease:all 0.2s ease-in-out;--grow:scale(1.1);--grow-sm:scale(1.04);--radius:0.25rem;--background:#fff;--primary:#000;--primary-variant:#27272a;--secondary:#aaa;--secondary-variant:#d0d4db;font-size:.8rem}.fab{align-items:center;display:flex;flex-direction:column;position:fixed;z-index:99999}.fab.bl,.fab.bl .picker,.fab.br,.fab.br .picker{flex-direction:column-reverse}.fab.br .inner,.fab.mr .inner,.fab.tr .inner{align-items:end}.fabHeader,.inner{display:flex;flex-direction:column;height:3.5rem;justify-content:center;width:3.5rem}.fabHeader{align-items:center;background-color:var(--secondary);border-radius:50%;filter:var(--drop-shadow);margin:0;padding:0;transition:background-color .25s linear,var(--ease)}.fabHeader:hover{transform:var(--grow-sm)}.fab.tl{left:1rem;top:2rem}.fab.ml{left:1rem;top:calc(50vh - 1.8rem)}.fab.bl{bottom:2rem;left:1rem}.fab.tr{right:1rem;top:2rem}.fab.mr{right:1rem;top:calc(50vh - 1.8rem)}.fab.br{bottom:1.75rem;right:1rem}.fabHeader img{border-radius:50%;height:3rem;width:3rem}.fabHeader .mask{background-color:#fff;border-radius:50%;height:100%;opacity:0;position:absolute;transition:transform 2s ease-in-out;width:100%}.fabHeader .indicator{background-color:gray;border:1px solid #fff;border-radius:50%;bottom:0;height:.8rem;position:absolute;right:0;width:.8rem}.fabHeader.connected .indicator{background-color:#90ee90}.fabHeader.busy .mask{animation:throbber 2s infinite}.fabHeader.connected{background-color:var(--primary)}.toast{align-items:center;background-color:var(--background);border:var(--border);border-radius:var(--radius);box-shadow:var(--box-shadow);display:flex;flex-flow:row;flex-wrap:nowrap;justify-content:left;margin-left:70px;margin-right:70px;max-width:25rem;min-width:12rem;opacity:.9;padding:.4rem;position:fixed;visibility:hidden}.toast.show{animation-duration:.3s;animation-name:fadeInUp;visibility:visible}.toast.hide{animation-duration:.26s;animation-name:fadeOutDown}.toast>img{height:1.5rem;margin-right:.4rem;width:1.5rem}.toast>button>img{height:1.2rem;width:1.2rem}.toast .title{font-weight:600}.toast .message{font-size:.7rem;margin-right:.5rem;overflow:hidden;text-overflow:ellipsis}.picker{align-items:center;color:var(--text-color);display:none;flex-direction:column;justify-content:center;padding:.2rem 0}.picker.show{display:flex}.picker button>img{filter:invert(1)}.picker.show button{animation-duration:.4s;animation-name:zoomIn;opacity:1;visibility:visible}.picker button{animation-duration:.5s;animation-name:zoomOut;opacity:0;visibility:hidden}.toolbar{align-items:center;display:flex;flex-flow:row}.toolbar>button{background-color:var(--primary-variant)}.toolbar .title{margin-left:.5rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:calc(100vw - 3rem)}.channels{display:none;flex-wrap:wrap;justify-content:center}.channels.show{display:flex}.resolver{background-color:var(--background);border:var(--border);border-radius:.6rem .6rem 0 0;box-shadow:var(--box-shadow);display:none;height:24rem;left:50%;margin-left:-15rem;margin-top:-12rem;opacity:0;position:fixed;top:50%;width:30rem;z-index:99999}.resolver.open{display:block;opacity:1;transition-duration:.3s;transition-property:opacity}.resolver .header{align-items:center;background-color:var(--primary-variant);border-top-left-radius:.6rem;border-top-right-radius:.6rem;display:flex;flex-direction:row;font-size:1rem;padding:.6rem 0 .3rem;width:100%}.resolver .header *{color:#fff}.resolver .header .logo img{height:1.5rem;margin:2px .5em 0;width:1.5rem}.resolver .header .title{flex-grow:1;overflow:hidden;white-space:wrap}.resolver .header .title:after{background:linear-gradient(90deg,transparent,transparent 85%,var(--primary-variant) 90%);border-top-right-radius:.6em;content:\"\";display:block;height:2em;left:0;pointer-events:none;position:absolute;top:0;width:100%}.resolver .header .title span{display:inline-block;margin:0 0 4px}.resolver .header .dismissContainer{align-items:start;display:flex}.resolver .header .dismiss{margin:0 .5em;z-index:1}.resolver .header .dismiss>div{background-color:transparent;border-radius:50%;cursor:pointer;height:1.2em;text-align:center;width:1.2em}.resolver .header .dismiss>div>span{position:relative;top:2px}.resolver .header .dismiss div:hover{background-color:#555}.resolver .list{height:20.5rem;overflow:scroll}.resolver .list .item{align-items:center;cursor:pointer;display:flex;flex-direction:row;flex-wrap:nowrap;height:2rem;overflow:hidden;padding:.3rem .3rem .3rem .6rem}.resolver .list .item:hover{background-color:#e7e7e7}.resolver .list .group{border-bottom:.5px solid #bbb;border-top:.5px solid #bbb;padding:.25rem .75rem}.resolver .list .item .icon-container{display:flex;flex-direction:row;flex-wrap:nowrap}.resolver .list .item img{background-repeat:no-repeat;background-size:contain;margin-right:.4rem}.resolver .list .item .title{flex-grow:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.resolver .list .item .info{display:flex;flex-direction:row;flex-wrap:nowrap;padding-right:.4rem}.resolver .list .item .info>div{background-repeat:no-repeat;background-size:contain;height:1.2rem;margin-left:.4rem;padding:.3em;text-align:center;width:1.2rem}.resolver .list .item .info .agent>div{margin-top:.1em}.resolver .list .item .info .more{background-color:#d3d3d3;height:1.2rem;padding-top:.5em;width:1.2rem}.resolver .list .item .info .more>span{border-color:#aaa;border-style:dashed;border-width:0 2px}.resolver .list .intentRow{background-color:#ddd;border-top:1px solid #bbb;padding-bottom:.6rem;padding-top:.6rem}.resolver .list .intentTitle{font-size:1rem;padding:0 .5em}.resolverBackground{background-color:#111;display:none;height:100%;left:0;opacity:.2;position:absolute;top:0;width:100%;z-index:9999}.resolverBackground.open{display:block}@media (max-width:600px){.resolver{margin-left:calc(-50vw - -1rem);width:calc(100vw - 2rem)}}@media (max-height:480px){.resolver{height:calc(100vh - 2rem);margin-top:calc(-50vh - -1rem)}.resolver .list{height:calc(100vh - 4.7rem)}}","/**\n * A composition of multiple HTML image elements that all should render the same current directory logo.\n */\nexport class LogoView {\n  constructor(private images: HTMLImageElement[]) {}\n\n  updateImageSource(imageSource: string) {\n    this.images.forEach((image) => {\n      image.src = imageSource;\n    });\n  }\n}\n","class HTMLElementDecorator<T extends keyof HTMLElementTagNameMap> {\n  element: HTMLElementTagNameMap[T];\n\n  constructor(type: T) {\n    this.element = document.createElement(type);\n  }\n}\n\nexport class HTMLDivDecorator extends HTMLElementDecorator<'div'> {\n  constructor() {\n    super('div');\n  }\n}\n\nexport class HTMLButtonDecorator extends HTMLElementDecorator<'button'> {\n  constructor() {\n    super('button');\n  }\n}\n\nexport class HTMLImageDecorator extends HTMLElementDecorator<'img'> {\n  constructor() {\n    super('img');\n  }\n}\n\nexport function clearTitle(element: HTMLElement) {\n  element.title = '';\n}\n","import { HTMLButtonDecorator } from '../html';\n\nexport class ReconnectButton extends HTMLButtonDecorator {\n  containerElement = document.createElement('span');\n\n  constructor(interopHost: string) {\n    super();\n    this.element.title = 'reconnect now';\n\n    const iconUrl = `${interopHost}/connect.png`;\n    const img = document.createElement('img');\n    img.src = iconUrl;\n    this.element.appendChild(img);\n  }\n}\n","import type { DirectoryProps } from '../../../types';\n\nimport { ChannelPicker } from '../channel-picker';\nimport { LogoView } from './logo';\n\n/**\n * A composition of multiple HTML elements that renders details about the current directory.\n */\nexport class DirectoryView {\n  constructor(private picker: ChannelPicker, private logo: LogoView) {}\n\n  update(directory: DirectoryProps) {\n    this.picker.updateInteropStrategy(directory.interopStrategy);\n\n    if (directory.icon) {\n      this.logo.updateImageSource(directory.icon);\n    }\n  }\n}\n","import { HTMLButtonDecorator } from '../../common/html';\n\nexport class ChannelPickerToolbarButton extends HTMLButtonDecorator {\n  private icon = document.createElement('img');\n\n  constructor() {\n    super();\n    this.element.appendChild(this.icon);\n  }\n\n  updateOwner(\n    interopHost: string,\n    interopStrategy: string,\n    owner: string | undefined,\n  ) {\n    if (interopStrategy !== 'strict' && interopStrategy !== 'openauth') {\n      this.element.style.display = 'none';\n      return;\n    }\n    this.element.style.display = '';\n\n    if (!owner) {\n      this.element.setAttribute('title', 'please sign in');\n      this.icon.src = `${interopHost}/signin.svg`;\n      return;\n    }\n    this.element.setAttribute('title', `sign out of ${owner}`);\n    this.icon.src = `${interopHost}/signout.svg`;\n  }\n}\n","import { HTMLDivDecorator } from '../../common/html';\nimport { ChannelPickerToolbarButton } from './button';\n\nexport class ChannelPickerToolbar extends HTMLDivDecorator {\n  button: ChannelPickerToolbarButton;\n\n  constructor() {\n    super();\n    this.element.classList.add('toolbar');\n\n    this.button = new ChannelPickerToolbarButton();\n    this.element.appendChild(this.button.element);\n  }\n}\n","export function createImage(src: string) {\n  const image = new Image();\n  image.src = src;\n  return image;\n}\n\nexport function getWarningImageUrl(interopHost: string) {\n  return `${interopHost}/warning.svg`;\n}\n\nexport function getErrorImageUrl(interopHost: string) {\n  return `${interopHost}/error.svg`;\n}\n\nexport function getCheckImageUrl(interopHost: string) {\n  return `${interopHost}/check.svg`;\n}\n\nexport function getUnlockImageUrl(interopHost: string) {\n  return `${interopHost}/unlock.svg`;\n}\n\nexport function getLogoImageUrl(interopHost: string) {\n  return `${interopHost}/connectifi-logo-white.png`;\n}\n\nexport function getChannelImageUrl(interopHost: string) {\n  return `${interopHost}/channel.svg`;\n}\n\nconst imageCache: Map<string, HTMLImageElement> = new Map();\nexport function getImageInstance(src: string) {\n  if (!imageCache.has(src)) {\n    imageCache.set(src, createImage(src));\n  }\n  return imageCache.get(src) as HTMLImageElement;\n}\n","import type { Channel } from '@finos/fdc3';\n\nimport { HTMLDivDecorator } from '../common/html';\nimport { createImage } from '../common/image';\n\nfunction isYOffScreen(el?: Element, marginFromWindow = 0) {\n  if (!el) return false;\n  const rect = el.getBoundingClientRect();\n  return (\n    rect.y + rect.height - marginFromWindow < 0 ||\n    rect.y > window.innerHeight - marginFromWindow\n  );\n}\n\nexport class ChannelPickerChannelsContainer extends HTMLDivDecorator {\n  constructor(\n    private channelSrc: string,\n    private onChannelPicked: (channel: string) => void,\n  ) {\n    super();\n    this.element.classList.add('channels');\n\n    this.addEventListeners();\n  }\n\n  private addEventListeners() {\n    window.addEventListener('resize', this.handleResize.bind(this));\n  }\n\n  private handleResize() {\n    const marginFromWindow = 45;\n    const child = this.element.children.item(0);\n    const childrenLength = this.element.children.length;\n\n    if (!child) return;\n\n    const childSize = child.getBoundingClientRect().height;\n    const childStyle = getComputedStyle(child);\n    const margin =\n      parseFloat(childStyle.marginTop) + parseFloat(childStyle.marginBottom);\n    const totalChildSize = childSize + margin;\n\n    for (let i = 1; i < childrenLength + 1; i++) {\n      const newWidth = totalChildSize * i + 'px';\n      this.element.style.width = newWidth;\n\n      if (\n        !isYOffScreen(this.element.firstChild as Element, marginFromWindow) &&\n        !isYOffScreen(this.element.lastChild as Element, marginFromWindow)\n      ) {\n        return;\n      }\n    }\n  }\n\n  private async pickChannel(channel: string, event?: Event) {\n    event?.stopPropagation();\n    this.onChannelPicked(channel);\n  }\n\n  private renderChannel(channel: Channel) {\n    const id = `channel-item-${channel.id}`;\n    const hasItem = this.element.querySelector(`#${id}`);\n\n    //don't render if we've already done it (prevent duplicating DOM), or if this is the 'global' channel\n    if (hasItem || channel.id === 'global') {\n      return;\n    }\n\n    const button = document.createElement('button');\n    const name = channel.displayMetadata?.name || channel.id;\n    const color = channel.displayMetadata?.color || 'black';\n\n    button.id = id;\n    button.title = name + ' Channel';\n    button.style.backgroundColor = color;\n\n    button.addEventListener('click', (event: Event) => {\n      this.pickChannel(channel.id as string, event);\n    });\n\n    button.appendChild(createImage(this.channelSrc));\n\n    this.element.appendChild(button);\n  }\n\n  renderChannels(channels: Channel[]) {\n    channels.forEach((channel) => this.renderChannel(channel));\n    this.handleResize();\n  }\n}\n","import { ChannelPickerToolbar } from './toolbar';\nimport { ChannelPickerChannelsContainer } from './channels';\nimport { HTMLDivDecorator } from '../common/html';\n\nexport class ChannelPicker extends HTMLDivDecorator {\n  private animationDelay = -1;\n  private isShowing = false;\n  public canShow = false;\n\n  toolbar: ChannelPickerToolbar;\n\n  channels: ChannelPickerChannelsContainer;\n\n  constructor(\n    hubSrc: string,\n    position: string,\n    private onChannelPicked: (channel: string) => void,\n  ) {\n    super();\n    this.element.classList.add('picker', position);\n\n    this.toolbar = new ChannelPickerToolbar();\n    this.element.appendChild(this.toolbar.element);\n\n    this.channels = new ChannelPickerChannelsContainer(\n      hubSrc,\n      this.handleChannelPicked.bind(this),\n    );\n    this.element.appendChild(this.channels.element);\n\n    this.stopRootClickPropagation();\n  }\n\n  private handleChannelPicked(channel: string) {\n    this.onChannelPicked(channel);\n    this.hide();\n  }\n\n  private stopRootClickPropagation() {\n    this.element.addEventListener('click', (event: Event) => {\n      event.stopPropagation();\n    });\n  }\n\n  hide(): void {\n    if (this.canShow) {\n      this.isShowing = false;\n      this.element.classList.remove('show');\n      this.animationDelay = window.setTimeout(() => {\n        this.channels.element.classList.remove('show');\n      }, 500);\n    }\n  }\n\n  show(): void {\n    if (this.canShow) {\n      window.clearTimeout(this.animationDelay);\n      this.isShowing = true;\n      this.channels.element.classList.add('show');\n      this.element.classList.add('show');\n    }\n  }\n\n  toggle(): void {\n    if (this.isShowing) {\n      return this.hide();\n    }\n    this.show();\n  }\n\n  updateInteropStrategy(interopStrategy: string | undefined) {\n    if (!interopStrategy) return;\n    this.element.classList.add(interopStrategy);\n  }\n}\n","import { HTMLImageDecorator } from '../common/html';\n\nexport class HeaderLogo extends HTMLImageDecorator {\n  constructor(logoSrc: string) {\n    super();\n    this.element.alt = 'connectifi';\n\n    this.element.classList.add('logo');\n    this.element.classList.add('loaded');\n    this.element.classList.add('connected');\n\n    this.element.src = logoSrc;\n  }\n}\n","import { HTMLDivDecorator, clearTitle } from '../common/html';\nimport { HeaderLogo } from './logo';\n\nexport class Header extends HTMLDivDecorator {\n  logo: HeaderLogo;\n  indicator = document.createElement('div');\n  mask = document.createElement('div');\n\n  constructor(logoSrc: string) {\n    super();\n\n    this.element.classList.add('fabHeader');\n\n    this.mask.classList.add('mask');\n    this.element.appendChild(this.mask);\n\n    this.indicator.classList.add('indicator');\n    this.element.appendChild(this.indicator);\n\n    this.logo = new HeaderLogo(logoSrc);\n    this.element.appendChild(this.logo.element);\n  }\n\n  connected(directory: string) {\n    this.element.classList.add('connected');\n    this.element.title = `Connected to directory '${directory}'.`;\n  }\n\n  disconnected() {\n    clearTitle(this.element);\n    this.element.classList.remove('connected');\n  }\n\n  loading() {\n    clearTitle(this.element);\n    this.element.classList.add('busy');\n  }\n\n  loaded() {\n    clearTitle(this.element);\n    this.element.classList.remove('busy');\n  }\n\n  setBackgroundColor(color: string) {\n    this.element.style.backgroundColor = color;\n  }\n}\n","import { HTMLDivDecorator } from '../../common/html';\n\nexport class ResolverHeaderDismiss extends HTMLDivDecorator {\n  constructor() {\n    super();\n\n    this.element.classList.add('dismissContainer');\n\n    const dismiss = document.createElement('div');\n    dismiss.classList.add('dismiss');\n\n    const span = document.createElement('span');\n    span.innerHTML = '&#215;';\n\n    const container = document.createElement('div');\n    container.appendChild(span);\n\n    dismiss.appendChild(container);\n\n    this.element.appendChild(dismiss);\n  }\n}\n","import { HTMLDivDecorator } from '../../common/html';\n\nexport class ResolverHeaderLogo extends HTMLDivDecorator {\n  icon = document.createElement('img');\n\n  constructor(logoSrc: string) {\n    super();\n\n    this.element.classList.add('logo');\n\n    this.icon.src = logoSrc;\n\n    this.element.appendChild(this.icon);\n  }\n}\n","import { HTMLDivDecorator } from './html';\n\nexport class Title extends HTMLDivDecorator {\n  constructor() {\n    super();\n    this.element.classList.add('title');\n  }\n\n  updateDirectoryName(directoryName: string) {\n    this.element.textContent = directoryName;\n    this.element.title = `Connected to directory: '${directoryName}'`;\n  }\n}\n","import { Title } from '../../common/title';\n\nexport class ResolverHeaderTitle extends Title {\n  containerElement = document.createElement('span');\n\n  constructor() {\n    super();\n    this.containerElement.innerHTML = '&#215;';\n    this.element.appendChild(this.containerElement);\n  }\n}\n","import { HTMLDivDecorator } from '../../common/html';\nimport { ResolverHeaderDismiss } from './dismiss';\nimport { ResolverHeaderLogo } from './logo';\nimport { ResolverHeaderTitle } from './title';\n\nexport class ResolverHeader extends HTMLDivDecorator {\n  logo: ResolverHeaderLogo;\n  dismiss = new ResolverHeaderDismiss();\n  title = new ResolverHeaderTitle();\n\n  constructor(logoSrc: string) {\n    super();\n\n    this.element.classList.add('header');\n\n    this.logo = new ResolverHeaderLogo(logoSrc);\n    this.element.appendChild(this.logo.element);\n    this.element.appendChild(this.title.element);\n    this.element.appendChild(this.dismiss.element);\n  }\n}\n","import { HTMLDivDecorator } from '../../common/html';\n\n//resolve for different icon data formats between 1.x and 2.x\nconst getIconPath = (\n  interopHost: string,\n  icon: string | { src: string },\n): string => {\n  if (icon) {\n    //detect relative URL - more room for improvement here\n    const url = typeof icon === 'string' ? icon : icon.src;\n    if (url.toLowerCase().startsWith('http')) {\n      return url;\n    }\n\n    return `${interopHost}/${url}`;\n  }\n\n  return '';\n};\n\nexport class ResolverAppRowIconContainer extends HTMLDivDecorator {\n  constructor(\n    interopHost: string,\n    bridge: boolean,\n    isSecure: boolean,\n    icons?: { src: string }[],\n  ) {\n    super();\n\n    this.element.classList.add('icon-container');\n\n    if (bridge) return;\n\n    const iconUrl = `${interopHost}/${isSecure ? 'lock' : 'warning'}.svg`;\n    const lockIcon: HTMLElement = document.createElement('div');\n    lockIcon.setAttribute('style', `background-image: url('${iconUrl}');`);\n    lockIcon.classList.add('icon', 'mask');\n    this.element.appendChild(lockIcon);\n\n    const img = document.createElement('img');\n    if (icons && icons.length > 0) {\n      img.src = getIconPath(interopHost, icons[0]);\n    }\n    this.element.appendChild(img);\n  }\n}\n","import { HTMLDivDecorator } from '../../../common/html';\n\nexport class ResolverAppRowAgentInfo extends HTMLDivDecorator {\n  containerElement: HTMLDivElement = document.createElement('div');\n\n  constructor(interopHost: string, type: string, device?: string) {\n    super();\n\n    const lowercaseType = type && type.toLocaleLowerCase();\n\n    this.element.setAttribute('class', `agent ${lowercaseType}`);\n\n    if (device) {\n      this.element.setAttribute('title', `${type} (${device})`);\n    } else {\n      this.element.title = type;\n    }\n\n    this.element.setAttribute(\n      'style',\n      `background-image: url('${interopHost}/${lowercaseType}.svg')`,\n    );\n\n    this.element.appendChild(this.containerElement);\n  }\n}\n","import { HTMLDivDecorator } from '../../../common/html';\nimport { ResolverAppRowAgentInfo } from './agent';\n\nexport class ResolverAppRowInfo extends HTMLDivDecorator {\n  constructor(\n    interopHost: string,\n    proximity: number,\n    type: string,\n    os?: string,\n    device?: string,\n    browser?: string,\n  ) {\n    super();\n\n    this.element.classList.add('info');\n    this.element.setAttribute('title', `proximity: ${proximity}`);\n\n    if (type === 'directory') return;\n\n    if (proximity > 1) {\n      const agentNode = new ResolverAppRowAgentInfo(\n        interopHost,\n        os as string,\n        device,\n      );\n      this.element.appendChild(agentNode.element);\n    }\n\n    if (proximity > 0) {\n      const agentNode = new ResolverAppRowAgentInfo(\n        interopHost,\n        browser as string,\n      );\n      this.element.appendChild(agentNode.element);\n    }\n  }\n}\n","import { Title } from '../../common/title';\n\nexport class AppRowTitle extends Title {\n  constructor(appTitle: string) {\n    super();\n    this.updateAppTitle(appTitle);\n  }\n\n  updateAppTitle(appTitle: string) {\n    this.element.textContent = appTitle;\n    this.element.setAttribute('title', `${appTitle}`);\n  }\n}\n","import { ConnectifiAppMetadata } from '../../../../main';\nimport { HTMLDivDecorator } from '../../common/html';\nimport { ResolverAppRowIconContainer } from './icon-container';\nimport { ResolverAppRowInfo } from './info';\nimport { AppRowTitle } from './title';\n\nconst getAppTitle = (app: ConnectifiAppMetadata): string => {\n  const title = app.title || app.name;\n  const instTitle = app.instanceTitle;\n\n  if (!instTitle) {\n    return title || 'unknown';\n  }\n\n  if (title && !instTitle.startsWith(title)) {\n    return `${title} - ${instTitle}`;\n  }\n\n  return instTitle;\n};\n\nexport class ResolverAppRow extends HTMLDivDecorator {\n  iconContainer: ResolverAppRowIconContainer;\n  title: AppRowTitle;\n  info: ResolverAppRowInfo;\n\n  constructor(\n    interopHost: string,\n    app: ConnectifiAppMetadata,\n    bridge: boolean,\n  ) {\n    super();\n\n    this.element.classList.add('item');\n\n    this.iconContainer = new ResolverAppRowIconContainer(\n      interopHost,\n      bridge,\n      app.isSecure,\n      app.icons,\n    );\n    this.element.appendChild(this.iconContainer.element);\n\n    const appTitle = getAppTitle(app);\n    this.title = new AppRowTitle(appTitle);\n    this.element.appendChild(this.title.element);\n\n    this.info = new ResolverAppRowInfo(\n      interopHost,\n      app.proximity,\n      app.type,\n      app.os,\n      app.device,\n      app.browser,\n    );\n    this.element.appendChild(this.info.element);\n  }\n}\n","import { IntentResultType } from '../../../main';\nimport { HTMLDivDecorator } from '../common/html';\n\nconst getAppTypeDisplayName = (intentResultType: IntentResultType) => {\n  if (intentResultType === 'directory') {\n    return 'Open New';\n  }\n\n  return 'Send To';\n};\n\nexport class ResolverGroup extends HTMLDivDecorator {\n  constructor(bridge: boolean, type: IntentResultType) {\n    super();\n\n    this.element.classList.add('group');\n\n    if (bridge) {\n      this.element.textContent = 'Local Container';\n    } else {\n      this.element.textContent = getAppTypeDisplayName(type);\n    }\n  }\n}\n","import { HTMLDivDecorator } from '../common/html';\n\nexport class ResolverIntentRow extends HTMLDivDecorator {\n  titleElement = document.createElement('div');\n\n  constructor(title: string) {\n    super();\n\n    this.element.classList.add('intentRow');\n\n    this.titleElement.className = 'intentTitle';\n    this.titleElement.textContent = title;\n\n    this.element.appendChild(this.titleElement);\n  }\n}\n","import type { ConnectifiAppMetadata } from '@/common/types';\nimport type { AppIntentResult } from '@/common/interop/down-messages';\n\nimport { ResolverAppRow } from './app-row';\nimport { ResolverGroup } from './group';\nimport { ResolverIntentRow } from './intent-row';\nimport { HTMLDivDecorator } from '../common/html';\n\nconst sortAppsOfSameType = (\n  a: ConnectifiAppMetadata,\n  b: ConnectifiAppMetadata,\n) => {\n  if (a.type !== 'window') {\n    return 0;\n  }\n\n  if (a.proximity === b.proximity) {\n    return b.lastUpdate! - a.lastUpdate!;\n  }\n\n  return a.proximity - b.proximity;\n};\n\n// for sorting/grouping apps by AppInstanceType\nexport const appsorter = (\n  a: ConnectifiAppMetadata,\n  b: ConnectifiAppMetadata,\n) => {\n  if (a.type === b.type) {\n    return sortAppsOfSameType(a, b);\n  }\n\n  if (a.type === 'directory') {\n    return 1;\n  }\n\n  return -1;\n};\n\nexport class ResolverList extends HTMLDivDecorator {\n  constructor() {\n    super();\n    this.element.classList.add('list');\n  }\n\n  clear() {\n    this.element.innerHTML = '';\n  }\n\n  renderIntentRow({\n    intent: { displayName, name } = { displayName: '', name: '' },\n  }: AppIntentResult) {\n    const intentRow = new ResolverIntentRow(displayName || name);\n    this.element.appendChild(intentRow.element);\n  }\n\n  renderAppRows(\n    interopHost: string,\n    intentRes: AppIntentResult,\n    onAppClicked: (\n      app: ConnectifiAppMetadata,\n      intentRes: AppIntentResult,\n      bridge: boolean,\n    ) => void,\n    bridge: boolean = false,\n  ) {\n    const { apps } = intentRes;\n    apps.sort(appsorter);\n\n    let group: string = '';\n    apps.forEach((app: ConnectifiAppMetadata) => {\n      if (app.type !== group) {\n        const groupRow = new ResolverGroup(bridge, app.type);\n        this.element.appendChild(groupRow.element);\n        group = app.type;\n      }\n      const row = new ResolverAppRow(interopHost, app, bridge);\n      this.element.appendChild(row.element);\n\n      row.element.addEventListener('click', (event) => {\n        event.stopPropagation();\n        onAppClicked(app, intentRes, bridge);\n      });\n    });\n  }\n}\n","import { HTMLDivDecorator } from '../common/html';\nimport { ResolverHeader } from './header';\nimport { ResolverList } from './list';\n\nexport class Resolver extends HTMLDivDecorator {\n  header: ResolverHeader;\n  list = new ResolverList();\n  isOpen = false;\n\n  constructor(logoSrc: string) {\n    super();\n\n    this.element.classList.add('resolver');\n\n    this.header = new ResolverHeader(logoSrc);\n    this.element.appendChild(this.header.element);\n\n    this.element.appendChild(this.list.element);\n\n    this.stopClickPropagation();\n  }\n\n  private stopClickPropagation() {\n    this.element.addEventListener('click', (event: Event) => {\n      event.stopPropagation();\n    });\n  }\n\n  open() {\n    this.element.classList.add('open');\n    this.isOpen = true;\n  }\n\n  close() {\n    this.element.classList.remove('open');\n    this.isOpen = false;\n  }\n}\n","import { HTMLDivDecorator } from './common/html';\n\nexport class ResolverBackground extends HTMLDivDecorator {\n  constructor() {\n    super();\n    this.element.classList.add('resolverBackground');\n  }\n\n  open() {\n    this.element.classList.add('open');\n  }\n\n  close() {\n    this.element.classList.remove('open');\n  }\n}\n","import { HTMLDivDecorator } from '../common/html';\n\nexport class ToastMessage extends HTMLDivDecorator {\n  constructor() {\n    super();\n    this.element.classList.add('message');\n  }\n\n  clear() {\n    this.element.innerHTML = '';\n  }\n\n  setMessage(message: string) {\n    this.element.innerText = message;\n  }\n}\n","import { HTMLDivDecorator } from '../common/html';\nimport { Title } from '../common/title';\nimport { ToastMessage } from './message';\n\nexport interface ShowToastInput {\n  title: string;\n  message: string;\n  image: HTMLImageElement;\n  duration?: number;\n  actionElement?: HTMLElement;\n}\n\nexport class Toast extends HTMLDivDecorator {\n  title = new Title();\n\n  private image: HTMLImageElement | undefined;\n  private action: HTMLElement | undefined;\n  private message = new ToastMessage();\n\n  private animationDurationMs = 250;\n  private durationTimer?: number;\n  private animationTimer?: number;\n\n  private hidePromise: Promise<void> | undefined;\n\n  constructor() {\n    super();\n\n    this.element.classList.add('toast');\n\n    const content = document.createElement('div');\n    content.appendChild(this.title.element);\n    content.appendChild(this.message.element);\n    this.element.appendChild(content);\n  }\n\n  private clearAction() {\n    if (!this.action) return;\n    this.element.removeChild(this.action);\n    this.action = undefined;\n  }\n\n  private setAction(action: HTMLElement | undefined) {\n    if (!action) return;\n    this.action = action;\n    this.element.appendChild(action);\n  }\n\n  private clearImage() {\n    if (!this.image) return;\n    this.element.removeChild(this.image);\n    this.image = undefined;\n  }\n\n  private setImage(image: HTMLImageElement) {\n    this.image = image;\n    this.element.insertBefore(image, this.element.firstChild);\n  }\n\n  private clear() {\n    clearTimeout(this.durationTimer);\n    this.element.classList.remove('success', 'show', 'hide', 'error');\n\n    this.message.clear();\n    this.clearAction();\n    this.clearImage();\n  }\n\n  async hide() {\n    if (this.hidePromise === undefined) {\n      this.hidePromise = new Promise<void>((res) => {\n        this.element.classList.add('hide');\n        this.animationTimer = window.setTimeout(() => {\n          this.element.classList.remove('hide', 'show');\n          this.hidePromise = undefined;\n          res();\n        }, this.animationDurationMs);\n      });\n    }\n    return this.hidePromise;\n  }\n\n  setDuration(duration: number) {\n    this.durationTimer = window.setTimeout(() => this.hide(), duration);\n  }\n\n  async show({\n    title,\n    message,\n    actionElement,\n    duration = 3000,\n    image,\n  }: ShowToastInput) {\n    if (this.element.classList.contains('show')) {\n      await this.hide();\n    }\n\n    this.clear();\n\n    this.title.element.innerText = title;\n    this.message.setMessage(message);\n    this.setAction(actionElement);\n    this.setImage(image);\n\n    this.element.classList.add('show');\n\n    if (duration > 0) {\n      this.setDuration(duration);\n    }\n  }\n\n  update(message: string) {\n    this.message.setMessage(message);\n  }\n}\n","import { ChannelPicker } from './channel-picker';\nimport { Header } from './header';\nimport { Resolver } from './resolver';\nimport { ResolverBackground } from './resolver-background';\nimport { Toast } from './toast';\nimport { HTMLDivDecorator } from './common/html';\n\nexport class Container extends HTMLDivDecorator {\n  header: Header;\n  picker: ChannelPicker;\n  toast: Toast;\n  resolver: Resolver;\n  resolverBackground = new ResolverBackground();\n\n  constructor(\n    logoSrc: string,\n    hubSrc: string,\n    position: string,\n    onChannelPicked: (channel: string) => void,\n  ) {\n    super();\n\n    this.element.classList.add('container');\n\n    const inner = document.createElement('div');\n    inner.classList.add('inner');\n\n    this.header = new Header(logoSrc);\n    inner.appendChild(this.header.element);\n\n    this.toast = new Toast();\n    inner.appendChild(this.toast.element);\n\n    const fab = document.createElement('div');\n    fab.classList.add('fab', position);\n\n    fab.appendChild(inner);\n\n    this.picker = new ChannelPicker(hubSrc, position, onChannelPicked);\n    fab.appendChild(this.picker.element);\n\n    this.element.appendChild(fab);\n\n    this.resolver = new Resolver(logoSrc);\n    this.element.appendChild(this.resolver.element);\n\n    this.element.appendChild(this.resolverBackground.element);\n  }\n}\n","import { HTMLButtonDecorator } from '../html';\n\nexport class LoginButton extends HTMLButtonDecorator {\n  constructor(interopHost: string) {\n    super();\n    this.element.title = 'sign in';\n\n    const iconUrl = `${interopHost}/signin.svg`;\n    const img = document.createElement('img');\n    img.src = iconUrl;\n    this.element.appendChild(img);\n  }\n}\n","import { RedirectStyle } from '../../types';\nimport { LoginButton } from '../components/common/button/login';\n\nexport class Logout {\n  private window: Window | null = null;\n\n  constructor(\n    private interopHost: string,\n    private style: RedirectStyle = 'sameWindow',\n  ) {}\n\n  createButton() {\n    const button = new LoginButton(this.interopHost);\n    const handleClick = (event: Event) => {\n      event.stopPropagation();\n      this.open();\n    };\n    button.element.addEventListener('click', handleClick);\n    return button;\n  }\n\n  close() {\n    this.window?.close();\n  }\n\n  open() {\n    if (this.style === 'newWindow') {\n      this.window = window.open(\n        `${this.interopHost}/api/logout?target=interop`,\n        '_blank',\n      );\n\n      return;\n    }\n\n    const url = window.location.href;\n\n    window.location.href = `${\n      this.interopHost\n    }/api/logout?target=interop&interopUrl=${encodeURIComponent(url)}`;\n  }\n}\n","import type { AuthenticateConfig, RedirectStyle } from '../types';\n\nimport { Toast } from './components/toast';\nimport { DirectoryView } from './components/view/directory';\nimport { getUnlockImageUrl, getImageInstance } from './components/common/image';\nimport { LoginButton } from './components/common/button/login';\n\nexport class ConnectifiAuthenticator {\n  constructor(\n    private readonly interopHost: string,\n    private readonly toast: Pick<Toast, 'show'>,\n    private readonly directoryView: Pick<DirectoryView, 'update'>,\n    private readonly redirectStyle?: RedirectStyle,\n  ) {}\n\n  async authenticate(config: AuthenticateConfig) {\n    const { name, authenticate } = config;\n\n    const button = new LoginButton(this.interopHost);\n\n    this.toast.show({\n      title: 'Sign In',\n      message: `Please sign in to '${name}'.`,\n      actionElement: button.element,\n      duration: -1,\n      image: getImageInstance(getUnlockImageUrl(this.interopHost)),\n    });\n    this.directoryView.update(config);\n\n    return new Promise<void>((res) =>\n      button.element.addEventListener('click', async (ev) => {\n        ev.preventDefault();\n        await authenticate(this.redirectStyle);\n        res();\n      }),\n    );\n  }\n}\n","import { HTMLButtonDecorator } from '../html';\n\nexport class OpenButton extends HTMLButtonDecorator {\n  constructor(interopHost: string) {\n    super();\n    this.element.title = 'Open';\n\n    const iconUrl = `${interopHost}/signin.svg`;\n    const img = document.createElement('img');\n    img.src = iconUrl;\n    this.element.appendChild(img);\n  }\n}\n","import type { Toast } from './components/toast';\n\nimport { RedirectStyle, RequestStorageAccessConfig } from '../types';\nimport { OpenButton } from './components/common/button/open';\nimport { getImageInstance, getUnlockImageUrl } from './components/common/image';\n\n/**\n * Extends Storage Access implementation to add user interface for requesting storage access.\n */\nexport class StorageAccess {\n  constructor(\n    private interopUrl: string,\n    private toast: Pick<Toast, 'show' | 'hide'>,\n    private consentRedirectStyle: RedirectStyle = 'sameWindow',\n  ) {}\n\n  private createConsentButton() {\n    return new OpenButton(this.interopUrl);\n  }\n\n  /**\n   * Displays a toast asking the user to consent to third party cookie usage.\n   * Upon pressing the button in said notification, a new window will be created for granting third party cookie consent.\n   */\n  async requestConsentInToast(\n    requestConsent: RequestStorageAccessConfig['requestConsent'],\n  ) {\n    const consentButton = this.createConsentButton();\n\n    await this.toast.show({\n      title: 'Accept Cookie Policy',\n      message: `Please accept Connectifi's cookie policy.`,\n      image: getImageInstance(getUnlockImageUrl(this.interopUrl)),\n      actionElement: consentButton.element,\n      duration: -1,\n    });\n\n    return new Promise<void>((res) => {\n      consentButton.element.addEventListener('click', async (ev) => {\n        ev.preventDefault();\n        await requestConsent('newWindow');\n        res();\n      });\n    });\n  }\n\n  async requestStorageAccess(\n    config: RequestStorageAccessConfig,\n  ): Promise<void> {\n    const { button, waitForStorageAccess, requestConsent } = config;\n\n    const host = new URL(this.interopUrl).host;\n    await this.toast.show({\n      title: 'Grant Connectifi Access',\n      message: `Please grant ${host} interop access.`,\n      image: getImageInstance(getUnlockImageUrl(this.interopUrl)),\n      actionElement: button,\n      duration: -1,\n    });\n\n    const success = await waitForStorageAccess();\n    if (success) {\n      return this.toast.hide();\n    }\n\n    if (this.consentRedirectStyle === 'sameWindow') {\n      // User will be redirected, so no need to continue this flow.\n      await requestConsent('sameWindow');\n      return;\n    }\n\n    await this.requestConsentInToast(requestConsent);\n  }\n}\n","import { ConnectifiOpenMessage } from '../types';\nimport { OpenButton } from './components/common/button/open';\nimport {\n  getImageInstance,\n  getWarningImageUrl,\n} from './components/common/image';\nimport { Toast } from './components/toast';\n\nexport class Opener {\n  constructor(private toast: Toast, private interopHost: string) {}\n\n  private createButton(url: string) {\n    const button = new OpenButton(this.interopHost);\n    button.element.addEventListener('click', () => {\n      window.open(url);\n    });\n    return button.element;\n  }\n\n  open(message: ConnectifiOpenMessage) {\n    if (!message.url) {\n      return;\n    }\n    const newWindow = window.open(message.url);\n    if (newWindow) {\n      return;\n    }\n    this.toast.show({\n      title: 'Open Application',\n      message: 'Press here if application did not open',\n      image: getImageInstance(getWarningImageUrl(this.interopHost)),\n      actionElement: this.createButton(message.url),\n      duration: 5000,\n    });\n  }\n}\n","import type { Channel, DesktopAgent } from '@finos/fdc3';\nimport type { ConnectifiAppMetadata } from '@/common/types';\nimport type { AppIntentResult } from '@/common/interop/down-messages';\n\nimport {\n  AgentConfig,\n  AgentGUI,\n  DirectoryProps,\n  FabProps,\n  ResolutionType,\n  IntentResolutionMessage,\n  CloseCallback,\n  ResolveCallback,\n  FDC3Agent,\n  ConnectifiOpenMessage,\n  RequestStorageAccessConfig,\n  AuthenticateConfig,\n} from '../types';\n\nimport styles from './index.css';\n\nimport { LogoView } from './components/view/logo';\nimport { ReconnectButton } from './components/common/button/reconnect';\nimport { DirectoryView } from './components/view/directory';\nimport { Container } from './components/container';\nimport { Logout } from './window/logout';\nimport { ConnectifiAuthenticator } from './authenticator';\nimport { StorageAccess } from './storage-access';\nimport {\n  getErrorImageUrl,\n  getChannelImageUrl,\n  getLogoImageUrl,\n  getWarningImageUrl,\n  getImageInstance,\n  getCheckImageUrl,\n} from './components/common/image';\nimport { Opener } from './opener';\n\n// amount of time in seconds before showing the manual reconnect button\nconst MANUAL_RECONNECT_ELAPSED_TIME: number = 27;\n\nexport const wrapConfig = (fab: ConnectifiFab, config: AgentConfig) => {\n  // allow override of the FAB's main click action\n  if (config.handleFABClicked) {\n    fab.handleClick = config.handleFABClicked;\n  }\n\n  const newConfig = {\n    handleAuthenticate: fab.handleAuthenticate.bind(fab),\n    handleRequestStorageAccess: fab.handleRequestStorageAccess.bind(fab),\n    handleIntentResolution: fab.handleIntentResolution.bind(fab),\n    handleOpen: fab.handleOpen.bind(fab),\n    ...config,\n  };\n  newConfig.onFDC3Ready = (fdc3: DesktopAgent) => {\n    fab.onFDC3Ready(fdc3);\n    config.onFDC3Ready?.(fdc3);\n  };\n  newConfig.onSessionStarted = (directory: DirectoryProps, owner?: string) => {\n    fab.onSessionStarted(directory, owner);\n    config.onSessionStarted?.(directory, owner);\n  };\n  newConfig.onSessionError = (err: string) => {\n    fab.onSessionError(err);\n    config.onSessionError?.(err);\n  };\n  newConfig.onSignedOut = () => {\n    fab.onSignedOut();\n    config.onSignedOut?.();\n  };\n  newConfig.onChannelJoined = (channelId: string) => {\n    fab.onChannelJoined(channelId);\n    config.onChannelJoined?.(channelId);\n  };\n  newConfig.onChannelLeft = () => {\n    fab.onChannelLeft();\n    config.onChannelLeft?.();\n  };\n  newConfig.onConnected = (initialConnect: boolean) => {\n    fab.onConnected(initialConnect);\n    config.onConnected?.(initialConnect);\n  };\n  newConfig.onDisconnected = (nextConnect?: number) => {\n    fab.onDisconnected(nextConnect);\n    config.onDisconnected?.(nextConnect);\n  };\n  newConfig.onWorkingChanged = (working: boolean) => {\n    fab.onWorkingChanged(working);\n    config.onWorkingChanged?.(working);\n  };\n  newConfig.onSessionAuthRequired = (directory: DirectoryProps) => {\n    fab.onSessionAuthRequired(directory);\n    config.onSessionAuthRequired?.(directory);\n  };\n  return newConfig;\n};\n\nexport class ConnectifiFab implements AgentGUI {\n  agent: FDC3Agent | undefined;\n\n  fdc3: DesktopAgent | undefined;\n\n  connected: boolean = false;\n\n  channel: string = 'global';\n\n  channels: Channel[] = [];\n\n  reconnectCountdownTimer: any;\n\n  resolveCallback: ResolveCallback | undefined;\n\n  closeResolverCallback: CloseCallback | undefined;\n\n  private owner: string | undefined;\n\n  private directory: DirectoryProps | null = null;\n\n  private authenticator: ConnectifiAuthenticator;\n\n  private storageAccess: StorageAccess;\n\n  private logout: Logout;\n\n  private directoryView: DirectoryView;\n\n  private logoView: LogoView;\n\n  private container: Container;\n\n  private opener: Opener;\n\n  handleClick: ((event: MouseEvent) => void) | undefined;\n\n  constructor(\n    private interopHost: string,\n    private root: HTMLElement,\n    props: FabProps = {},\n  ) {\n    let position = props.position || 'br';\n    const validPositions = ['tl', 'ml', 'bl', 'tr', 'mr', 'br'];\n    if (validPositions.includes(position) === false) {\n      position = 'br';\n    }\n\n    this.logout = new Logout(interopHost, props.loginStyle);\n\n    const logoSrc = props.logoSrc || getLogoImageUrl(interopHost);\n    this.container = new Container(\n      logoSrc,\n      getChannelImageUrl(interopHost),\n      position,\n      this.handleChannelPicked.bind(this),\n    );\n    this.logoView = new LogoView([\n      this.container.header.logo.element,\n      this.container.resolver.header.logo.icon,\n    ]);\n    this.directoryView = new DirectoryView(\n      this.container.picker,\n      this.logoView,\n    );\n    this.authenticator = new ConnectifiAuthenticator(\n      interopHost,\n      this.container.toast,\n      this.directoryView,\n      props.loginStyle,\n    );\n    this.storageAccess = new StorageAccess(\n      interopHost,\n      this.container.toast,\n      props.loginStyle,\n    );\n    this.opener = new Opener(this.container.toast, interopHost);\n\n    this.createRoot();\n  }\n\n  // TODO sort out this last dependency on agent\n  bind(agent: FDC3Agent) {\n    this.agent = agent;\n  }\n\n  private preloadImages() {\n    [getErrorImageUrl, getWarningImageUrl].forEach((getImageUrl) =>\n      getImageInstance(getImageUrl(this.interopHost)),\n    );\n  }\n\n  handleChannelPicked(channel: string) {\n    if (channel === this.channel) {\n      this.fdc3?.leaveCurrentChannel();\n    } else {\n      this.fdc3?.joinUserChannel(channel);\n    }\n  }\n\n  createRoot() {\n    const shadowRoot = this.root.attachShadow({\n      mode: 'open',\n      slotAssignment: 'named',\n    });\n    const style = document.createElement('style');\n    style.innerHTML = styles;\n    shadowRoot.appendChild(style);\n\n    const fab = document.createElement('div');\n    fab.appendChild(this.container.element);\n    shadowRoot.appendChild(fab);\n\n    this.preloadImages();\n\n    // assign click/event handlers to elements\n    this.container.header.element.addEventListener('click', (event) => {\n      event.stopPropagation();\n      if (this.handleClick) {\n        this.handleClick(event);\n      } else {\n        this.container.picker.toggle();\n      }\n    });\n\n    // global/document handlers\n    document.addEventListener('click', (event: MouseEvent) => {\n      event.stopPropagation();\n      this.container.picker.hide();\n      if (this.container.resolver.isOpen) {\n        this.closeResolverCallback?.();\n        this.hideResolver();\n      }\n    });\n    document.addEventListener('keydown', (k: KeyboardEvent) => {\n      if (this.container.resolver.isOpen && k.code === 'Escape') {\n        this.closeResolverCallback?.();\n        this.hideResolver();\n      }\n    });\n\n    // resolver \"title bar close icon\"\n    this.container.resolver.header.dismiss.element.addEventListener(\n      'click',\n      () => {\n        this.closeResolverCallback?.();\n        this.hideResolver();\n      },\n    );\n\n    const picker = this.container.picker;\n    picker.toolbar.button.element.addEventListener('click', (event) => {\n      event.stopPropagation();\n\n      picker.hide();\n\n      if (!this.hasOwner()) {\n        return this.agent?.authenticate();\n      }\n      this.logout.open();\n    });\n\n    this.startLoading();\n  }\n\n  onChannelJoined = (channelId: string) => {\n    this.channel = channelId;\n    this.updateChannelColor();\n  };\n\n  onChannelLeft = () => {\n    this.channel = 'global';\n    this.updateChannelColor();\n  };\n\n  onSignedOut() {\n    this.owner = '';\n    this.logout.close();\n  }\n\n  onSessionStarted(directory: DirectoryProps, username?: string) {\n    this.directory = directory;\n    this.directoryView.update(directory);\n    if (username) {\n      this.owner = username;\n      this.container.picker.toolbar.button.updateOwner(\n        this.interopHost,\n        this.directory.interopStrategy,\n        this.owner,\n      );\n    }\n  }\n\n  onSessionError(errorMessage: string) {\n    this.container.toast.show({\n      title: 'Error',\n      message: errorMessage,\n      image: getImageInstance(getErrorImageUrl(this.interopHost)),\n    });\n  }\n\n  onFDC3Ready(fdc3: DesktopAgent): void {\n    this.fdc3 = fdc3;\n    fdc3.getUserChannels().then((chans: Channel[]) => {\n      this.channels = chans;\n      this.container.picker.channels.renderChannels(chans);\n      this.container.picker.canShow = true;\n    });\n  }\n\n  handleOpen(message: ConnectifiOpenMessage) {\n    this.opener.open(message);\n  }\n\n  handleAuthenticate(config: AuthenticateConfig) {\n    return this.authenticator.authenticate(config);\n  }\n\n  handleRequestStorageAccess(config: RequestStorageAccessConfig) {\n    return this.storageAccess.requestStorageAccess(config);\n  }\n\n  onSessionAuthRequired(dirProps: DirectoryProps) {\n    this.directoryView.update(dirProps);\n    this.container.picker.toolbar.button.updateOwner(\n      this.interopHost,\n      dirProps.interopStrategy,\n      undefined,\n    );\n  }\n\n  onConnected(initialConnect: boolean): void {\n    const directory = this.directory?.name as string;\n    // only show \"connect success\" toast on initial connection\n    if (initialConnect === true) {\n      this.container.toast.show({\n        title: 'Connected',\n        message: `Connected to directory '${directory}'`,\n        image: getImageInstance(getCheckImageUrl(this.interopHost)),\n      });\n    } else {\n      this.container.toast.hide();\n    }\n    this.container.header.connected(directory);\n    clearInterval(this.reconnectCountdownTimer);\n    this.stopLoading();\n  }\n\n  createReconnectButton(interopHost: string) {\n    const reconnectButton = new ReconnectButton(interopHost);\n    reconnectButton.element.addEventListener('click', () => {\n      this.agent?.connect();\n    });\n    return reconnectButton;\n  }\n\n  onDisconnected(nextConnect?: number): void {\n    this.container.header.disconnected();\n    clearInterval(this.reconnectCountdownTimer);\n    if (nextConnect !== undefined && nextConnect > 0) {\n      const nextSeconds = Math.floor(nextConnect / 1000);\n      const toastMsg = `Reconnecting in ${nextSeconds}s`;\n      if (nextSeconds > MANUAL_RECONNECT_ELAPSED_TIME) {\n        this.container.toast.show({\n          title: 'Reconnecting',\n          message: toastMsg,\n          actionElement: this.createReconnectButton(this.interopHost).element,\n          duration: -1,\n          image: getImageInstance(getWarningImageUrl(this.interopHost)),\n        });\n      } else {\n        this.container.toast.show({\n          title: 'Reconnecting',\n          message: toastMsg,\n          duration: -1,\n          image: getImageInstance(getWarningImageUrl(this.interopHost)),\n        });\n      }\n      // start the countdown timer\n      let seconds = nextSeconds;\n      this.reconnectCountdownTimer = setInterval(() => {\n        seconds = seconds > 0 ? seconds - 1 : 0;\n        this.container.toast.update(`Reconnecting in ${seconds}s`);\n      }, 1000);\n    } else {\n      // no next reconnect, permanent error\n      this.container.toast.show({\n        title: 'Disconnected',\n        message: `Disconnected from directory ${this.directory?.name}`,\n        actionElement: this.createReconnectButton(this.interopHost).element,\n        duration: -1,\n        image: getImageInstance(getErrorImageUrl(this.interopHost)),\n      });\n      this.stopLoading();\n    }\n  }\n\n  onWorkingChanged = (workInProgress: boolean) => {\n    if (workInProgress) {\n      this.startLoading();\n    } else {\n      this.stopLoading();\n    }\n  };\n\n  startLoading() {\n    this.container.header.loading();\n  }\n\n  stopLoading() {\n    this.container.header.loaded();\n  }\n\n  updateChannelColor() {\n    const uc = this.channels.find((c) => {\n      return c.id === this.channel;\n    });\n    this.container.header.setBackgroundColor(\n      uc?.displayMetadata?.color || 'black',\n    );\n  }\n\n  hasOwner() {\n    return !!this.owner;\n  }\n\n  handleIntentResolution(\n    message: IntentResolutionMessage,\n    callback: ResolveCallback,\n    closeCallback: CloseCallback,\n  ): void {\n    this.resolveCallback = callback;\n    this.closeResolverCallback = closeCallback;\n\n    this.container.resolver.open();\n    this.container.resolverBackground.open();\n\n    const onAppClicked = (\n      app: ConnectifiAppMetadata,\n      intentRes: AppIntentResult,\n      bridge: boolean,\n    ) => {\n      if (!this.resolveCallback) return;\n      this.hideResolver();\n      this.resolveCallback({\n        selected: app,\n        intent: intentRes.intent.name,\n        context: message.context,\n        bridge,\n      });\n    };\n\n    // resolver \"window title\"\n    const resTitle = this.container.resolver.header.title.containerElement;\n    const ctxName = this.getContextDisplayName(message.context);\n\n    if (message.resolutionType === ResolutionType.Intent) {\n      const result = Array.isArray(message.data)\n        ? message.data[0]\n        : message.data;\n      const intent = result.intent;\n      const title = `${intent.name} for ${ctxName}`;\n\n      resTitle.innerHTML = title;\n      resTitle.setAttribute('title', title);\n    } else if (message.resolutionType === ResolutionType.Context) {\n      resTitle.innerHTML = ctxName;\n    }\n\n    // resolver list\n    const resolverList = this.container.resolver.list;\n    resolverList.clear();\n\n    if (message.resolutionType === ResolutionType.Intent) {\n      const intentResult = Array.isArray(message.data)\n        ? message.data[0]\n        : message.data;\n\n      resolverList.renderAppRows(this.interopHost, intentResult, onAppClicked);\n      if (message.bridgeData) {\n        const bridgeResult = Array.isArray(message.bridgeData)\n          ? message.bridgeData[0]\n          : message.bridgeData;\n        resolverList.renderAppRows(\n          this.interopHost,\n          bridgeResult as AppIntentResult,\n          onAppClicked,\n          true,\n        );\n      }\n    } else if (message.resolutionType === ResolutionType.Context) {\n      const results = Array.isArray(message.data)\n        ? message.data\n        : [message.data];\n\n      results.forEach((intentRes) => {\n        resolverList.renderIntentRow(intentRes);\n        resolverList.renderAppRows(this.interopHost, intentRes, onAppClicked);\n      });\n\n      if (message.bridgeData) {\n        const bridgeResults = message.bridgeData as AppIntentResult[];\n\n        bridgeResults.forEach((intentRes: AppIntentResult) => {\n          resolverList.renderIntentRow(intentRes);\n          resolverList.renderAppRows(\n            this.interopHost,\n            intentRes,\n            onAppClicked,\n            true,\n          );\n        });\n      }\n    }\n  }\n\n  hideResolver(): void {\n    this.container.resolver.close();\n    this.container.resolverBackground.close();\n  }\n\n  getContextDisplayName(context: any) {\n    let name = context.name || context.type || '';\n\n    if (context.type === 'fdc3.instrument') {\n      name = `${context.id?.ticker} - ${context.name}`;\n    }\n\n    return name;\n  }\n}\n","import type { DesktopAgent } from '@finos/fdc3';\nimport type {\n  AgentConfig,\n  AgentConfigHandlerInfo,\n  AgentConfigInfo,\n} from './types';\nimport type { ConnectifiFab } from './fab';\nexport type { IntentContextGroup } from '@/common/apps';\n\nimport { ConnectifiAgent } from './agent';\nimport { registerIframePort } from './agent/iframe';\nimport { addToDocumentBody, hideElement } from './common/element';\nimport { parseAppId } from './common/app-id';\nimport { addSandboxAttributes } from './common/iframe';\nexport {\n  InteropStrategies,\n  ConnectifiAppMetadata,\n  IntentResultType,\n} from '@/common/types';\n\nexport {\n  AgentConfig,\n  AppIntentResult,\n  FabProps,\n  ResolveCallback,\n  CloseCallback,\n  ResolveCallbackProps,\n  IntentResolutionMessage,\n  ResolutionType,\n  AuthenticateConfig,\n  RequestStorageAccessConfig,\n  ValidPositions,\n  ConnectifiOpenMessage,\n  DirectoryProps,\n  LogLevel,\n} from './types';\n\nexport const createAgent = async (\n  interopHost: string,\n  appId: string,\n  config?: AgentConfig,\n): Promise<DesktopAgent | undefined> => {\n  if (!appId || appId.length === 0 || appId.indexOf('@') < 1) {\n    throw new Error('missing or malformed appId');\n  }\n  if (!interopHost || interopHost.length === 0) {\n    throw new Error('invalid interop host');\n  }\n\n  const interopUrl = new URL(interopHost);\n  interopHost = `${interopUrl.protocol}//${interopUrl.host}`;\n\n  const configInfo = configToInfo(config);\n\n  const root = document.createElement('div');\n  await addToDocumentBody(root);\n\n  const iframe = document.createElement('iframe');\n  addSandboxAttributes(iframe);\n  hideElement(iframe);\n  root.appendChild(iframe);\n\n  const port = await registerIframePort(iframe, interopHost, appId);\n\n  const { directory, namespace, appName } = parseAppId(appId);\n\n  let wrappedConfig = config;\n  let fab: ConnectifiFab | undefined;\n  const isFabEnabled = !config?.headless;\n  if (isFabEnabled) {\n    // Import dynamically so esbuild can code split fab.\n    const { wrapConfig, ConnectifiFab } = await import('./fab');\n    fab = new ConnectifiFab(interopHost, root, config?.props);\n    wrappedConfig = wrapConfig(fab, config || {});\n  }\n\n  const agent = new ConnectifiAgent(\n    interopHost,\n    appName,\n    namespace,\n    directory,\n    port,\n    wrappedConfig,\n    configInfo,\n  );\n  if (fab) {\n    fab.bind(agent); // FAB probably shouldn't need agent\n  }\n\n  return agent.start();\n};\n\nconst configToInfo = (\n  config: AgentConfig | undefined,\n): AgentConfigInfo | undefined => {\n  if (!config) {\n    return undefined;\n  }\n  const { logLevel, props } = config;\n  const activeHandlers = Object.entries(config).reduce(\n    (result, [key, value]) => {\n      if (\n        (key.startsWith('on') || key.startsWith('handle')) &&\n        value !== undefined\n      ) {\n        result[key as keyof AgentConfigHandlerInfo] = true;\n      }\n      return result;\n    },\n    {} as AgentConfigHandlerInfo,\n  );\n  return {\n    bridgeGlobal: config.bridgeGlobal === true,\n    headless: config.headless === true,\n    logLevel,\n    props,\n    activeHandlers,\n  };\n};\n","import type {\n  Channel,\n  Context,\n  ContextHandler,\n  DisplayMetadata,\n  Listener,\n} from '@finos/fdc3';\nimport type { SubscriptionManager } from './subscription';\nimport { AgentWebSocket } from './websocket';\n\n/**\n * the Channel class\n */\nexport class ConnectifiChannel implements Channel {\n  constructor(\n    private ws: Pick<AgentWebSocket, 'action' | 'request'>,\n    private subManager: SubscriptionManager,\n    public readonly id: string,\n    public readonly type: Channel['type'],\n    public readonly displayMetadata?: DisplayMetadata,\n  ) {}\n\n  async broadcast(context: Context): Promise<void> {\n    return this.ws.request('broadcast', { context, channel: this.id });\n  }\n\n  async getCurrentContext(contextType?: string): Promise<Context | null> {\n    const result = await this.ws.request('getCurrentContext', {\n      channel: this.id,\n      contextType,\n    });\n    return result.context;\n  }\n\n  addContextListener(handler: ContextHandler): Promise<Listener>;\n\n  addContextListener(\n    contextType: string | null,\n    handler: ContextHandler,\n  ): Promise<Listener>;\n\n  async addContextListener(\n    contextTypeOrHandler: string | null | ContextHandler,\n    handlerSecondArg?: ContextHandler,\n  ): Promise<Listener> {\n    const handler: ContextHandler =\n      typeof contextTypeOrHandler === 'function'\n        ? contextTypeOrHandler\n        : handlerSecondArg!;\n    const contextType: string =\n      typeof contextTypeOrHandler === 'string' ? contextTypeOrHandler : '*';\n\n    await this.ws.request('addContextListener', {\n      contextType: contextType,\n      channel: this.id,\n    });\n\n    return this.subManager.createContextListener(\n      this.ws,\n      contextType,\n      this.id,\n      handler,\n    );\n  }\n}\n","import type { DownResponseData } from '@/common/interop/down-messages';\nimport type {\n  AppIdentifier,\n  AppIntent,\n  AppMetadata,\n  Channel,\n  Context,\n  ContextHandler,\n  DesktopAgent,\n  ImplementationMetadata,\n  IntentResolution,\n  Listener,\n  PrivateChannel,\n} from '@finos/fdc3';\nimport type { AgentWebSocket } from './websocket';\n\nimport { ConnectifiChannel } from './channel';\nimport { SubscriptionManager } from './subscription';\n\nconst hasBridgeChannel = async (channel: string): Promise<boolean> => {\n  const bridgeChannels = await window.fdc3?.getUserChannels();\n  return bridgeChannels?.some((c) => c.id === channel);\n};\n\nconst createIntentResolution = (\n  resolution: DownResponseData['raiseIntent'],\n): IntentResolution => {\n  return {\n    source: resolution.source,\n    version: resolution.version,\n    intent: resolution.intent,\n    getResult: async () => resolution.result!,\n  };\n};\n\nexport class ConnectifiFDC3Api implements DesktopAgent {\n  constructor(\n    private ws: Pick<AgentWebSocket, 'action' | 'request'>,\n    private subManager: SubscriptionManager,\n    private bridge: boolean,\n  ) {}\n\n  open(\n    target: AppIdentifier | string,\n    context?: Context,\n  ): Promise<AppIdentifier> {\n    return this.ws.request('open', {\n      target: target,\n      context: context,\n    });\n  }\n\n  async broadcast(context: Context): Promise<void> {\n    const broadcastPromise = this.ws.request('broadcast', {\n      context: context,\n    });\n\n    if (this.bridge) {\n      await window.fdc3?.broadcast(context);\n    }\n\n    await broadcastPromise;\n  }\n\n  async raiseIntent(\n    intent: string,\n    context: Context,\n    app?: AppIdentifier | string | undefined,\n  ): Promise<IntentResolution> {\n    const resolution = await this.ws.request('raiseIntent', {\n      intent: intent,\n      target: app,\n      context: context,\n    });\n    return createIntentResolution(resolution);\n  }\n\n  async raiseIntentForContext(\n    context: Context,\n    app?: AppIdentifier | string | undefined,\n  ): Promise<IntentResolution> {\n    const resolution = await this.ws.request('raiseIntentForContext', {\n      target: app,\n      context: context,\n    });\n    return createIntentResolution(resolution);\n  }\n\n  addContextListener(handler: ContextHandler): Promise<Listener>;\n\n  addContextListener(\n    contextType: string | null,\n    handler: ContextHandler,\n  ): Promise<Listener>;\n\n  async addContextListener(\n    contextTypeOrHandler: string | null | ContextHandler,\n    handlerSecondArg?: ContextHandler,\n  ): Promise<Listener> {\n    const handler: ContextHandler =\n      typeof contextTypeOrHandler === 'function'\n        ? contextTypeOrHandler\n        : handlerSecondArg!;\n    const contextType: string =\n      typeof contextTypeOrHandler === 'string' ? contextTypeOrHandler : '*';\n\n    await this.ws.request('addContextListener', {\n      contextType: contextType,\n    });\n\n    return this.subManager.createContextListener(\n      this.ws,\n      contextType,\n      undefined,\n      handler,\n    );\n  }\n\n  async addIntentListener(\n    intent: string,\n    handler: ContextHandler,\n  ): Promise<Listener> {\n    await this.ws.request('addIntentListener', {\n      intent: intent,\n    });\n\n    return this.subManager.createIntentListener(this.ws, intent, handler);\n  }\n\n  async findIntent(intent: string, context: Context): Promise<AppIntent> {\n    return this.ws.request('findIntent', {\n      intent: intent,\n      context: context,\n    });\n  }\n\n  findIntentsByContext(context: Context): Promise<AppIntent[]> {\n    return this.ws.request('findIntentsByContext', {\n      context: context,\n    });\n  }\n\n  // Left here to satisfy Desktop Agent interface. Not used anywhere\n  async getSystemChannels(): Promise<Channel[]> {\n    return this.getUserChannels();\n  }\n\n  async getUserChannels(): Promise<Channel[]> {\n    const channels = await this.ws.request('getUserChannels', {});\n    return channels.map(\n      (c) =>\n        new ConnectifiChannel(\n          this.ws,\n          this.subManager,\n          c.id,\n          'user',\n          c.displayMetadata,\n        ),\n    );\n  }\n\n  async getOrCreateChannel(channelId: string): Promise<Channel> {\n    const channel = await this.ws.request('getOrCreateChannel', {\n      channelId,\n    });\n    return new ConnectifiChannel(\n      this.ws,\n      this.subManager,\n      channel.id,\n      // TODO: See what really should be done about system channels\n      channel.type as Channel['type'],\n      channel.displayMetadata,\n    );\n  }\n\n  async joinChannel(channel: string): Promise<void> {\n    const joinChannelPromise = this.ws.request('joinChannel', { channel });\n\n    if (this.bridge) {\n      const isBridgeChannel = await hasBridgeChannel(channel);\n      if (isBridgeChannel) {\n        if (window.fdc3.joinUserChannel) {\n          window.fdc3.joinUserChannel(channel);\n        } else if (window.fdc3.joinChannel) {\n          window.fdc3.joinChannel(channel);\n        }\n      }\n    }\n\n    await joinChannelPromise;\n  }\n\n  async joinUserChannel(channel: string): Promise<void> {\n    const joinChannelPromise = this.ws.request('joinChannel', { channel });\n\n    if (this.bridge) {\n      const isBridgeChannel = await hasBridgeChannel(channel);\n      if (isBridgeChannel) {\n        if (window.fdc3.joinUserChannel) {\n          window.fdc3.joinUserChannel(channel);\n        } else if (window.fdc3.joinChannel) {\n          window.fdc3.joinChannel(channel);\n        }\n      }\n    }\n\n    await joinChannelPromise;\n  }\n\n  async leaveCurrentChannel(): Promise<void> {\n    const leaveChannelPromise = this.ws.request('leaveCurrentChannel', {});\n\n    if (this.bridge) {\n      const channel = await this.getCurrentChannel();\n      if (channel) {\n        const isBridgeChannel = await hasBridgeChannel(channel.id);\n        if (isBridgeChannel) {\n          window.fdc3.leaveCurrentChannel();\n        }\n      }\n    }\n\n    await leaveChannelPromise;\n  }\n\n  async getCurrentChannel(): Promise<Channel | null> {\n    const channel = await this.ws.request('getCurrentChannel', {});\n    if (!channel) {\n      return null;\n    }\n\n    return new ConnectifiChannel(\n      this.ws,\n      this.subManager,\n      channel.id,\n      channel.type as Channel['type'],\n      channel.displayMetadata,\n    );\n  }\n\n  getInfo(): Promise<ImplementationMetadata> {\n    return this.ws.request('getInfo', {});\n  }\n\n  findInstances(app: AppIdentifier): Promise<AppIdentifier[]> {\n    return this.ws.request('findInstances', app);\n  }\n\n  getAppMetadata(app: AppIdentifier): Promise<AppMetadata> {\n    return this.ws.request('getAppMetadata', app);\n  }\n\n  createPrivateChannel(): Promise<PrivateChannel> {\n    return this.ws.request('createPrivateChannel', {});\n  }\n}\n","import type { DesktopAgent } from '@finos/fdc3';\n\nimport { ConnectifiFDC3Api } from './api';\nimport {\n  FDC3Agent,\n  Logger,\n  AgentConfig,\n  ResolveCallbackProps,\n  IntentResolutionMessage,\n  ResolutionType,\n  DownEventHandlers,\n  DownResponseHandlerMap,\n  DirectoryProps,\n  AgentConfigInfo,\n  RedirectStyle,\n} from '../types';\n\nimport {\n  DownEvent,\n  DownEventData,\n  DownEventTopic,\n  DownResponse,\n  DownResponseData,\n  DownResponseTopic,\n} from '@/common/interop/down-messages';\nimport { InteropStrategies } from '@/common/types';\nimport {\n  TunnelResponse,\n  TunnelResponseTopic,\n  TunnelSessionErrorResponse,\n} from '@/common/interop/tunnel';\n\nimport { SubscriptionManager } from './subscription';\nimport { Tunnel } from './tunnel';\nimport { AgentWebSocket } from './websocket';\n\nimport { Envelope } from '@/common/interop/envelope';\nimport { createLogger } from '../common/logger';\nimport { isPortTimeoutError, portTimeoutError } from '../common/port';\nimport {\n  requestConsent,\n  waitForStorageAccess,\n  createStorageAccessIframe,\n} from './storage-access';\nimport { createAppId } from '../common/app-id';\nimport {\n  authenticate,\n  AuthTargetType,\n  getAuthenticationUrl,\n} from './authentication';\nimport { hasStorageAccess } from './iframe';\n\n// default/global fdc3 channel id\nconst GLOBAL_CHANNEL = 'global';\n\n// pending id prefix - if pending id starts with this, we can reliably use window.name\nconst PENDING_ID_PREFIX = '_cfi_';\n\n// error message when server rejects the app identity\nexport const APP_IDENTITY_ERROR_MSG = 'invalid app identity';\n\nexport class ConnectifiAgent implements FDC3Agent {\n  // build/compile time variable\n  version: string | undefined = process.env.AGENT_VERSION;\n\n  // agent properties (createAgent/ctor args)\n  config: AgentConfig;\n  configInfo: AgentConfigInfo | undefined;\n\n  // agent state\n  currentChannel = GLOBAL_CHANNEL;\n  // TODO - currently open resolver modal state !!!! ???\n  // this is pendingEventId for an open intent resolver UI - these must be modal\n  resolverPendingEventId: string | undefined;\n\n  // fdc3 api - created/returned in createAgent\n  fdc3: DesktopAgent;\n\n  ws: AgentWebSocket;\n\n  pendingId: string | undefined;\n\n  logger: Logger;\n\n  subManager = new SubscriptionManager();\n\n  tunnel: Tunnel;\n\n  hasNeverBeenConnected: boolean = true;\n\n  constructor(\n    private interopHost: string,\n    private appName: string,\n    private namespace: string,\n    private directoryName: string,\n    private port: MessagePort,\n    config?: AgentConfig,\n    configInfo?: AgentConfigInfo,\n  ) {\n    this.config = { ...config };\n    this.configInfo = configInfo;\n\n    this.logger = createLogger(config?.logLevel || 'info', config?.logger);\n\n    this.ws = new AgentWebSocket(port, this.logger);\n    this.tunnel = new Tunnel(\n      port,\n      this.logger,\n      document.location.href,\n      document.title,\n    );\n\n    this.fdc3 = new ConnectifiFDC3Api(\n      this.ws,\n      this.subManager,\n      this.config.bridgeGlobal || false,\n    );\n  }\n\n  handleWebsocketConnect(): void {\n    // send version and pendingId on initial connect\n    if (this.hasNeverBeenConnected) {\n      this.ws.action('updateInstance', {\n        pendingId: this.pendingId,\n        version: this.version,\n        config: this.configInfo,\n      });\n      window.name = '';\n      this.config.onFDC3Ready?.(this.fdc3);\n    }\n    this.config.onConnected?.(this.hasNeverBeenConnected);\n    this.hasNeverBeenConnected = false;\n  }\n\n  setWorkingState(workInProgress: boolean): void {\n    this.config.onWorkingChanged?.call(this, workInProgress);\n  }\n\n  // start promise is also rejected when these events occur\n  onAppIdentityError(): void {\n    this.setWorkingState(false);\n    this.config.onSessionError?.(APP_IDENTITY_ERROR_MSG);\n  }\n\n  handleTunnelTimeout(): void {\n    this.setWorkingState(false);\n    this.config.onSessionError?.(portTimeoutError.message);\n  }\n\n  mustTunnelInstanceId() {\n    const instanceId = this.tunnel.instance?.id;\n    if (!instanceId) {\n      throw new Error('Tunnel instance ID is undefined.');\n    }\n    return instanceId;\n  }\n\n  async ensureStorageAccess() {\n    if (await hasStorageAccess(this.port)) {\n      return;\n    }\n\n    const button = createStorageAccessIframe(\n      this.interopHost,\n      createAppId(this.appName, this.namespace, this.directoryName),\n    );\n    await this.config.handleRequestStorageAccess?.({\n      button,\n      waitForStorageAccess,\n      requestConsent: requestConsent.bind(\n        undefined,\n        this.interopHost,\n        this.namespace,\n        this.directoryName,\n      ),\n    });\n\n    await this.ensureStorageAccess();\n  }\n\n  async connect() {\n    return this.ws.connect(\n      this.namespace,\n      this.directoryName,\n      this.mustTunnelInstanceId(),\n    );\n  }\n\n  async handleWindowOnline() {\n    this.logger.debug('browser online, connecting');\n    await this.connect();\n  }\n\n  handleWindowOffline() {\n    // destroy all reconnects, only online mode can save us now\n    this.logger.debug(\n      'browser offline, canceling reconnects, waiting for online event',\n    );\n    this.ws.disconnect();\n  }\n\n  handleLogoutComplete() {\n    this.setWorkingState(false);\n    this.config.onSignedOut?.();\n    // reload tunnel to re-initialize login prompt\n    return this.touchTunnelAndHandleResponse(true);\n  }\n\n  async handleStartSession(\n    directory: string,\n    owner: string,\n    icon: string | undefined,\n    interopStrategy: InteropStrategies,\n  ) {\n    const dirProps: DirectoryProps = {\n      name: directory,\n      interopStrategy,\n    };\n    if (icon) {\n      dirProps.icon = `${this.interopHost}/${icon}`;\n    }\n    this.config.onSessionStarted?.(dirProps, owner);\n    await this.connect();\n\n    this.setWorkingState(false);\n  }\n\n  // TODO: Refactor login.\n  async handleLogin(event: MessageEvent) {\n    const { data } = event;\n    if (typeof data !== 'string') return;\n    try {\n      const { topic } = JSON.parse(data);\n      if (topic === 'logout') {\n        this.handleLogoutComplete();\n      }\n    } catch (err) {\n      // Ignore message unrelated to login.\n    }\n  }\n\n  async handleSessionError(response: TunnelSessionErrorResponse) {\n    const { directory, icon, interopStrategy } = response;\n\n    this.logger.debug('session requires authentication', response);\n\n    const dirProps: DirectoryProps = {\n      name: directory,\n      interopStrategy: interopStrategy as InteropStrategies,\n    };\n    if (icon) {\n      dirProps.icon = `${this.interopHost}/${icon}`;\n    }\n\n    this.setWorkingState(false);\n\n    this.config.onSessionAuthRequired?.(dirProps);\n\n    const handleAuthenticate = this.config.handleAuthenticate;\n    if (!handleAuthenticate) {\n      return;\n    }\n\n    this.logger.debug('requesting and waiting for authentication ', response);\n\n    await handleAuthenticate({\n      ...dirProps,\n      authenticate: authenticate.bind(undefined, this.interopHost),\n      getAuthenticationUrl: (targetType?: AuthTargetType) => {\n        return getAuthenticationUrl(this.interopHost, targetType);\n      },\n    });\n\n    this.setWorkingState(true);\n    this.config.onSignedIn?.();\n\n    this.logger.debug(\n      'reloading tunnel due to authentication success',\n      response,\n    );\n\n    await this.touchTunnelAndHandleResponse();\n  }\n\n  handleIdentityError() {\n    this.setWorkingState(false);\n    this.onAppIdentityError();\n    throw new Error(APP_IDENTITY_ERROR_MSG);\n  }\n\n  async handleTunnelResponse(response: TunnelResponse): Promise<void> {\n    const isStartSession = response.topic === TunnelResponseTopic.StartSession;\n\n    // prefer window.name if correct format, otherwise use the pendingId in the message\n    this.pendingId = window.name.startsWith(PENDING_ID_PREFIX)\n      ? window.name.substring(5)\n      : isStartSession\n      ? response.pendingId\n      : undefined;\n\n    const isSessionError = response.topic === TunnelResponseTopic.SessionError;\n\n    const isDirectoryMismatch =\n      (isStartSession || isSessionError) &&\n      (this.directoryName !== response.directory ||\n        this.namespace != response.namespace);\n    if (isDirectoryMismatch) {\n      const errMessage = `received response from tunnel with mismatching directory: expected ${this.directoryName}, got ${response.directory}`;\n      this.logger.error(errMessage, response);\n      throw new Error(errMessage);\n    }\n\n    if (isStartSession) {\n      const { directory, owner, interopStrategy, icon } = response;\n      await this.handleStartSession(\n        directory,\n        owner,\n        icon,\n        interopStrategy as InteropStrategies,\n      );\n    } else if (response.topic === TunnelResponseTopic.IdentityError) {\n      this.handleIdentityError();\n    } else if (isSessionError) {\n      await this.handleSessionError(response);\n    }\n  }\n\n  async touchTunnelAndHandleResponse(reset: boolean = false) {\n    await this.ensureStorageAccess();\n    if (reset) {\n      this.tunnel.resetInstance();\n    }\n    const tunnelResponse = await this.tunnel.touch().catch((err) => {\n      if (isPortTimeoutError(err)) {\n        this.handleTunnelTimeout();\n      } else {\n        this.logger.error(`failed to touch tunnel`, err);\n      }\n      throw err;\n    });\n    return this.handleTunnelResponse(tunnelResponse);\n  }\n\n  async start() {\n    window.addEventListener('message', this.handleLogin.bind(this));\n    window.addEventListener('online', this.handleWindowOnline.bind(this));\n    window.addEventListener('offline', this.handleWindowOffline.bind(this));\n\n    this.ws.addEventListener('working', this.handleWebsocketWorking.bind(this));\n    this.ws.addEventListener('connect', this.handleWebsocketConnect.bind(this));\n    this.ws.addEventListener(\n      'disconnect',\n      this.handleWebsocketDisconnect.bind(this),\n    );\n    this.ws.addEventListener('message', this.handleWebsocketMessage.bind(this));\n\n    await this.touchTunnelAndHandleResponse();\n\n    return this.fdc3;\n  }\n\n  handleContextEvent(data: DownEventData['contextEvent']) {\n    this.createPendingTitleCheck();\n    this.subManager.callContextListeners(\n      this.currentChannel,\n      data.context,\n      data.channel,\n    );\n    if (window.fdc3 && this.shouldBridgeGlobal()) {\n      window.fdc3.broadcast(data.context);\n    }\n  }\n\n  async handleIntentEvent(data: DownEventData['intentEvent']) {\n    this.createPendingTitleCheck();\n    const result = await this.subManager.callIntentListener(\n      data.intent || '',\n      data.context,\n    );\n    //send completeIntent back to service\n    this.ws.action('completeIntent', {\n      intent: data.intent,\n      resultPendingId: data.resultPendingId,\n      result: result,\n    });\n  }\n\n  handleOpenEvent(data: DownEventData['openEvent']) {\n    if (this.config.handleOpen) {\n      return this.config.handleOpen.call(this, {\n        name: data.name,\n        appId: data.pendingId,\n        url: data.url,\n      });\n    }\n    if (data.url) {\n      return window.open(data.url);\n    }\n  }\n\n  handleJoinChannelResponse(data: DownResponseData['joinChannel']) {\n    if (data.channel) {\n      this.currentChannel = data.channel;\n      this.config.onChannelJoined?.(data.channel);\n    }\n  }\n\n  handleLeaveChannelResponse() {\n    this.currentChannel = 'global';\n    this.config.onChannelLeft?.();\n  }\n\n  sendIntentResolutionMessage(irm: IntentResolutionMessage) {\n    this.setWorkingState(false);\n    if (this.config.handleIntentResolution) {\n      this.config.handleIntentResolution(\n        irm,\n        this.resolveResolver.bind(this),\n        this.closeResolver.bind(this),\n      );\n    } else {\n      this.logger.error('no resolver handler configured');\n    }\n  }\n\n  async handleRaiseIntentResolutionEvent(\n    data: DownEventData['intent-resolver'],\n  ) {\n    const { context, intent } = data;\n\n    this.resolverPendingEventId = data.pendingEventId;\n    const irm: IntentResolutionMessage = {\n      resolutionType: ResolutionType.Intent,\n      context,\n      data,\n    };\n\n    if (intent && window.fdc3 && this.shouldBridgeGlobal()) {\n      const appIntent = await window.fdc3.findIntent(intent.name, irm.context);\n\n      irm.bridgeData = {\n        intent,\n        apps: appIntent.apps,\n      };\n    }\n\n    this.sendIntentResolutionMessage(irm);\n  }\n\n  async handleRaiseIntentForContextResolutionEvent({\n    pendingEventId,\n    context,\n    data,\n  }: DownEventData['context-resolver']) {\n    this.resolverPendingEventId = pendingEventId;\n    const irm = {\n      resolutionType: ResolutionType.Context,\n      context,\n      data,\n    } as IntentResolutionMessage;\n\n    if (window.fdc3 && this.shouldBridgeGlobal()) {\n      const intentResult = await window.fdc3.findIntentsByContext(irm.context);\n      irm.bridgeData = intentResult;\n    }\n\n    this.sendIntentResolutionMessage(irm);\n  }\n\n  eventHandlerMap: DownEventHandlers = {\n    'context-resolver': (data) =>\n      this.handleRaiseIntentForContextResolutionEvent(data),\n    'intent-resolver': (data) => this.handleRaiseIntentResolutionEvent(data),\n    intentEvent: (data) => this.handleIntentEvent(data),\n    contextEvent: (data) => this.handleContextEvent(data),\n    openEvent: (data) => this.handleOpenEvent(data),\n    errorEvent: (data) =>\n      this.logger.error('Received Error from server: ', data.error),\n  };\n\n  handleWebsocketEvent<TTopic extends DownEventTopic>({\n    topic,\n    data,\n  }: DownEvent<TTopic>) {\n    const handler = this.eventHandlerMap[topic];\n    handler(data);\n  }\n\n  responseSpyHandlers: Partial<DownResponseHandlerMap> = {\n    joinChannel: (data) => this.handleJoinChannelResponse(data),\n    leaveCurrentChannel: () => this.handleLeaveChannelResponse(),\n  };\n  handleWebsocketResponse<TTopic extends DownResponseTopic>({\n    topic,\n    data,\n  }: DownResponse<TTopic>) {\n    const handler = this.responseSpyHandlers[topic];\n    if (handler) handler(data);\n  }\n\n  handleWebsocketMessage(envelope: Envelope) {\n    if (!envelope.eventId) {\n      return this.handleWebsocketEvent(envelope as DownEvent<DownEventTopic>);\n    }\n    return this.handleWebsocketResponse(\n      envelope as DownResponse<DownResponseTopic>,\n    );\n  }\n\n  handleWebsocketWorking(isWorking: boolean) {\n    this.setWorkingState(isWorking);\n  }\n\n  handleWebsocketDisconnect(retryInMillis: number) {\n    this.config.onDisconnected?.(retryInMillis);\n  }\n\n  authenticate(redirectStyle?: RedirectStyle) {\n    return authenticate(this.interopHost, redirectStyle);\n  }\n\n  //exit the current resolver state without resolving\n  closeResolver() {\n    this.ws.action('completeIntent', {\n      resultPendingId: this.resolverPendingEventId!,\n    });\n  }\n\n  createPendingTitleCheck() {\n    const instance = this.tunnel.instance;\n    if (!instance) return;\n    setTimeout(() => {\n      if (document.title === instance.title) return;\n\n      this.logger.info(\n        `updating instance title - old: ${instance.title}, new: ${document.title}`,\n      );\n      instance.title = document.title;\n      this.ws.action('updateInstance', {\n        title: document.title,\n        url: document.location.href,\n      });\n    }, 500);\n  }\n\n  // resolution - app selected by user\n  // raiseIntent to the bridge or send to interop server\n  resolveResolver({\n    context,\n    intent,\n    selected,\n    bridge,\n    metadata,\n  }: ResolveCallbackProps) {\n    if (bridge && window.fdc3) {\n      this.logger.debug('opening with fdc3 global bridge', selected);\n      window.fdc3.raiseIntent(intent, context, {\n        appId: selected.appId,\n      });\n      return;\n    }\n    this.ws.action('resolveIntent', {\n      selected: {\n        name: selected.name,\n        id: selected.id,\n        type: selected.type,\n      },\n      intent: intent,\n      context: context,\n      pendingEventId: this.resolverPendingEventId!,\n      metadata,\n    });\n  }\n\n  shouldBridgeGlobal() {\n    return this.config.bridgeGlobal || false;\n  }\n}\n","export function promiseIsFulfilled<T>(\n  result: PromiseSettledResult<T>,\n): result is PromiseFulfilledResult<T> {\n  return result.status === 'fulfilled';\n}\n","export function createContextListenerKey(\n  contextType: string | undefined,\n  channel: string | undefined,\n) {\n  return `${contextType ?? '*'}${channel ? `|${channel}` : ''}`;\n}\n","import type { AgentWebSocket } from './websocket';\nimport type {\n  Context,\n  ContextHandler,\n  IntentHandler,\n  Listener,\n} from '@finos/fdc3';\n\nimport { promiseIsFulfilled } from '../common/promise';\nimport { createContextListenerKey } from '@/common/interop/subscriptions';\n\nexport class Subscription<T> {\n  public readonly id = crypto.randomUUID();\n  constructor(public readonly handler: T) {}\n}\n\nexport class SubscriptionManager {\n  constructor(\n    private contextListeners: Map<\n      string,\n      Subscription<ContextHandler>[]\n    > = new Map(),\n    private intentListeners: Map<\n      string,\n      Subscription<IntentHandler>[]\n    > = new Map(),\n  ) {}\n\n  async callIntentListener(\n    intent: string,\n    context?: Context,\n  ): Promise<Context | void> {\n    const listeners = this.intentListeners.get(intent);\n    if (!listeners) {\n      return;\n    }\n\n    const allSettled = await Promise.allSettled(\n      listeners.map((l) =>\n        // Need the Promise.resolve since the handler can be synchronous\n        Promise.resolve(\n          (l.handler as IntentHandler).call(\n            window,\n            context || { type: 'fdc3.nothing' },\n          ),\n        ),\n      ),\n    );\n    const results = allSettled\n      .filter(promiseIsFulfilled)\n      .map((p) => p.value)\n      .filter(Boolean) as Context[];\n\n    if (results.length === 0) {\n      return;\n    }\n\n    if (results.length === 1) {\n      return results[0];\n    }\n\n    return {\n      type: 'connectifi.intentResults',\n      results: results,\n    };\n  }\n\n  callContextListeners = (\n    currentChannel: string,\n    context: Context,\n    contextChannel?: string,\n  ) => {\n    let listeners: Subscription<ContextHandler>[] = [];\n    // if context is for current channel, include any \"channel-less\" listeners\n    if (currentChannel === contextChannel || contextChannel === undefined) {\n      // listeners for all contexts\n      const l = this.contextListeners.get('*');\n\n      if (l) {\n        listeners = listeners.concat(...l);\n      }\n\n      // listeners for context type\n      const lc = this.contextListeners.get(context.type);\n\n      if (lc) {\n        listeners = listeners.concat(...lc);\n      }\n    }\n\n    // channel listeners for all contexts\n    const cl = this.contextListeners.get(`*|${contextChannel}`);\n\n    if (cl) {\n      listeners = listeners.concat(...cl);\n    }\n\n    // channel listeners for context type\n    const clc = this.contextListeners.get(`${context.type}|${contextChannel}`);\n\n    if (clc) {\n      listeners = listeners.concat(...clc);\n    }\n\n    for (const listener of listeners) {\n      listener.handler.call(window, context);\n    }\n  };\n\n  dropContextListener(type: string, id: string): boolean {\n    const listeners = this.contextListeners.get(type) || [];\n    for (let i = 0; i < listeners.length; i++) {\n      if (listeners[i].id === id) {\n        listeners.splice(i, 1);\n      }\n    }\n\n    return Boolean(!listeners.length);\n  }\n\n  createContextListener(\n    ws: Pick<AgentWebSocket, 'action' | 'request'>,\n    contextType: string,\n    channel: string | undefined,\n    handler: ContextHandler,\n  ): Listener {\n    const listenerItem = new Subscription(handler);\n    const key = createContextListenerKey(contextType, channel);\n    if (this.contextListeners.has(key)) {\n      const listeners = this.contextListeners.get(key);\n      listeners?.push(listenerItem);\n    } else {\n      this.contextListeners.set(key, [listenerItem]);\n    }\n\n    return {\n      unsubscribe: () => {\n        const noRemaining = this.dropContextListener(key, listenerItem.id);\n        if (noRemaining) {\n          ws.action('dropContextListener', {\n            type: key,\n          });\n        }\n      },\n    };\n  }\n\n  dropIntentListener(intent: string, id: string): boolean {\n    const listeners = this.intentListeners.get(intent) || [];\n    for (let i = 0; i < listeners.length; i++) {\n      if (listeners[i].id === id) {\n        listeners.splice(i, 1);\n      }\n    }\n\n    return Boolean(!listeners.length);\n  }\n\n  createIntentListener(\n    ws: Pick<AgentWebSocket, 'action' | 'request'>,\n    intent: string,\n    handler: IntentHandler,\n  ): Listener {\n    const listenerItem = new Subscription(handler);\n    if (this.intentListeners.has(intent)) {\n      const listeners = this.intentListeners.get(intent);\n      listeners?.push(listenerItem);\n    } else {\n      this.intentListeners.set(intent, [listenerItem]);\n    }\n\n    return {\n      unsubscribe: () => {\n        const noRemaining = this.dropIntentListener(intent, listenerItem.id);\n        if (noRemaining) {\n          ws.action('dropIntentListener', {\n            intent,\n          });\n        }\n      },\n    };\n  }\n}\n","export function postMessageToIframe<TMessage>(\n  iframe: {\n    contentWindow?: { postMessage: Window['postMessage'] } | null;\n  },\n  origin: string,\n  port: MessagePort,\n  message: TMessage,\n) {\n  iframe.contentWindow?.postMessage(JSON.stringify(message), origin, [port]);\n}\n\nexport function addSandboxAttributes(iframe: HTMLIFrameElement) {\n  iframe.sandbox.add(\n    'allow-storage-access-by-user-activation',\n    'allow-scripts',\n    'allow-same-origin',\n    'allow-popups',\n  );\n}\n\nexport function getIframeUrl(\n  interopHost: string,\n  appId: string,\n  bundle: string,\n) {\n  return `${interopHost}/api/iframe/${appId}/${bundle}`;\n}\n","export const portTimeoutError = new Error(\n  'timed out waiting for iframe message',\n);\n\nexport function isPortTimeoutError(err: unknown) {\n  return portTimeoutError === err;\n}\n\nexport function waitForPortMessage<TMessage extends { topic: string }>(\n  port: MessagePort,\n  topics: Array<TMessage['topic']>,\n  timeoutMs: number = 15000,\n) {\n  const topicsSet = new Set(topics);\n  return new Promise<TMessage>((res, rej) => {\n    const timeout =\n      timeoutMs > 0\n        ? window.setTimeout(() => {\n            port.removeEventListener('message', listener);\n            rej(portTimeoutError);\n          }, timeoutMs)\n        : undefined;\n    const listener = (event: MessageEvent) => {\n      try {\n        const response: TMessage = JSON.parse(event.data);\n        if (!topicsSet.has(response.topic)) return;\n        res(response);\n        clearTimeout(timeout);\n        port.removeEventListener('message', listener);\n      } catch (err) {\n        // ignored\n      }\n    };\n    port.addEventListener('message', listener);\n  });\n}\n\nexport function postMessageToPort<TMessage extends { topic: string }>(\n  port: MessagePort,\n  message?: TMessage,\n) {\n  if (!message) return;\n  port.postMessage(JSON.stringify(message));\n}\n","import type {\n  IframeConnectRequest,\n  IframeHandshakeRequest,\n  IframeHandshakeResponse,\n  IframeHasStorageAccessResponse,\n  IframeOpenResponse,\n  IframeTunnelRequest,\n} from '@/common/interop/iframe';\nimport type { UpMessage } from '@/common/interop/up-messages';\n\nimport { getIframeUrl, postMessageToIframe } from '../common/iframe';\nimport { postMessageToPort, waitForPortMessage } from '../common/port';\nimport { TunnelResponse, TunnelResponseTopic } from '@/common/interop/tunnel';\n\nasync function mustEmbedIframe(iframeUrl: string) {\n  const res = await fetch(iframeUrl, {\n    method: 'GET',\n    headers: {\n      Accept: 'application/json',\n    },\n  });\n  if (res.status !== 200) {\n    const json = await res.json();\n    throw new Error(`failed to embed iframe: ${json?.reason}`);\n  }\n}\n\nexport async function registerIframePort(\n  iframe: HTMLIFrameElement,\n  interopHost: string,\n  appId: string,\n) {\n  const iframeUrl = getIframeUrl(interopHost, appId, 'agent-iframe.bundle.js');\n  await mustEmbedIframe(iframeUrl);\n\n  const channel = new MessageChannel();\n\n  channel.port1.start();\n  const handshakePromise = waitForPortMessage<IframeHandshakeResponse>(\n    channel.port1,\n    ['handshake'],\n  );\n\n  const handleLoad = () => {\n    postMessageToIframe<IframeHandshakeRequest>(\n      iframe,\n      interopHost,\n      channel.port2,\n      {\n        topic: 'handshake',\n      },\n    );\n  };\n  iframe.addEventListener('load', handleLoad);\n\n  iframe.src = iframeUrl;\n  await handshakePromise;\n\n  return channel.port1;\n}\n\nexport function tunnel(\n  port: MessagePort,\n  message: Omit<IframeTunnelRequest, 'topic'>,\n) {\n  postMessageToPort(port, {\n    topic: 'tunnel',\n    ...message,\n  });\n  return waitForPortMessage<TunnelResponse>(port, [\n    TunnelResponseTopic.IdentityError,\n    TunnelResponseTopic.RefreshSession,\n    TunnelResponseTopic.SessionError,\n    TunnelResponseTopic.StartSession,\n  ]);\n}\n\nexport async function connectWebSocket(\n  port: MessagePort,\n  message: Omit<IframeConnectRequest, 'topic'>,\n) {\n  postMessageToPort(port, {\n    topic: 'connect',\n    ...message,\n  });\n  await waitForPortMessage<IframeOpenResponse>(port, ['open']);\n}\n\nexport function closeWebSocket(port: MessagePort) {\n  postMessageToPort(port, { topic: 'close' });\n}\n\nexport function sendWebSocketMessage(port: MessagePort, message: UpMessage) {\n  postMessageToPort(port, {\n    topic: 'send',\n    message: JSON.stringify(message),\n  });\n}\n\nexport async function hasStorageAccess(port: MessagePort) {\n  postMessageToPort(port, { topic: 'has-storage-access' });\n  const response = await waitForPortMessage<IframeHasStorageAccessResponse>(\n    port,\n    ['has-storage-access'],\n    -1,\n  );\n  return response.hasStorageAccess;\n}\n","import type { Logger } from '../types';\n\nimport { TunnelResponse, TunnelResponseTopic } from '@/common/interop/tunnel';\nimport { tunnel } from './iframe';\n\n/**\n * Represents an interop session instance established via the tunnel.\n */\nexport class TunnelInstance {\n  public id: string;\n  public title = document.title;\n\n  constructor(id: string) {\n    this.id = id;\n  }\n}\n\n/**\n * The Tunnel class encapsulates an iframe that navigates to the Connectifi interop host's tunnel endpoint.\n * This endpoint plays a crucial role in validating and authenticating the current user, facilitating\n * the establishment of an interop session.\n *\n * Upon successful session establishment, users gain access to connect to the interop server's WebSocket endpoint.\n * Attempting to connect to this WebSocket endpoint without a previously established interop session through the\n * tunnel will result in a forbidden access response.\n */\nexport class Tunnel {\n  private nextRefresh = 0;\n  private refreshSessionTimer: number | undefined;\n\n  constructor(\n    private port: MessagePort,\n    private logger: Logger,\n    private appUrl: string,\n    private appTitle: string,\n  ) {}\n\n  /**\n   * An instance will be instantiated when an interop session is successfully established.\n   */\n  public instance: TunnelInstance | undefined;\n\n  private createInstance(instanceId: string) {\n    this.instance = new TunnelInstance(instanceId);\n  }\n\n  private clearRefreshSession() {\n    clearInterval(this.refreshSessionTimer); // kill session refresh watcher\n  }\n\n  /**\n   * An interop session is only valid for limited period of time defined by the server.\n   * Once a session has expired the WebSocket is unusable and must be closed.\n   * However, by calling the tunnel we can refresh and extend the length of our session.\n   *\n   * @param expiresMs the UTC time in milliseconds that the session expires.\n   */\n  private scheduleRefreshSession(refreshInMs: number | undefined) {\n    if (!refreshInMs) return;\n    this.logger.debug(`schedule session refresh in ${refreshInMs}ms`, {\n      refreshInMs,\n    });\n    this.nextRefresh = new Date().getTime() + refreshInMs;\n    this.refreshSessionTimer = window.setInterval(() => {\n      const now = new Date().getTime();\n      if (now > this.nextRefresh) {\n        this.logger.debug(`calling tunnel to refresh session`);\n        this.clearRefreshSession(); // tunnel reload will trigger scheduleRefreshSession\n        this.touch();\n      }\n    }, 5000);\n  }\n\n  private handleTunnelResponse(response: TunnelResponse) {\n    const isStartSession = response.topic === TunnelResponseTopic.StartSession;\n    const isRefreshSession =\n      response.topic === TunnelResponseTopic.RefreshSession;\n    if (isStartSession) {\n      this.createInstance(response.instanceId);\n    }\n    if (isStartSession || isRefreshSession) {\n      this.scheduleRefreshSession(response.refreshInMs);\n    }\n  }\n\n  async resetInstance() {\n    if (!this.instance) {\n      return;\n    }\n    // this should ensure a session/instanceId is created\n    this.instance.id = '';\n  }\n\n  async touch() {\n    const response = await tunnel(this.port, {\n      instanceId: this.instance?.id,\n      instanceTitle: this.appTitle,\n      instanceUrl: this.appUrl,\n    });\n    this.handleTunnelResponse(response);\n    return response;\n  }\n}\n","export type Envelope<TTopic = string, TData = unknown> = {\n  eventId?: string;\n  topic: TTopic;\n  data: TData;\n};\n\nexport function isErrorEnvelope(\n  envelope: Envelope,\n): envelope is Envelope<'error', { error: string }> {\n  return envelope.topic === 'error';\n}\n","import type {\n  UpAction,\n  UpActionData,\n  UpActionTopic,\n  UpMessage,\n  UpRequest,\n  UpRequestData,\n  UpTopic,\n} from '@/common/interop/up-messages';\nimport type {\n  IframeCloseResponse,\n  IframeResponse,\n} from '@/common/interop/iframe';\nimport type { RoundTripTopic } from '@/common/interop/round-trip';\nimport type { DownResponseData } from '@/common/interop/down-messages';\n\nimport { Envelope, isErrorEnvelope } from '@/common/interop/envelope';\n\nimport { ConnectionError, Logger } from '../types';\nimport { EventEmitter } from '../common/event-emitter';\nimport {\n  closeWebSocket,\n  connectWebSocket,\n  sendWebSocketMessage,\n} from './iframe';\n\nexport class AgentWebSocket extends EventEmitter {\n  private hasAddedListeners = false;\n\n  private connected = false;\n  private neverBeenConnected = true;\n  private connectAttempts = 1;\n\n  private autoReconnect = true;\n  private reconnectTimer: number | undefined;\n\n  private pendingEventIds = new Set<string>();\n\n  constructor(\n    private port: MessagePort,\n    private logger: Logger,\n    /** Max reconnect intterval in milliseconds. */\n    private maxReconnectInterval: number = 60000,\n    /** Max number of reconnects before giving up.*/\n    private maxReconnectAttempts: number = 77,\n  ) {\n    super();\n  }\n\n  private clearReconnect() {\n    this.connectAttempts = 1;\n    clearTimeout(this.reconnectTimer);\n  }\n\n  // calculate the next connection retry interval\n  // exponential backoff with jitter\n  private calcReconnectInterval(): number {\n    let retryInterval: number = (Math.pow(2, this.connectAttempts) - 1) * 1000;\n\n    if (retryInterval > this.maxReconnectInterval) {\n      retryInterval = this.maxReconnectInterval;\n    }\n\n    // jitter is random number between +/- 10% of retry interval\n    const jitter =\n      Math.random() * retryInterval * 0.1 * (Math.random() >= 0.5 ? 1 : -1);\n\n    return retryInterval + jitter;\n  }\n\n  private scheduleReconnect(\n    namespace: string,\n    directory: string,\n    instanceId: string,\n  ) {\n    const reconnectMillis = this.calcReconnectInterval();\n\n    this.logger.debug(`scheduleReconnect in ${reconnectMillis}ms`);\n\n    this.reconnectTimer = window.setTimeout(() => {\n      this.connectAttempts++;\n      if (this.connectAttempts > this.maxReconnectAttempts) {\n        this.clearReconnect();\n        this.logger.error(\n          'connection permanent failure, manual reconnection required',\n        );\n        this.handleDisconnected();\n        return;\n      }\n\n      this.connect(namespace, directory, instanceId);\n    }, reconnectMillis);\n\n    return reconnectMillis;\n  }\n\n  private handleOpen() {\n    this.logger.debug('connected to connectifi service');\n    this.clearReconnect();\n    this.connected = true;\n    this.emit('connect', this.neverBeenConnected);\n    this.neverBeenConnected = false;\n  }\n\n  private handleError() {\n    this.logger.error('connectifi service error');\n  }\n\n  private handleMessage(event: MessageEvent) {\n    const response: IframeResponse = JSON.parse(event.data);\n\n    this.logger.debug('message received from connectifi service', response);\n\n    switch (response.topic) {\n      case 'message':\n        return this.emit('message', JSON.parse(response.data));\n      case 'close':\n        return this.handleClose(response);\n      case 'error':\n        return this.handleError();\n      case 'open':\n        return this.handleOpen();\n    }\n  }\n\n  private handleDisconnected(retryInMillis?: number) {\n    this.connected = false;\n    this.emit('disconnect', retryInMillis);\n  }\n\n  private handleClose({\n    code,\n    namespace,\n    directory,\n    instanceId,\n  }: IframeCloseResponse) {\n    this.logger.debug(\n      `socket closed: ${code}, reconnect? ${this.autoReconnect}`,\n    );\n\n    if (this.autoReconnect) {\n      const retryInMillis = this.scheduleReconnect(\n        namespace,\n        directory,\n        instanceId,\n      );\n      this.handleDisconnected(retryInMillis);\n    } else {\n      this.handleDisconnected();\n    }\n  }\n\n  private handleWindowBeforeUnload() {\n    this.autoReconnect = false;\n    closeWebSocket(this.port);\n  }\n\n  private addPendingEventId(eventId: string) {\n    this.pendingEventIds.add(eventId);\n    this.emit('working', true);\n  }\n\n  private removePendingEventId(eventId: string) {\n    this.pendingEventIds.delete(eventId);\n    if (!this.pendingEventIds.size) {\n      this.emit('working', false);\n    }\n  }\n\n  private addListeners() {\n    if (this.hasAddedListeners) return;\n    this.hasAddedListeners = true;\n\n    this.port.addEventListener('message', this.handleMessage.bind(this));\n\n    //close socket on window unload\n    window.addEventListener(\n      'beforeUnload',\n      this.handleWindowBeforeUnload.bind(this),\n    );\n  }\n\n  /** Connect WebSocket to interop server. */\n  async connect(\n    namespace: string,\n    directory: string,\n    instanceId: string,\n  ): Promise<void> {\n    this.addListeners();\n    this.autoReconnect = true;\n\n    this.logger.debug(\n      `connecting to service, namespace: ${namespace}, directory: ${directory}, instance: ${instanceId}`,\n    );\n\n    return connectWebSocket(this.port, {\n      namespace,\n      directory,\n      instanceId,\n    });\n  }\n\n  /** Disconnect active websocket connection. */\n  disconnect(): void {\n    this.autoReconnect = false;\n    this.clearReconnect();\n\n    closeWebSocket(this.port);\n  }\n\n  send<TTopic extends UpTopic>(msg: UpMessage<TTopic>): void {\n    this.logger.debug('sending message to connectifi service', msg);\n    if (this.connected) {\n      sendWebSocketMessage(this.port, msg);\n    } else {\n      throw new Error(ConnectionError.NoConnectionAvailable);\n    }\n  }\n\n  async request<TTopic extends RoundTripTopic>(\n    topic: TTopic,\n    data: UpRequestData[TTopic],\n  ) {\n    const eventId = `${topic}_${crypto.randomUUID()}`;\n    const message: UpRequest<TTopic> = { topic, data, eventId };\n\n    // Need cast here because of https://github.com/microsoft/TypeScript/issues/25879\n    this.send(message as UpMessage<TTopic>);\n\n    return new Promise<DownResponseData[TTopic]>((res, rej) => {\n      const listener = (envelope: Envelope) => {\n        if (eventId !== envelope.eventId) return;\n        this.removePendingEventId(eventId);\n        this.removeEventListener('message', listener);\n        if (isErrorEnvelope(envelope)) {\n          return rej(envelope.data.error);\n        }\n        res(envelope.data as DownResponseData[TTopic]);\n      };\n      this.addPendingEventId(eventId);\n      this.addEventListener('message', listener);\n    });\n  }\n\n  action<TTopic extends UpActionTopic>(\n    topic: TTopic,\n    data: UpActionData[TTopic],\n  ): void {\n    const message: UpAction<TTopic> = { topic, data };\n    // Need cast here because of https://github.com/microsoft/TypeScript/issues/25879\n    this.send(message as UpMessage<TTopic>);\n  }\n\n  isConnected() {\n    return this.connected;\n  }\n\n  addEventListener(\n    type: 'working',\n    listener: (isWorking: boolean) => void,\n  ): void;\n  addEventListener(\n    type: 'connect',\n    listener: (hasNeverBeenConnected: boolean) => void,\n  ): void;\n  addEventListener(\n    type: 'disconnect',\n    listener: (retryInMillis: number) => void,\n  ): void;\n  addEventListener(type: 'message', listener: (event: Envelope) => void): void;\n  override addEventListener(type: string, listener: (event: any) => void) {\n    super.addEventListener(type, listener);\n  }\n}\n","export class EventEmitter {\n  private eventListeners = new Map<string, Set<(event: unknown) => void>>();\n\n  emit(type: string, event?: unknown) {\n    const listeners = this.eventListeners.get(type);\n    listeners?.forEach((listener) => listener(event));\n  }\n\n  addEventListener(type: string, listener: (event: any) => void) {\n    let listeners = this.eventListeners.get(type);\n    if (!listeners) {\n      listeners = new Set();\n      this.eventListeners.set(type, listeners);\n    }\n    listeners.add(listener);\n  }\n\n  removeEventListener(type: string, listener: (event: any) => void) {\n    this.eventListeners.get(type)?.delete(listener);\n  }\n}\n","import type { LogLevel, Logger } from '../types';\n\nexport const createLogger = (\n  level: LogLevel,\n  externalLogger?: (...params: any) => void,\n): Logger => {\n  const logIt = (...params: any) => {\n    console.log(...params);\n    externalLogger && externalLogger(...params);\n  };\n\n  return {\n    info(...params: any) {\n      if (level !== 'silent') {\n        logIt(...params);\n      }\n    },\n    debug(...params: any) {\n      if (level === 'debug') {\n        logIt(...params);\n      }\n    },\n    error(...params: any) {\n      logIt(...params);\n    },\n  };\n};\n","/**\n * Parameter name for directory identifier.\n * Directories can contain a collection of apps.\n */\nexport const directoryParamName = 'subDirectory';\n\n/**\n * Parameter name for namespace identifier.\n * Namespaces can contain a collection of directories, intents and contexts.\n */\nexport const namespaceParamName = 'directory';\n","import { WindowEventTopic } from '@/common/interop/window';\n\nconst windowListeners = new Map<WindowEventTopic, Set<() => void>>();\n\nfunction handleWindowMessage(event: MessageEvent) {\n  if (!event.data) return;\n  try {\n    const authEvent =\n      typeof event.data === 'string' ? JSON.parse(event.data) : event.data;\n    const listeners = windowListeners.get(authEvent.topic) || new Set();\n    listeners.forEach((listener) => listener());\n  } catch (err) {\n    // ignored\n  }\n}\n\nlet isRegistered = false;\n\nfunction registerWindowMessageHandler() {\n  if (isRegistered) return;\n  isRegistered = true;\n  window.addEventListener('message', handleWindowMessage);\n}\n\nfunction addWindowListener(topics: WindowEventTopic, listener: () => void) {\n  registerWindowMessageHandler();\n\n  let listeners = windowListeners.get(topics);\n  if (!listeners) {\n    listeners = new Set();\n    windowListeners.set(topics, listeners);\n  }\n  listeners.add(listener);\n}\n\nfunction removeWindowListener(topics: WindowEventTopic, listener: () => void) {\n  windowListeners.get(topics)?.delete(listener);\n}\n\nexport function waitForWindowEvent(...topics: WindowEventTopic[]) {\n  return new Promise<WindowEventTopic>((res) => {\n    const removeListeners: (() => void)[] = [];\n    topics.forEach((topic) => {\n      const handleEvent = () => {\n        removeListeners.forEach((listener) => listener());\n        res(topic);\n      };\n      removeListeners.push(() => removeWindowListener(topic, handleEvent));\n      addWindowListener(topic, handleEvent);\n    });\n  });\n}\n","import type { RedirectStyle } from '../types';\n\nimport { directoryParamName, namespaceParamName } from '@/common/directories';\nimport { waitForWindowEvent } from './window-listener';\nimport { addSandboxAttributes, getIframeUrl } from '../common/iframe';\n\nfunction getConsentUrl(\n  interopHost: string,\n  namespace: string,\n  directoryName: string,\n  landingPage?: string,\n) {\n  let url = `${interopHost}/consent?${directoryParamName}=${directoryName}&${namespaceParamName}=${namespace}`;\n  if (landingPage) {\n    url += `&interopUrl=${landingPage}`;\n  }\n  return url;\n}\n\nasync function requestConsentInWindow(\n  interopHost: string,\n  namespace: string,\n  directoryName: string,\n) {\n  const consentWindow = window.open(\n    getConsentUrl(interopHost, namespace, directoryName),\n  );\n  if (!consentWindow) return false;\n\n  const topic = await waitForWindowEvent('login', 'consent-denied');\n\n  consentWindow.close();\n  return topic === 'login';\n}\n\nasync function redirectToRequestConsent(\n  interopHost: string,\n  namespace: string,\n  directoryName: string,\n) {\n  window.location.href = getConsentUrl(\n    interopHost,\n    namespace,\n    directoryName,\n    window.location.href,\n  );\n  return false;\n}\n\nexport async function requestConsent(\n  interopHost: string,\n  namespace: string,\n  directoryName: string,\n  consentRedirectStyle: RedirectStyle = 'sameWindow',\n) {\n  return consentRedirectStyle === 'newWindow'\n    ? requestConsentInWindow(interopHost, namespace, directoryName)\n    : redirectToRequestConsent(interopHost, namespace, directoryName);\n}\n\nexport async function waitForStorageAccess() {\n  const topic = await waitForWindowEvent(\n    'storage-access-granted',\n    'storage-access-denied',\n  );\n  return topic === 'storage-access-granted';\n}\n\nexport function createStorageAccessIframe(interopHost: string, appId: string) {\n  const iframe = document.createElement('iframe');\n  addSandboxAttributes(iframe);\n  iframe.src = getIframeUrl(\n    interopHost,\n    appId,\n    'request-storage-access-iframe.bundle.js',\n  );\n  iframe.style.display = 'flex';\n  iframe.style.border = 'none';\n  iframe.width = '50px';\n  iframe.height = '35px';\n  return iframe;\n}\n","export function parseAppId(fullAppId: string) {\n  const [appName, directoryWithNamespace] = fullAppId.split('@');\n  const [namespace, directory] = directoryWithNamespace.split('.');\n  return { appName, namespace, directory };\n}\n\nexport function createAppId(\n  appName: string,\n  namespace: string,\n  directory: string,\n) {\n  return `${appName}@${namespace}.${directory}`;\n}\n","import { RedirectStyle } from '../types';\nimport { waitForWindowEvent } from './window-listener';\n\nexport type AuthTargetType = 'interop' | 'addin';\n\nexport function getAuthenticationUrl(\n  interopHost: string,\n  target: AuthTargetType = 'interop',\n  landingPage?: string,\n) {\n  let url = `${interopHost}/api/oauth?target=${target}`;\n  if (landingPage) {\n    url += `&interopUrl=${encodeURIComponent(landingPage)}`;\n  }\n  return url;\n}\n\nasync function redirectToAuthenticate(interopHost: string) {\n  const landingPage = window.location.href;\n  window.location.href = getAuthenticationUrl(\n    interopHost,\n    'interop',\n    landingPage,\n  );\n}\n\nasync function authenticateInWindow(interopHost: string) {\n  const newWindow = window.open(getAuthenticationUrl(interopHost), '_blank');\n  await waitForWindowEvent('login');\n  newWindow?.close();\n}\n\nexport function authenticate(\n  interopHost: string,\n  redirectStyle: RedirectStyle = 'sameWindow',\n) {\n  if (redirectStyle === 'newWindow') {\n    return authenticateInWindow(interopHost);\n  }\n  return redirectToAuthenticate(interopHost);\n}\n","export function showElement(element: HTMLElement) {\n  element.style.display = 'flex';\n}\n\nexport function hideElement(element: HTMLElement) {\n  element.style.display = 'none';\n}\n\nasync function waitForDocumentBody() {\n  if (document.body) return;\n  await new Promise<void>((res) =>\n    window.addEventListener('DOMContentLoaded', () => res()),\n  );\n}\n\nexport async function addToDocumentBody(element: HTMLElement) {\n  await waitForDocumentBody();\n  document.body.appendChild(element);\n}\n","import { Context as FDC3Context } from '@finos/fdc3';\n\nimport type { z } from 'zod';\nimport type {\n  intentResultTypeParser,\n  hookParser,\n  contextHookParser,\n} from './parsers';\n\nexport interface CreateOrganization {\n  name: string;\n  owners: string[];\n}\n\nexport interface Organization extends CreateOrganization {\n  id: string;\n}\n\n/**\n * An interface to make entities searchable\n *\n * Intended to be derived from existing entity properties (e.g. name, displayname), and\n * normalized case-wise for search.\n *\n * Not intended to be exposed to front end APIs/hooks\n */\nexport interface Searchable {\n  searchText: string;\n}\n\nexport type Hook = z.infer<typeof hookParser>;\n\nexport type ContextHook = z.infer<typeof contextHookParser>;\n\n/**\n * APP: app origin validation\n *\n * OPEN: no app origin validation\n *\n * OPENAUTH: user authentication, no app origin validation\n *\n * STRICT: user authentication and app origin validation\n */\nexport enum InteropStrategies {\n  OPEN = 'open',\n  OPENAUTH = 'openauth',\n  APP = 'app',\n  STRICT = 'strict',\n}\n\nexport interface UserChannel {\n  id: string;\n  name?: string;\n  color?: string;\n}\n\nexport interface Lifecycle {\n  createdAt: number;\n  createdBy?: string;\n  updatedAt: number;\n  updatedBy?: string;\n}\n\nexport interface Directory extends Searchable, Lifecycle {\n  name: string;\n  description: string;\n  icon?: string;\n  deliveryHooks?: ContextHook[];\n  allowInstanceDiscovery: boolean;\n  interopStrategy:\n    | InteropStrategies.APP\n    | InteropStrategies.OPEN\n    | InteropStrategies.OPENAUTH\n    | InteropStrategies.STRICT;\n  channels: UserChannel[];\n  allowGlobalBroadcast: boolean;\n  useCustomChannels: boolean;\n  generatedFrom?: string;\n}\n\nexport interface Context extends Searchable, Lifecycle {\n  type: string;\n  description: string;\n  schema?: object;\n  details?: string;\n  examples?: string;\n}\n\nexport interface Intent extends Searchable, Lifecycle {\n  name: string;\n  displayName: string;\n  returnContext?: string;\n  contexts: Array<string>;\n  description?: string;\n  examples?: string;\n}\n\nexport type IntentResultType = z.infer<typeof intentResultTypeParser>;\n\nexport type ConnectifiAppMetadata = {\n  type: 'window' | 'directory';\n  id: string;\n  name: string;\n  appId: string;\n  isSecure: boolean;\n  proximity: number;\n  title: string;\n  instanceTitle: string;\n  icons?: { src: string }[];\n  lastUpdate?: number;\n  os?: string;\n  device?: string;\n  browser?: string;\n};\n\n/**\n * Topics that can be handled by the Connectifi agent.\n */\nexport enum AgentTopic {\n  /**\n   * Directs the agent to open a URL.\n   */\n  Open = 'open',\n}\n\nexport interface DeliveryHookChange {\n  /**\n   * The destination to send the changed response to.\n   */\n  destination: string;\n\n  /**\n   *If defined changes the context in the response for the destination.\n   */\n  context: Context;\n}\n\nexport interface DeliveryHookRequest {\n  context: FDC3Context;\n  source: string;\n  destinations: string[];\n}\n\nexport interface DeliveryHookResponse {\n  context: FDC3Context | undefined | null;\n  changes?: DeliveryHookChange[];\n}\n\nexport interface OpenHookRequest {\n  intent?: string;\n  context?: FDC3Context;\n  source: string;\n  target: string;\n}\n\nexport interface OpenHookResponse {\n  /**\n   * Changes the URL location that the Connectifi agent will open.\n   */\n  url?: string;\n}\n\nexport interface IntentResultHookRequest {\n  intent: string;\n  context?: FDC3Context;\n  source: string;\n  target: string;\n}\n"],"mappings":"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","names":["ResolutionType","init_types","__esmMin","fab_default","init_fab","__esmMin","LogoView","init_logo","__esmMin","images","imageSource","image","clearTitle","element","HTMLElementDecorator","HTMLDivDecorator","HTMLButtonDecorator","HTMLImageDecorator","init_html","__esmMin","type","ReconnectButton","init_reconnect","__esmMin","init_html","HTMLButtonDecorator","interopHost","iconUrl","img","DirectoryView","init_directory","__esmMin","picker","logo","directory","ChannelPickerToolbarButton","init_button","__esmMin","init_html","HTMLButtonDecorator","interopHost","interopStrategy","owner","ChannelPickerToolbar","init_toolbar","__esmMin","init_html","init_button","HTMLDivDecorator","ChannelPickerToolbarButton","createImage","src","image","getWarningImageUrl","interopHost","getErrorImageUrl","getCheckImageUrl","getUnlockImageUrl","getLogoImageUrl","getChannelImageUrl","getImageInstance","imageCache","init_image","__esmMin","isYOffScreen","el","marginFromWindow","rect","ChannelPickerChannelsContainer","init_channels","__esmMin","init_html","init_image","HTMLDivDecorator","channelSrc","onChannelPicked","child","childrenLength","childSize","childStyle","margin","totalChildSize","i","newWidth","channel","event","_a","_b","id","button","name","color","createImage","channels","ChannelPicker","init_channel_picker","__esmMin","init_toolbar","init_channels","init_html","HTMLDivDecorator","hubSrc","position","onChannelPicked","ChannelPickerToolbar","ChannelPickerChannelsContainer","channel","event","interopStrategy","HeaderLogo","init_logo","__esmMin","init_html","HTMLImageDecorator","logoSrc","Header","init_header","__esmMin","init_html","init_logo","HTMLDivDecorator","logoSrc","HeaderLogo","directory","clearTitle","color","ResolverHeaderDismiss","init_dismiss","__esmMin","init_html","HTMLDivDecorator","dismiss","span","container","ResolverHeaderLogo","init_logo","__esmMin","init_html","HTMLDivDecorator","logoSrc","Title","init_title","__esmMin","init_html","HTMLDivDecorator","directoryName","ResolverHeaderTitle","init_title","__esmMin","Title","ResolverHeader","init_header","__esmMin","init_html","init_dismiss","init_logo","init_title","HTMLDivDecorator","logoSrc","ResolverHeaderDismiss","ResolverHeaderTitle","ResolverHeaderLogo","getIconPath","ResolverAppRowIconContainer","init_icon_container","__esmMin","init_html","interopHost","icon","url","HTMLDivDecorator","bridge","isSecure","icons","iconUrl","lockIcon","img","ResolverAppRowAgentInfo","init_agent","__esmMin","init_html","HTMLDivDecorator","interopHost","type","device","lowercaseType","ResolverAppRowInfo","init_info","__esmMin","init_html","init_agent","HTMLDivDecorator","interopHost","proximity","type","os","device","browser","agentNode","ResolverAppRowAgentInfo","AppRowTitle","init_title","__esmMin","Title","appTitle","getAppTitle","ResolverAppRow","init_app_row","__esmMin","init_html","init_icon_container","init_info","init_title","app","title","instTitle","HTMLDivDecorator","interopHost","bridge","ResolverAppRowIconContainer","appTitle","AppRowTitle","ResolverAppRowInfo","getAppTypeDisplayName","ResolverGroup","init_group","__esmMin","init_html","intentResultType","HTMLDivDecorator","bridge","type","ResolverIntentRow","init_intent_row","__esmMin","init_html","HTMLDivDecorator","title","sortAppsOfSameType","appsorter","ResolverList","init_list","__esmMin","init_app_row","init_group","init_intent_row","init_html","a","b","HTMLDivDecorator","displayName","name","intentRow","ResolverIntentRow","interopHost","intentRes","onAppClicked","bridge","apps","group","app","groupRow","ResolverGroup","row","ResolverAppRow","event","Resolver","init_resolver","__esmMin","init_html","init_header","init_list","HTMLDivDecorator","logoSrc","ResolverList","ResolverHeader","event","ResolverBackground","init_resolver_background","__esmMin","init_html","HTMLDivDecorator","ToastMessage","init_message","__esmMin","init_html","HTMLDivDecorator","message","Toast","init_toast","__esmMin","init_html","init_title","init_message","HTMLDivDecorator","Title","ToastMessage","content","action","image","res","duration","title","message","actionElement","Container","init_container","__esmMin","init_channel_picker","init_header","init_resolver","init_resolver_background","init_toast","init_html","HTMLDivDecorator","logoSrc","hubSrc","position","onChannelPicked","ResolverBackground","inner","Header","Toast","fab","ChannelPicker","Resolver","LoginButton","init_login","__esmMin","init_html","HTMLButtonDecorator","interopHost","iconUrl","img","Logout","init_logout","__esmMin","init_login","interopHost","style","button","LoginButton","handleClick","event","_a","url","ConnectifiAuthenticator","init_authenticator","__esmMin","init_image","init_login","interopHost","toast","directoryView","redirectStyle","config","name","authenticate","button","LoginButton","getImageInstance","getUnlockImageUrl","res","ev","OpenButton","init_open","__esmMin","init_html","HTMLButtonDecorator","interopHost","iconUrl","img","StorageAccess","init_storage_access","__esmMin","init_open","init_image","interopUrl","toast","consentRedirectStyle","OpenButton","requestConsent","consentButton","getImageInstance","getUnlockImageUrl","res","ev","config","button","waitForStorageAccess","host","Opener","init_opener","__esmMin","init_open","init_image","toast","interopHost","url","button","OpenButton","message","getImageInstance","getWarningImageUrl","fab_exports","__export","ConnectifiFab","wrapConfig","MANUAL_RECONNECT_ELAPSED_TIME","init_fab","__esmMin","init_types","init_logo","init_reconnect","init_directory","init_container","init_logout","init_authenticator","init_storage_access","init_image","init_opener","fab","config","newConfig","fdc3","_a","directory","owner","err","channelId","initialConnect","nextConnect","working","interopHost","root","props","workInProgress","position","Logout","logoSrc","getLogoImageUrl","Container","getChannelImageUrl","LogoView","DirectoryView","ConnectifiAuthenticator","StorageAccess","Opener","agent","getErrorImageUrl","getWarningImageUrl","getImageUrl","getImageInstance","channel","_b","shadowRoot","style","fab_default","event","k","picker","username","errorMessage","chans","message","dirProps","getCheckImageUrl","reconnectButton","ReconnectButton","nextSeconds","toastMsg","seconds","uc","c","callback","closeCallback","onAppClicked","app","intentRes","bridge","resTitle","ctxName","title","resolverList","intentResult","bridgeResult","context","name","main_exports","__export","InteropStrategies","ResolutionType","createAgent","__toCommonJS","ConnectifiChannel","ws","subManager","id","type","displayMetadata","context","contextType","contextTypeOrHandler","handlerSecondArg","handler","hasBridgeChannel","channel","_a","bridgeChannels","c","createIntentResolution","resolution","ConnectifiFDC3Api","ws","subManager","bridge","target","context","broadcastPromise","intent","app","contextTypeOrHandler","handlerSecondArg","handler","contextType","ConnectifiChannel","channelId","joinChannelPromise","leaveChannelPromise","init_types","promiseIsFulfilled","result","createContextListenerKey","contextType","channel","Subscription","handler","SubscriptionManager","contextListeners","intentListeners","currentChannel","context","contextChannel","listeners","l","lc","cl","clc","listener","intent","results","promiseIsFulfilled","p","type","id","i","ws","contextType","channel","listenerItem","key","createContextListenerKey","postMessageToIframe","iframe","origin","port","message","_a","addSandboxAttributes","getIframeUrl","interopHost","appId","bundle","portTimeoutError","isPortTimeoutError","err","waitForPortMessage","port","topics","timeoutMs","topicsSet","res","rej","timeout","listener","event","response","postMessageToPort","message","mustEmbedIframe","iframeUrl","res","json","registerIframePort","iframe","interopHost","appId","getIframeUrl","channel","handshakePromise","waitForPortMessage","handleLoad","postMessageToIframe","tunnel","port","message","postMessageToPort","connectWebSocket","closeWebSocket","sendWebSocketMessage","hasStorageAccess","TunnelInstance","id","Tunnel","port","logger","appUrl","appTitle","instanceId","refreshInMs","response","isStartSession","isRefreshSession","_a","tunnel","isErrorEnvelope","envelope","init_types","EventEmitter","type","event","listeners","listener","_a","AgentWebSocket","EventEmitter","port","logger","maxReconnectInterval","maxReconnectAttempts","retryInterval","jitter","namespace","directory","instanceId","reconnectMillis","event","response","retryInMillis","code","closeWebSocket","eventId","connectWebSocket","msg","sendWebSocketMessage","topic","data","message","res","rej","listener","envelope","isErrorEnvelope","type","createLogger","level","externalLogger","logIt","params","directoryParamName","namespaceParamName","windowListeners","handleWindowMessage","event","authEvent","listener","isRegistered","registerWindowMessageHandler","addWindowListener","topics","listeners","removeWindowListener","_a","waitForWindowEvent","res","removeListeners","topic","handleEvent","getConsentUrl","interopHost","namespace","directoryName","landingPage","url","directoryParamName","namespaceParamName","requestConsentInWindow","consentWindow","topic","waitForWindowEvent","redirectToRequestConsent","requestConsent","consentRedirectStyle","waitForStorageAccess","createStorageAccessIframe","appId","iframe","addSandboxAttributes","getIframeUrl","parseAppId","fullAppId","appName","directoryWithNamespace","namespace","directory","createAppId","getAuthenticationUrl","interopHost","target","landingPage","url","redirectToAuthenticate","authenticateInWindow","newWindow","waitForWindowEvent","authenticate","redirectStyle","GLOBAL_CHANNEL","PENDING_ID_PREFIX","APP_IDENTITY_ERROR_MSG","ConnectifiAgent","interopHost","appName","namespace","directoryName","port","config","configInfo","SubscriptionManager","data","createLogger","AgentWebSocket","Tunnel","ConnectifiFDC3Api","_a","_b","_c","_d","workInProgress","portTimeoutError","instanceId","hasStorageAccess","button","createStorageAccessIframe","createAppId","waitForStorageAccess","requestConsent","directory","owner","icon","interopStrategy","dirProps","event","topic","response","handleAuthenticate","authenticate","targetType","getAuthenticationUrl","isStartSession","isSessionError","errMessage","reset","tunnelResponse","err","isPortTimeoutError","result","irm","context","intent","appIntent","pendingEventId","intentResult","handler","envelope","isWorking","retryInMillis","redirectStyle","instance","selected","bridge","metadata","hideElement","element","waitForDocumentBody","res","addToDocumentBody","InteropStrategies","init_types","createAgent","interopHost","appId","config","interopUrl","configInfo","configToInfo","root","addToDocumentBody","iframe","addSandboxAttributes","hideElement","port","registerIframePort","directory","namespace","appName","parseAppId","wrappedConfig","fab","wrapConfig","ConnectifiFab","agent","ConnectifiAgent","logLevel","props","activeHandlers","result","key","value"]}