// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var ResponseStopCause;
(function (ResponseStopCause) {
    /** User cancelled response. */
    ResponseStopCause[ResponseStopCause["USER"] = 0] = "USER";
    /** System cancelled response for another reason. */
    ResponseStopCause[ResponseStopCause["OTHER"] = 1] = "OTHER";
})(ResponseStopCause || (ResponseStopCause = {}));
/** Reason why the web client could not initialize. */
var WebClientInitializeErrorReason;
(function (WebClientInitializeErrorReason) {
    /**
     * Unknown reason. The user can manually retry loading, which reloads the
     * entire webview.
     */
    WebClientInitializeErrorReason[WebClientInitializeErrorReason["UNKNOWN"] = 0] = "UNKNOWN";
    /** This list will be expanded later. */
})(WebClientInitializeErrorReason || (WebClientInitializeErrorReason = {}));
/** Reason for failure while acting in the focused tab. */
var ActInFocusedTabErrorReason;
(function (ActInFocusedTabErrorReason) {
    ActInFocusedTabErrorReason[ActInFocusedTabErrorReason["UNKNOWN"] = 0] = "UNKNOWN";
    /** Context could not be gathered after acting. */
    ActInFocusedTabErrorReason[ActInFocusedTabErrorReason["GET_CONTEXT_FAILED"] = 1] = "GET_CONTEXT_FAILED";
    /** The action proto is invalid. */
    ActInFocusedTabErrorReason[ActInFocusedTabErrorReason["INVALID_ACTION_PROTO"] = 2] = "INVALID_ACTION_PROTO";
    /** Action target is not found. */
    ActInFocusedTabErrorReason[ActInFocusedTabErrorReason["TARGET_NOT_FOUND"] = 3] = "TARGET_NOT_FOUND";
    /** Failed to start a new task. */
    ActInFocusedTabErrorReason[ActInFocusedTabErrorReason["FAILED_TO_START_TASK"] = 4] = "FAILED_TO_START_TASK";
})(ActInFocusedTabErrorReason || (ActInFocusedTabErrorReason = {}));
///////////////////////////////////////////////////////////////////////////////
/// BEGIN_GENERATED - DO NOT MODIFY BELOW
// This block is generated by
// chrome/browser/resources/glic/glic_api_impl/generate.py
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// The type of user input reaction.
var MetricUserInputReactionType;
(function (MetricUserInputReactionType) {
    // An unknown reaction type.
    MetricUserInputReactionType[MetricUserInputReactionType["UNKNOWN"] = 0] = "UNKNOWN";
    // A canned reaction which can be presented without communication with the
    // server.
    MetricUserInputReactionType[MetricUserInputReactionType["CANNED"] = 1] = "CANNED";
    // A reaction which requires some generic modeling to produce.
    MetricUserInputReactionType[MetricUserInputReactionType["MODEL"] = 2] = "MODEL";
})(MetricUserInputReactionType || (MetricUserInputReactionType = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Reason for failure while acting.
var PerformActionsErrorReason;
(function (PerformActionsErrorReason) {
    PerformActionsErrorReason[PerformActionsErrorReason["UNKNOWN"] = 0] = "UNKNOWN";
    // The serialized actions proto failed to parse.
    PerformActionsErrorReason[PerformActionsErrorReason["INVALID_ACTION_PROTO"] = 1] = "INVALID_ACTION_PROTO";
})(PerformActionsErrorReason || (PerformActionsErrorReason = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Reason for failure when creating an actor task.
var CreateTaskErrorReason;
(function (CreateTaskErrorReason) {
    CreateTaskErrorReason[CreateTaskErrorReason["UNKNOWN"] = 0] = "UNKNOWN";
    // The host does not support the actor task system.
    CreateTaskErrorReason[CreateTaskErrorReason["TASK_SYSTEM_UNAVAILABLE"] = 1] = "TASK_SYSTEM_UNAVAILABLE";
    // The host already has an existing task in progress. The client must stop it
    // before requesting a new task.
    CreateTaskErrorReason[CreateTaskErrorReason["EXISTING_ACTIVE_TASK"] = 2] = "EXISTING_ACTIVE_TASK";
    // The user's browser policy or account settings prevent creating actor tasks.
    CreateTaskErrorReason[CreateTaskErrorReason["BLOCKED_BY_POLICY"] = 3] = "BLOCKED_BY_POLICY";
    // CreateTask was called on a Glic instance which does not have a registered
    // conversation.
    CreateTaskErrorReason[CreateTaskErrorReason["CONVERSATION_NOT_REGISTERED"] = 4] = "CONVERSATION_NOT_REGISTERED";
})(CreateTaskErrorReason || (CreateTaskErrorReason = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// The state of an actor task.
var ActorTaskState;
(function (ActorTaskState) {
    ActorTaskState[ActorTaskState["UNKNOWN"] = 0] = "UNKNOWN";
    // The actor task is idle and waiting for the next action instruction.
    ActorTaskState[ActorTaskState["IDLE"] = 1] = "IDLE";
    // The actor task is performing an action.
    ActorTaskState[ActorTaskState["ACTING"] = 2] = "ACTING";
    // The actor task is paused and waiting to be resumed or stopped.
    ActorTaskState[ActorTaskState["PAUSED"] = 3] = "PAUSED";
    // The actor task is stopped and going away.
    ActorTaskState[ActorTaskState["STOPPED"] = 4] = "STOPPED";
})(ActorTaskState || (ActorTaskState = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// The reason/source of why an actor task was paused.
var ActorTaskPauseReason;
(function (ActorTaskPauseReason) {
    // Actor task was paused by the model.
    ActorTaskPauseReason[ActorTaskPauseReason["PAUSED_BY_MODEL"] = 0] = "PAUSED_BY_MODEL";
    // Actor task was puased by the user.
    ActorTaskPauseReason[ActorTaskPauseReason["PAUSED_BY_USER"] = 1] = "PAUSED_BY_USER";
})(ActorTaskPauseReason || (ActorTaskPauseReason = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// The reason/source of why an actor task was stopped.
var ActorTaskStopReason;
(function (ActorTaskStopReason) {
    // Actor task is complete.
    ActorTaskStopReason[ActorTaskStopReason["TASK_COMPLETE"] = 0] = "TASK_COMPLETE";
    // Actor task was stopped by the user.
    ActorTaskStopReason[ActorTaskStopReason["STOPPED_BY_USER"] = 1] = "STOPPED_BY_USER";
    // Actor task was stopped because the model reported a failure.
    ActorTaskStopReason[ActorTaskStopReason["MODEL_ERROR"] = 2] = "MODEL_ERROR";
    // Actor task was stopped by choosing a new conversation.
    ActorTaskStopReason[ActorTaskStopReason["USER_STARTED_NEW_CHAT"] = 3] = "USER_STARTED_NEW_CHAT";
    // Actor task was stopped by choosing a previous conversation.
    ActorTaskStopReason[ActorTaskStopReason["USER_LOADED_PREVIOUS_CHAT"] = 4] = "USER_LOADED_PREVIOUS_CHAT";
})(ActorTaskStopReason || (ActorTaskStopReason = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// The reason/source of why an actor task was interrupted.
var ActorTaskInterruptReason;
(function (ActorTaskInterruptReason) {
    // Actor task is interrupted for an unknown reason.
    ActorTaskInterruptReason[ActorTaskInterruptReason["UNKNOWN_REASON"] = 0] = "UNKNOWN_REASON";
    // Actor task is complete.
    ActorTaskInterruptReason[ActorTaskInterruptReason["TASK_COMPLETE"] = 1] = "TASK_COMPLETE";
    // Actor task was waiting for user input.
    ActorTaskInterruptReason[ActorTaskInterruptReason["WAITING_USER_INPUT"] = 2] = "WAITING_USER_INPUT";
    // Actor task was waiting for user to provide clarifications on the current
    // task.
    ActorTaskInterruptReason[ActorTaskInterruptReason["WAITING_USER_CLARIFICATION"] = 3] = "WAITING_USER_CLARIFICATION";
    // Actor task was waiting for user to confirm an action.
    ActorTaskInterruptReason[ActorTaskInterruptReason["WAITING_USER_CONFIRMATION"] = 4] = "WAITING_USER_CONFIRMATION";
    // Actor task was waiting for user to take over.
    ActorTaskInterruptReason[ActorTaskInterruptReason["WAITING_USER_TAKE_OVER"] = 5] = "WAITING_USER_TAKE_OVER";
    // Actor task was waiting for irrelevant user input.
    ActorTaskInterruptReason[ActorTaskInterruptReason["WAITING_IRRELEVANT_USER_INPUT"] = 6] = "WAITING_IRRELEVANT_USER_INPUT";
    // Actor task was waiting for user to respond to unsafe counter-abuse verdict.
    ActorTaskInterruptReason[ActorTaskInterruptReason["WAITING_UNSAFE_COUNTER_ABUSE_VERDICT"] = 7] = "WAITING_UNSAFE_COUNTER_ABUSE_VERDICT";
})(ActorTaskInterruptReason || (ActorTaskInterruptReason = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Reason why capturing desktop screenshot failed. NOTE: This may be extended in
// the future so avoid using complete switches on the currently used enum
// values.
var CaptureScreenshotErrorReason;
(function (CaptureScreenshotErrorReason) {
    // Screen capture or frame encoding failure.
    CaptureScreenshotErrorReason[CaptureScreenshotErrorReason["UNKNOWN"] = 0] = "UNKNOWN";
    // Screen capture requested but already in progress of serving another
    // request.
    CaptureScreenshotErrorReason[CaptureScreenshotErrorReason["SCREEN_CAPTURE_REQUEST_THROTTLED"] = 1] = "SCREEN_CAPTURE_REQUEST_THROTTLED";
    // User declined screen capture dialog before taking a screenshot.
    CaptureScreenshotErrorReason[CaptureScreenshotErrorReason["USER_CANCELLED_SCREEN_PICKER_DIALOG"] = 2] = "USER_CANCELLED_SCREEN_PICKER_DIALOG";
})(CaptureScreenshotErrorReason || (CaptureScreenshotErrorReason = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Safe Browsing Threat Type.
var SbThreatType;
(function (SbThreatType) {
    // Default value.
    SbThreatType[SbThreatType["UNSPECIFIED"] = 0] = "UNSPECIFIED";
    SbThreatType[SbThreatType["SOCIAL_ENGINEERING"] = 1] = "SOCIAL_ENGINEERING";
    SbThreatType[SbThreatType["MALWARE"] = 2] = "MALWARE";
    SbThreatType[SbThreatType["UNWANTED_SOFTWARE"] = 3] = "UNWANTED_SOFTWARE";
})(SbThreatType || (SbThreatType = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// The platform glic is running on.
var Platform;
(function (Platform) {
    Platform[Platform["UNKNOWN"] = 0] = "UNKNOWN";
    Platform[Platform["MAC_OS"] = 1] = "MAC_OS";
    Platform[Platform["WINDOWS"] = 2] = "WINDOWS";
    Platform[Platform["LINUX"] = 3] = "LINUX";
    Platform[Platform["CHROME_OS"] = 4] = "CHROME_OS";
    Platform[Platform["ANDROID"] = 5] = "ANDROID";
})(Platform || (Platform = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// The form factor of the device glic is running on.
var FormFactor;
(function (FormFactor) {
    FormFactor[FormFactor["UNKNOWN"] = 0] = "UNKNOWN";
    FormFactor[FormFactor["DESKTOP"] = 1] = "DESKTOP";
    FormFactor[FormFactor["PHONE"] = 2] = "PHONE";
    FormFactor[FormFactor["TABLET"] = 3] = "TABLET";
})(FormFactor || (FormFactor = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Enum to specify the image format of the screenshot.
var ScreenshotImageFormat;
(function (ScreenshotImageFormat) {
    // JPEG screenshot format. This is the default format.
    ScreenshotImageFormat[ScreenshotImageFormat["JPEG"] = 0] = "JPEG";
    // PNG screenshot format.
    ScreenshotImageFormat[ScreenshotImageFormat["PNG"] = 1] = "PNG";
    // WEBP screenshot format.
    ScreenshotImageFormat[ScreenshotImageFormat["WEBP"] = 2] = "WEBP";
})(ScreenshotImageFormat || (ScreenshotImageFormat = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Enum to specify the compression quality of the screenshot. Depending on
// screenshot format, the compression quality may not be respected or may mean
// something different.
var ScreenshotCompressionQuality;
(function (ScreenshotCompressionQuality) {
    // No compression.
    ScreenshotCompressionQuality[ScreenshotCompressionQuality["NONE"] = 0] = "NONE";
    // Low compression quality.
    ScreenshotCompressionQuality[ScreenshotCompressionQuality["LOW"] = 1] = "LOW";
    // Medium compression quality.
    ScreenshotCompressionQuality[ScreenshotCompressionQuality["MEDIUM"] = 2] = "MEDIUM";
    // High compression quality.
    ScreenshotCompressionQuality[ScreenshotCompressionQuality["HIGH"] = 3] = "HIGH";
})(ScreenshotCompressionQuality || (ScreenshotCompressionQuality = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Reason why scrollTo() failed.
var ScrollToErrorReason;
(function (ScrollToErrorReason) {
    // Invalid params were provided to scrollTo(), or the browser doesn't support
    // scrollTo() yet.
    ScrollToErrorReason[ScrollToErrorReason["NOT_SUPPORTED"] = 0] = "NOT_SUPPORTED";
    // scrollTo() was called again before this call finished processing.
    ScrollToErrorReason[ScrollToErrorReason["NEWER_SCROLL_TO_CALL"] = 1] = "NEWER_SCROLL_TO_CALL";
    // There is no tab currently in focus.
    ScrollToErrorReason[ScrollToErrorReason["NO_FOCUSED_TAB"] = 2] = "NO_FOCUSED_TAB";
    // The input selector did not match any content in the document or a given
    // range.
    ScrollToErrorReason[ScrollToErrorReason["NO_MATCH_FOUND"] = 3] = "NO_MATCH_FOUND";
    // The currently focused tab changed or navigated while processing the
    // scrollTo() call.
    ScrollToErrorReason[ScrollToErrorReason["FOCUSED_TAB_CHANGED_OR_NAVIGATED"] = 4] = "FOCUSED_TAB_CHANGED_OR_NAVIGATED";
    // The document_id or url provided doesn't match the active document in the
    // primary main frame of the currently focused tab. The document may have been
    // navigated away, may not currently be in focus, or may not be in a primary
    // main frame (we don't currently support iframes).
    ScrollToErrorReason[ScrollToErrorReason["NO_MATCHING_DOCUMENT"] = 5] = "NO_MATCHING_DOCUMENT";
    // The search range starting from DOMNodeId did not result in a valid range.
    ScrollToErrorReason[ScrollToErrorReason["SEARCH_RANGE_INVALID"] = 6] = "SEARCH_RANGE_INVALID";
    // Page context access is disabled.
    ScrollToErrorReason[ScrollToErrorReason["TAB_CONTEXT_PERMISSION_DISABLED"] = 7] = "TAB_CONTEXT_PERMISSION_DISABLED";
    // The web client requested to drop the highlight via
    // `dropScrollToHighlight()`.
    ScrollToErrorReason[ScrollToErrorReason["DROPPED_BY_WEB_CLIENT"] = 8] = "DROPPED_BY_WEB_CLIENT";
})(ScrollToErrorReason || (ScrollToErrorReason = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Enum to specify the source of the Skill.
var SkillSource;
(function (SkillSource) {
    SkillSource[SkillSource["UNKNOWN"] = 0] = "UNKNOWN";
    // Skill created by Google.
    SkillSource[SkillSource["FIRST_PARTY"] = 1] = "FIRST_PARTY";
    // Skill created by an end-user.
    SkillSource[SkillSource["USER_CREATED"] = 2] = "USER_CREATED";
    // Skill derived from a first party skill.
    SkillSource[SkillSource["DERIVED_FROM_FIRST_PARTY"] = 3] = "DERIVED_FROM_FIRST_PARTY";
})(SkillSource || (SkillSource = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Enum to specify the skills web client event for metrics recording.
// Includes both direct user interactions and WebClient state
// transitions to track feature funnels.
var SkillsWebClientEvent;
(function (SkillsWebClientEvent) {
    // Default value for unknown or uninitialized actions.
    SkillsWebClientEvent[SkillsWebClientEvent["UNKNOWN"] = 0] = "UNKNOWN";
    // User invoked a first-party skill.
    SkillsWebClientEvent[SkillsWebClientEvent["USED_FIRST_PARTY_SKILL"] = 1] = "USED_FIRST_PARTY_SKILL";
    // User invoked a skill they created themselves.
    SkillsWebClientEvent[SkillsWebClientEvent["USED_USER_CREATED_SKILL"] = 2] = "USED_USER_CREATED_SKILL";
    // User invoked a skill that was remix/derived from a first-party skill.
    SkillsWebClientEvent[SkillsWebClientEvent["USED_DERIVED_FIRST_PARTY_SKILL"] = 3] = "USED_DERIVED_FIRST_PARTY_SKILL";
    // User typed '/' or triggered the skills menu.
    SkillsWebClientEvent[SkillsWebClientEvent["OPENED_MENU"] = 4] = "OPENED_MENU";
    // User clicked the 'Manage skills' button from the slash menu.
    SkillsWebClientEvent[SkillsWebClientEvent["CLICKED_MANAGE_FROM_MENU"] = 5] = "CLICKED_MANAGE_FROM_MENU";
    // User clicked the 'Add skill' button from the slash menu.
    SkillsWebClientEvent[SkillsWebClientEvent["CLICKED_ADD_FROM_MENU"] = 6] = "CLICKED_ADD_FROM_MENU";
    // User clicked the edit button on an existing skill preview.
    SkillsWebClientEvent[SkillsWebClientEvent["CLICKED_EDIT_FROM_MENU"] = 7] = "CLICKED_EDIT_FROM_MENU";
    // User clicked the generic '+' button on a 1P skill preview.
    SkillsWebClientEvent[SkillsWebClientEvent["CLICKED_ADD_ON1P_SKILL"] = 8] = "CLICKED_ADD_ON1P_SKILL";
    // User clicked the 'Save as Skill' chip that appears on hover.
    SkillsWebClientEvent[SkillsWebClientEvent["CLICKED_SAVE_AS_SKILL_HOVER_CHIP"] = 9] = "CLICKED_SAVE_AS_SKILL_HOVER_CHIP";
    // User clicked the 'Edit Skill' chip that appears on hover.
    SkillsWebClientEvent[SkillsWebClientEvent["CLICKED_EDIT_SKILL_HOVER_CHIP"] = 10] = "CLICKED_EDIT_SKILL_HOVER_CHIP";
    // User clicked the 'Browse skills' button from the plus menu.
    SkillsWebClientEvent[SkillsWebClientEvent["CLICKED_BROWSE_SKILL_FROM_PLUS_MENU"] = 11] = "CLICKED_BROWSE_SKILL_FROM_PLUS_MENU";
    // User clicked a skill from the plus menu.
    SkillsWebClientEvent[SkillsWebClientEvent["CLICKED_SKILL_FROM_PLUS_MENU"] = 12] = "CLICKED_SKILL_FROM_PLUS_MENU";
    // User clicked the 'Manage skills' button from the plus menu.
    SkillsWebClientEvent[SkillsWebClientEvent["CLICKED_MANAGE_SKILL_FROM_PLUS_MENU"] = 13] = "CLICKED_MANAGE_SKILL_FROM_PLUS_MENU";
    // User clicked the 'More' button from the slash menu.
    SkillsWebClientEvent[SkillsWebClientEvent["CLICKED_MORE_FROM_MENU"] = 14] = "CLICKED_MORE_FROM_MENU";
    // User clicked the 'Manage skills' button from the slash skills submenu.
    // Deprecated. Use kClickedManageFromMenu instead.
    SkillsWebClientEvent[SkillsWebClientEvent["CLICKED_MANAGE_SKILL_FROM_MENU"] = 15] = "CLICKED_MANAGE_SKILL_FROM_MENU";
    // User clicked a skill from the slash menu.
    SkillsWebClientEvent[SkillsWebClientEvent["CLICKED_SKILL_FROM_MENU"] = 16] = "CLICKED_SKILL_FROM_MENU";
    // User clicked the 'Browse skills' button from the slash menu.
    SkillsWebClientEvent[SkillsWebClientEvent["CLICKED_BROWSE_SKILLS_FROM_MENU"] = 17] = "CLICKED_BROWSE_SKILLS_FROM_MENU";
    // Skill Builder Step 1: User clicked the promo chip to start the flow.
    SkillsWebClientEvent[SkillsWebClientEvent["SKILL_BUILDER_CLICKED_PROMO_CHIP"] = 20] = "SKILL_BUILDER_CLICKED_PROMO_CHIP";
    // Skill Builder Step 2: A draft skill was successfully generated by the AI.
    SkillsWebClientEvent[SkillsWebClientEvent["SKILL_BUILDER_PROMPT_GENERATED"] = 21] = "SKILL_BUILDER_PROMPT_GENERATED";
    // Skill Builder Step 3: User clicked save on the generated draft.
    SkillsWebClientEvent[SkillsWebClientEvent["SKILL_BUILDER_CLICKED_SAVE_AS_SKILL"] = 22] = "SKILL_BUILDER_CLICKED_SAVE_AS_SKILL";
})(SkillsWebClientEvent || (SkillsWebClientEvent = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Describes what triggered the pin.
var PinTrigger;
(function (PinTrigger) {
    // The pin occurred for unknown reasons. Specifies 'web client' to align with
    // `GlicPinTrigger` enum (which disambiguates from unknown triggers
    // originating elsewhere).
    PinTrigger[PinTrigger["WEB_CLIENT_UNKNOWN"] = 0] = "WEB_CLIENT_UNKNOWN";
    // The pin was triggered by the toggle UI for pin candidates.
    PinTrigger[PinTrigger["CANDIDATES_TOGGLE"] = 1] = "CANDIDATES_TOGGLE";
    // The pin was triggered by the inline '@' mention feature.
    PinTrigger[PinTrigger["AT_MENTION"] = 2] = "AT_MENTION";
    // The pin was triggered as part of actor/actuation behavior.
    PinTrigger[PinTrigger["ACTUATION"] = 3] = "ACTUATION";
})(PinTrigger || (PinTrigger = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Describes what triggered the unpin.
var UnpinTrigger;
(function (UnpinTrigger) {
    // The unpin occurred for unknown reasons. Specifies 'web client' to align
    // with `GlicUnpinTrigger` enum (which disambiguates from unknown triggers
    // originating elsewhere).
    UnpinTrigger[UnpinTrigger["WEB_CLIENT_UNKNOWN"] = 0] = "WEB_CLIENT_UNKNOWN";
    // The unpin was triggered by the toggle UI for pin candidates.
    UnpinTrigger[UnpinTrigger["CANDIDATES_TOGGLE"] = 1] = "CANDIDATES_TOGGLE";
    // The unpin was triggered by a chip.
    UnpinTrigger[UnpinTrigger["CHIP"] = 2] = "CHIP";
    // The unpin was triggered as part of actor/actuation behavior.
    UnpinTrigger[UnpinTrigger["ACTUATION"] = 3] = "ACTUATION";
})(UnpinTrigger || (UnpinTrigger = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Result of CancelActions().
var CancelActionsResult;
(function (CancelActionsResult) {
    // Do not manually use this value. Fail safe when an old client receives an
    // extended new enum.
    CancelActionsResult[CancelActionsResult["UNKNOWN"] = 0] = "UNKNOWN";
    // Actions were successfully cancelled.
    CancelActionsResult[CancelActionsResult["SUCCESS"] = 1] = "SUCCESS";
    // The task was not found.
    CancelActionsResult[CancelActionsResult["TASK_NOT_FOUND"] = 2] = "TASK_NOT_FOUND";
    // Could not cancel the actions for other reasons (e.g., the task is already
    // completed).
    CancelActionsResult[CancelActionsResult["FAILED"] = 3] = "FAILED";
})(CancelActionsResult || (CancelActionsResult = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Reason for failure when switching a conversation.
var SwitchConversationErrorReason;
(function (SwitchConversationErrorReason) {
    SwitchConversationErrorReason[SwitchConversationErrorReason["UNKNOWN"] = 0] = "UNKNOWN";
})(SwitchConversationErrorReason || (SwitchConversationErrorReason = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Reason for failure when registering a conversation.
var RegisterConversationErrorReason;
(function (RegisterConversationErrorReason) {
    RegisterConversationErrorReason[RegisterConversationErrorReason["UNKNOWN"] = 0] = "UNKNOWN";
    // The instance already has a conversation ID.
    RegisterConversationErrorReason[RegisterConversationErrorReason["INSTANCE_ALREADY_HAS_CONVERSATION_ID"] = 1] = "INSTANCE_ALREADY_HAS_CONVERSATION_ID";
})(RegisterConversationErrorReason || (RegisterConversationErrorReason = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// The panel can be in one of these three states.
var PanelStateKind;
(function (PanelStateKind) {
    // The panel is hidden.
    PanelStateKind[PanelStateKind["HIDDEN"] = 0] = "HIDDEN";
    // The panel is a floating window, detached from any browser window.
    PanelStateKind[PanelStateKind["DETACHED"] = 1] = "DETACHED";
    // The panel is a side panel, attached to a browser window.
    PanelStateKind[PanelStateKind["ATTACHED"] = 2] = "ATTACHED";
})(PanelStateKind || (PanelStateKind = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Represents an override of the First Run Experience (FRE).
var FreOverride;
(function (FreOverride) {
    FreOverride[FreOverride["UNSPECIFIED"] = 0] = "UNSPECIFIED";
    // Deprecated: No longer used.
    // Variation that requires text input from the user to unlock full client.
    FreOverride[FreOverride["TRUST_FIRST_TEXT"] = 1] = "TRUST_FIRST_TEXT";
    // Variation that requires mouse click from the user to unlock full client.
    FreOverride[FreOverride["TRUST_FIRST_CLICK"] = 2] = "TRUST_FIRST_CLICK";
    // Variation that starts with full client unlocked and shows inline consent.
    FreOverride[FreOverride["TRUST_FIRST_INLINE"] = 3] = "TRUST_FIRST_INLINE";
})(FreOverride || (FreOverride = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Entry points that can trigger the opening of the panel.
var InvocationSource;
(function (InvocationSource) {
    // Button in the OS.
    InvocationSource[InvocationSource["OS_BUTTON"] = 0] = "OS_BUTTON";
    // Menu from button in the OS.
    InvocationSource[InvocationSource["OS_BUTTON_MENU"] = 1] = "OS_BUTTON_MENU";
    // OS-level hotkey.
    InvocationSource[InvocationSource["OS_HOTKEY"] = 2] = "OS_HOTKEY";
    // Button in top-chrome.
    InvocationSource[InvocationSource["TOP_CHROME_BUTTON"] = 3] = "TOP_CHROME_BUTTON";
    // First run experience.
    InvocationSource[InvocationSource["FRE"] = 4] = "FRE";
    // From the profile picker.
    InvocationSource[InvocationSource["PROFILE_PICKER"] = 5] = "PROFILE_PICKER";
    // From tab strip nudge.
    InvocationSource[InvocationSource["NUDGE"] = 6] = "NUDGE";
    // From 3-dot menu.
    InvocationSource[InvocationSource["THREE_DOTS_MENU"] = 7] = "THREE_DOTS_MENU";
    // An unsupported/unknown source.
    InvocationSource[InvocationSource["UNSUPPORTED"] = 8] = "UNSUPPORTED";
    // From the What's New page.
    InvocationSource[InvocationSource["WHATS_NEW"] = 9] = "WHATS_NEW";
    // User clicked the sign-in button and signed in.
    InvocationSource[InvocationSource["AFTER_SIGN_IN"] = 10] = "AFTER_SIGN_IN";
    // User shared a tab via the tab context menu.
    InvocationSource[InvocationSource["SHARED_TAB"] = 11] = "SHARED_TAB";
    // From the actor task icon.
    InvocationSource[InvocationSource["ACTOR_TASK_ICON"] = 12] = "ACTOR_TASK_ICON";
    // User shared an image via the context menu.
    InvocationSource[InvocationSource["SHARED_IMAGE"] = 13] = "SHARED_IMAGE";
    // From the handoff button.
    InvocationSource[InvocationSource["HANDOFF_BUTTON"] = 14] = "HANDOFF_BUTTON";
    // From invoking skills.
    InvocationSource[InvocationSource["SKILLS"] = 15] = "SKILLS";
    // Automatically opened from contextual cueing.
    InvocationSource[InvocationSource["AUTO_OPENED_BY_CONTEXTUAL_CUE"] = 16] = "AUTO_OPENED_BY_CONTEXTUAL_CUE";
    // User clicked the summarize button in the PDF viewer.
    InvocationSource[InvocationSource["PDF_SUMMARIZE_BUTTON"] = 17] = "PDF_SUMMARIZE_BUTTON";
    // From a navigation capture.
    InvocationSource[InvocationSource["NAVIGATION_CAPTURE"] = 18] = "NAVIGATION_CAPTURE";
    // Automatically opened for a PDF.
    InvocationSource[InvocationSource["AUTO_OPENED_FOR_PDF"] = 19] = "AUTO_OPENED_FOR_PDF";
    // Selection hotkey.
    InvocationSource[InvocationSource["CAPTURE_REGION_HOTKEY"] = 20] = "CAPTURE_REGION_HOTKEY";
    // From the in-product-help (IPH) entrypoint.
    InvocationSource[InvocationSource["IPH"] = 21] = "IPH";
    // User clicked an anchored contextual cue chip.
    InvocationSource[InvocationSource["ANCHORED_CONTEXTUAL_CUE"] = 22] = "ANCHORED_CONTEXTUAL_CUE";
    // From the context menu.
    InvocationSource[InvocationSource["WEB_CONTENTS_CONTEXT_MENU"] = 23] = "WEB_CONTENTS_CONTEXT_MENU";
    // User clicked on text selection nudge.
    InvocationSource[InvocationSource["TEXT_SELECTION_NUDGE"] = 24] = "TEXT_SELECTION_NUDGE";
    // User clicked on text selection widget.
    InvocationSource[InvocationSource["TEXT_SELECTION_WIDGET"] = 25] = "TEXT_SELECTION_WIDGET";
    // Automatic summarization upon opening.
    // Deprecated.
    InvocationSource[InvocationSource["ZERO_STATE_AUTO_SUMMARIZE"] = 26] = "ZERO_STATE_AUTO_SUMMARIZE";
    // From the universal cart.
    InvocationSource[InvocationSource["UNIVERSAL_CART"] = 27] = "UNIVERSAL_CART";
    // Used exclusively for invocations originating from the
    // GlicExperimentalTriggeringMessageHandler.
    InvocationSource[InvocationSource["EXPERIMENTAL_TRIGGERING"] = 28] = "EXPERIMENTAL_TRIGGERING";
    // Actuation triggered by the password change feature.
    InvocationSource[InvocationSource["PASSWORD_CHANGE"] = 29] = "PASSWORD_CHANGE";
    // From an Autofill action.
    InvocationSource[InvocationSource["AUTOFILL"] = 30] = "AUTOFILL";
    // Button in the toolbar.
    InvocationSource[InvocationSource["TOOLBAR_BUTTON"] = 31] = "TOOLBAR_BUTTON";
    // User clicked on an Indigo page action.
    InvocationSource[InvocationSource["INDIGO_PAGE_ACTION"] = 32] = "INDIGO_PAGE_ACTION";
    // User dropped a file/image onto the GLIC panel.
    InvocationSource[InvocationSource["WEB_DRAG_DROP"] = 33] = "WEB_DRAG_DROP";
    // From the promotion page.
    InvocationSource[InvocationSource["PROMOTION_PAGE"] = 34] = "PROMOTION_PAGE";
    // Side panel remained open on a new tab.
    InvocationSource[InvocationSource["DAISY_CHAIN_ON_NEW_TAB"] = 35] = "DAISY_CHAIN_ON_NEW_TAB";
    // Side panel remained open on a follow-link.
    InvocationSource[InvocationSource["DAISY_CHAIN_ON_FOLLOW_LINK"] = 36] = "DAISY_CHAIN_ON_FOLLOW_LINK";
    // User switched conversation.
    InvocationSource[InvocationSource["CONVERSATION_SWITCH"] = 37] = "CONVERSATION_SWITCH";
    // User detached or attached the panel.
    InvocationSource[InvocationSource["DETACH_ATTACH_BUTTON"] = 38] = "DETACH_ATTACH_BUTTON";
    // Restarted from a restored tab.
    InvocationSource[InvocationSource["TAB_RESTORE"] = 39] = "TAB_RESTORE";
    // Implicitly focused or revealed, e.g., on tab switch or re-focus.
    InvocationSource[InvocationSource["RESHOW_INACTIVE"] = 40] = "RESHOW_INACTIVE";
})(InvocationSource || (InvocationSource = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
//  //tools/metrics/histograms/metadata/glic/enums.xml:GlicInvocationSource,
//  //tools/metrics/histograms/metadata/glic/histograms.xml:GlicInvocationSource,
//  //chrome/browser/glic/service/metrics/metrics_types.h:ResponseSegmentation
// )
// Target for actuation.
var ActuationTarget;
(function (ActuationTarget) {
    // Will default to the agent if the target is unknown.
    ActuationTarget[ActuationTarget["UNKNOWN"] = 0] = "UNKNOWN";
    // Agent infers the best location based on the prompt.
    ActuationTarget[ActuationTarget["AGENT_DECIDES"] = 1] = "AGENT_DECIDES";
    // Forces actuation on the initiating tab.
    ActuationTarget[ActuationTarget["CURRENT_TAB"] = 2] = "CURRENT_TAB";
    // Forces actuation in a new tab.
    ActuationTarget[ActuationTarget["NEW_TAB"] = 3] = "NEW_TAB";
    // Forces actuation on the target surface, if the surface is a valid tab.
    // Note: kTargetSurface can be different than kCurrentTab if the target
    // surface is not the foregrounded tab. This option has no effect if the
    // surface does not resolve to a valid tab.
    ActuationTarget[ActuationTarget["TARGET_SURFACE"] = 4] = "TARGET_SURFACE";
})(ActuationTarget || (ActuationTarget = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Web client's operation modes.
var WebClientMode;
(function (WebClientMode) {
    // Text operation mode.
    WebClientMode[WebClientMode["TEXT"] = 0] = "TEXT";
    // Audio operation mode.
    WebClientMode[WebClientMode["AUDIO"] = 1] = "AUDIO";
})(WebClientMode || (WebClientMode = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Microphone status.
var MicrophoneStatus;
(function (MicrophoneStatus) {
    MicrophoneStatus[MicrophoneStatus["NOT_LISTENING"] = 0] = "NOT_LISTENING";
    MicrophoneStatus[MicrophoneStatus["LISTENING"] = 1] = "LISTENING";
    MicrophoneStatus[MicrophoneStatus["UNKNOWN"] = 2] = "UNKNOWN";
})(MicrophoneStatus || (MicrophoneStatus = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Web client's operation model.
var WebClientModel;
(function (WebClientModel) {
    // Default model.
    WebClientModel[WebClientModel["DEFAULT"] = 0] = "DEFAULT";
    // Actor operation mode.
    WebClientModel[WebClientModel["ACTOR"] = 1] = "ACTOR";
})(WebClientModel || (WebClientModel = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Web client's user counter.
var WebUseCounter;
(function (WebUseCounter) {
    // Default counter. Never used.
    WebUseCounter[WebUseCounter["DEFAULT"] = 0] = "DEFAULT";
    WebUseCounter[WebUseCounter["SUBMIT_PROMPT_WITH_AUTO_MODE"] = 1] = "SUBMIT_PROMPT_WITH_AUTO_MODE";
    WebUseCounter[WebUseCounter["TASK_INTERRUPTED_FOR_USER_CONFIRMATION"] = 2] = "TASK_INTERRUPTED_FOR_USER_CONFIRMATION";
    WebUseCounter[WebUseCounter["TASK_INTERRUPTED_FOR_USER_CLARIFICATION"] = 3] = "TASK_INTERRUPTED_FOR_USER_CLARIFICATION";
    WebUseCounter[WebUseCounter["SELECTION_TOGGLED_VIA_SHARED_MENU"] = 4] = "SELECTION_TOGGLED_VIA_SHARED_MENU";
    WebUseCounter[WebUseCounter["SELECTION_TOGGLED_VIA_HOT_KEY"] = 5] = "SELECTION_TOGGLED_VIA_HOT_KEY";
    WebUseCounter[WebUseCounter["SUBMIT_PROMPT_WITH_TEXT_SELECTION_CUE"] = 6] = "SUBMIT_PROMPT_WITH_TEXT_SELECTION_CUE";
})(WebUseCounter || (WebUseCounter = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Client error dialog types.
var ClientErrorDialogType;
(function (ClientErrorDialogType) {
    ClientErrorDialogType[ClientErrorDialogType["UNKNOWN"] = 0] = "UNKNOWN";
    ClientErrorDialogType[ClientErrorDialogType["DISABLED_BY_ORGANIZATION"] = 1] = "DISABLED_BY_ORGANIZATION";
    ClientErrorDialogType[ClientErrorDialogType["GENERIC_AVAILABILITY"] = 2] = "GENERIC_AVAILABILITY";
    ClientErrorDialogType[ClientErrorDialogType["INELIGIBLE_ACCOUNT"] = 3] = "INELIGIBLE_ACCOUNT";
    ClientErrorDialogType[ClientErrorDialogType["SIGNOUT"] = 4] = "SIGNOUT";
    ClientErrorDialogType[ClientErrorDialogType["UNSUPPORTED_LOCATION"] = 5] = "UNSUPPORTED_LOCATION";
})(ClientErrorDialogType || (ClientErrorDialogType = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
var AdditionalContextSource;
(function (AdditionalContextSource) {
    AdditionalContextSource[AdditionalContextSource["UNKNOWN"] = 2] = "UNKNOWN";
    AdditionalContextSource[AdditionalContextSource["SHARE_CONTEXT_MENU"] = 0] = "SHARE_CONTEXT_MENU";
    AdditionalContextSource[AdditionalContextSource["REGION_SELECTION"] = 1] = "REGION_SELECTION";
    AdditionalContextSource[AdditionalContextSource["TEXT_SELECTION"] = 3] = "TEXT_SELECTION";
    AdditionalContextSource[AdditionalContextSource["WEB_DRAG_DROP"] = 4] = "WEB_DRAG_DROP";
    AdditionalContextSource[AdditionalContextSource["EXPERIMENTAL_TRIGGERING"] = 5] = "EXPERIMENTAL_TRIGGERING";
})(AdditionalContextSource || (AdditionalContextSource = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Types of updates that may be relayed back by the web client.
var ExperimentalTriggeringUpdateType;
(function (ExperimentalTriggeringUpdateType) {
    // An unknown, non-terminal update type.
    ExperimentalTriggeringUpdateType[ExperimentalTriggeringUpdateType["UNKNOWN"] = 0] = "UNKNOWN";
    // A log entry describing internal steps or "thought" process.
    ExperimentalTriggeringUpdateType[ExperimentalTriggeringUpdateType["WORKLOG"] = 1] = "WORKLOG";
    // The interaction was paused.
    ExperimentalTriggeringUpdateType[ExperimentalTriggeringUpdateType["PAUSED"] = 2] = "PAUSED";
    // A final status update or metadata about the completed task.
    ExperimentalTriggeringUpdateType[ExperimentalTriggeringUpdateType["TERMINAL_COMPLETION"] = 3] = "TERMINAL_COMPLETION";
    // The interaction was stopped or cancelled.
    ExperimentalTriggeringUpdateType[ExperimentalTriggeringUpdateType["TERMINAL_STOPPED"] = 4] = "TERMINAL_STOPPED";
    // The interaction failed.
    ExperimentalTriggeringUpdateType[ExperimentalTriggeringUpdateType["TERMINAL_FAILED"] = 5] = "TERMINAL_FAILED";
    // The interaction yielded to the user.
    ExperimentalTriggeringUpdateType[ExperimentalTriggeringUpdateType["YIELD_TO_USER"] = 6] = "YIELD_TO_USER";
})(ExperimentalTriggeringUpdateType || (ExperimentalTriggeringUpdateType = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Lightweight page features detected on the page.
var LightweightPageFeature;
(function (LightweightPageFeature) {
    LightweightPageFeature[LightweightPageFeature["UNKNOWN"] = 0] = "UNKNOWN";
    // The YouTube "Ask" button is visible.
    LightweightPageFeature[LightweightPageFeature["YT_ASK_BUTTON_PRESENT"] = 1] = "YT_ASK_BUTTON_PRESENT";
})(LightweightPageFeature || (LightweightPageFeature = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Reason for `captureRegion` error.
var CaptureRegionErrorReason;
(function (CaptureRegionErrorReason) {
    CaptureRegionErrorReason[CaptureRegionErrorReason["UNKNOWN"] = 0] = "UNKNOWN";
    // There is no focused tab that can be used for region capture.
    CaptureRegionErrorReason[CaptureRegionErrorReason["NO_FOCUSABLE_TAB"] = 1] = "NO_FOCUSABLE_TAB";
})(CaptureRegionErrorReason || (CaptureRegionErrorReason = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Fields of interest from the Glic settings page.
var SettingsPageField;
(function (SettingsPageField) {
    // The OS hotkey configuration field.
    SettingsPageField[SettingsPageField["OS_HOTKEY"] = 1] = "OS_HOTKEY";
    // The OS entrypoint enabling field.
    SettingsPageField[SettingsPageField["OS_ENTRYPOINT_TOGGLE"] = 2] = "OS_ENTRYPOINT_TOGGLE";
})(SettingsPageField || (SettingsPageField = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Describes the capability of the glic host.
var HostCapability;
(function (HostCapability) {
    // Glic host supports scrollTo() with PDF documents.
    HostCapability[HostCapability["SCROLL_TO_PDF"] = 0] = "SCROLL_TO_PDF";
    // Glic host will reset panel size and location on open.
    HostCapability[HostCapability["RESET_SIZE_AND_LOCATION_ON_OPEN"] = 1] = "RESET_SIZE_AND_LOCATION_ON_OPEN";
    // The glic host's getModelQualityClientId() is enabled and can be called
    // safely.
    HostCapability[HostCapability["GET_MODEL_QUALITY_CLIENT_ID"] = 2] = "GET_MODEL_QUALITY_CLIENT_ID";
    // Glic is in multi-instance mode.
    HostCapability[HostCapability["MULTI_INSTANCE"] = 3] = "MULTI_INSTANCE";
    // Enables the experimental "Trust First" (Arm 1 - "Start Chat") onboarding
    // UI flow, bypassing the standard FRE flow.
    HostCapability[HostCapability["TRUST_FIRST_ONBOARDING_ARM1"] = 4] = "TRUST_FIRST_ONBOARDING_ARM1";
    // Enables the experimental "Trust First" (Arm 2 - "Welcome Screen")
    // onboarding UI flow, bypassing the standard FRE flow.
    HostCapability[HostCapability["TRUST_FIRST_ONBOARDING_ARM2"] = 5] = "TRUST_FIRST_ONBOARDING_ARM2";
    // Glic host supports sharing additional image context.
    HostCapability[HostCapability["SHARE_ADDITIONAL_IMAGE_CONTEXT"] = 6] = "SHARE_ADDITIONAL_IMAGE_CONTEXT";
    // Enables the PDF Zero State Web UI.
    HostCapability[HostCapability["PDF_ZERO_STATE"] = 7] = "PDF_ZERO_STATE";
    // Indicates that the host supports the invoke mechanism.
    HostCapability[HostCapability["INVOKE"] = 8] = "INVOKE";
    // Indicates that the host does not support Live Mode.
    HostCapability[HostCapability["NO_LIVE_MODE"] = 9] = "NO_LIVE_MODE";
    // Indicates that the host supports auto browse attempting login using Sign in
    // with Google.
    HostCapability[HostCapability["AUTO_LOGIN_SIGN_IN_WITH_GOOGLE"] = 10] = "AUTO_LOGIN_SIGN_IN_WITH_GOOGLE";
    // Indicates that the host supports sharing images via the invoke mechanism.
    HostCapability[HostCapability["SHARE_IMAGE_VIA_INVOKE"] = 11] = "SHARE_IMAGE_VIA_INVOKE";
    // Indicates that the host supports image drag and drop from the web
    HostCapability[HostCapability["IMG_WEB_DRAG_DROP"] = 12] = "IMG_WEB_DRAG_DROP";
    // Indicates that the host does not show the WebUi preloader.
    HostCapability[HostCapability["NO_WEB_UI_LOADER"] = 13] = "NO_WEB_UI_LOADER";
})(HostCapability || (HostCapability = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Lists capabilities that the glic web client may support.
var ClientCapabilities;
(function (ClientCapabilities) {
    // The glic web client does not use favicons in TabData, so they can
    // be omitted from TabData.
    ClientCapabilities[ClientCapabilities["IGNORES_TAB_DATA_FAVICONS"] = 0] = "IGNORES_TAB_DATA_FAVICONS";
})(ClientCapabilities || (ClientCapabilities = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
//
// Place the mojom structs that require Javascript bindings here.
//
// Describes the duration of the actions in the task.  This is used by the actor
// to customize the task UI.
var TaskDuration;
(function (TaskDuration) {
    // The task has actions that permit user observation and intervention in the
    // browser.
    TaskDuration[TaskDuration["DEFAULT"] = 1] = "DEFAULT";
    // The task has fast actions that do not permit observation and intervention.
    TaskDuration[TaskDuration["TRANSIENT"] = 2] = "TRANSIENT";
})(TaskDuration || (TaskDuration = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Describes how long the user grants the actor with the permission to actuate.
// Used when the actor is to actuate with sensitive data, such as entering
// payment information or login credentials.
var UserGrantedPermissionDuration;
(function (UserGrantedPermissionDuration) {
    // The user only grants a one-time permission. The user will be asked again.
    // This is the default behavior.
    UserGrantedPermissionDuration[UserGrantedPermissionDuration["ONE_TIME"] = 0] = "ONE_TIME";
    // The user grants a permission to always allow the actor to actuate with
    // sensitive data. The persistence of this permission is defined differently
    // for different features.
    UserGrantedPermissionDuration[UserGrantedPermissionDuration["ALWAYS_ALLOW"] = 1] = "ALWAYS_ALLOW";
})(UserGrantedPermissionDuration || (UserGrantedPermissionDuration = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Describes the login method for the credential.
var CredentialType;
(function (CredentialType) {
    // Used to fill in a username/password form.
    CredentialType[CredentialType["PASSWORD"] = 0] = "PASSWORD";
    // Used with an identity provider (e.g. Sign in with Google).
    CredentialType[CredentialType["FEDERATED"] = 1] = "FEDERATED";
})(CredentialType || (CredentialType = {}));
///////////////////////////////////////////////
// WARNING - GENERATED FROM MOJOM, DO NOT EDIT.
// Mode for specific feature behaviors.
var FeatureMode;
(function (FeatureMode) {
    FeatureMode[FeatureMode["UNSPECIFIED"] = 0] = "UNSPECIFIED";
    FeatureMode[FeatureMode["IMAGE_GENERATION"] = 1] = "IMAGE_GENERATION";
    FeatureMode[FeatureMode["ACTUATION"] = 2] = "ACTUATION";
    // Client feature mode to initiate actuation for Experimental Triggering.
    FeatureMode[FeatureMode["EXPERIMENTAL_TRIGGERING"] = 3] = "EXPERIMENTAL_TRIGGERING";
    // Client feature mode to initiate actuation for Universal Cart.
    FeatureMode[FeatureMode["UNIVERSAL_CART"] = 4] = "UNIVERSAL_CART";
    // Client feature mode for Promotion Page.
    FeatureMode[FeatureMode["PROMOTION_PAGE"] = 5] = "PROMOTION_PAGE";
})(FeatureMode || (FeatureMode = {}));
/// END_GENERATED - DO NOT MODIFY ABOVE
///////////////////////////////////////////////////////////////////////////////

// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Note: this code is made to conform to glic_api's Observable, but can also be
// used independently.
function assertNotReachedCase(_param, message) {
    throw new Error('Assertion failed' + (message ? `: ${message}` : ''));
}
class ObservableSubscription {
    observer;
    onUnsubscribe;
    constructor(observer, onUnsubscribe) {
        this.observer = observer;
        this.onUnsubscribe = onUnsubscribe;
    }
    unsubscribe() {
        this.onUnsubscribe(this);
    }
}
/**
 * A base class for observables that handles subscribers.
 */
class ObservableBase {
    subscribers = new Set();
    state_ = 'active';
    errorValue;
    next(value) {
        switch (this.state_) {
            case 'active':
                break;
            case 'complete':
            case 'error':
                throw new Error('Observable is not active');
            default:
                assertNotReachedCase(this.state_);
        }
        this.subscribers.forEach((sub) => {
            // Ignore if removed since forEach was called.
            if (this.subscribers.has(sub)) {
                try {
                    sub.observer.next?.(value);
                }
                catch (e) {
                    console.warn(e);
                }
            }
        });
    }
    error(e) {
        switch (this.state_) {
            case 'active':
                this.state_ = 'error';
                this.errorValue = e;
                break;
            case 'complete':
            case 'error':
                throw new Error('Observable is not active');
            default:
                assertNotReachedCase(this.state_);
        }
        let loggedWarning = false;
        const hadSubscribers = this.hasActiveSubscription();
        this.subscribers.forEach((sub) => {
            // Ignore if removed since forEach was called.
            if (this.subscribers.has(sub)) {
                if (sub.observer.error) {
                    try {
                        sub.observer.error(e);
                    }
                    catch (e) {
                        console.warn(e);
                    }
                }
                else {
                    if (!loggedWarning) {
                        console.warn('unhandled error: ', e);
                        loggedWarning = true;
                    }
                }
            }
        });
        this.subscribers.clear();
        if (hadSubscribers) {
            this.activeSubscriptionChanged(false);
        }
    }
    complete() {
        switch (this.state_) {
            case 'active':
                this.state_ = 'complete';
                break;
            case 'complete':
            case 'error':
                throw new Error('Observable is not active');
            default:
                assertNotReachedCase(this.state_);
        }
        const hadSubscribers = this.hasActiveSubscription();
        this.subscribers.forEach((sub) => {
            // Ignore if removed since forEach was called.
            if (this.subscribers.has(sub)) {
                try {
                    sub.observer.complete?.();
                }
                catch (e) {
                    console.warn(e);
                }
            }
        });
        this.subscribers.clear();
        if (hadSubscribers) {
            this.activeSubscriptionChanged(false);
        }
    }
    isStopped() {
        return this.state_ !== 'active';
    }
    subscribe(changeOrObserver) {
        if (typeof changeOrObserver === 'function') {
            return this.subscribeObserver({
                next: (value) => {
                    changeOrObserver(value);
                },
            });
        }
        else {
            return this.subscribeObserver(changeOrObserver);
        }
    }
    /**
     * Subscribe to changes with an Observer.
     * This API was added in later, and provided as a separate function for Glic
     * API discovery purposes.
     */
    subscribeObserver(observer) {
        switch (this.state_) {
            case 'active':
                break;
            case 'complete':
                observer.complete?.();
                return { unsubscribe: () => { } };
            case 'error':
                observer.error?.(this.errorValue);
                return { unsubscribe: () => { } };
            default:
                assertNotReachedCase(this.state_);
        }
        const newSub = new ObservableSubscription(observer, this.onUnsubscribe.bind(this));
        if (this.subscribers.size === 0) {
            this.activeSubscriptionChanged(true);
        }
        this.subscribers.add(newSub);
        this.subscriberAdded(newSub);
        return newSub;
    }
    onUnsubscribe(sub) {
        if (!this.subscribers) {
            return;
        }
        if (this.subscribers.size === 0) {
            return;
        }
        this.subscribers.delete(sub);
        if (this.subscribers.size === 0) {
            this.activeSubscriptionChanged(false);
        }
    }
    subscriberAdded(_sub) { }
    activeSubscriptionChanged(_hasActiveSubscription) { }
    hasActiveSubscription() {
        return this.subscribers.size > 0;
    }
}
/**
 * A simple observable with no memory of previous values.
 */
class Subject extends ObservableBase {
    next(value) {
        super.next(value);
    }
}
/**
 * A observable value that can change over time. If value is initialized, sends
 * it to new subscribers upon subscribe().
 */
class ObservableValue extends Subject {
    isSet;
    value;
    hasActiveSubscriptionCallback;
    constructor(isSet, value, hasActiveSubscriptionCallback) {
        super();
        this.isSet = isSet;
        this.value = value;
        this.hasActiveSubscriptionCallback = hasActiveSubscriptionCallback;
    }
    /**
     * Create an ObservableValue which has an initial value. Optionally a
     * `hasActiveSubscriptionCallback` can be added which will be called with
     * `true` when this observable has its first subscriber and `false` when there
     * are no longer any subscribers to this observable.
     */
    static withValue(value, hasActiveSubscriptionCallback) {
        return new ObservableValue(true, value, hasActiveSubscriptionCallback);
    }
    /**
     * Create an ObservableValue which has no initial value. Subscribers will not
     * be called until after assignAndSignal() is called the first time.
     * Optionally a `hasActiveSubscriptionCallback` can be added which will be
     * called with `true` when this observable has its first subscriber and
     * false` when there are no longer any subscribers to this observable.
     */
    static withNoValue(hasActiveSubscriptionCallback) {
        return new ObservableValue(false, undefined, hasActiveSubscriptionCallback);
    }
    /**
     * Assigns a new value to the ObservableValue and signals all subscribers.
     * Does nothing if the value is unchanged.
     */
    assignAndSignal(v, force = false) {
        if (this.isStopped()) {
            throw new Error('ObservableValue is not active');
        }
        const send = !this.isSet || this.value !== v || force;
        this.isSet = true;
        this.value = v;
        if (!send) {
            return;
        }
        super.next(v);
    }
    /** Returns the current value, or undefined if not initialized. */
    getCurrentValue() {
        return this.value;
    }
    /**
     * Asynchronously waits until the ObservableValue's current value satisfies a
     * given criteria.
     */
    async waitUntil(criteria) {
        const { promise, resolve, reject } = Promise.withResolvers();
        const sub = this.subscribe({
            next(newValue) {
                if (criteria(newValue)) {
                    resolve(newValue);
                }
            },
            error: reject,
            complete() {
                reject(new Error('Observable completed'));
            },
        });
        let resultValue;
        try {
            resultValue = await promise;
        }
        finally {
            sub.unsubscribe();
        }
        return resultValue;
    }
    subscriberAdded(sub) {
        if (this.isSet) {
            sub.observer.next?.(this.value);
        }
    }
    activeSubscriptionChanged(hasActiveSubscription) {
        super.activeSubscriptionChanged(hasActiveSubscription);
        this.hasActiveSubscriptionCallback?.(hasActiveSubscription);
    }
}

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
 * Verify |value| is truthy.
 * @param value A value to check for truthiness. Note that this
 *     may be used to test whether |value| is defined or not, and we don't want
 *     to force a cast to boolean.
 */
function assert(value, message) {
    if (value) {
        return;
    }
    throw new Error('Assertion failed' + (message ? `: ${message}` : ''));
}

// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
class ResponseExtras {
    transfers = [];
    // Add objects to transfer when sending the response over postMessage.
    addTransfer(...transfers) {
        this.transfers.push(...transfers);
    }
}
// Defines a message type. Ensures the message is structured cloneable.
// Currently returns undefined, as no information about the message is retained
// at runtime.
function defMessage() {
    return undefined;
}
function defInterface(def) {
    const tidyRequest = (m) => {
        const id = m.histogram?.id;
        if (id === undefined) {
            return m;
        }
        let name = m.histogram.name;
        if (name === undefined) {
            name = m.name.charAt(0).toUpperCase() + m.name.slice(1);
        }
        return { ...m, histogram: { name, id } };
    };
    return {
        ...def,
        methodMap: new Map(def.methods.map(m => [m.name, tidyRequest(m)])),
    };
}

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/*
This file defines messages sent over postMessage in-between the Glic WebUI
and the Glic web client.

Most requests closely match signatures of API methods. Where possible, name
messages by concatenating the interface name with the method name. This helps
readability, and ensures that each name is unique.
*/
defInterface({
    name: 'WebClientHost',
    methods: [
        {
            name: 'webClientCreated',
            request: defMessage(),
            response: defMessage(),
            histogram: { name: 'WebClientCreated', id: 1 },
        },
        {
            name: 'webClientInitialized',
            request: defMessage(),
            histogram: { id: 2 },
        },
        {
            name: 'onExperimentalTriggeringUpdate',
            request: defMessage(),
            histogram: { id: 98 },
        },
        {
            name: 'createTab',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 3 },
        },
        {
            name: 'activateTabWithUrl',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 102 },
        },
        {
            name: 'openGlicSettingsPage',
            request: defMessage(),
            histogram: { id: 4 },
        },
        {
            name: 'openPasswordManagerSettingsPage',
            histogram: { id: 78 },
        },
        {
            name: 'closePanel',
            histogram: { id: 5 },
        },
        {
            name: 'closePanelAndShutdown',
            histogram: { id: 6 },
        },
        {
            name: 'showProfilePicker',
            histogram: { id: 7 },
        },
        {
            name: 'getModelQualityClientId',
            response: defMessage(),
            histogram: { id: 8 },
        },
        {
            name: 'switchConversation',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 64 },
        },
        {
            name: 'registerConversation',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 65 },
        },
        {
            name: 'getContextFromFocusedTab',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 9 },
        },
        {
            name: 'getContextFromTab',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 10 },
        },
        {
            name: 'getImageBytesFromTab',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 101 },
        },
        {
            name: 'setMaximumNumberOfPinnedTabs',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 12 },
        },
        {
            name: 'activateTab',
            request: defMessage(),
            histogram: { id: 76 },
        },
        {
            name: 'captureScreenshot',
            response: defMessage(),
            histogram: { id: 16 },
        },
        {
            name: 'resizeWindow',
            request: defMessage(),
            histogram: { id: 17 },
        },
        {
            name: 'enableDragResize',
            request: defMessage(),
            histogram: { id: 18 },
        },
        {
            name: 'setMinimumWidgetSize',
            request: defMessage(),
            histogram: { id: 20 },
        },
        {
            name: 'setMicrophonePermissionState',
            request: defMessage(),
            histogram: { id: 21 },
        },
        {
            name: 'setLocationPermissionState',
            request: defMessage(),
            histogram: { id: 22 },
        },
        {
            name: 'setTabContextPermissionState',
            request: defMessage(),
            histogram: { id: 23 },
        },
        {
            name: 'setClosedCaptioningSetting',
            request: defMessage(),
            histogram: { id: 56 },
        },
        {
            name: 'setContextAccessIndicator',
            request: defMessage(),
            histogram: { id: 24 },
        },
        {
            name: 'setActuationOnWebSetting',
            request: defMessage(),
            histogram: { id: 69 },
        },
        {
            name: 'getUserProfileInfo',
            response: defMessage(),
            histogram: { id: 25 },
        },
        {
            name: 'refreshSignInCookies',
            response: defMessage(),
            histogram: { id: 26 },
        },
        {
            name: 'attachPanel',
            histogram: { id: 27 },
        },
        {
            name: 'detachPanel',
            histogram: { id: 28 },
        },
        {
            name: 'setAudioDucking',
            request: defMessage(),
            histogram: { id: 29 },
        },
        {
            name: 'onUserInputSubmitted',
            request: defMessage(),
            histogram: { id: 38 },
        },
        {
            name: 'onReaction',
            request: defMessage(),
            histogram: { id: 66 },
        },
        {
            name: 'onOptinImpression',
            histogram: { id: 99 },
        },
        {
            name: 'onContextUploadStarted',
            histogram: { id: 68 },
        },
        {
            name: 'onContextUploadCompleted',
            histogram: { id: 67 },
        },
        {
            name: 'onResponseStarted',
            histogram: { id: 40 },
        },
        {
            name: 'onResponseStopped',
            request: defMessage(),
            histogram: { id: 41 },
        },
        {
            name: 'onSessionTerminated',
            histogram: { id: 42 },
        },
        {
            name: 'onTurnCompleted',
            request: defMessage(),
            histogram: { id: 43 },
        },
        {
            name: 'onResponseRated',
            request: defMessage(),
            histogram: { id: 39 },
        },
        {
            name: 'onClosedCaptionsShown',
            histogram: { id: 59 },
        },
        {
            name: 'onActionSubmitted',
            request: defMessage(),
            histogram: { id: 93 },
        },
        {
            name: 'setSyntheticExperimentState',
            request: defMessage(),
            histogram: { id: 46 },
        },
        {
            name: 'openOsPermissionSettingsMenu',
            request: defMessage(),
            histogram: { id: 47 },
        },
        {
            name: 'getOsMicrophonePermissionStatus',
            response: defMessage(),
            histogram: { id: 48 },
        },
        {
            name: 'pinTabs',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 49 },
        },
        {
            name: 'unpinTabs',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 50 },
        },
        {
            name: 'unpinAllTabs',
            request: defMessage(),
            histogram: { id: 51 },
        },
        {
            name: 'createSkill',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 82 },
        },
        {
            name: 'updateSkill',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 83 },
        },
        {
            name: 'showManageSkillsUi',
            histogram: { id: 86 },
        },
        {
            name: 'showBrowseSkillsUi',
            histogram: { id: 95 },
        },
        {
            name: 'getSkill',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 84 },
        },
        {
            name: 'recordSkillsWebClientEvent',
            request: defMessage(),
            histogram: { id: 91 },
        },
        {
            name: 'subscribeToPinCandidates',
            request: defMessage(),
            histogram: { id: 52 },
        },
        {
            name: 'subscribeToCaptureRegion',
            request: defMessage(),
            histogram: { id: 71 },
        },
        {
            name: 'deleteCapturedRegion',
            request: defMessage(),
            histogram: { id: 92 },
        },
        {
            name: 'getZeroStateSuggestionsForFocusedTab',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 54 },
        },
        {
            name: 'maybeRefreshUserStatus',
            histogram: { id: 58 },
        },
        {
            name: 'getZeroStateSuggestionsAndSubscribe',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 55 },
        },
        {
            name: 'subscribeToPageMetadata',
            request: defMessage(),
            response: defMessage(),
            histogram: { id: 63 },
        },
        {
            name: 'onModeChange',
            request: defMessage(),
            histogram: { id: 70 },
        },
        {
            name: 'setOnboardingCompleted',
            histogram: { id: 80 },
        },
        {
            name: 'subscribeToTabData',
            request: defMessage(),
            histogram: { id: 81 },
        },
        {
            name: 'subscribeToTabFavicon',
            request: defMessage(),
            histogram: { id: 94 },
        },
        {
            name: 'onMicrophoneStatusChange',
            request: defMessage(),
            histogram: { id: 90 },
        },
        {
            name: 'recordHistogram',
            request: defMessage(),
        },
        {
            name: 'setErrorDialogState',
            request: defMessage(),
        },
        {
            name: 'reportClientTransientError',
            request: defMessage(),
        },
        {
            name: 'processCounterAbuseVerdict',
            request: defMessage(),
            histogram: { id: 100 },
        },
        {
            name: 'subscribeToZoomLevel',
            histogram: { id: 96 },
        },
        {
            name: 'unsubscribeFromZoomLevel',
            histogram: { id: 97 },
        },
        {
            name: 'createAnnotationHandler',
            request: defMessage(),
        },
    ],
});
// Types of requests to the GlicWebClient.
const WebClientDef = defInterface({
    name: 'WebClient',
    methods: [
        {
            name: 'notifyPanelWillOpen',
            request: defMessage(),
            response: defMessage(),
        },
        {
            name: 'notifyPanelWasClosed',
        },
        {
            name: 'stopMicrophone',
        },
        {
            name: 'panelStateChanged',
            request: defMessage(),
        },
        {
            name: 'canAttachStateChanged',
            request: defMessage(),
        },
        {
            name: 'notifyGeminiEnterpriseSettingsChanged',
            request: defMessage(),
        },
        {
            name: 'notifyMicrophonePermissionStateChanged',
            request: defMessage(),
        },
        {
            name: 'notifyLocationPermissionStateChanged',
            request: defMessage(),
        },
        {
            name: 'notifyTabContextPermissionStateChanged',
            request: defMessage(),
        },
        {
            name: 'notifyDefaultTabContextPermissionStateChanged',
            request: defMessage(),
        },
        {
            name: 'notifyOsLocationPermissionStateChanged',
            request: defMessage(),
        },
        {
            name: 'notifyClosedCaptioningSettingChanged',
            request: defMessage(),
        },
        {
            name: 'notifyActuationOnWebSettingChanged',
            request: defMessage(),
        },
        {
            name: 'notifyFocusedTabChanged',
            request: defMessage(),
        },
        {
            name: 'notifyPanelActiveChanged',
            request: defMessage(),
        },
        {
            name: 'checkResponsive',
            response: defMessage(),
        },
        {
            name: 'notifyManualResizeChanged',
            request: defMessage(),
        },
        {
            name: 'browserIsOpenChanged',
            request: defMessage(),
        },
        {
            name: 'notifyOsHotkeyStateChanged',
            request: defMessage(),
        },
        {
            name: 'notifyPinnedTabsChanged',
            request: defMessage(),
        },
        {
            name: 'notifyPinnedTabDataChanged',
            request: defMessage(),
        },
        {
            name: 'notifySkillPreviewsChanged',
            request: defMessage(),
        },
        {
            name: 'notifySkillPreviewChanged',
            request: defMessage(),
        },
        {
            name: 'notifyContextualSkillPreviewsChanged',
            request: defMessage(),
        },
        {
            name: 'notifySkillDeleted',
            request: defMessage(),
        },
        {
            name: 'zeroStateSuggestionsChanged',
            request: defMessage(),
        },
        {
            name: 'pageMetadataChanged',
            request: defMessage(),
        },
        {
            name: 'notifyAdditionalContext',
            request: defMessage(),
        },
        {
            name: 'notifyActOnWebCapabilityChanged',
            request: defMessage(),
        },
        {
            name: 'onboardingCompletedChanged',
            request: defMessage(),
        },
        {
            name: 'notifyActorTaskListRowClicked',
            request: defMessage(),
        },
        {
            name: 'invoke',
            request: defMessage(),
        },
        {
            name: 'getExperimentalTriggeringUpdates',
            request: defMessage(),
            response: defMessage(),
        },
        {
            name: 'notifyZoomLevelChanged',
            request: defMessage(),
        },
    ],
});
const WebClientRegionCaptureDef = defInterface({
    name: 'WebClientRegionCapture',
    methods: [
        {
            name: 'captureRegionUpdate',
            request: defMessage(),
        },
    ],
});
const WebClientPinCandidatesObserverDef = defInterface({
    name: 'WebClientPinCandidatesObserver',
    methods: [
        {
            name: 'pinCandidatesChanged',
            request: defMessage(),
        },
    ],
});
const WebClientTabDataObserverDef = defInterface({
    name: 'WebClientTabDataObserver',
    methods: [
        {
            name: 'tabDataChanged',
            request: defMessage(),
        },
    ],
});
const WebClientTabFaviconObserverDef = defInterface({
    name: 'WebClientTabFaviconObserver',
    methods: [
        {
            name: 'tabFaviconChanged',
            request: defMessage(),
        },
    ],
});
// LINT.IfChange(ApiRequestType)
// New values here must be added to histograms.xml and to enums.xml.
// Note: Not for accessing in code, so it can be stripped from compiled js.
const RECORDED_REQUEST_IDS = {
    WebClientCreated: 1,
    WebClientInitialized: 2,
    CreateTab: 3,
    ActivateTabWithUrl: 102,
    OpenGlicSettingsPage: 4,
    ClosePanel: 5,
    ClosePanelAndShutdown: 6,
    ShowProfilePicker: 7,
    GetModelQualityClientId: 8,
    GetContextFromFocusedTab: 9,
    GetContextFromTab: 10,
    GetContextForActorFromTab: 11,
    SetMaximumNumberOfPinnedTabs: 12,
    StopActorTask: 13,
    PauseActorTask: 14,
    ResumeActorTask: 15,
    CaptureScreenshot: 16,
    ResizeWindow: 17,
    EnableDragResize: 18,
    // Do not reuse deleted request ID: 19,
    SetMinimumWidgetSize: 20,
    SetMicrophonePermissionState: 21,
    SetLocationPermissionState: 22,
    SetTabContextPermissionState: 23,
    SetContextAccessIndicator: 24,
    GetUserProfileInfo: 25,
    RefreshSignInCookies: 26,
    AttachPanel: 27,
    DetachPanel: 28,
    SetAudioDucking: 29,
    LogBeginAsyncEvent: 30,
    LogEndAsyncEvent: 31,
    LogInstantEvent: 32,
    JournalClear: 33,
    JournalSnapshot: 34,
    JournalStart: 35,
    JournalStop: 36,
    JournalRecordFeedback: 37,
    OnUserInputSubmitted: 38,
    OnResponseRated: 39,
    OnResponseStarted: 40,
    OnResponseStopped: 41,
    OnSessionTerminated: 42,
    OnTurnCompleted: 43,
    // Do not reuse deleted request ID: 44,
    ScrollTo: 45,
    SetSyntheticExperimentState: 46,
    OpenOsPermissionSettingsMenu: 47,
    GetOsMicrophonePermissionStatus: 48,
    PinTabs: 49,
    UnpinTabs: 50,
    UnpinAllTabs: 51,
    SubscribeToPinCandidates: 52,
    // Do not reuse deleted request ID: 53,
    GetZeroStateSuggestionsForFocusedTab: 54,
    GetZeroStateSuggestionsAndSubscribe: 55,
    SetClosedCaptioningSetting: 56,
    DropScrollToHighlight: 57,
    MaybeRefreshUserStatus: 58,
    OnClosedCaptionsShown: 59,
    CreateTask: 60,
    PerformActions: 61,
    // Do not reuse deleted request ID: 62,
    SubscribeToPageMetadata: 63,
    SwitchConversation: 64,
    RegisterConversation: 65,
    OnReaction: 66,
    OnContextUploadCompleted: 67,
    OnContextUploadStarted: 68,
    SetActuationOnWebSetting: 69,
    OnModeChange: 70,
    SubscribeToCaptureRegion: 71,
    // Do not reuse deleted request ID: 72,
    // Do not reuse deleted request ID: 73,
    InterruptActorTask: 74,
    UninterruptActorTask: 75,
    ActivateTab: 76,
    CreateActorTab: 77,
    OpenPasswordManagerSettingsPage: 78,
    SetOnboardingCompleted: 80,
    SubscribeToTabData: 81,
    CreateSkill: 82,
    UpdateSkill: 83,
    GetSkill: 84,
    CancelActions: 85,
    ShowManageSkillsUi: 86,
    AutofillSuggestionDialogOnFormPresented: 87,
    AutofillSuggestionDialogOnFormPreviewChanged: 88,
    AutofillSuggestionDialogOnFormConfirmed: 89,
    OnMicrophoneStatusChange: 90,
    RecordSkillsWebClientEvent: 91,
    DeleteCapturedRegion: 92,
    OnActionSubmitted: 93,
    SubscribeToTabFavicon: 94,
    ShowBrowseSkillsUi: 95,
    SubscribeToZoomLevel: 96,
    UnsubscribeFromZoomLevel: 97,
    OnExperimentalTriggeringUpdate: 98,
    OnOptinImpression: 99,
    ProcessCounterAbuseVerdict: 100,
    GetImageBytesFromTab: 101,
};
Math.max(...Object.values(RECORDED_REQUEST_IDS));
var ImageAlphaType;
(function (ImageAlphaType) {
    // RGB values are unmodified.
    ImageAlphaType[ImageAlphaType["UNPREMUL"] = 0] = "UNPREMUL";
    // RGB values have been premultiplied by alpha.
    ImageAlphaType[ImageAlphaType["PREMUL"] = 1] = "PREMUL";
})(ImageAlphaType || (ImageAlphaType = {}));
// Chromium currently only uses a single color type for BitmapN32.
var ImageColorType;
(function (ImageColorType) {
    ImageColorType[ImageColorType["BGRA"] = 0] = "BGRA";
    ImageColorType[ImageColorType["RGBA"] = 1] = "RGBA";
})(ImageColorType || (ImageColorType = {}));
// Types of subscriber observations that may be observed.
var SubscriberObservationType;
(function (SubscriberObservationType) {
    // An update was observed.
    SubscriberObservationType[SubscriberObservationType["UPDATE"] = 0] = "UPDATE";
    // Completed all observations.
    SubscriberObservationType[SubscriberObservationType["COMPLETE"] = 1] = "COMPLETE";
    // An unexpected error was observed.
    SubscriberObservationType[SubscriberObservationType["ERROR"] = 2] = "ERROR";
})(SubscriberObservationType || (SubscriberObservationType = {}));
class ErrorWithReasonImpl extends Error {
    reasonType;
    reason;
    constructor(reasonType, reason, message) {
        super(message ?? `${reasonType} Error: ${reason}`);
        this.reasonType = reasonType;
        this.reason = reason;
    }
}
// Constructs an exception from a TransferableException.
function exceptionFromTransferable(e) {
    // Error types are serializable, but they do not serialize all members.
    // If exceptionReason is provided, we use it to reconstruct a
    // ErrorWithReason by just setting additional fields after
    // serialization.
    if (e.exceptionReason !== undefined) {
        const withReason = e.exception;
        withReason.reason = e.exceptionReason.reason;
        withReason.reasonType = e.exceptionReason.reasonType;
    }
    return e.exception;
}
// Transform an Error into a TransferableException.
function newTransferableException(e) {
    let exceptionReason = undefined;
    const maybeWithReason = e;
    if (maybeWithReason.reasonType !== undefined &&
        maybeWithReason.reason !== undefined) {
        exceptionReason = {
            reason: maybeWithReason.reason,
            reasonType: maybeWithReason.reasonType,
        };
    }
    return { exception: e, exceptionReason };
}
const ERROR_CODEC = {
    serialize: newTransferableException,
    deserialize: exceptionFromTransferable,
};

// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
class BitmapHeaderGenerator {
    colorType;
    template;
    bytesPerPixel = 4;
    fileHeaderSize = 14;
    // Offsets of each field. 14 bytes total.
    // https://en.wikipedia.org/wiki/BMP_file_format#Bitmap_file_header
    bitmapFileHeaderFields = {
        'bfType': 0, // 2 bytes
        'bFileSize': 2, // 4 bytes
        // 'bReserved1': 6, // 2 bytes
        // 'bReserved2': 8, // 2 bytes
        'bOffBits': 10, // 4 bytes
    };
    // Offsets of each header field, 124 bytes total.
    // https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapv5header
    bitmapv5HeaderFields = {
        'bV5Size': 0, // 4 bytes
        'bV5Width': 4, // 4 bytes
        'bV5Height': 8, // 4 bytes
        'bV5Planes': 12, // 2 bytes
        'bV5BitCount': 14, // 2 bytes
        'bV5Compression': 16, // 4 bytes
        // 'bV5SizeImage': 20, // 4 bytes
        // 'bV5XPelsPerMeter': 24, // 4 bytes
        // 'bV5YPelsPerMeter': 28, // 4 bytes
        // 'bV5ClrUsed': 32, // 4 bytes
        // 'bV5ClrImportant': 36, // 4 bytes
        'bV5RedMask': 40, // 4 bytes
        'bV5GreenMask': 44, // 4 bytes
        'bV5BlueMask': 48, // 4 bytes
        'bV5AlphaMask': 52, // 4 bytes
        'bV5CSType': 56, // 4 bytes
        // 'bV5Endpoints': 60, // 36 bytes
        // 'bV5GammaRed': 96, // 4 bytes
        // 'bV5GammaGreen': 100, // 4 bytes
        // 'bV5GammaBlue': 104, // 4 bytes
        'bV5Intent': 108, // 4 bytes
        // 'bV5ProfileData': 112, // 4 bytes
        // 'bV5ProfileSize': 116, // 4 bytes
        // 'bV5Reserved': 120, // 4 bytes
    };
    totalHeaderSize = 138; // 14 + 124
    constructor(colorType) {
        this.colorType = colorType;
        this.template = this.createTemplate();
    }
    createBmpHeader(width, height) {
        // Copy the template.
        const buffer = this.template.slice(0);
        const dataView = new DataView(buffer);
        const pixelSize = Math.abs(width * height * this.bytesPerPixel);
        {
            const F = this.bitmapFileHeaderFields;
            dataView.setUint32(F.bFileSize, this.totalHeaderSize + pixelSize, true);
        }
        {
            const F = this.bitmapv5HeaderFields;
            const OFFSET = this.fileHeaderSize;
            dataView.setInt32(OFFSET + F.bV5Width, width, true);
            dataView.setInt32(OFFSET + F.bV5Height, height, true);
            if (this.colorType === ImageColorType.RGBA) {
                dataView.setUint32(OFFSET + F.bV5RedMask, 0x000000ff, true);
                dataView.setUint32(OFFSET + F.bV5GreenMask, 0x0000ff00, true);
                dataView.setUint32(OFFSET + F.bV5BlueMask, 0x00ff0000, true);
            }
        }
        return buffer;
    }
    // Creates a template for the bitmap header, which sets fields that
    // will not change depending on the image.
    createTemplate() {
        // Values here should match those in
        // skia/ext/skia_utils_win.cc.
        // Create the buffer for the header
        const buffer = new ArrayBuffer(this.totalHeaderSize);
        // Use a DataView to write bytes into the buffer.
        // In setUint*(), true = use little-endian
        const dataView = new DataView(buffer);
        {
            const F = this.bitmapFileHeaderFields;
            dataView.setUint8(F.bfType, 0x42); // 'B'
            dataView.setUint8(F.bfType + 1, 0x4D); // 'M'
            dataView.setUint32(F.bOffBits, this.totalHeaderSize, true);
        }
        {
            const F = this.bitmapv5HeaderFields;
            const OFFSET = this.fileHeaderSize;
            dataView.setUint32(OFFSET + F.bV5Size, 124, true);
            dataView.setUint16(OFFSET + F.bV5Planes, 1, true);
            dataView.setUint16(OFFSET + F.bV5BitCount, 32, true);
            dataView.setUint32(OFFSET + F.bV5Compression, this.colorType === ImageColorType.RGBA ? 3 /*BI_BITFIELDS*/ :
                0 /*BI_RGB*/, true);
            dataView.setUint32(OFFSET + F.bV5AlphaMask, 0xff000000, true);
            dataView.setUint32(OFFSET + F.bV5CSType, 0x57696E20 /*LCS_WINDOWS_COLOR_SPACE*/, true);
            dataView.setUint32(OFFSET + F.bV5Intent, 4 /*LCS_GM_IMAGES*/, true);
        }
        return buffer;
    }
}
const bitmapHeaderGenerators = [undefined, undefined];
// Converts an RgbaImage into a Blob. Output is a BMP.
function rgbaImageToBlob(image) {
    // It would be abnormal to see more than one color type, but we handle it
    // for safety.
    let headerGenerator = bitmapHeaderGenerators[image.colorType];
    if (!headerGenerator) {
        headerGenerator = new BitmapHeaderGenerator(image.colorType);
        bitmapHeaderGenerators[image.colorType] = headerGenerator;
    }
    return new Blob([
        // Note: A negative height indicates the pixel data's first row is at
        // the top of the image instead of the bottom.
        headerGenerator.createBmpHeader(image.width, -image.height),
        image.dataRGBA,
    ], {
        type: 'image/bmp',
    });
}

// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Shared between host and client.
defInterface({
    name: 'ActorHost',
    methods: [
        {
            name: 'getContextForActorFromTab',
            request: defMessage(),
            response: defMessage(),
            histogram: {
                id: 11,
            },
        },
        {
            name: 'createTask',
            request: defMessage(),
            response: defMessage(),
            histogram: {
                id: 60,
            },
        },
        {
            name: 'performActions',
            request: defMessage(),
            response: defMessage(),
            histogram: {
                id: 61,
            },
        },
        {
            name: 'cancelActions',
            request: defMessage(),
            response: defMessage(),
            histogram: {
                id: 85,
            },
        },
        {
            name: 'stopActorTask',
            request: defMessage(),
            histogram: {
                id: 13,
            },
        },
        {
            name: 'pauseActorTask',
            request: defMessage(),
            histogram: {
                id: 14,
            },
        },
        {
            name: 'resumeActorTask',
            request: defMessage(),
            response: defMessage(),
            histogram: {
                id: 15,
            },
        },
        {
            name: 'interruptActorTask',
            request: defMessage(),
            histogram: {
                id: 74,
            },
        },
        {
            name: 'uninterruptActorTask',
            request: defMessage(),
            histogram: {
                id: 75,
            },
        },
        {
            name: 'createActorTab',
            request: defMessage(),
            response: defMessage(),
            histogram: {
                id: 77,
            },
        },
        {
            name: 'logBeginAsyncEvent',
            request: defMessage(),
            histogram: {
                id: 30,
            },
        },
        {
            name: 'logEndAsyncEvent',
            request: defMessage(),
            histogram: {
                id: 31,
            },
        },
        {
            name: 'logInstantEvent',
            request: defMessage(),
            histogram: {
                id: 32,
            },
        },
        {
            name: 'journalClear',
            histogram: {
                id: 33,
            },
        },
        {
            name: 'journalSnapshot',
            request: defMessage(),
            response: defMessage(),
            histogram: {
                id: 34,
            },
        },
        {
            name: 'journalStart',
            request: defMessage(),
            histogram: {
                id: 35,
            },
        },
        {
            name: 'journalStop',
            histogram: {
                id: 36,
            },
        },
        {
            name: 'journalRecordFeedback',
            request: defMessage(),
            histogram: {
                id: 37,
            },
        },
        {
            name: 'autofillSuggestionDialogOnFormPresented',
            request: defMessage(),
            histogram: {
                id: 87,
            },
        },
        {
            name: 'autofillSuggestionDialogOnFormPreviewChanged',
            request: defMessage(),
            histogram: {
                id: 88,
            },
        },
        {
            name: 'autofillSuggestionDialogOnFormConfirmed',
            request: defMessage(),
            histogram: {
                id: 89,
            },
        },
    ],
});
const ActorClientDef = defInterface({
    name: 'ActorClient',
    methods: [
        {
            name: 'notifyActorTaskStateChanged',
            request: defMessage(),
        },
        {
            name: 'requestToShowDialog',
            request: defMessage(),
            response: defMessage(),
        },
        {
            name: 'requestToShowConfirmationDialog',
            request: defMessage(),
            response: defMessage(),
        },
        {
            name: 'requestToConfirmNavigation',
            request: defMessage(),
            response: defMessage(),
        },
        {
            name: 'requestToShowAutofillSuggestionsDialog',
            request: defMessage(),
            response: defMessage(),
        },
        {
            name: 'requestToShowGmailOtpOptInDialog',
            request: defMessage(),
            response: defMessage(),
            backgroundAllowed: true,
        },
    ],
});
var ConfirmationRequestErrorReason;
(function (ConfirmationRequestErrorReason) {
    // The hosting WebUI received the request, but the web client has not
    // subscribed to the request yet. We couldn't show the dialog in this case.
    ConfirmationRequestErrorReason[ConfirmationRequestErrorReason["REQUEST_PROMISE_NO_SUBSCRIBER"] = 0] = "REQUEST_PROMISE_NO_SUBSCRIBER";
    // The task requested a new user confirmation dialog before the current
    // one completed.
    ConfirmationRequestErrorReason[ConfirmationRequestErrorReason["PREEMPTED_BY_NEW_REQUEST"] = 1] = "PREEMPTED_BY_NEW_REQUEST";
})(ConfirmationRequestErrorReason || (ConfirmationRequestErrorReason = {}));
/** Reasons why the credential selection dialog request failed. */
var SelectCredentialDialogErrorReason;
(function (SelectCredentialDialogErrorReason) {
    // The hosting WebUI received the request, but the web client has not
    // subscribed to the request yet. We couldn't show the dialog in this case.
    SelectCredentialDialogErrorReason[SelectCredentialDialogErrorReason["DIALOG_PROMISE_NO_SUBSCRIBER"] = 0] = "DIALOG_PROMISE_NO_SUBSCRIBER";
})(SelectCredentialDialogErrorReason || (SelectCredentialDialogErrorReason = {}));
// LINT.IfChange(SelectAutofillSuggestionsDialogErrorReason)
/** Reasons why the autofill suggestion selection dialog request failed. */
var SelectAutofillSuggestionsDialogErrorReason;
(function (SelectAutofillSuggestionsDialogErrorReason) {
    // The hosting WebUI received the request, but the web client has not
    // subscribed to the request yet. We couldn't show the dialog in this case.
    SelectAutofillSuggestionsDialogErrorReason[SelectAutofillSuggestionsDialogErrorReason["DIALOG_PROMISE_NO_SUBSCRIBER"] = 0] = "DIALOG_PROMISE_NO_SUBSCRIBER";
    // The requested task id did not match the response task id. This error is
    // internal to the browser and not sent by the client over mojo.
    SelectAutofillSuggestionsDialogErrorReason[SelectAutofillSuggestionsDialogErrorReason["MISMATCHED_TASK_ID"] = 1] = "MISMATCHED_TASK_ID";
    // The task is not connected to a delegate. I.e. attempting to run the task
    // from the experimental actor API. This error is internal to the browser and
    // not sent by the client over mojo.
    SelectAutofillSuggestionsDialogErrorReason[SelectAutofillSuggestionsDialogErrorReason["NO_ACTOR_TASK_DELEGATE"] = 2] = "NO_ACTOR_TASK_DELEGATE";
})(SelectAutofillSuggestionsDialogErrorReason || (SelectAutofillSuggestionsDialogErrorReason = {}));
// LINT.IfChange(GmailOtpOptInErrorReason)
var GmailOtpOptInErrorReason;
(function (GmailOtpOptInErrorReason) {
    GmailOtpOptInErrorReason[GmailOtpOptInErrorReason["REQUEST_PROMISE_NO_SUBSCRIBER"] = 0] = "REQUEST_PROMISE_NO_SUBSCRIBER";
})(GmailOtpOptInErrorReason || (GmailOtpOptInErrorReason = {}));
// LINT.ThenChange(//chrome/common/actor_webui.mojom:GmailOtpOptInErrorReason)

// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Web client side actor message handler.
// Implements actor-specific methods on GlicBrowserHost.
class GlicBrowserHostActor {
    actorWebClientMessageHandler;
    userConfirmationDialogRequestSubject = new Subject();
    selectCredentialDialogRequestSubject = new Subject();
    navigationConfirmationRequestSubject = new Subject();
    actorSender;
    actorTaskState = new Map();
    selectAutofillSuggestionsDialogRequestSubject = new Subject();
    selectGmailOtpOptInRequestSubject = new Subject();
    journalHost;
    actOnWebCapabilityValue = ObservableValue.withNoValue();
    actorTaskListRowClickedSubject = new Subject();
    constructor() {
        this.actorWebClientMessageHandler = new ActorWebClientMessageHandler(this);
    }
    initializeActor(initialState, router, actorRemote, actorReceiver) {
        if (actorRemote === undefined || actorReceiver === undefined ||
            !initialState.enableActInFocusedTab) {
            this.createTask = undefined;
            this.performActions = undefined;
            this.cancelActions = undefined;
            this.stopActorTask = undefined;
            this.pauseActorTask = undefined;
            this.resumeActorTask = undefined;
            this.interruptActorTask = undefined;
            this.uninterruptActorTask = undefined;
            this.getActOnWebCapability = undefined;
            this.createActorTab = undefined;
            this.actorTaskListRowClicked = undefined;
            this.getJournalHost = undefined;
            return;
        }
        this.actorSender = router.newRemote(actorRemote);
        router.newReceiver(actorReceiver, this.actorWebClientMessageHandler, ActorClientDef);
        this.journalHost = new GlicBrowserHostJournalImpl(this.actorSender);
        if (!initialState.enableGmailOtpOptIn) {
            this.selectGmailOtpOptInRequestHandler = undefined;
        }
    }
    setActorTaskState(taskId, state) {
        this.getActorTaskState(taskId).assignAndSignal(state);
        if (state === ActorTaskState.STOPPED) {
            this.actorTaskState.delete(taskId);
        }
    }
    selectUserConfirmationDialogRequestHandler() {
        return this.userConfirmationDialogRequestSubject;
    }
    selectCredentialDialogRequestHandler() {
        return this.selectCredentialDialogRequestSubject;
    }
    selectNavigationConfirmationRequestHandler() {
        return this.navigationConfirmationRequestSubject;
    }
    selectGmailOtpOptInRequestHandler() {
        return this.selectGmailOtpOptInRequestSubject;
    }
    autofillSuggestionDialogOnFormPresented(taskId, params) {
        this.actorSender?.requestNoResponse('autofillSuggestionDialogOnFormPresented', { taskId, params });
    }
    autofillSuggestionDialogOnFormPreviewChanged(taskId, params) {
        this.actorSender?.requestNoResponse('autofillSuggestionDialogOnFormPreviewChanged', { taskId, params });
    }
    autofillSuggestionDialogOnFormConfirmed(taskId, params) {
        this.actorSender?.requestNoResponse('autofillSuggestionDialogOnFormConfirmed', { taskId, params });
    }
    async getContextForActorFromTab(tabId, options) {
        assert(this.actorSender);
        const result = await this.actorSender.requestWithResponse('getContextForActorFromTab', { tabId, options });
        return convertTabContextResultFromPrivate(result.tabContextResult);
    }
    async createTask(taskOptions) {
        assert(this.actorSender);
        const result = await this.actorSender.requestWithResponse('createTask', { taskOptions });
        return result.taskId;
    }
    async performActions(actions) {
        assert(this.actorSender);
        const result = await this.actorSender.requestWithResponse('performActions', { actions });
        return result.actionsResult;
    }
    async cancelActions(taskId) {
        assert(this.actorSender);
        const response = await this.actorSender.requestWithResponse('cancelActions', { taskId });
        return response.result;
    }
    stopActorTask(taskId, stopReason) {
        this.actorSender?.requestNoResponse('stopActorTask', {
            taskId: taskId ?? 0,
            stopReason: stopReason ?? ActorTaskStopReason.TASK_COMPLETE,
        });
    }
    pauseActorTask(taskId, pauseReason, tabId) {
        this.actorSender?.requestNoResponse('pauseActorTask', {
            taskId,
            pauseReason: pauseReason ?? ActorTaskPauseReason.PAUSED_BY_MODEL,
            tabId: tabId ?? '',
        });
    }
    async resumeActorTask(taskId, tabContextOptions) {
        assert(this.actorSender);
        const response = await this.actorSender.requestWithResponse('resumeActorTask', { taskId, tabContextOptions });
        return convertTabContextResultFromPrivate(response.resumeActorTaskResult);
    }
    interruptActorTask(taskId, interruptReason) {
        this.actorSender?.requestNoResponse('interruptActorTask', {
            taskId,
            interruptReason,
        });
    }
    uninterruptActorTask(taskId) {
        this.actorSender?.requestNoResponse('uninterruptActorTask', {
            taskId,
        });
    }
    getActorTaskState(taskId) {
        const stateObs = this.actorTaskState.get(taskId);
        if (stateObs) {
            return stateObs;
        }
        // TODO(mcnee): The client could pass an id that will never have
        // state updates (e.g. the task already finished and we cleared the old
        // observable in setActorTaskState). Consider removing these cases from the
        // map when all subscribers are removed.
        const newObs = ObservableValue.withNoValue();
        this.actorTaskState.set(taskId, newObs);
        return newObs;
    }
    async createActorTab(taskId, options) {
        assert(this.actorSender);
        const result = await this.actorSender.requestWithResponse('createActorTab', { taskId, options });
        if (!result.tabData) {
            throw new Error('createActorTab: failed');
        }
        return convertTabDataFromPrivate(result.tabData);
    }
    getActOnWebCapability() {
        return this.actOnWebCapabilityValue;
    }
    actorTaskListRowClicked() {
        return this.actorTaskListRowClickedSubject;
    }
    getJournalHost() {
        assert(this.journalHost);
        return this.journalHost;
    }
}
// Handles postMessage messages from the host.
class ActorWebClientMessageHandler {
    actorHost;
    constructor(actorHost) {
        this.actorHost = actorHost;
    }
    notifyActorTaskStateChanged(payload) {
        this.actorHost.setActorTaskState(payload.taskId, payload.state);
    }
    async requestToShowDialog(payload) {
        const request = payload.request;
        return new Promise(resolve => {
            if (!this.actorHost.selectCredentialDialogRequestSubject
                .hasActiveSubscription()) {
                // Since there is no subscriber, respond to the browser immediately as
                // if no credential is selected.
                window.console.warn('GlicWebClient: no subscriber for' +
                    ' selectCredentialDialogRequest()!');
                resolve({
                    response: {
                        taskId: request.taskId,
                        errorReason: SelectCredentialDialogErrorReason.DIALOG_PROMISE_NO_SUBSCRIBER,
                    },
                });
                return;
            }
            const iconsGetter = new Map();
            for (const [id, image] of payload.request.icons.entries()) {
                let promise;
                iconsGetter.set(id, () => {
                    if (!promise) {
                        promise = Promise.resolve(rgbaImageToBlob(image));
                    }
                    return promise;
                });
            }
            const credentials = request.credentials.map((credential) => {
                const getIcon = iconsGetter.get(credential.sourceSiteOrApp);
                const accountPicture = credential.accountPicture;
                const getAccountPicture = accountPicture ?
                    () => Promise.resolve(rgbaImageToBlob(accountPicture)) :
                    undefined;
                return {
                    ...credential,
                    getIcon,
                    getAccountPicture,
                };
            });
            const requestWithCallback = {
                ...request,
                credentials,
                onDialogClosed: resolve,
            };
            this.actorHost.selectCredentialDialogRequestSubject.next(requestWithCallback);
        });
    }
    requestToShowConfirmationDialog(payload) {
        return new Promise(resolve => {
            if (!this.actorHost.userConfirmationDialogRequestSubject
                .hasActiveSubscription()) {
                // Since there is no subscriber, respond to the browser immediately as
                // if the user denied the request.
                window.console.warn('GlicWebClient: no subscriber for ' +
                    'userConfirmationDialogRequest()!');
                resolve({
                    response: {
                        permissionGranted: false,
                        errorReason: ConfirmationRequestErrorReason.REQUEST_PROMISE_NO_SUBSCRIBER,
                    },
                });
                return;
            }
            const requestWithCallback = {
                ...payload.request,
                onDialogClosed: resolve,
            };
            this.actorHost.userConfirmationDialogRequestSubject.next(requestWithCallback);
        });
    }
    requestToConfirmNavigation(payload) {
        return new Promise(resolve => {
            if (!this.actorHost.navigationConfirmationRequestSubject
                .hasActiveSubscription()) {
                // Since there is no subscriber, respond to the browser immediately as
                // if the user denied the request.
                window.console.warn('GlicWebClient: no subscriber for ' +
                    'navigationConfirmationRequest()!');
                resolve({
                    response: {
                        errorReason: ConfirmationRequestErrorReason.REQUEST_PROMISE_NO_SUBSCRIBER,
                    },
                });
                return;
            }
            const requestWithCallback = {
                ...payload.request,
                onConfirmationDecision: resolve,
            };
            this.actorHost.navigationConfirmationRequestSubject.next(requestWithCallback);
        });
    }
    async requestToShowAutofillSuggestionsDialog(payload) {
        const request = payload.request;
        return new Promise(resolve => {
            if (!this.actorHost.selectAutofillSuggestionsDialogRequestSubject
                .hasActiveSubscription()) {
                resolve({
                    response: {
                        taskId: request.taskId,
                        errorReason: SelectAutofillSuggestionsDialogErrorReason
                            .DIALOG_PROMISE_NO_SUBSCRIBER,
                        selectedSuggestions: [],
                    },
                });
                return;
            }
            const requestWithCallback = {
                ...request,
                formFillingRequests: request.formFillingRequests.map(formFillingRequest => ({
                    ...formFillingRequest,
                    suggestions: formFillingRequest.suggestions.map(suggestion => {
                        const icon = suggestion.icon;
                        const getIcon = icon ?
                            () => Promise.resolve(rgbaImageToBlob(icon)) :
                            undefined;
                        return { ...suggestion, getIcon };
                    }),
                })),
                onDialogClosed: (result) => {
                    const response = {
                        ...result.response,
                        taskId: request.taskId,
                    };
                    resolve({
                        response: response,
                    });
                },
                onFormPresented: (params) => {
                    this.actorHost.autofillSuggestionDialogOnFormPresented(request.taskId, params);
                },
                onFormPreviewChanged: (params) => {
                    this.actorHost.autofillSuggestionDialogOnFormPreviewChanged(request.taskId, params);
                },
                onFormConfirmed: (params) => {
                    this.actorHost.autofillSuggestionDialogOnFormConfirmed(request.taskId, params);
                },
            };
            this.actorHost.selectAutofillSuggestionsDialogRequestSubject.next(requestWithCallback);
        });
    }
    requestToShowGmailOtpOptInDialog(payload) {
        return new Promise(resolve => {
            if (!this.actorHost.selectGmailOtpOptInRequestSubject
                .hasActiveSubscription()) {
                window.console.warn('GlicWebClient: no subscriber for ' +
                    'selectGmailOtpOptInRequestHandler()!');
                resolve({
                    response: {
                        permissionGranted: false,
                        errorReason: GmailOtpOptInErrorReason.REQUEST_PROMISE_NO_SUBSCRIBER,
                    },
                });
                return;
            }
            const requestWithCallback = {
                ...payload.request,
                onDialogClosed: (response) => {
                    resolve({ response });
                },
            };
            this.actorHost.selectGmailOtpOptInRequestSubject.next(requestWithCallback);
        });
    }
}
class GlicBrowserHostJournalImpl {
    sender;
    constructor(sender) {
        this.sender = sender;
    }
    beginAsyncEvent(asyncEventId, taskId, event, details) {
        this.sender.requestNoResponse('logBeginAsyncEvent', { asyncEventId, taskId, event, details });
    }
    clear() {
        this.sender.requestNoResponse('journalClear', undefined);
    }
    endAsyncEvent(asyncEventId, details) {
        this.sender.requestNoResponse('logEndAsyncEvent', { asyncEventId, details });
    }
    instantEvent(taskId, event, details) {
        this.sender.requestNoResponse('logInstantEvent', { taskId, event, details });
    }
    async snapshot(clear) {
        const snapshotResult = await this.sender.requestWithResponse('journalSnapshot', { clear });
        return snapshotResult.journal;
    }
    start(maxBytes, captureScreenshots) {
        this.sender.requestNoResponse('journalStart', { maxBytes, captureScreenshots });
    }
    stop() {
        this.sender.requestNoResponse('journalStop', undefined);
    }
    recordFeedback(positive, reason) {
        this.sender.requestNoResponse('journalRecordFeedback', { positive, reason });
    }
}

// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Shared between host and client.
const AnnotationHostDef = defInterface({
    name: 'AnnotationHost',
    methods: [
        {
            name: 'scrollTo',
            request: defMessage(),
            histogram: { id: 45 },
        },
        {
            name: 'dropScrollToHighlight',
            request: defMessage(),
            histogram: { id: 57 },
        },
    ],
});
defInterface({
    name: 'AnnotationClient',
    methods: [],
});

// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function glicBrowserHostAnnotationMixin(base) {
    return class extends base {
        annotationSender;
        annotationReceiver;
        mainClientRemote;
        initializeAnnotation(initialState, router, clientRemote) {
            if (!initialState.enableScrollTo) {
                this.scrollTo = undefined;
                this.dropScrollToHighlight = undefined;
                return;
            }
            const { remote, receiver } = router.newPipeWithRemote(AnnotationHostDef);
            this.annotationSender = remote;
            this.annotationReceiver = receiver;
            this.mainClientRemote = clientRemote;
        }
        async scrollTo(params) {
            this.ensureAnnotationHandlerCreated();
            return this.annotationSender.requestWithResponse('scrollTo', { params });
        }
        dropScrollToHighlight() {
            this.ensureAnnotationHandlerCreated();
            this.annotationSender.requestNoResponse('dropScrollToHighlight', undefined);
        }
        ensureAnnotationHandlerCreated() {
            if (this.annotationReceiver === undefined) {
                return;
            }
            this.mainClientRemote.requestNoResponse('createAnnotationHandler', {
                annotationReceiver: this.annotationReceiver,
            });
            this.annotationReceiver = undefined;
        }
    };
}

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const ROOT_PIPE = 0;
const ON_PIPE_CLOSED = Symbol('ON_PIPE_CLOSED');
function newSenderId() {
    const array = new Uint8Array(8);
    crypto.getRandomValues(array);
    return Array.from(array).map((n) => n.toString(16)).join('');
}
class MessageLogger {
    prefix;
    loggingEnabled = false;
    loggingPrefix;
    constructor(senderId, prefix) {
        this.prefix = prefix;
        this.loggingPrefix = `${prefix}(${senderId.substring(0, 6)})`;
    }
    setLoggingEnabled(v) {
        this.loggingEnabled = v;
    }
    shouldLogMessage(requestType) {
        return this.loggingEnabled && requestType !== 'checkResponsive';
    }
    maybeLogMessage(requestType, message, payload) {
        if (!this.shouldLogMessage(requestType)) {
            return;
        }
        console.info(`${this.loggingPrefix} [${requestType}] ${message}: ${toDebugJson(payload)}`, payload);
    }
}
// Implements a simple queue with O(1) push and shift.
class Queue {
    // An array where elements are always pushed.
    next = [];
    // An array frozen in size from which elements are consumed.
    // When all elements are consumed, `next` is swapped into `current`.
    current = [];
    // Next element index in `current`.
    index = 0;
    push(item) {
        this.next.push(item);
    }
    popFront() {
        if (this.index < this.current.length) {
            const result = this.current[this.index];
            this.current[this.index] = undefined;
            this.index++;
            return result;
        }
        if (this.next.length === 0) {
            return undefined;
        }
        this.current = this.next;
        this.next = [];
        this.index = 0;
        return this.popFront();
    }
    get length() {
        return this.current.length - this.index + this.next.length;
    }
    empty() {
        return this.next.length === 0 && this.index === this.current.length;
    }
}
class ClosedPipe {
    open = false;
    messageHandler = undefined;
    interfaceDef = undefined;
    addCloseHandler(f) {
        f();
    }
    close() { }
    setMessageHandler(_handler, _interfaceDef) { }
    getHandlerFunction(_type) {
        return undefined;
    }
    pending() {
        return false;
    }
    pushPendingMessage(_pmReceiver, _requestMessage) { }
}
const CLOSED_PIPE = new ClosedPipe();
// Used by PostMessageRouterImpl to track a pipe.
class Pipe {
    id;
    onCloseHandlers = [];
    open = true;
    // The message handler for this pipe, if the pipe is bound as a receiver.
    messageHandler;
    interfaceDef;
    pendingMessages = [];
    constructor(
    // The id of the pipe, which is a unique number.
    id) {
        this.id = id;
    }
    close() {
        if (!this.open) {
            return;
        }
        this.open = false;
        this.onCloseHandlers.forEach((f) => {
            try {
                f();
            }
            catch (e) {
                console.error('Error in pipe onClose callback', e);
            }
        });
        this.onCloseHandlers = [];
        this.pendingMessages = [];
    }
    addCloseHandler(f) {
        if (this.open) {
            this.onCloseHandlers.push(f);
        }
        else {
            f();
        }
    }
    setMessageHandler(handler, interfaceDef) {
        this.messageHandler = handler;
        this.interfaceDef = interfaceDef;
        if (this.messageHandler && this.pendingMessages.length) {
            const messages = this.pendingMessages;
            this.pendingMessages = [];
            if (!this.open) {
                return;
            }
            setTimeout(() => {
                messages.forEach(([pmReceiver, requestMessage]) => {
                    pmReceiver.onMessage(requestMessage);
                });
            }, 0);
        }
    }
    getHandlerFunction(type) {
        if (!this.open) {
            return undefined;
        }
        if (this.messageHandler) {
            const handleFn = this.messageHandler[type];
            if (typeof handleFn !== 'function') {
                return undefined;
            }
            return handleFn.bind(this.messageHandler);
        }
        return undefined;
    }
    pending() {
        return this.open &&
            (!this.messageHandler || this.pendingMessages.length > 0);
    }
    pushPendingMessage(pmReceiver, requestMessage) {
        this.pendingMessages.push([pmReceiver, requestMessage]);
    }
}
class PostMessageRouterImpl extends MessageLogger {
    remoteOrigin;
    senderId;
    messageSender;
    isHost;
    errorCodec;
    onDestroy;
    sender;
    receiver;
    // Pipes that are not closed.
    pipes = new Map();
    // Tracks IDs of pipes that have been closed.
    closedPipes = new InverseSet();
    nextPipeId;
    constructor(remoteOrigin, senderId, messageSender, logPrefix, isHost, errorCodec = {
        serialize: e => ({ exception: e }),
        deserialize: raw => raw.exception,
    }) {
        super(senderId, logPrefix);
        this.remoteOrigin = remoteOrigin;
        this.senderId = senderId;
        this.messageSender = messageSender;
        this.isHost = isHost;
        this.errorCodec = errorCodec;
        // Use even and odd scheme to ensure host and client pipe ids don't clash.
        this.nextPipeId = isHost ? 2 : 1;
        const handler = this.onMessage.bind(this);
        window.addEventListener('message', handler);
        this.onDestroy = () => {
            window.removeEventListener('message', handler);
        };
    }
    destroy() {
        this.onDestroy();
    }
    onMessage(event) {
        if (event.origin !== this.remoteOrigin) {
            return;
        }
        // Check properties on MessageBase.
        const data = event.data;
        if (data.type === undefined || data.senderId === undefined ||
            !event.source) {
            return;
        }
        if (data.responseId === undefined) {
            // For RequestMessage, only process messages if they are not from this
            // sender.
            if (this.receiver && data.senderId !== this.senderId &&
                data.glicRequest === true) {
                this.receiver?.onMessage(data);
            }
        }
        else {
            // For ResponseMessage, only process messages if they are from this
            // sender.
            if (this.sender && data.senderId === this.senderId) {
                this.sender?.onMessage(data);
            }
        }
    }
    sendRequest(pipeId, type, requestId, requestPayload, transfer = []) {
        const request = {
            glicRequest: true,
            pipeId,
            type,
            requestId,
            requestPayload,
            senderId: this.senderId,
        };
        this.maybeLogMessage(type, 'sending request', request);
        this.messageSender.postMessage(request, this.remoteOrigin, transfer);
    }
    sendResponse(pipeId, type, senderId, responseId, responsePayload, exception, transfer = []) {
        const response = {
            pipeId,
            type,
            responseId,
            responsePayload,
            senderId,
        };
        if (exception) {
            response.exception = exception;
        }
        this.maybeLogMessage(type, 'sending response', response);
        this.messageSender.postMessage(response, this.remoteOrigin, transfer);
    }
    newPipe() {
        const id = this.nextPipeId;
        this.nextPipeId += 2;
        return {
            receiver: id,
            remote: id,
        };
    }
    newPipeWithReceiver(receiverHandler, interfaceDef) {
        const { receiver, remote } = this.newPipe();
        return {
            receiver: this.newReceiver(receiver, receiverHandler, interfaceDef),
            remote,
        };
    }
    newPipeWithRemote(_remoteInterfaceDef) {
        const { receiver, remote } = this.newPipe();
        return {
            receiver,
            remote: this.newRemote(remote),
        };
    }
    newReceiver(receiver, handler, interfaceDef) {
        const pipe = this.getOrMakePipe(receiver);
        if (pipe.open && handler) {
            pipe.setMessageHandler(handler, interfaceDef);
        }
        return new PostMessageReceiverImpl(pipe, receiver, handler, this);
    }
    newRemote(remote) {
        this.getOrMakePipe(remote);
        return new PostMessageRemoteImpl(remote, this.sender, this);
    }
    closePipe(pipe) {
        this.closedPipes.add(pipe);
        const existing = this.pipes.get(pipe);
        if (!existing) {
            return;
        }
        this.pipes.delete(pipe);
        existing.close();
        this.sendRequest(pipe, '__closePipe', undefined, undefined);
    }
    remoteClosedPipe(pipeId) {
        this.closedPipes.add(pipeId);
        const pipe = this.pipes.get(pipeId);
        if (pipe) {
            pipe.close();
            this.pipes.delete(pipeId);
        }
    }
    getOrMakePipe(id) {
        if (this.closedPipes.has(id)) {
            return CLOSED_PIPE;
        }
        let pipe = this.pipes.get(id);
        if (!pipe) {
            pipe = new Pipe(id);
            this.pipes.set(id, pipe);
        }
        return pipe;
    }
    addCloseHandler(pipeId, handler) {
        this.getOrMakePipe(pipeId).addCloseHandler(handler);
    }
}
class PostMessageRemoteImpl {
    pipeId;
    sender;
    router;
    constructor(pipeId, sender, router) {
        this.pipeId = pipeId;
        this.sender = sender;
        this.router = router;
    }
    addCloseHandler(f) {
        const pipe = this.router.pipes.get(this.pipeId);
        pipe?.addCloseHandler(f);
    }
    close() {
        this.router.closePipe(this.pipeId);
    }
    requestWithResponse(requestType, request, transfer = []) {
        return this.sender.requestWithResponse(this.pipeId, requestType, request, transfer);
    }
    requestNoResponse(requestType, request, transfer = []) {
        this.sender.requestNoResponse(this.pipeId, requestType, request, transfer);
    }
    rawSender() {
        return this.sender;
    }
}
/**
 * Receives messages sent via a `PostMessageRemote`, and forwards them to a
 * message handler.
 */
class PostMessageReceiverImpl {
    pipe;
    pipeId;
    handler;
    router;
    constructor(pipe, pipeId, handler, router) {
        this.pipe = pipe;
        this.pipeId = pipeId;
        this.handler = handler;
        this.router = router;
        this.pipe.addCloseHandler(() => {
            this.handler?.[ON_PIPE_CLOSED]?.();
        });
    }
    close() {
        this.router.closePipe(this.pipeId);
    }
    setMessageHandler(handler, interfaceDef) {
        this.pipe.setMessageHandler(handler, interfaceDef);
    }
    addCloseHandler(f) {
        this.pipe.addCloseHandler(f);
    }
}
// Sends requests over postMessage.
class PostMessageRequestSender {
    router;
    requestId = 1;
    responseHandlers = new Map();
    // We limit the number of in-flight requests because it fails in a better way
    // than doing no limiting. The WebUI code heavily relies on promises to
    // dispatch work in processing mojo requests and requests over postMessage.
    // Ideally, we could prioritize processing of mojo requests, but that's not
    // currently tractable. Instead, we limit the number of in-flight requests
    // which in practice prevents the situation where the WebUI is too busy
    // processing new postMessage requests to respond to existing ones.
    maxInFlightRequests = Infinity;
    // If true, send responses for all requests even if the request doesn't
    // require one. This ensures in-flight request tracking is accurate.
    // Without this, in-flight request tracking just ignores requests that don't
    // require a response until after the `maxInFlightRequests` limit is reached.
    sendResponsesForAllRequests = false;
    sendQueue = new Queue();
    queueNoticeLogged = false;
    constructor(router) {
        this.router = router;
        assert(router.sender === undefined);
        router.sender = this;
    }
    inFlightRequestCount() {
        return this.responseHandlers.size;
    }
    messageQueueLength() {
        return this.sendQueue.length;
    }
    // Handles responses from the host.
    onMessage(response) {
        const entry = this.responseHandlers.get(response.responseId);
        if (!entry) {
            // No handler for this request.
            return;
        }
        this.responseHandlers.delete(response.responseId);
        if (!this.sendQueue.empty() &&
            this.responseHandlers.size < this.maxInFlightRequests) {
            // Running a queued send will always register another response handler.
            // This should ensure a steady state of MAX_IN_FLIGHT_REQUESTS until
            // the queue is empty.
            this.sendQueue.popFront()();
        }
        entry.handler(response);
    }
    // Sends a request to the host, and returns a promise that resolves with its
    // response.
    requestWithResponse(pipeId, requestType, request, transfer = []) {
        const { promise, resolve, reject } = Promise.withResolvers();
        const requestId = this.requestId++;
        const processFn = () => {
            this.responseHandlers.set(requestId, {
                type: requestType,
                handler: (response) => {
                    if (response.exception !== undefined) {
                        this.router.maybeLogMessage(requestType, 'received response with exception', response.exception);
                        reject(this.router.errorCodec.deserialize(response.exception));
                    }
                    else {
                        this.router.maybeLogMessage(requestType, 'received response', response.responsePayload);
                        resolve(response.responsePayload);
                    }
                },
            });
            this.router.sendRequest(pipeId, requestType, requestId, request, transfer);
        };
        if (this.isQueueing()) {
            if (!this.queueNoticeLogged) {
                console.warn(`WARNING! ${this.router.loggingPrefix}:` +
                    ` Too many in-flight requests, starting to queue them.`);
                this.logInFlightRequestsForDebugging();
                this.queueNoticeLogged = true;
            }
            this.sendQueue.push(processFn);
        }
        else {
            processFn();
        }
        return promise;
    }
    requestNoResponse(pipeId, requestType, request, transfer = []) {
        if (!this.sendResponsesForAllRequests && !this.isQueueing()) {
            this.router.sendRequest(pipeId, requestType, undefined, request, transfer);
            return;
        }
        this.requestWithResponse(pipeId, requestType, request, transfer);
    }
    setMaxInFlightRequests(maxInFlightRequests) {
        if (maxInFlightRequests < 1) {
            this.maxInFlightRequests = Infinity;
        }
        else {
            this.maxInFlightRequests = maxInFlightRequests;
        }
    }
    isQueueing() {
        return this.inFlightRequestCount() >= this.maxInFlightRequests ||
            this.sendQueue.length > 0;
    }
    logInFlightRequestsForDebugging() {
        const counts = new Map();
        for (const entry of this.responseHandlers.values()) {
            counts.set(entry.type, (counts.get(entry.type) || 0) + 1);
        }
        const entries = Array.from(counts.entries());
        entries.sort((a, b) => b[1] - a[1]);
        const entriesString = entries.map(([type, count]) => `${type}: ${count}`).join(', ');
        console.info(`${this.router.loggingPrefix}: In-flight requests: ${entriesString}`);
    }
}
// Receives requests over postMessage and forward them to a
// `PostMessageLifecycleObserver`.
class PostMessageRequestReceiver {
    router;
    requestObserver;
    handlerWrapper = (_type, _interfaceName, payload, extras, handler) => handler(payload, extras);
    constructor(router, requestObserver) {
        this.router = router;
        this.requestObserver = requestObserver;
        assert(router.receiver === undefined);
        router.receiver = this;
    }
    setHandlerWrapper(wrapper) {
        this.handlerWrapper = wrapper;
    }
    async onMessage(requestMessage) {
        const { pipeId, senderId, requestId, type, requestPayload } = requestMessage;
        if (type === '__closePipe') {
            this.router.remoteClosedPipe(requestMessage.pipeId);
            return;
        }
        const pipe = this.router.getOrMakePipe(pipeId);
        // TODO(harringtond): Consider adding more debug logging for pending
        // messages or messages dropped due to pipe closure.
        if (pipe.pending()) {
            pipe.pushPendingMessage(this, requestMessage);
            return;
        }
        if (!pipe.open) {
            const exception = this.router.errorCodec.serialize(new Error(`Pipe closed`));
            if (requestId) {
                this.router.sendResponse(pipeId, type, senderId, requestId, undefined, exception);
            }
            return;
        }
        this.requestObserver.onRequestReceived?.(type, pipe.interfaceDef);
        const handleFn = pipe.getHandlerFunction(type);
        if (!handleFn) {
            return;
        }
        this.router.maybeLogMessage(type, 'processing request', requestPayload);
        let response;
        let exception;
        const extras = new ResponseExtras();
        try {
            response = await this.handlerWrapper(type, pipe.interfaceDef, requestPayload, extras, handleFn);
        }
        catch (error) {
            this.requestObserver.onRequestHandlerException?.(type, pipe.interfaceDef);
            console.warn('Unexpected error', error);
            if (error instanceof Error) {
                exception = this.router.errorCodec.serialize(error);
            }
            else {
                exception = this.router.errorCodec.serialize(new Error(`Unexpected error: ${error}`));
            }
        }
        if (!exception) {
            this.requestObserver.onRequestCompleted?.(type, pipe.interfaceDef);
        }
        // If the message contains no `requestId`, a response is not requested.
        if (!requestId) {
            return;
        }
        this.router.sendResponse(pipeId, type, senderId, requestId, response, exception, extras.transfers);
    }
}
function createBidirectionalPostMessageTransport(remoteOrigin, postMessageSender, lifecycleObserver, rootMessageHandler, logPrefix, isHost, errorCodec, interfaceDef, _remoteInterfaceDef) {
    const senderId = newSenderId();
    const router = new PostMessageRouterImpl(remoteOrigin, senderId, postMessageSender, logPrefix, isHost, errorCodec);
    const sender = new PostMessageRequestSender(router);
    const receiver = new PostMessageRequestReceiver(router, lifecycleObserver);
    const rootReceiver = router.newReceiver(ROOT_PIPE, rootMessageHandler, interfaceDef);
    const rootRemote = new PostMessageRemoteImpl(ROOT_PIPE, sender, router);
    return { router, sender, receiver, rootRemote, rootReceiver };
}
// Converts a value to JSON for debug logging.
function toDebugJson(v) {
    return JSON.stringify(v, (_key, value) => {
        // stringify throws on bigint, so convert it.
        if (typeof value === 'bigint') {
            return value.toString();
        }
        if (value instanceof ArrayBuffer) {
            return `ArrayBuffer(${value.byteLength})`;
        }
        if (ArrayBuffer.isView(value)) {
            return `${value.constructor.name}(${value.byteLength})`;
        }
        return value;
    });
}
// Stores a set of non-negative integers in O(N) memory where N is the largest
// integer _not_ stored between [0, M], and M is the largest
// integer stored.
class InverseSet {
    notContained = new Set();
    maxValue = -1;
    add(v) {
        assert(v >= 0);
        while (v > this.maxValue) {
            this.maxValue++;
            this.notContained.add(this.maxValue);
        }
        this.notContained.delete(v);
    }
    delete(v) {
        if (v <= this.maxValue) {
            this.notContained.add(v);
        }
    }
    has(v) {
        return v <= this.maxValue && !this.notContained.has(v);
    }
}

// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Helper function to shallow-copy an object and replace some properties.
// Useful to convert from these private types to public types. This will fail to
// compile if a property is missed.
function replaceProperties(original, replacements) {
    return Object.assign({}, original, replacements);
}

// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
class OneShotTimer {
    delayMs;
    timerId;
    promiseReject;
    constructor(delayMs) {
        this.delayMs = delayMs;
    }
    // Cancels any running timer.
    reset() {
        if (this.timerId !== undefined) {
            clearTimeout(this.timerId);
            this.timerId = undefined;
            if (this.promiseReject) {
                this.promiseReject(new Error('Timer reset'));
                this.promiseReject = undefined;
            }
        }
    }
    // Cancels any running timer, starts a new one. Callback is only
    // run if the timer is not reset first.
    start(callback) {
        this.startPromise().then(callback).catch(() => {
            // Catch and ignore timer reset.
        });
    }
    // Cancels any running timer, starts a new one. Resolves when
    // complete, rejects if canceled.
    startPromise() {
        this.reset();
        return new Promise((resolve, reject) => {
            this.promiseReject = reject;
            this.timerId = setTimeout(() => {
                this.timerId = undefined;
                resolve();
                this.promiseReject = undefined;
            }, this.delayMs);
        });
    }
}

// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Manages a set of observables which each observe a tab.
// When a tab is closed, the corresponding observable is completed, and
// removed from the set. Otherwise, observables are kept in the set,
// so they can be re-subscribed to later.
class ObservableSetByTabId {
    delegate;
    clientRemote;
    router;
    observablesByTabId = new Map();
    constructor(delegate, clientRemote, router) {
        this.delegate = delegate;
        this.clientRemote = clientRemote;
        this.router = router;
    }
    getObservableByTabId(tabId) {
        let obs = this.observablesByTabId.get(tabId);
        if (obs !== undefined) {
            return obs;
        }
        obs = new ObservableSetByTabIdObservable(tabId, this.clientRemote, this.router, this.delegate, () => {
            this.observablesByTabId.delete(tabId);
        });
        this.observablesByTabId.set(tabId, obs);
        return obs;
    }
}
// An observable representing a lazy, reference-counted, and debounced
// stream of updates for a specific tab from the host.
//
// It connects when the first subscriber joins, disconnects with a delay when
// the last subscriber leaves, and cleans itself up on completion.
class ObservableSetByTabIdObservable extends ObservableValue {
    tabId;
    clientRemote;
    router;
    delegate;
    onComplete;
    unsubscribeTimer;
    receiver;
    isCompleting = false;
    constructor(tabId, clientRemote, router, delegate, onComplete) {
        super(/*isSet=*/ false);
        this.tabId = tabId;
        this.clientRemote = clientRemote;
        this.router = router;
        this.delegate = delegate;
        this.onComplete = onComplete;
        this.unsubscribeTimer = new OneShotTimer(delegate.unsubscribeDelay);
    }
    activeSubscriptionChanged(hasActiveSubscription) {
        super.activeSubscriptionChanged(hasActiveSubscription);
        if (!hasActiveSubscription) {
            this.unsubscribeTimer.start(() => {
                if (this.hasActiveSubscription()) {
                    return;
                }
                this.complete();
            });
            return;
        }
        this.unsubscribeTimer.reset();
        if (!this.receiver) {
            const { receiver, remote } = this.router.newPipeWithReceiver(this.delegate.createHandler(this), this.delegate.interfaceDef);
            this.receiver = receiver;
            this.receiver.addCloseHandler(() => {
                this.complete();
            });
            this.delegate.subscribe(this.clientRemote, this.tabId, remote);
        }
    }
    complete() {
        // As this is an observable, it can be completed only once. Early exit if
        // already complete.
        if (this.isCompleting || this.isStopped()) {
            return;
        }
        this.isCompleting = true;
        this.receiver?.close();
        this.receiver = undefined;
        this.onComplete();
        super.complete();
    }
}

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Web client side of the Glic API.
// Communicates with the Chrome-WebUI-side in glic_api_host.ts
class GlicHostRegistryImpl {
    windowProxy;
    host;
    constructor(windowProxy) {
        this.windowProxy = windowProxy;
    }
    async registerWebClient(webClient) {
        this.host = new GlicBrowserHostImpl(webClient, this.windowProxy);
        const clientCapabilities = webClient.getClientCapabilities?.() ?? new Set();
        await this.host.webClientCreated(clientCapabilities);
        let success = false;
        let exception;
        try {
            await webClient.initialize(this.host);
            success = true;
        }
        catch (e) {
            console.warn(e);
            if (e instanceof Error) {
                exception = newTransferableException(e);
            }
        }
        if (this.host) {
            this.host.webClientInitialized(success, exception);
        }
    }
}
// A type which the guest should implement.
// This helps verify that WebClientMessageHandler is implemented with the
// correct parameter and return types.
class WebClientMessageHandler {
    webClient;
    host;
    cachedPinnedTabs = undefined;
    cachedSkillPreviews = [];
    cachedContextualSkillPreviews = [];
    cachedSkillPrompts = new Map();
    constructor(webClient, host) {
        this.webClient = webClient;
        this.host = host;
    }
    async notifyPanelWillOpen(payload) {
        let openPanelInfo;
        try {
            const mergedArgument = Object.assign({}, payload.panelOpeningData, payload.panelOpeningData.panelState);
            const completedPromise = this.host.notifyPanelWillOpenCompleted;
            const result = await this.webClient.notifyPanelWillOpen?.(mergedArgument);
            completedPromise.resolve();
            if (result) {
                openPanelInfo = result;
            }
        }
        catch (e) {
            console.warn(e);
        }
        return { openPanelInfo };
    }
    async notifyPanelWasClosed() {
        try {
            this.host.notifyPanelWillOpenCompleted = Promise.withResolvers();
            await this.webClient.notifyPanelWasClosed?.();
        }
        catch (e) {
            console.warn(e);
        }
    }
    panelStateChanged(payload) {
        this.host.getPanelState?.().assignAndSignal(payload.panelState);
    }
    zeroStateSuggestionsChanged(payload) {
        this.host.currentZeroStateObserver?.assignAndSignal(payload.suggestions);
    }
    canAttachStateChanged(payload) {
        this.host.canAttachPanelValue.assignAndSignal(payload.canAttach);
    }
    notifyGeminiEnterpriseSettingsChanged(payload) {
        this.host.getGeminiEnterpriseSettings?.().assignAndSignal(payload.settings);
    }
    notifyMicrophonePermissionStateChanged(payload) {
        this.host.getMicrophonePermissionState().assignAndSignal(payload.enabled);
    }
    async stopMicrophone() {
        await this.webClient.stopMicrophone?.();
    }
    notifyLocationPermissionStateChanged(payload) {
        this.host.getLocationPermissionState().assignAndSignal(payload.enabled);
    }
    notifyTabContextPermissionStateChanged(payload) {
        this.host.getTabContextPermissionState().assignAndSignal(payload.enabled);
    }
    notifyDefaultTabContextPermissionStateChanged(payload) {
        this.host.defaultTabContextPermission.assignAndSignal(payload.enabled);
    }
    notifyOsLocationPermissionStateChanged(payload) {
        this.host.getOsLocationPermissionState().assignAndSignal(payload.enabled);
    }
    notifyClosedCaptioningSettingChanged(payload) {
        this.host.closedCaptioningState.assignAndSignal(payload.enabled);
    }
    async invoke(payload) {
        try {
            const options = convertInvokeOptionsFromPrivate(payload.options);
            // Wait until notifyPanelWillOpen has resolved before invoking.
            await this.host.notifyPanelWillOpenCompleted.promise;
            await this.webClient.invoke?.(options);
        }
        catch (e) {
            console.warn(e);
        }
    }
    async getExperimentalTriggeringUpdates(payload, _extras) {
        const getUpdates = this.webClient.getExperimentalTriggeringUpdates;
        if (!getUpdates) {
            return { success: false };
        }
        const observable = await getUpdates.call(this.webClient);
        if (!observable) {
            return { success: false };
        }
        const subscriber = observable.subscribeObserver({
            next: (update) => {
                this.host.clientRemote.requestNoResponse('onExperimentalTriggeringUpdate', {
                    observationId: payload.observationId,
                    update,
                    observation: SubscriberObservationType.UPDATE,
                });
            },
            complete: () => {
                this.host.clientRemote.requestNoResponse('onExperimentalTriggeringUpdate', {
                    observationId: payload.observationId,
                    observation: SubscriberObservationType.COMPLETE,
                });
                if (subscriber) {
                    subscriber.unsubscribe();
                }
            },
            error: (_err) => {
                this.host.clientRemote.requestNoResponse('onExperimentalTriggeringUpdate', {
                    observationId: payload.observationId,
                    observation: SubscriberObservationType.ERROR,
                });
                if (subscriber) {
                    subscriber.unsubscribe();
                }
            },
        });
        return { success: true };
    }
    notifyActuationOnWebSettingChanged(payload) {
        this.host.actuationOnWebState.assignAndSignal(payload.enabled);
    }
    notifyFocusedTabChanged(payload) {
        const focusedTabData = convertFocusedTabDataFromPrivate(payload.focusedTabDataPrivate);
        this.host.getFocusedTabStateV2().assignAndSignal(focusedTabData);
    }
    notifyZoomLevelChanged(payload) {
        this.host.getZoomLevel().assignAndSignal(payload.zoomFactor);
    }
    notifyPanelActiveChanged(payload) {
        this.host.panelActiveValue.assignAndSignal(payload.panelActive);
    }
    async checkResponsive() {
        await this.webClient.checkResponsive?.();
        return {
            clientSendMessageQueueLength: this.host.clientRemote.rawSender().messageQueueLength() +
                this.host.clientRemote.rawSender().inFlightRequestCount(),
        };
    }
    notifyManualResizeChanged(payload) {
        this.host.isManuallyResizing().assignAndSignal(payload.resizing);
    }
    browserIsOpenChanged(payload) {
        this.host.isBrowserOpenValue.assignAndSignal(payload.browserIsOpen);
    }
    notifyOsHotkeyStateChanged(payload) {
        this.host.getOsHotkeyState().assignAndSignal(payload);
    }
    notifyPinnedTabsChanged(payload) {
        this.cachedPinnedTabs =
            payload.tabData.map((x) => convertTabDataFromPrivate(x));
        this.host.pinnedTabs?.assignAndSignal(this.cachedPinnedTabs);
    }
    notifyPinnedTabDataChanged(payload) {
        if (!this.cachedPinnedTabs) {
            return;
        }
        const tabData = convertTabDataFromPrivate(payload.tabData);
        this.cachedPinnedTabs = this.cachedPinnedTabs.map((cachedTab) => {
            if (cachedTab.tabId === tabData.tabId) {
                return tabData;
            }
            return cachedTab;
        });
        this.host.pinnedTabs.assignAndSignal(this.cachedPinnedTabs);
    }
    notifySkillPreviewsChanged(payload) {
        this.cachedSkillPrompts.clear();
        this.cachedSkillPreviews = payload.skillPreviews;
        this.host.skillPreviews.assignAndSignal(this.combineSkillPreviews());
    }
    notifyContextualSkillPreviewsChanged(payload) {
        this.cachedContextualSkillPreviews = payload.contextualSkillPreviews;
        this.host.skillPreviews.assignAndSignal(this.combineSkillPreviews());
    }
    notifySkillPreviewChanged(payload) {
        const skillPreview = payload.skillPreview;
        this.cachedSkillPrompts.delete(skillPreview.id);
        const index = this.cachedSkillPreviews.findIndex((cachedSkillPreview) => cachedSkillPreview.id === skillPreview.id);
        if (index !== -1) {
            // SkillPreview with the same ID exists, replace it.
            this.cachedSkillPreviews = [
                ...this.cachedSkillPreviews.slice(0, index),
                skillPreview,
                ...this.cachedSkillPreviews.slice(index + 1),
            ];
        }
        else {
            // SkillPreview with this ID not found, add it to the cache.
            this.cachedSkillPreviews = [...this.cachedSkillPreviews, skillPreview];
        }
        // Signal the change to the host.
        this.host.skillPreviews.assignAndSignal(this.combineSkillPreviews());
    }
    notifySkillDeleted(payload) {
        const skillId = payload.skillId;
        this.cachedSkillPrompts.delete(skillId);
        const index = this.cachedSkillPreviews.findIndex((cachedSkillPreview) => cachedSkillPreview.id === skillId);
        if (index !== -1) {
            // SkillPreview with the same ID exists, remove it.
            this.cachedSkillPreviews = [
                ...this.cachedSkillPreviews.slice(0, index),
                ...this.cachedSkillPreviews.slice(index + 1),
            ];
        }
        this.host.skillPreviews.assignAndSignal(this.combineSkillPreviews());
    }
    pageMetadataChanged(payload) {
        const observable = this.host.pageMetadataObservers.get(payload.tabId);
        if (!observable) {
            return;
        }
        if (payload.pageMetadata) {
            observable.assignAndSignal(payload.pageMetadata);
        }
        else {
            if (!observable.isStopped()) {
                observable.complete();
            }
            this.host.pageMetadataObservers.delete(payload.tabId);
        }
    }
    notifyAdditionalContext(payload) {
        const context = convertAdditionalContextFromPrivate(payload.context);
        this.host.additionalContextSubject.next(context);
    }
    notifyActOnWebCapabilityChanged(payload) {
        this.host.actOnWebCapabilityValue.assignAndSignal(payload.canActOnWeb);
    }
    onboardingCompletedChanged(payload) {
        this.host.onboardingCompleted.assignAndSignal(payload.completed);
    }
    notifyActorTaskListRowClicked(payload) {
        this.host.actorTaskListRowClickedSubject.next(payload.taskId);
    }
    cacheSkillPrompt(skill) {
        const preview = skill.preview;
        if (preview.id && skill.prompt) {
            this.cachedSkillPrompts.set(preview.id, skill.prompt);
        }
    }
    combineSkillPreviews() {
        return [...this.cachedContextualSkillPreviews, ...this.cachedSkillPreviews];
    }
}
class WebClientRegionCaptureHandler {
    observable;
    constructor(observable) {
        this.observable = observable;
    }
    captureRegionUpdate(payload) {
        if (payload.result) {
            this.observable.processUpdate(payload.result);
        }
        else if (payload.reason !== undefined) {
            this.observable.processError(payload.reason);
        }
    }
}
class GlicBrowserHostImpl extends glicBrowserHostAnnotationMixin(GlicBrowserHostActor) {
    webClient;
    router;
    clientRemote;
    webClientMessageHandler;
    chromeVersion;
    platform;
    formFactor;
    panelState = ObservableValue.withNoValue();
    canAttachPanelValue = ObservableValue.withNoValue();
    focusedTabStateV2 = ObservableValue.withNoValue();
    geminiEnterpriseSettings = ObservableValue.withNoValue();
    zoomLevel = ObservableValue.withNoValue(async (isActive) => {
        if (isActive) {
            await this.clientRemote.requestWithResponse('subscribeToZoomLevel', undefined);
        }
        else {
            this.clientRemote.requestNoResponse('unsubscribeFromZoomLevel', undefined);
        }
    });
    permissionStateMicrophone = ObservableValue.withNoValue();
    permissionStateLocation = ObservableValue.withNoValue();
    permissionStateTabContext = ObservableValue.withNoValue();
    defaultTabContextPermission = ObservableValue.withNoValue();
    enableDefaultTabContextSettingFeature = false;
    permissionStateOsLocation = ObservableValue.withNoValue();
    closedCaptioningState = ObservableValue.withNoValue();
    actuationOnWebState = ObservableValue.withNoValue();
    osHotkeyState = ObservableValue.withNoValue();
    onboardingCompleted = ObservableValue.withNoValue();
    panelActiveValue = ObservableValue.withNoValue();
    isBrowserOpenValue = ObservableValue.withNoValue();
    metrics;
    manuallyResizing = ObservableValue.withValue(false);
    cachedUserProfile;
    enableCachedGetUserProfileInfo;
    pinnedTabs = ObservableValue.withNoValue();
    skillPreviews = ObservableValue.withNoValue();
    skillToInvoke = ObservableValue.withNoValue();
    pinCandidates;
    captureRegionObservable;
    currentZeroStateSuggestionOptions = {
        isFirstRun: false,
        supportedTools: [],
    };
    currentZeroStateObserver = ObservableValue.withNoValue();
    hostCapabilities = new Set();
    additionalContextSubject = new Subject();
    pageMetadataObservers = new Map();
    getTabByIdObservableSet;
    getTabFaviconByIdObservableSet;
    notifyPanelWillOpenCompleted = Promise.withResolvers();
    constructor(webClient, windowProxy) {
        super();
        this.webClient = webClient;
        // TODO(harringtond): Ideally, we could ensure we only process requests from
        // the single senderId used by the web client. This would avoid accidental
        // processing of requests from a previous client. This risk is very minimal,
        // as it would require reloading the webview page and initializing a new
        // web client very quickly, and in normal operation, the webview does not
        // reload after successful load.
        this.webClientMessageHandler =
            new WebClientMessageHandler(this.webClient, this);
        const { router, rootRemote } = createBidirectionalPostMessageTransport('chrome://glic', windowProxy, 
        /*lifecycleObserver=*/ {}, this.webClientMessageHandler, 'glic_api_client', 
        /*isHost=*/ false, ERROR_CODEC, WebClientDef);
        this.router = router;
        this.clientRemote = rootRemote;
        this.getTabByIdObservableSet =
            new ObservableSetByTabId(new GetTabByIdObservableSetImpl(), this.clientRemote, this.router);
        this.getTabFaviconByIdObservableSet =
            new ObservableSetByTabId(new GetTabFaviconByIdObservableSetImpl(), this.clientRemote, this.router);
        this.metrics = new GlicBrowserHostMetricsImpl(this.clientRemote);
    }
    destroy() {
        this.router.destroy();
    }
    async webClientCreated(clientCapabilities) {
        const response = await this.clientRemote.requestWithResponse('webClientCreated', { clientCapabilities: Array.from(clientCapabilities) });
        if (response.actorRemote !== undefined &&
            response.actorReceiver !== undefined) {
            this.initializeActor(response.initialState, this.router, response.actorRemote, response.actorReceiver);
        }
        this.initializeAnnotation(response.initialState, this.router, this.clientRemote);
        const state = response.initialState;
        this.geminiEnterpriseSettings.assignAndSignal(state.geminiEnterpriseSettings ?? undefined);
        this.router.setLoggingEnabled(state.loggingEnabled);
        this.clientRemote.rawSender().setMaxInFlightRequests(state.maxInFlightRequests);
        this.clientRemote.rawSender().sendResponsesForAllRequests =
            state.sendResponsesForAllRequests;
        this.panelState.assignAndSignal(state.panelState);
        const focusedTabData = convertFocusedTabDataFromPrivate(state.focusedTabData);
        this.focusedTabStateV2.assignAndSignal(focusedTabData);
        this.permissionStateMicrophone.assignAndSignal(state.microphonePermissionEnabled);
        this.permissionStateLocation.assignAndSignal(state.locationPermissionEnabled);
        if (state.enableDefaultTabContextSettingFeature) {
            this.permissionStateTabContext.assignAndSignal(state.defaultTabContextSettingEnabled);
        }
        else {
            this.permissionStateTabContext.assignAndSignal(state.tabContextPermissionEnabled);
        }
        this.defaultTabContextPermission.assignAndSignal(state.defaultTabContextSettingEnabled);
        this.enableDefaultTabContextSettingFeature =
            state.enableDefaultTabContextSettingFeature;
        this.permissionStateOsLocation.assignAndSignal(state.osLocationPermissionEnabled);
        this.canAttachPanelValue.assignAndSignal(state.canAttach);
        this.chromeVersion = state.chromeVersion;
        this.platform = state.platform;
        this.formFactor = state.formFactor;
        this.enableCachedGetUserProfileInfo = state.enableCachedGetUserProfileInfo;
        this.panelActiveValue.assignAndSignal(state.panelIsActive);
        this.isBrowserOpenValue.assignAndSignal(state.browserIsOpen);
        this.osHotkeyState.assignAndSignal({ hotkey: state.hotkey });
        this.closedCaptioningState.assignAndSignal(state.closedCaptioningSettingEnabled);
        this.actuationOnWebState.assignAndSignal(state.actuationOnWebSettingEnabled);
        for (const capability of state.hostCapabilities) {
            this.hostCapabilities.add(capability);
        }
        this.actOnWebCapabilityValue.assignAndSignal(state.canActOnWeb);
        this.onboardingCompleted.assignAndSignal(state.onboardingCompleted);
        // Set the method to undefined since it's gated behind a mojo
        // RuntimeFeature. Calling a such a method when the feature is disabled
        // results in a mojo pipe closure.
        if (!this.hostCapabilities.has(HostCapability.GET_MODEL_QUALITY_CLIENT_ID)) {
            // MOJO_RUNTIME_FEATURE_GATED GetModelQualityClientId
            this.getModelQualityClientId = undefined;
        }
        if (!state.enableSkills) {
            this.createSkill = undefined;
            this.updateSkill = undefined;
            this.showManageSkillsUi = undefined;
            this.showBrowseSkillsUi = undefined;
            this.getSkill = undefined;
        }
        if (!state.enableScrollTo) {
            this.scrollTo = undefined;
            this.dropScrollToHighlight = undefined;
        }
        if (!state.enableZeroStateSuggestions) {
            this.getZeroStateSuggestionsForFocusedTab = undefined;
            // MOJO_RUNTIME_FEATURE_GATED GetZeroStateSuggestionsAndSubscribe
            this.getZeroStateSuggestions = undefined;
        }
        if (!state.enableDefaultTabContextSettingFeature) {
            this.getDefaultTabContextPermissionState = undefined;
        }
        if (!state.enableMaybeRefreshUserStatus) {
            this.maybeRefreshUserStatus = undefined;
        }
        if (!state.enableGetContextActor) {
            // MOJO_RUNTIME_FEATURE_GATED GetContextForActorFromTab
            this.getContextForActorFromTab = undefined;
        }
        if (!state.enableGetPageMetadata) {
            this.getPageMetadata = undefined;
        }
        if (!state.enableWebActuationSettingFeature) {
            this.getActuationOnWebSetting = undefined;
            this.setActuationOnWebSetting = undefined;
        }
        if (!state.enableCaptureRegion) {
            this.captureRegion = undefined;
            this.deleteCapturedRegion = undefined;
        }
        if (!state.enableActivateTab) {
            // MOJO_RUNTIME_FEATURE_GATED ActivateTab
            this.activateTab = undefined;
        }
        if (!state.enableGetTabById) {
            this.getTabById = undefined;
        }
        if (!state.enableOpenPasswordManagerSettingsPage) {
            this.openPasswordManagerSettingsPage = undefined;
        }
        if (!state.enableGetTabFaviconById) {
            this.getTabFaviconById = undefined;
        }
        if (!state.enableProcessCounterAbuseVerdict) {
            this.processCounterAbuseVerdict = undefined;
        }
    }
    webClientInitialized(success, exception) {
        this.clientRemote.requestNoResponse('webClientInitialized', { success, exception });
    }
    // GlicBrowserHost implementation.
    getChromeVersion() {
        return Promise.resolve(this.chromeVersion);
    }
    getPlatform() {
        return this.platform;
    }
    getFormFactor() {
        return this.formFactor;
    }
    async createTab(url, options) {
        const result = await this.clientRemote.requestWithResponse('createTab', {
            url,
            options,
        });
        if (!result.tabData) {
            throw new Error('createTab: failed');
        }
        return convertTabDataFromPrivate(result.tabData);
    }
    async activateTabWithUrl(exactUrl, options = {}) {
        const result = await this.clientRemote.requestWithResponse('activateTabWithUrl', {
            exactUrl,
            options,
        });
        if (!result.tabData) {
            throw new Error('activateTabWithUrl: failed');
        }
        return convertTabDataFromPrivate(result.tabData);
    }
    openGlicSettingsPage(options) {
        this.clientRemote.requestNoResponse('openGlicSettingsPage', { options });
    }
    openPasswordManagerSettingsPage() {
        this.clientRemote.requestNoResponse('openPasswordManagerSettingsPage', undefined);
    }
    reportClientTransientError(abslStatus) {
        this.clientRemote.requestNoResponse('reportClientTransientError', { abslStatus });
    }
    processCounterAbuseVerdict(tabId, verdict) {
        this.clientRemote.requestNoResponse('processCounterAbuseVerdict', { tabId, verdict });
    }
    closePanel() {
        return this.clientRemote.requestWithResponse('closePanel', undefined);
    }
    closePanelAndShutdown() {
        this.clientRemote.requestNoResponse('closePanelAndShutdown', undefined);
    }
    attachPanel() {
        this.clientRemote.requestNoResponse('attachPanel', undefined);
    }
    detachPanel() {
        if (this.hostCapabilities.has(HostCapability.NO_LIVE_MODE)) {
            throw new Error('NO_LIVE_MODE: detachPanel not supported');
        }
        this.clientRemote.requestNoResponse('detachPanel', undefined);
    }
    showProfilePicker() {
        this.clientRemote.requestNoResponse('showProfilePicker', undefined);
    }
    async getModelQualityClientId() {
        const result = await this.clientRemote.requestWithResponse('getModelQualityClientId', undefined);
        return result.modelQualityClientId;
    }
    getGeminiEnterpriseSettings() {
        return this.geminiEnterpriseSettings;
    }
    async switchConversation(info) {
        await this.clientRemote.requestWithResponse('switchConversation', { info });
    }
    async registerConversation(info) {
        await this.clientRemote.requestWithResponse('registerConversation', { info });
    }
    async getContextFromFocusedTab(options) {
        const context = await this.clientRemote.requestWithResponse('getContextFromFocusedTab', { options });
        return convertTabContextResultFromPrivate(context.tabContextResult);
    }
    async setMaximumNumberOfPinnedTabs(requestedMax) {
        const result = await this.clientRemote.requestWithResponse('setMaximumNumberOfPinnedTabs', { requestedMax });
        return result.effectiveMax;
    }
    async getContextFromTab(tabId, options) {
        const result = await this.clientRemote.requestWithResponse('getContextFromTab', { tabId, options });
        return convertTabContextResultFromPrivate(result.tabContextResult);
    }
    async getImageBytesFromTab(tabId, documentId, domNodeId) {
        const response = await this.clientRemote.requestWithResponse('getImageBytesFromTab', { tabId, documentId, domNodeId });
        if (!response.result) {
            throw new Error('Failed to get image bytes');
        }
        return convertImageBytesResultFromPrivate(response.result);
    }
    getTabById(tabId) {
        return this.getTabByIdObservableSet.getObservableByTabId(tabId);
    }
    getTabFaviconById(tabId) {
        return this.getTabFaviconByIdObservableSet.getObservableByTabId(tabId);
    }
    activateTab(tabId) {
        this.clientRemote.requestNoResponse('activateTab', { tabId });
    }
    onModeChange(newMode) {
        this.clientRemote.requestNoResponse('onModeChange', { newMode });
    }
    onMicrophoneStatusChange(status) {
        this.clientRemote.requestNoResponse('onMicrophoneStatusChange', { status });
    }
    setErrorDialogState(shownDialogType) {
        this.clientRemote.requestNoResponse('setErrorDialogState', { shownDialogType });
    }
    async resizeWindow(width, height, options) {
        return this.clientRemote.requestWithResponse('resizeWindow', { size: { width, height }, options });
    }
    enableDragResize(enabled) {
        return this.clientRemote.requestWithResponse('enableDragResize', { enabled });
    }
    async captureScreenshot() {
        const screenshotResult = await this.clientRemote.requestWithResponse('captureScreenshot', undefined);
        return screenshotResult.screenshot;
    }
    captureRegion(params) {
        if (this.captureRegionObservable) {
            this.captureRegionObservable.complete();
        }
        this.captureRegionObservable =
            new CaptureRegionObservable(this.clientRemote, this.router, params);
        return this.captureRegionObservable;
    }
    deleteCapturedRegion(tabId, regionId) {
        this.clientRemote.requestNoResponse('deleteCapturedRegion', { tabId, regionId });
    }
    setMinimumWidgetSize(width, height) {
        return this.clientRemote.requestWithResponse('setMinimumWidgetSize', { size: { width, height } });
    }
    getPanelState() {
        return this.panelState;
    }
    panelActive() {
        return this.panelActiveValue;
    }
    canAttachPanel() {
        return this.canAttachPanelValue;
    }
    isBrowserOpen() {
        return this.isBrowserOpenValue;
    }
    getFocusedTabStateV2() {
        return this.focusedTabStateV2;
    }
    getZoomLevel() {
        return this.zoomLevel;
    }
    getMicrophonePermissionState() {
        return this.permissionStateMicrophone;
    }
    getLocationPermissionState() {
        return this.permissionStateLocation;
    }
    getTabContextPermissionState() {
        return this.permissionStateTabContext;
    }
    getDefaultTabContextPermissionState() {
        return this.defaultTabContextPermission;
    }
    getOsLocationPermissionState() {
        return this.permissionStateOsLocation;
    }
    getClosedCaptioningSetting() {
        return this.closedCaptioningState;
    }
    getActuationOnWebSetting() {
        return this.actuationOnWebState;
    }
    setMicrophonePermissionState(enabled) {
        return this.clientRemote.requestWithResponse('setMicrophonePermissionState', { enabled });
    }
    setLocationPermissionState(enabled) {
        return this.clientRemote.requestWithResponse('setLocationPermissionState', { enabled });
    }
    setTabContextPermissionState(enabled) {
        if (this.enableDefaultTabContextSettingFeature) {
            this.permissionStateTabContext.assignAndSignal(enabled);
            return Promise.resolve();
        }
        return this.clientRemote.requestWithResponse('setTabContextPermissionState', { enabled });
    }
    setClosedCaptioningSetting(enabled) {
        return this.clientRemote.requestWithResponse('setClosedCaptioningSetting', { enabled });
    }
    setContextAccessIndicator(show) {
        this.clientRemote.requestWithResponse('setContextAccessIndicator', { show });
    }
    setActuationOnWebSetting(enabled) {
        return this.clientRemote.requestWithResponse('setActuationOnWebSetting', { enabled });
    }
    async getUserProfileInfo() {
        return this.enableCachedGetUserProfileInfo ? this.fetchUserProfileCached() :
            this.fetchUserProfileDirect();
    }
    async fetchUserProfileDirect() {
        const { profileInfo } = await this.clientRemote.requestWithResponse('getUserProfileInfo', undefined);
        if (!profileInfo) {
            throw new Error('getUserProfileInfo failed');
        }
        const { avatarIcon } = profileInfo;
        return replaceProperties(profileInfo, {
            avatarIcon: async () => avatarIcon && Promise.resolve(rgbaImageToBlob(avatarIcon)),
        });
    }
    async fetchUserProfileCached() {
        if (this.cachedUserProfile) {
            return this.cachedUserProfile;
        }
        this.cachedUserProfile = (async () => {
            try {
                const { profileInfo } = await this.clientRemote.requestWithResponse('getUserProfileInfo', undefined);
                if (!profileInfo) {
                    throw new Error('getUserProfileInfo failed');
                }
                let blobPromise;
                return replaceProperties(profileInfo, {
                    avatarIcon: () => {
                        if (blobPromise) {
                            return blobPromise;
                        }
                        if (!profileInfo.avatarIcon) {
                            blobPromise = Promise.resolve(undefined);
                            return blobPromise;
                        }
                        const newBlob = rgbaImageToBlob(profileInfo.avatarIcon);
                        // Clear memory after conversion
                        profileInfo.avatarIcon = undefined;
                        blobPromise = Promise.resolve(newBlob);
                        return blobPromise;
                    },
                });
            }
            catch (e) {
                this.cachedUserProfile = undefined;
                throw e;
            }
        })();
        return this.cachedUserProfile;
    }
    async refreshSignInCookies() {
        const result = await this.clientRemote.requestWithResponse('refreshSignInCookies', undefined);
        if (!result.success) {
            throw Error('refreshSignInCookies failed');
        }
    }
    setAudioDucking(enabled) {
        this.clientRemote.requestNoResponse('setAudioDucking', { enabled });
    }
    getMetrics() {
        return this.metrics;
    }
    setSyntheticExperimentState(trialName, groupName) {
        this.clientRemote.requestNoResponse('setSyntheticExperimentState', { trialName, groupName });
    }
    openOsPermissionSettingsMenu(permission) {
        this.clientRemote.requestNoResponse('openOsPermissionSettingsMenu', { permission });
    }
    async getOsMicrophonePermissionStatus() {
        return (await this.clientRemote.requestWithResponse('getOsMicrophonePermissionStatus', undefined))
            .enabled;
    }
    isManuallyResizing() {
        return this.manuallyResizing;
    }
    getOsHotkeyState() {
        return this.osHotkeyState;
    }
    getPinnedTabs() {
        return this.pinnedTabs;
    }
    async pinTabs(tabIds, options) {
        return (await this.clientRemote.requestWithResponse('pinTabs', { tabIds, options }))
            .pinnedAll;
    }
    async unpinTabs(tabIds, options) {
        return (await this.clientRemote.requestWithResponse('unpinTabs', { tabIds, options }))
            .unpinnedAll;
    }
    async createSkill(request) {
        const result = await this.clientRemote.requestWithResponse('createSkill', { request });
        if (!result.modalOpened) {
            throw new Error('createSkill: failed to open dialog');
        }
    }
    async updateSkill(request) {
        const result = await this.clientRemote.requestWithResponse('updateSkill', { request });
        if (!result.modalOpened) {
            throw new Error('updateSkill: failed to open dialog');
        }
    }
    showManageSkillsUi() {
        this.clientRemote.requestNoResponse('showManageSkillsUi', undefined);
    }
    showBrowseSkillsUi() {
        this.clientRemote.requestNoResponse('showBrowseSkillsUi', undefined);
    }
    async getSkill(id) {
        const result = await this.clientRemote.requestWithResponse('getSkill', { id });
        if (!result.skill) {
            throw new Error('getSkill: failed');
        }
        this.webClientMessageHandler.cacheSkillPrompt(result.skill);
        return result.skill;
    }
    recordSkillsWebClientEvent(event) {
        this.clientRemote.requestNoResponse('recordSkillsWebClientEvent', { event });
    }
    getSkillPreviews() {
        return this.skillPreviews;
    }
    getSkillToInvoke() {
        return this.skillToInvoke;
    }
    unpinAllTabs(options) {
        this.clientRemote.requestNoResponse('unpinAllTabs', { options });
    }
    getPinCandidates(options) {
        this.pinCandidates?.setObsolete();
        return this.pinCandidates = new PinCandidatesObservable(this.clientRemote, this.router, options);
    }
    async getZeroStateSuggestionsForFocusedTab(isFirstRun) {
        const zeroStateResult = await this.clientRemote.requestWithResponse('getZeroStateSuggestionsForFocusedTab', { isFirstRun });
        if (!zeroStateResult.suggestions) {
            return {
                suggestions: [],
                tabId: '',
                url: '',
            };
        }
        return zeroStateResult.suggestions;
    }
    async zeroStateActiveSubscriptionStateChanged(options, hasActiveSubscription) {
        if (options !== this.currentZeroStateSuggestionOptions) {
            // Dont send out of date updates.
            return;
        }
        const zeroStateResult = await this.clientRemote.requestWithResponse('getZeroStateSuggestionsAndSubscribe', {
            hasActiveSubscription: hasActiveSubscription,
            options: options,
        });
        if (zeroStateResult.suggestions) {
            this.currentZeroStateObserver?.assignAndSignal(zeroStateResult.suggestions);
        }
    }
    getZeroStateSuggestions(options) {
        options = options ?? {
            isFirstRun: false,
            supportedTools: [],
        };
        this.currentZeroStateSuggestionOptions = options;
        this.currentZeroStateObserver =
            ObservableValue.withNoValue(this.zeroStateActiveSubscriptionStateChanged.bind(this, options));
        return this.currentZeroStateObserver;
    }
    maybeRefreshUserStatus() {
        this.cachedUserProfile = undefined;
        this.clientRemote.requestNoResponse('maybeRefreshUserStatus', undefined);
    }
    getAdditionalContext() {
        return this.additionalContextSubject;
    }
    getHostCapabilities() {
        return this.hostCapabilities;
    }
    getPageMetadata(tabId, names) {
        if (this.pageMetadataObservers.has(tabId)) {
            // Currently, we assume that names do not change and keep only
            // one observer per tabId.
            return this.pageMetadataObservers.get(tabId);
        }
        if (names.length === 0) {
            throw Error('names must not be empty');
        }
        const observableValue = ObservableValue.withNoValue(async (isActive) => {
            // If the client subscribes to an Observable with an invalid tabId,
            // it will emit nothing, even if the tab later becomes valid.
            const { success } = await this.clientRemote.requestWithResponse('subscribeToPageMetadata', { tabId, names: isActive ? names : [] });
            if (!success) {
                if (!observableValue.isStopped()) {
                    observableValue.complete();
                }
                this.pageMetadataObservers.delete(tabId);
            }
        });
        this.pageMetadataObservers.set(tabId, observableValue);
        return observableValue;
    }
    selectAutofillSuggestionsDialogRequestHandler() {
        return this.selectAutofillSuggestionsDialogRequestSubject;
    }
    setOnboardingCompleted() {
        return this.clientRemote.requestNoResponse('setOnboardingCompleted', undefined);
    }
    isOnboardingCompleted() {
        return this.onboardingCompleted;
    }
}
class GlicBrowserHostMetricsImpl {
    sender;
    constructor(sender) {
        this.sender = sender;
    }
    onOptinImpression() {
        this.sender.requestNoResponse('onOptinImpression', undefined);
    }
    onUserInputSubmitted(mode) {
        this.sender.requestNoResponse('onUserInputSubmitted', { mode });
    }
    onReaction(reactionType) {
        this.sender.requestNoResponse('onReaction', { reactionType });
    }
    onPerformActionResultSubmitted(isRetry) {
        this.sender.requestNoResponse('onActionSubmitted', { isRetry });
    }
    onContextUploadStarted() {
        this.sender.requestNoResponse('onContextUploadStarted', undefined);
    }
    onContextUploadCompleted() {
        this.sender.requestNoResponse('onContextUploadCompleted', undefined);
    }
    onResponseStarted() {
        this.sender.requestNoResponse('onResponseStarted', undefined);
    }
    onResponseStopped(details) {
        this.sender.requestNoResponse('onResponseStopped', { details });
    }
    onSessionTerminated() {
        this.sender.requestNoResponse('onSessionTerminated', undefined);
    }
    onResponseRated(positive) {
        this.sender.requestNoResponse('onResponseRated', { positive });
    }
    onClosedCaptionsShown() {
        this.sender.requestNoResponse('onClosedCaptionsShown', undefined);
    }
    onTurnCompleted(model, duration) {
        this.sender.requestNoResponse('onTurnCompleted', { model, duration });
    }
    onRecordUseCounter(counter) {
        // Since the frontend can contain a newer version than what Chrome is
        // built against, we use a sparse histogram.
        this.sender.requestNoResponse('recordHistogram', { name: 'Glic.Api.UseCounter', sparseValue: counter });
    }
}
class CaptureRegionObservable extends ObservableValue {
    remote;
    router;
    params;
    receiver;
    constructor(remote, router, params) {
        super(false);
        this.remote = remote;
        this.router = router;
        this.params = params;
    }
    close() {
        this.receiver?.close();
        this.receiver = undefined;
    }
    activeSubscriptionChanged(hasActiveSubscription) {
        super.activeSubscriptionChanged(hasActiveSubscription);
        if (this.isStopped()) {
            return;
        }
        if (hasActiveSubscription) {
            const { receiver, remote } = this.router.newPipeWithReceiver(new WebClientRegionCaptureHandler(this), WebClientRegionCaptureDef);
            this.receiver = receiver;
            this.receiver.addCloseHandler(() => {
                this.processError(CaptureRegionErrorReason.UNKNOWN);
            });
            this.remote.requestNoResponse('subscribeToCaptureRegion', {
                remote,
                params: this.params,
            });
        }
        else {
            this.complete();
        }
    }
    error(e) {
        if (this.isStopped()) {
            return;
        }
        super.error(e);
    }
    complete() {
        if (this.isStopped()) {
            return;
        }
        super.complete();
        this.close();
    }
    processUpdate(result) {
        this.assignAndSignal(result);
    }
    processError(reason) {
        this.error(new ErrorWithReasonImpl('captureRegion', reason));
        this.close();
    }
}
class PinCandidatesObservable extends ObservableValue {
    remote;
    router;
    options;
    isObsolete = false;
    receiver;
    constructor(remote, router, options) {
        super(false);
        this.remote = remote;
        this.router = router;
        this.options = options;
    }
    activeSubscriptionChanged(hasActiveSubscription) {
        super.activeSubscriptionChanged(hasActiveSubscription);
        if (this.isObsolete) {
            console.warn(`getPinCandidates() observable is in use while obsolete.`);
            return;
        }
        if (hasActiveSubscription) {
            const { receiver, remote } = this.router.newPipeWithReceiver(new WebClientPinCandidatesObserverHandler(this), WebClientPinCandidatesObserverDef);
            this.receiver = receiver;
            this.remote.requestNoResponse('subscribeToPinCandidates', { options: this.options, pinCandidatesPipe: remote });
        }
        else if (this.receiver) {
            this.receiver.close();
            this.receiver = undefined;
        }
    }
    processUpdate(candidates) {
        this.assignAndSignal(candidates.map(c => ({ tabData: convertTabDataFromPrivate(c.tabData) })));
    }
    // Mark this observable as obsolete. It should not be used any further.
    // Only one PinCandidatesObservable is active at one time.
    setObsolete() {
        if (this.hasActiveSubscription()) {
            console.warn(`getPinCandidates() observable was made obsolete with subscribers.`);
        }
        this.isObsolete = true;
        this.receiver?.close();
        this.receiver = undefined;
    }
}
class WebClientPinCandidatesObserverHandler {
    observable;
    constructor(observable) {
        this.observable = observable;
    }
    pinCandidatesChanged(payload) {
        this.observable.processUpdate(payload.candidates);
    }
}
class GetTabByIdObservableSetImpl {
    interfaceDef = WebClientTabDataObserverDef;
    unsubscribeDelay = 1000;
    subscribe(clientRemote, tabId, remote) {
        clientRemote.requestNoResponse('subscribeToTabData', { tabId, remote });
    }
    createHandler(observable) {
        return new WebClientTabDataObserverHandler(observable);
    }
}
class WebClientTabDataObserverHandler {
    observable;
    constructor(observable) {
        this.observable = observable;
    }
    tabDataChanged(payload) {
        this.observable.assignAndSignal(convertTabDataFromPrivate(payload.tabData));
    }
}
class GetTabFaviconByIdObservableSetImpl {
    interfaceDef = WebClientTabFaviconObserverDef;
    unsubscribeDelay = 1000;
    subscribe(clientRemote, tabId, remote) {
        clientRemote.requestNoResponse('subscribeToTabFavicon', { tabId, remote });
    }
    createHandler(observable) {
        return new WebClientTabFaviconObserverHandler(observable);
    }
}
class WebClientTabFaviconObserverHandler {
    observable;
    constructor(observable) {
        this.observable = observable;
    }
    tabFaviconChanged(payload) {
        if (payload.favicon === undefined) {
            this.observable.assignAndSignal(undefined);
        }
        else {
            this.observable.assignAndSignal(rgbaImageToBlob(payload.favicon));
        }
    }
}
function convertTabDataFromPrivate(data) {
    if (!data) {
        return undefined;
    }
    let faviconResult;
    const dataFavicon = data.favicon;
    async function getFavicon() {
        if (dataFavicon && !faviconResult) {
            faviconResult = Promise.resolve(rgbaImageToBlob(dataFavicon));
            return faviconResult;
        }
        return faviconResult;
    }
    const favicon = dataFavicon && getFavicon;
    return replaceProperties(data, { favicon });
}
function convertFocusedTabDataFromPrivate(data) {
    const result = {};
    if (data.hasFocus) {
        result.hasFocus = replaceProperties(data.hasFocus, {
            tabData: convertTabDataFromPrivate(data.hasFocus.tabData),
        });
    }
    if (data.hasNoFocus) {
        result.hasNoFocus = replaceProperties(data.hasNoFocus, {
            tabFocusCandidateData: convertTabDataFromPrivate(data.hasNoFocus.tabFocusCandidateData),
        });
    }
    return result;
}
function streamFromBuffer(buffer) {
    return new ReadableStream({
        start(controller) {
            controller.enqueue(buffer);
            controller.close();
        },
    });
}
function convertPdfDocumentDataFromPrivate(data) {
    const pdfData = data.pdfData && streamFromBuffer(new Uint8Array(data.pdfData));
    return replaceProperties(data, { pdfData });
}
function convertAnnotatedPageDataFromPrivate(data) {
    const annotatedPageContent = data.annotatedPageContent &&
        streamFromBuffer(new Uint8Array(data.annotatedPageContent));
    return replaceProperties(data, { annotatedPageContent });
}
function convertTabContextResultFromPrivate(data) {
    const tabData = convertTabDataFromPrivate(data.tabData);
    const screenshotInfo = data.screenshotInfo &&
        streamFromBuffer(new Uint8Array(data.screenshotInfo));
    const pdfDocumentData = data.pdfDocumentData &&
        convertPdfDocumentDataFromPrivate(data.pdfDocumentData);
    const annotatedPageData = data.annotatedPageData &&
        convertAnnotatedPageDataFromPrivate(data.annotatedPageData);
    return replaceProperties(data, { tabData, screenshotInfo, pdfDocumentData, annotatedPageData });
}
function convertAdditionalContextFromPrivate(context) {
    const parts = context.parts.map(p => {
        const annotatedPageData = p.annotatedPageData &&
            convertAnnotatedPageDataFromPrivate(p.annotatedPageData);
        const pdf = p.pdf && convertPdfDocumentDataFromPrivate(p.pdf);
        const data = p.data && new Blob([p.data.data], { type: p.data.mimeType });
        const filename = p.filename;
        const tabContext = p.tabContext && convertTabContextResultFromPrivate(p.tabContext);
        return {
            ...p,
            data,
            filename,
            annotatedPageData,
            pdf,
            tabContext,
        };
    });
    return {
        ...context,
        parts,
    };
}
function convertInvokeOptionsFromPrivate(options) {
    return {
        ...options,
        context: options.context ?
            convertAdditionalContextFromPrivate(options.context) :
            undefined,
    };
}
function convertImageInfoFromPrivate(data) {
    return {
        caption: data.caption,
        sourceOrigin: data.sourceOrigin,
        url: data.url,
        mimeType: data.mimeType,
    };
}
function convertImageBytesResultFromPrivate(data) {
    return {
        bytes: data.bytes,
        imageInfo: convertImageInfoFromPrivate(data.imageInfo),
    };
}

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/*
This is bundled into a js file, and sent to the web client. It should be
directly executable in a <script> element, and therefore should not have any
exports.
*/
window.internalAutoGlicBoot = (windowProxy) => new GlicHostRegistryImpl(windowProxy);
//# sourceMappingURL=glic_api_injected_client.rollup.js.map
