/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { forceUpdate, h, Host, } from "@stencil/core";
import { SceneTreeAPIClient } from "@vertexvis/scene-tree-protos/scenetree/protos/scene_tree_api_pb_service";
import { parseAndValidateConfig, } from "../../lib/config";
import { isSceneTreeTableCellElement } from "../scene-tree-table-cell/utils";
import { SceneTreeError } from "./errors";
import { SceneTreeController, } from "./lib/controller";
import { getSceneTreeContainsElement } from "./lib/dom";
import { SceneTreeErrorCode, SceneTreeErrorDetails } from "./lib/errors";
import { webSocketSubscriptionTransportFactory } from "./lib/grpc";
import { isLoadedRow } from "./lib/row";
import { deselectItem, hideItem, isolateItem, selectFilterResults, selectItem, selectRangeInSceneTree, showItem, } from "./lib/viewer-ops";
import { SCENE_ITEM_NAME_METADATA_KEY, } from "./types";
/**
 * The minimum amount of time provided by requestIdleCallback to clear purged
 * data. A value too low may cause contention with browser rendering. A value
 * too high will cause too many items to be accumulated.
 */
const MIN_CLEAR_UNUSED_DATA_MS = 25;
/**
 * @slot header - A slot that places content above the rows in the tree. By
 *  default, a search toolbar will be placed in this slot. Elements can be
 *  stacked by assigning multiple elements to this slot.
 * @slot footer - A slot that places content below the rows in the tree.
 * Elements can be stacked by assigning multiple elements to this slot.
 */
export class SceneTree {
    constructor() {
        /**
         * The number of offscreen rows above and below the viewport to render. Having
         * a higher number reduces the chance of the browser not displaying a row
         * while scrolling.
         */
        this.overScanCount = 25;
        /**
         * Sets the default environment for the viewer. This setting is used for
         * auto-configuring network hosts.
         *
         * Use the `config` property for manually setting hosts.
         */
        this.configEnv = 'platprod';
        /**
         * A set of options to configure scene tree searching behavior.
         */
        this.searchOptions = {};
        /**
         * @deprecated Use `searchOptions`
         * Indicates whether the metadata search should use an exact match.
         */
        this.metadataSearchExactMatch = false;
        /**
         * @deprecated Use `searchOptions`
         * A list of the metadata keys that a scene tree search should be performed on.
         */
        this.metadataSearchKeys = [];
        /**
         * A list of part metadata keys that will be made available to each row. This
         * metadata can be used for data binding inside the scene tree's template.
         *
         * **Note:** for the values of these metadata keys to be evaluated for search,
         * they must be provided to the `metadataSearchKeys` specified in the `searchOptions`.
         * Otherwise, the search will only be performed against the item name.
         */
        this.metadataKeys = [];
        /**
         * The duration of operations with animations, in milliseconds, when a user performs
         * an action that results in an animation such as isolate. Defaults to 500ms.
         */
        this.operationAnimationDuration = 500;
        this.rows = [];
        this.totalRows = 0;
        this.showLoader = false;
        this.showEmptyResults = false;
        /**
         * This stores internal state that you want to preserve across live-reloads,
         * but shouldn't trigger a refresh if the data changes. Marking this with
         * @State to allow to preserve state across live-reloads.
         */
        this.stateMap = {
            componentLoaded: false,
        };
        this.hasPartialFilterResults = false;
        this.refreshingResults = false;
        this.attemptingRetry = false;
        this.firstCellRendered = false;
    }
    /**
     * Schedules a render of the rows in the scene tree. Useful if any custom
     * data in your scene tree has changed, and you want to update the row's
     * contents.
     *
     * **Note:** This is an asynchronous operation. The update may happen on the
     * next frame.
     */
    async invalidateRows() {
        forceUpdate(this.getLayoutElement());
    }
    /**
     * Scrolls the tree to the given row index.
     *
     * @param index An index of the row to scroll to.
     * @param options A set of options to configure the scrolling behavior.
     */
    async scrollToIndex(index, options = {}) {
        const { animate, position = 'middle' } = options;
        const i = Math.max(0, Math.min(index, this.totalRows));
        const top = this.getScrollToPosition(i, position);
        await this.getLayoutElement().scrollToPosition(top, {
            behavior: animate ? 'smooth' : undefined,
        });
    }
    /**
     * Scrolls the tree to an item with the given ID. If the node for the item is
     * not expanded, the tree will expand each of its parent nodes.
     *
     * @param itemId An ID of an item to scroll to.
     * @param options A set of options to configure the scrolling behavior.
     * @returns A promise that resolves when the operation is finished.
     */
    async scrollToItem(itemId, options = {}) {
        var _a;
        const rowsBeforeExpand = this.totalRows;
        const index = await ((_a = this.controller) === null || _a === void 0 ? void 0 : _a.expandParentNodes(itemId));
        if (index != null && rowsBeforeExpand !== this.totalRows) {
            return new Promise((resolve) => {
                const layoutEl = this.getLayoutElement();
                const handleLayoutRendered = async () => {
                    layoutEl.removeEventListener('layoutRendered', handleLayoutRendered);
                    await this.scrollToIndex(index, options);
                    resolve();
                };
                layoutEl.addEventListener('layoutRendered', handleLayoutRendered);
            });
        }
        else if (index != null) {
            await this.scrollToIndex(index, options);
        }
    }
    /**
     * Performs an API call to expand all nodes in the tree.
     */
    async expandAll() {
        var _a;
        await ((_a = this.controller) === null || _a === void 0 ? void 0 : _a.expandAll());
    }
    /**
     * Performs an API call to collapse all nodes in the tree.
     */
    async collapseAll() {
        var _a;
        await ((_a = this.controller) === null || _a === void 0 ? void 0 : _a.collapseAll());
    }
    /**
     * Performs an API call that will expand the node associated to the specified
     * row or row index.
     *
     * @param row A row, row index, or node to expand.
     */
    async expandItem(row) {
        await this.performRowOperation(row, async ({ id, node }) => {
            var _a;
            if (!node.expanded) {
                await ((_a = this.controller) === null || _a === void 0 ? void 0 : _a.expandNode(id));
            }
        });
    }
    /**
     * Performs an API call that will collapse the node associated to the
     * specified row or row index.
     *
     * @param row A row, row index, or node to collapse.
     */
    async collapseItem(row) {
        await this.performRowOperation(row, async ({ id, node }) => {
            var _a;
            if (node.expanded) {
                await ((_a = this.controller) === null || _a === void 0 ? void 0 : _a.collapseNode(id));
            }
        });
    }
    /**
     * Performs an API call that will either expand or collapse the node
     * associated to the given row or row index.
     *
     * @param row The row, row index, or node to collapse or expand.
     */
    async toggleExpandItem(row) {
        await this.performRowOperation(row, async ({ node }) => {
            if (node.expanded) {
                await this.collapseItem(node);
            }
            else {
                await this.expandItem(node);
            }
        });
    }
    /**
     * Performs an API call that will either hide or show the item associated to
     * the given row or row index.
     *
     * @param row The row, row index, or node to toggle visibility.
     */
    async toggleItemVisibility(row) {
        await this.performRowOperation(row, async ({ viewer, id, node }) => {
            if (node.visible || node.partiallyVisible) {
                await hideItem(viewer, id);
            }
            else {
                await showItem(viewer, id);
            }
        });
    }
    /**
     * Performs an API call that will hide the item associated to the given row
     * or row index.
     *
     * @param row The row, row index, or node to hide.
     */
    async hideItem(row) {
        await this.performRowOperation(row, async ({ viewer, id, node }) => {
            if (node.visible) {
                await hideItem(viewer, id);
            }
        });
    }
    /**
     * Performs an API call that will show the item associated to the given row
     * or row index.
     *
     * @param row The row, row index, or node to show.
     */
    async showItem(row) {
        await this.performRowOperation(row, async ({ viewer, id, node }) => {
            if (!node.visible) {
                await showItem(viewer, id);
            }
        });
    }
    /**
     * Performs an API call that will select the item associated to the given row
     * or row index.
     *
     * This method supports a `recurseParent` option that allows for recursively
     * selecting the next unselected parent node. This behavior is considered
     * stateful. Each call to `selectItem` will track the ancestry of the passed
     * in `rowArg`. If calling `selectItem` with a row not belonging to the
     * ancestry of a previous selection, then this method will perform a standard
     * selection.
     *
     * @param row The row, row index or node to select.
     * @param options A set of options to configure selection behavior.
     */
    async selectItem(row, { recurseParent, ...options } = {}) {
        await this.performRowOperation(row, async ({ viewer, id }) => {
            var _a, _b, _c, _d;
            const ancestors = (await ((_a = this.controller) === null || _a === void 0 ? void 0 : _a.fetchNodeAncestors(id))) || [];
            // The parent node should be selected if recurseParent is true and either
            // the given node is in the selection path (so was intentionally selected by clicking in the tree)
            // or if the given node is selected, but its immediate parent is not. The second case covers the
            // situation that the given node was selected as part of a previous ancestor selection and the
            // user wishes to clear the selection list and only select the given node.
            const isInPath = (_b = this.stateMap.selectionPath) === null || _b === void 0 ? void 0 : _b.includes(id);
            const nodeForRow = this.getNodeFromRowOrIndex(row);
            const immediateParentNodeIsSelected = ancestors.length > 0 ? ancestors[0].selected : true;
            const nodeIsSelectedAndParentIsUnselected = nodeForRow.selected && !immediateParentNodeIsSelected;
            if (recurseParent && (isInPath || nodeIsSelectedAndParentIsUnselected)) {
                const nextNode = ancestors.find(({ selected }) => !selected);
                if (nextNode != null) {
                    await this.selectItem(nextNode, options);
                    this.lastSelectedItemId = id;
                }
                else {
                    await selectItem(viewer, id, options);
                    this.lastSelectedItemId = id;
                }
            }
            else if (options.range && this.lastSelectedItemId != null) {
                const currentRowIndex = await ((_c = this.controller) === null || _c === void 0 ? void 0 : _c.expandParentNodes(id));
                const previouslySelectedIndex = await ((_d = this.controller) === null || _d === void 0 ? void 0 : _d.expandParentNodes(this.lastSelectedItemId));
                if (previouslySelectedIndex && currentRowIndex) {
                    const start = Math.min(previouslySelectedIndex, currentRowIndex);
                    const end = Math.max(previouslySelectedIndex, currentRowIndex);
                    await selectRangeInSceneTree(viewer, start, end, options);
                }
            }
            else {
                await selectItem(viewer, id, options);
                this.lastSelectedItemId = id;
            }
            this.stateMap.selectionPath = [
                ...ancestors.map(({ id }) => (id === null || id === void 0 ? void 0 : id.hex) || ''),
                id,
            ];
        });
    }
    /**
     * Performs an API call that will deselect the item associated to the given
     * row or row index.
     *
     * @param row The row, row index, or node to deselect.
     */
    async deselectItem(row) {
        await this.performRowOperation(row, async ({ viewer, id, node }) => {
            if (node.selected) {
                this.lastSelectedItemId = undefined;
                await deselectItem(viewer, id);
            }
        });
    }
    /**
     * Performs an API call that will show only the item associated to
     * the given row or row index and fit the camera to the item's bounding box.
     *
     * @param row The row, row index, or node to isolate.
     */
    async isolateItem(row) {
        await this.performRowOperation(row, async ({ viewer, id }) => {
            await isolateItem(viewer, id, {
                animationDurationMs: this.operationAnimationDuration,
            });
        });
    }
    /**
     * Returns a row at the given index. If the row data has not been loaded,
     * returns `undefined`.
     *
     * @param index The index of the row.
     * @returns A row, or `undefined` if the row hasn't been loaded.
     */
    async getRowAtIndex(index) {
        return this.rows[index];
    }
    /**
     * Returns the row with the given id. If there is not a row
     * matching the id, returns `undefined`.
     *
     * @param itemId An ID of an item to return the row for.
     * @returns A row, or `undefined` if a corresponding row doesn't exist
     */
    async getRowForItemId(itemId) {
        var _a;
        const index = await ((_a = this.controller) === null || _a === void 0 ? void 0 : _a.expandParentNodes(itemId));
        if (index != null) {
            return this.rows[index];
        }
        else {
            return undefined;
        }
    }
    /**
     * Returns the row data from the given mouse or pointer event. The event must
     * originate from a `vertex-scene-tree-table-cell` contained by this element,
     * otherwise `undefined` is returned.
     *
     * @param event A mouse or pointer event that originated from this component.
     * @returns A row, or `undefined` if the row hasn't been loaded.
     */
    async getRowForEvent(event) {
        const { clientY, target } = event;
        if (target != null &&
            this.errorDetails == null &&
            getSceneTreeContainsElement(this.el, target) &&
            isSceneTreeTableCellElement(target)) {
            return this.getRowAtClientY(clientY);
        }
        else {
            return undefined;
        }
    }
    /**
     * Returns the row data from the given vertical client position.
     *
     * @param clientY The vertical client position.
     * @returns A row or `undefined` if the row hasn't been loaded.
     */
    getRowAtClientY(clientY) {
        const layoutEl = this.getLayoutElement();
        const top = layoutEl.layoutOffset;
        const index = Math.floor((clientY - top + layoutEl.scrollOffset) / layoutEl.rowHeight);
        return this.getRowAtIndex(index);
    }
    /**
     * Performs an async request that will filter the displayed items in the tree
     * that match the given term and options.
     *
     * @param term The filter term.
     * @param options The options to apply to the filter.
     * @returns A promise that completes when the request has completed. Note,
     *  items are displayed asynchronously. So the displayed items may not reflect
     *  the result of this filter when the promise completes.
     */
    async filterItems(term, options = {}) {
        var _a;
        const optionsAsFilterOptions = {
            ...options,
            metadataSearchKeys: options.columns,
        };
        const columnsToSearch = this.getMetadataSearchKeys(optionsAsFilterOptions);
        return (_a = this.controller) === null || _a === void 0 ? void 0 : _a.filter(term, {
            ...options,
            columns: columnsToSearch,
        });
    }
    /**
     * Performs an async request that will select the filtered items in the tree
     * that match the given term.
     *
     * @param term The filter term.
     * @returns A promise that completes when the request has completed.
     */
    async selectFilteredItems(term, options) {
        var _a, _b, _c, _d, _e, _f;
        if (this.viewer != null) {
            const metadataSearchKeys = (_b = (_a = this.searchOptions) === null || _a === void 0 ? void 0 : _a.metadataSearchKeys) !== null && _b !== void 0 ? _b : this.metadataSearchKeys;
            const definedMetadataKeys = metadataSearchKeys.length > 0 ? metadataSearchKeys : this.metadataKeys;
            const columnsToSearch = definedMetadataKeys.length > 0
                ? definedMetadataKeys
                : ['VERTEX_SCENE_ITEM_NAME'];
            const shouldSearchExactMatch = (_d = (_c = this.searchOptions) === null || _c === void 0 ? void 0 : _c.exactMatch) !== null && _d !== void 0 ? _d : this.metadataSearchExactMatch;
            const shouldSearchRemoveHiddenItems = (_f = (_e = this.searchOptions) === null || _e === void 0 ? void 0 : _e.removeHiddenItems) !== null && _f !== void 0 ? _f : false;
            await selectFilterResults(this.viewer, term, columnsToSearch, shouldSearchExactMatch, shouldSearchRemoveHiddenItems, {
                append: false,
                ...options,
            });
        }
    }
    /**
     * Fetches the metadata keys that are available to the scene tree. Metadata
     * keys can be assigned to the scene tree using the `metadataKeys` property.
     * The scene tree will fetch this metadata and make these values available
     * for data binding.
     *
     * @returns A promise that resolves with the names of available keys.
     */
    async fetchMetadataKeys() {
        var _a, _b;
        return (_b = (_a = this.controller) === null || _a === void 0 ? void 0 : _a.fetchMetadataKeys()) !== null && _b !== void 0 ? _b : [];
    }
    /**
     * @ignore
     */
    disconnectedCallback() {
        var _a, _b, _c;
        (_a = this.stateMap.viewerDisposable) === null || _a === void 0 ? void 0 : _a.dispose();
        (_b = this.stateMap.viewerSceneReadyDisposable) === null || _b === void 0 ? void 0 : _b.dispose();
        (_c = this.controller) === null || _c === void 0 ? void 0 : _c.cancel();
    }
    /**
     * @ignore
     */
    connectedCallback() {
        this.connectToViewer();
    }
    /**
     * @ignore
     */
    componentWillLoad() {
        var _a;
        if (this.controller == null) {
            const { sceneTreeHost } = this.getConfig().network;
            const client = new SceneTreeAPIClient(sceneTreeHost, this.getConfig().flags.grpcUseStreamingWebSocketTransport
                ? {
                    transport: webSocketSubscriptionTransportFactory,
                }
                : undefined);
            this.controller = new SceneTreeController(client, 100);
            (_a = this.controller) === null || _a === void 0 ? void 0 : _a.setMetadataKeys(this.metadataKeys);
        }
        this.stateMap.onStateChangeDisposable = this.controller.onStateChange.on((state) => this.handleControllerStateChange(state));
        this.connectToViewer();
    }
    /**
     * @ignore
     */
    async componentDidLoad() {
        var _a;
        this.ensureLayoutDefined();
        this.updateLayoutElement();
        const layoutEl = this.getLayoutElement();
        const resizeObserver = new ResizeObserver(() => {
            this.invalidateRows();
        });
        resizeObserver.observe(layoutEl);
        this.stateMap.resizeObserver = resizeObserver;
        this.stateMap.componentLoaded = true;
        (_a = this.controller) === null || _a === void 0 ? void 0 : _a.setMetadataKeys(this.metadataKeys);
        if (this.viewer == null) {
            this.errorDetails = new SceneTreeErrorDetails('MISSING_VIEWER', SceneTreeErrorCode.MISSING_VIEWER);
        }
    }
    componentWillRender() {
        // The controller can load data prior to the first render
        // ensure that this renders any time the state changes.
        this.updateLayoutElement();
    }
    /**
     * @ignore
     */
    render() {
        return (h(Host, { key: '8e9ef4a71e8d7d1a1aeefa2016624eab34392923' }, h("div", { key: 'ebd64d4b347759e00a71f1230cd70d2809a5404e', class: "header" }, h("slot", { key: '6fca7d74ee3bd07e9c940bf4c13d6c92b4ec71f7', name: "header" }, h("vertex-scene-tree-toolbar", { key: '75aab7028ba9d4514976f8ba40df63761b3941b0', class: "search-toolbar" }, h("vertex-scene-tree-search", { key: '4f9d9c05120a4410b34c206d7bfce754978aa285', controller: this.controller })))), h("slot", { key: '84b5977063e55cc88ee740375f710591b1245b0a', name: "partial-filter-results-banner" }, this.hasPartialFilterResults && (h("vertex-scene-tree-notification-banner", { key: 'a6784c2c811cadfd1354c1df227d1dd5a24c0ef0', message: this.refreshingResults
                ? 'Refreshing results...'
                : 'Data loading, refresh for more.', actionLabel: "Refresh", onAction: () => { var _a; return (_a = this.controller) === null || _a === void 0 ? void 0 : _a.refreshFilter(); } }))), this.errorDetails != null && this.renderError(this.errorDetails), this.errorDetails == null && (h("div", { key: 'b31b8dd61936644886963a14690a5e6a7e89f253', class: "rows-scroll" }, this.showLoader && (h("slot", { key: '974d731c0430a9d739b3b4142a1e3b1d40ca3a35', name: "loading" }, h("vertex-viewer-spinner", { key: 'f0bdfbe2bb315527b523d4d318f155310b3af0ba', class: "loading", size: "md" }))), h("slot", { key: '0f8ee9a72cc72b43782ad40249f5f76f7b9147b3' }), this.showEmptyResults && (h("slot", { key: '64b69d0144e2a149181aead8d18f2a351c996664', name: "empty-results" }, h("div", { key: '2152af85264c466ed75d26193e242f9bd0db04c5', class: "empty-results" }, "No Results Found."))))), h("div", { key: '45fc6cdc33b3decc4352b0d5747ee299e8324ff0', class: "footer" }, h("slot", { key: 'd6b197db964a2c55c29172d39060ece3584da7d9', name: "footer" }))));
    }
    renderError(details) {
        if (details.code !== SceneTreeErrorCode.SCENE_TREE_DISABLED) {
            return (h(SceneTreeError, { details: details }, h("button", { class: "button button-secondary", onClick: () => this.retryConnectToViewer(), disabled: this.attemptingRetry }, "Retry")));
        }
        else {
            return h(SceneTreeError, { details: details });
        }
    }
    /**
     * @ignore
     */
    handleViewerChanged(newViewer, oldViewer) {
        // StencilJS will invoke this callback even before the component has been
        // loaded. According to their docs, this shouldn't happen. Return if the
        // component hasn't been loaded.
        // See https://stenciljs.com/docs/reactive-data#watch-decorator
        if (!this.stateMap.componentLoaded) {
            return;
        }
        this.connectToViewer();
    }
    /**
     * @ignore
     */
    handleControllerChanged(newController) {
        var _a;
        // StencilJS will invoke this callback even before the component has been
        // loaded. According to their docs, this shouldn't happen. Return if the
        // component hasn't been loaded.
        // See https://stenciljs.com/docs/reactive-data#watch-decorator
        if (!this.stateMap.componentLoaded) {
            return;
        }
        (_a = this.stateMap.onStateChangeDisposable) === null || _a === void 0 ? void 0 : _a.dispose();
        this.stateMap.onStateChangeDisposable = newController.onStateChange.on((state) => this.handleControllerStateChange(state));
        newController.setMetadataKeys(this.metadataKeys);
    }
    /**
     * @ignore
     */
    handleMetadataKeysChanged() {
        var _a;
        (_a = this.controller) === null || _a === void 0 ? void 0 : _a.setMetadataKeys(this.metadataKeys);
    }
    retryConnectToViewer() {
        this.attemptingRetry = true;
        this.errorDetails = undefined;
        this.connectToViewer();
    }
    connectToViewer() {
        var _a, _b, _c;
        (_a = this.stateMap.viewerDisposable) === null || _a === void 0 ? void 0 : _a.dispose();
        (_b = this.stateMap.viewerSceneReadyDisposable) === null || _b === void 0 ? void 0 : _b.dispose();
        if (this.viewer == null && this.viewerSelector != null) {
            this.viewer = document.querySelector(this.viewerSelector);
        }
        if (this.viewer != null) {
            const handleSceneReady = async () => {
                const layoutEl = this.getLayoutElement();
                await layoutEl.attemptComputeCellHeight();
            };
            this.viewer.addEventListener('sceneReady', handleSceneReady);
            this.stateMap.viewerDisposable = (_c = this.controller) === null || _c === void 0 ? void 0 : _c.connectToViewer(this.viewer);
            this.stateMap.viewerSceneReadyDisposable = {
                dispose: () => { var _a; return (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.removeEventListener('sceneReady', handleSceneReady); },
            };
        }
        else {
            this.attemptingRetry = false;
        }
    }
    scheduleClearUnusedData() {
        if (this.stateMap.idleCallbackId != null) {
            window.cancelIdleCallback(this.stateMap.idleCallbackId);
        }
        this.stateMap.idleCallbackId = window.requestIdleCallback((foo) => {
            var _a, _b, _c;
            const remaining = (_a = foo.timeRemaining) === null || _a === void 0 ? void 0 : _a.call(foo);
            if (remaining == null || remaining >= MIN_CLEAR_UNUSED_DATA_MS) {
                const layoutEl = this.getLayoutElement();
                const startIndex = layoutEl.viewportStartIndex;
                const endIndex = layoutEl.viewportEndIndex;
                const [start, end] = ((_b = this.controller) === null || _b === void 0 ? void 0 : _b.getPageIndexesForRange(startIndex, endIndex)) || [];
                if (start != null && end != null) {
                    (_c = this.controller) === null || _c === void 0 ? void 0 : _c.invalidatePagesOutsideRange(start, end, 50);
                }
            }
            else {
                this.scheduleClearUnusedData();
            }
        });
    }
    handleControllerStateChange(state) {
        this.showLoader = !!state.shouldShowLoading;
        this.showEmptyResults = !!state.shouldShowEmptyResults;
        this.rows = state.rows;
        this.totalRows = state.totalRows;
        this.hasPartialFilterResults = !!state.isPartialFilterResponse;
        this.refreshingResults = !!state.isSearching;
        if (state.connection.type === 'failure') {
            this.errorDetails = state.connection.details;
            this.connectionError.emit(state.connection.details);
        }
        else if (state.connection.type === 'disconnected') {
            this.errorDetails = new SceneTreeErrorDetails('DISCONNECTED', SceneTreeErrorCode.DISCONNECTED);
        }
        else {
            this.errorDetails = undefined;
        }
        if (state.connection.type === 'connected' ||
            state.connection.type === 'failure') {
            this.attemptingRetry = false;
        }
    }
    getNodeFromRowOrIndex(rowOrIndex) {
        const row = typeof rowOrIndex === 'number' ? this.rows[rowOrIndex] : rowOrIndex;
        if (row == null) {
            throw new Error(`Cannot perform scene tree operation. Row not found.`);
        }
        return isLoadedRow(row) ? row.node : row;
    }
    async performRowOperation(rowOrIndex, op) {
        const node = this.getNodeFromRowOrIndex(rowOrIndex);
        if (node.id == null) {
            throw new Error(`Cannot perform scene tree operation. ID is undefined.`);
        }
        if (this.viewer == null) {
            throw new Error(`Cannot perform scene tree operation. Cannot get reference to viewer.`);
        }
        await op({ viewer: this.viewer, id: node.id.hex, node });
    }
    async handleSearch(event) {
        var _a, _b, _c, _d;
        const columnsToSearch = this.getMetadataSearchKeys(this.searchOptions);
        const shouldSearchExactMatch = (_b = (_a = this.searchOptions) === null || _a === void 0 ? void 0 : _a.exactMatch) !== null && _b !== void 0 ? _b : this.metadataSearchExactMatch;
        const shouldSearchRemoveHiddenItems = (_d = (_c = this.searchOptions) === null || _c === void 0 ? void 0 : _c.removeHiddenItems) !== null && _d !== void 0 ? _d : false;
        try {
            await this.filterItems(event.detail, {
                columns: columnsToSearch,
                exactMatch: shouldSearchExactMatch,
                removeHiddenItems: shouldSearchRemoveHiddenItems,
            });
        }
        catch (e) {
            console.error('Failed to filter tree with exception: ', e);
        }
    }
    async handleCellLoaded() {
        if (!this.firstCellRendered && this.rows.length > 0) {
            this.firstCellRendered = true;
            this.firstRowRendered.emit();
        }
    }
    getScrollToPosition(index, position) {
        var _a;
        const layoutEl = this.getLayoutElement();
        const constrainedIndex = Math.max(0, Math.min(index, this.totalRows - 1));
        const viewportHeight = (_a = layoutEl.layoutHeight) !== null && _a !== void 0 ? _a : 0;
        const rowHeight = layoutEl.rowHeight;
        if (position === 'start') {
            return constrainedIndex * rowHeight;
        }
        else if (position === 'middle') {
            const rowCenterY = constrainedIndex * rowHeight + rowHeight / 2;
            return rowCenterY - viewportHeight / 2;
        }
        else {
            const rowBottomY = constrainedIndex * rowHeight + rowHeight;
            return rowBottomY - viewportHeight;
        }
    }
    getConfig() {
        return parseAndValidateConfig(this.configEnv, this.config);
    }
    ensureLayoutDefined() {
        let layout = this.el.querySelector('vertex-scene-tree-table-layout');
        if (layout == null) {
            layout = document.createElement('vertex-scene-tree-table-layout');
            layout.innerHTML = `
      <vertex-scene-tree-table-column>
        <template>
        <vertex-scene-tree-table-cell prop:value="{{row.node.name}}" expand-toggle isolate-button visibility-toggle></vertex-scene-tree-table-cell>
        </template>
      </vertex-scene-tree-table-column>
      `;
            this.el.appendChild(layout);
        }
        this.stateMap.layoutEl = layout;
    }
    updateLayoutElement() {
        const layout = this.stateMap.layoutEl;
        if (layout != null) {
            layout.rows = this.rows;
            layout.tree = this.el;
            layout.totalRows = this.totalRows;
            layout.controller = this.controller;
            layout.rowData = this.rowData;
        }
        else if (!this.stateMap.componentLoaded && this.totalRows > 0) {
            console.debug('Scene tree has rows, but the component has not yet rendered');
        }
    }
    getLayoutElement() {
        if (this.stateMap.layoutEl != null) {
            return this.stateMap.layoutEl;
        }
        else {
            throw new Error('Layout element is undefined');
        }
    }
    getMetadataSearchKeys(options) {
        var _a, _b;
        const metadataSearchKeys = (_a = options === null || options === void 0 ? void 0 : options.metadataSearchKeys) !== null && _a !== void 0 ? _a : this.metadataSearchKeys;
        const shouldSearchExactMatch = (_b = options === null || options === void 0 ? void 0 : options.exactMatch) !== null && _b !== void 0 ? _b : this.metadataSearchExactMatch;
        if (shouldSearchExactMatch) {
            // If we're performing an exact match search, we want to include the searched
            // metadata keys if provided. In the case that none have been provided, simply
            // fall back the item name.
            const definedMetadataKeys = metadataSearchKeys.length > 0
                ? metadataSearchKeys
                : [SCENE_ITEM_NAME_METADATA_KEY];
            return definedMetadataKeys;
        }
        else if (metadataSearchKeys.length > 0) {
            // If we're not performing an exact match search, and a set of metadata keys
            // to search against have been provided, we want to include those in the request.
            return metadataSearchKeys;
        }
        // If we're not performing an exact match search, and we have no provided metadata
        // search keys, we can perform a name-only search, and omit the array of keys.
        return undefined;
    }
    static get is() { return "vertex-scene-tree"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["scene-tree.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["scene-tree.css"]
        };
    }
    static get properties() {
        return {
            "overScanCount": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The number of offscreen rows above and below the viewport to render. Having\na higher number reduces the chance of the browser not displaying a row\nwhile scrolling."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "over-scan-count",
                "defaultValue": "25"
            },
            "viewerSelector": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "A CSS selector that points to a `<vertex-viewer>` element. Either this\nproperty or `viewer` must be set."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "viewer-selector"
            },
            "viewer": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "HTMLVertexViewerElement | null",
                    "resolved": "HTMLVertexViewerElement | null | undefined",
                    "references": {
                        "HTMLVertexViewerElement": {
                            "location": "global",
                            "id": "global::HTMLVertexViewerElement"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "An instance of a `<vertex-viewer>` element. Either this property or\n`viewerSelector` must be set."
                },
                "getter": false,
                "setter": false
            },
            "rowData": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "RowDataProvider",
                    "resolved": "((row: Row) => Record<string, unknown>) | undefined",
                    "references": {
                        "RowDataProvider": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::RowDataProvider",
                            "referenceLocation": "RowDataProvider"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "example",
                            "text": "```html\n<script>\n  const table = document.querySelector('vertex-scene-tree-table');\n  table.rowData = (row) => {\n    return { func: () => console.log('row', row.node.name) };\n  }\n</script>\n\n<vertex-scene-tree>\n <vertex-scene-tree-table>\n   <vertex-scene-tree-table-column>\n     <template>\n       <button event:click=\"{{row.data.func}}\">Hi</button>\n     </template>\n   </vertex-scene-tree-table-column>\n </vertex-scene-tree-table>\n</vertex-scene-tree>\n```"
                        }],
                    "text": "A callback that is invoked immediately before a row is about to be rendered.\nThis callback can return additional data that can be bound to in a\ntemplate."
                },
                "getter": false,
                "setter": false
            },
            "config": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "PartialConfig | string",
                    "resolved": "Config | string | undefined",
                    "references": {
                        "PartialConfig": {
                            "location": "import",
                            "path": "../../lib/config",
                            "id": "src/lib/config.ts::PartialConfig",
                            "referenceLocation": "PartialConfig"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "An object to configure the scene tree."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "config"
            },
            "configEnv": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "Environment",
                    "resolved": "\"platdev\" | \"platprod\" | \"platstaging\"",
                    "references": {
                        "Environment": {
                            "location": "import",
                            "path": "../../lib/environment",
                            "id": "src/lib/environment.ts::Environment",
                            "referenceLocation": "Environment"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Sets the default environment for the viewer. This setting is used for\nauto-configuring network hosts.\n\nUse the `config` property for manually setting hosts."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "config-env",
                "defaultValue": "'platprod'"
            },
            "controller": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "SceneTreeController",
                    "resolved": "SceneTreeController | undefined",
                    "references": {
                        "SceneTreeController": {
                            "location": "import",
                            "path": "./lib/controller",
                            "id": "src/components/scene-tree/lib/controller.ts::SceneTreeController",
                            "referenceLocation": "SceneTreeController"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false
            },
            "searchOptions": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "FilterOptions",
                    "resolved": "FilterOptions",
                    "references": {
                        "FilterOptions": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::FilterOptions",
                            "referenceLocation": "FilterOptions"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "A set of options to configure scene tree searching behavior."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "{}"
            },
            "metadataSearchExactMatch": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "deprecated",
                            "text": "Use `searchOptions`\nIndicates whether the metadata search should use an exact match."
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "metadata-search-exact-match",
                "defaultValue": "false"
            },
            "metadataSearchKeys": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "MetadataKey[]",
                    "resolved": "string[]",
                    "references": {
                        "MetadataKey": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::MetadataKey",
                            "referenceLocation": "MetadataKey"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "deprecated",
                            "text": "Use `searchOptions`\nA list of the metadata keys that a scene tree search should be performed on."
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            },
            "metadataKeys": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "MetadataKey[]",
                    "resolved": "string[]",
                    "references": {
                        "MetadataKey": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::MetadataKey",
                            "referenceLocation": "MetadataKey"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "A list of part metadata keys that will be made available to each row. This\nmetadata can be used for data binding inside the scene tree's template.\n\n**Note:** for the values of these metadata keys to be evaluated for search,\nthey must be provided to the `metadataSearchKeys` specified in the `searchOptions`.\nOtherwise, the search will only be performed against the item name."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            },
            "operationAnimationDuration": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The duration of operations with animations, in milliseconds, when a user performs\nan action that results in an animation such as isolate. Defaults to 500ms."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "operation-animation-duration",
                "defaultValue": "500"
            }
        };
    }
    static get states() {
        return {
            "rows": {},
            "totalRows": {},
            "showLoader": {},
            "showEmptyResults": {},
            "stateMap": {},
            "errorDetails": {},
            "hasPartialFilterResults": {},
            "refreshingResults": {},
            "attemptingRetry": {}
        };
    }
    static get events() {
        return [{
                "method": "connectionError",
                "name": "connectionError",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "An event that is emitted when this <vertex-scene-tree> encounters a connection\nerror."
                },
                "complexType": {
                    "original": "SceneTreeErrorDetails",
                    "resolved": "SceneTreeErrorDetails",
                    "references": {
                        "SceneTreeErrorDetails": {
                            "location": "import",
                            "path": "./lib/errors",
                            "id": "src/components/scene-tree/lib/errors.ts::SceneTreeErrorDetails",
                            "referenceLocation": "SceneTreeErrorDetails"
                        }
                    }
                }
            }, {
                "method": "firstRowRendered",
                "name": "firstRowRendered",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "An event that is emitted when the first row of this <vertex-scene-tree> has\nbeen rendered."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }];
    }
    static get methods() {
        return {
            "invalidateRows": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Schedules a render of the rows in the scene tree. Useful if any custom\ndata in your scene tree has changed, and you want to update the row's\ncontents.\n\n**Note:** This is an asynchronous operation. The update may happen on the\nnext frame.",
                    "tags": []
                }
            },
            "scrollToIndex": {
                "complexType": {
                    "signature": "(index: number, options?: ScrollToOptions) => Promise<void>",
                    "parameters": [{
                            "name": "index",
                            "type": "number",
                            "docs": "An index of the row to scroll to."
                        }, {
                            "name": "options",
                            "type": "ScrollToOptions",
                            "docs": "A set of options to configure the scrolling behavior."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "ScrollToOptions": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::ScrollToOptions",
                            "referenceLocation": "ScrollToOptions"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Scrolls the tree to the given row index.",
                    "tags": [{
                            "name": "param",
                            "text": "index An index of the row to scroll to."
                        }, {
                            "name": "param",
                            "text": "options A set of options to configure the scrolling behavior."
                        }]
                }
            },
            "scrollToItem": {
                "complexType": {
                    "signature": "(itemId: string, options?: ScrollToOptions) => Promise<void>",
                    "parameters": [{
                            "name": "itemId",
                            "type": "string",
                            "docs": "An ID of an item to scroll to."
                        }, {
                            "name": "options",
                            "type": "ScrollToOptions",
                            "docs": "A set of options to configure the scrolling behavior."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "ScrollToOptions": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::ScrollToOptions",
                            "referenceLocation": "ScrollToOptions"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Scrolls the tree to an item with the given ID. If the node for the item is\nnot expanded, the tree will expand each of its parent nodes.",
                    "tags": [{
                            "name": "param",
                            "text": "itemId An ID of an item to scroll to."
                        }, {
                            "name": "param",
                            "text": "options A set of options to configure the scrolling behavior."
                        }, {
                            "name": "returns",
                            "text": "A promise that resolves when the operation is finished."
                        }]
                }
            },
            "expandAll": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Performs an API call to expand all nodes in the tree.",
                    "tags": []
                }
            },
            "collapseAll": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Performs an API call to collapse all nodes in the tree.",
                    "tags": []
                }
            },
            "expandItem": {
                "complexType": {
                    "signature": "(row: RowArg) => Promise<void>",
                    "parameters": [{
                            "name": "row",
                            "type": "number | AsObject | Row",
                            "docs": "A row, row index, or node to expand."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "RowArg": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::RowArg",
                            "referenceLocation": "RowArg"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Performs an API call that will expand the node associated to the specified\nrow or row index.",
                    "tags": [{
                            "name": "param",
                            "text": "row A row, row index, or node to expand."
                        }]
                }
            },
            "collapseItem": {
                "complexType": {
                    "signature": "(row: RowArg) => Promise<void>",
                    "parameters": [{
                            "name": "row",
                            "type": "number | AsObject | Row",
                            "docs": "A row, row index, or node to collapse."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "RowArg": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::RowArg",
                            "referenceLocation": "RowArg"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Performs an API call that will collapse the node associated to the\nspecified row or row index.",
                    "tags": [{
                            "name": "param",
                            "text": "row A row, row index, or node to collapse."
                        }]
                }
            },
            "toggleExpandItem": {
                "complexType": {
                    "signature": "(row: RowArg) => Promise<void>",
                    "parameters": [{
                            "name": "row",
                            "type": "number | AsObject | Row",
                            "docs": "The row, row index, or node to collapse or expand."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "RowArg": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::RowArg",
                            "referenceLocation": "RowArg"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Performs an API call that will either expand or collapse the node\nassociated to the given row or row index.",
                    "tags": [{
                            "name": "param",
                            "text": "row The row, row index, or node to collapse or expand."
                        }]
                }
            },
            "toggleItemVisibility": {
                "complexType": {
                    "signature": "(row: RowArg) => Promise<void>",
                    "parameters": [{
                            "name": "row",
                            "type": "number | AsObject | Row",
                            "docs": "The row, row index, or node to toggle visibility."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "RowArg": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::RowArg",
                            "referenceLocation": "RowArg"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Performs an API call that will either hide or show the item associated to\nthe given row or row index.",
                    "tags": [{
                            "name": "param",
                            "text": "row The row, row index, or node to toggle visibility."
                        }]
                }
            },
            "hideItem": {
                "complexType": {
                    "signature": "(row: RowArg) => Promise<void>",
                    "parameters": [{
                            "name": "row",
                            "type": "number | AsObject | Row",
                            "docs": "The row, row index, or node to hide."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "RowArg": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::RowArg",
                            "referenceLocation": "RowArg"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Performs an API call that will hide the item associated to the given row\nor row index.",
                    "tags": [{
                            "name": "param",
                            "text": "row The row, row index, or node to hide."
                        }]
                }
            },
            "showItem": {
                "complexType": {
                    "signature": "(row: RowArg) => Promise<void>",
                    "parameters": [{
                            "name": "row",
                            "type": "number | AsObject | Row",
                            "docs": "The row, row index, or node to show."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "RowArg": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::RowArg",
                            "referenceLocation": "RowArg"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Performs an API call that will show the item associated to the given row\nor row index.",
                    "tags": [{
                            "name": "param",
                            "text": "row The row, row index, or node to show."
                        }]
                }
            },
            "selectItem": {
                "complexType": {
                    "signature": "(row: RowArg, { recurseParent, ...options }?: SelectItemOptions) => Promise<void>",
                    "parameters": [{
                            "name": "row",
                            "type": "number | AsObject | Row",
                            "docs": "The row, row index or node to select."
                        }, {
                            "name": "__1",
                            "type": "SelectItemOptions",
                            "docs": "A set of options to configure selection behavior."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "RowArg": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::RowArg",
                            "referenceLocation": "RowArg"
                        },
                        "SelectItemOptions": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::SelectItemOptions",
                            "referenceLocation": "SelectItemOptions"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Performs an API call that will select the item associated to the given row\nor row index.\n\nThis method supports a `recurseParent` option that allows for recursively\nselecting the next unselected parent node. This behavior is considered\nstateful. Each call to `selectItem` will track the ancestry of the passed\nin `rowArg`. If calling `selectItem` with a row not belonging to the\nancestry of a previous selection, then this method will perform a standard\nselection.",
                    "tags": [{
                            "name": "param",
                            "text": "row The row, row index or node to select."
                        }, {
                            "name": "param",
                            "text": "options A set of options to configure selection behavior."
                        }]
                }
            },
            "deselectItem": {
                "complexType": {
                    "signature": "(row: RowArg) => Promise<void>",
                    "parameters": [{
                            "name": "row",
                            "type": "number | AsObject | Row",
                            "docs": "The row, row index, or node to deselect."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "RowArg": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::RowArg",
                            "referenceLocation": "RowArg"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Performs an API call that will deselect the item associated to the given\nrow or row index.",
                    "tags": [{
                            "name": "param",
                            "text": "row The row, row index, or node to deselect."
                        }]
                }
            },
            "isolateItem": {
                "complexType": {
                    "signature": "(row: RowArg) => Promise<void>",
                    "parameters": [{
                            "name": "row",
                            "type": "number | AsObject | Row",
                            "docs": "The row, row index, or node to isolate."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "RowArg": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::RowArg",
                            "referenceLocation": "RowArg"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Performs an API call that will show only the item associated to\nthe given row or row index and fit the camera to the item's bounding box.",
                    "tags": [{
                            "name": "param",
                            "text": "row The row, row index, or node to isolate."
                        }]
                }
            },
            "getRowAtIndex": {
                "complexType": {
                    "signature": "(index: number) => Promise<Row>",
                    "parameters": [{
                            "name": "index",
                            "type": "number",
                            "docs": "The index of the row."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "Row": {
                            "location": "import",
                            "path": "./lib/row",
                            "id": "src/components/scene-tree/lib/row.ts::Row",
                            "referenceLocation": "Row"
                        }
                    },
                    "return": "Promise<Row>"
                },
                "docs": {
                    "text": "Returns a row at the given index. If the row data has not been loaded,\nreturns `undefined`.",
                    "tags": [{
                            "name": "param",
                            "text": "index The index of the row."
                        }, {
                            "name": "returns",
                            "text": "A row, or `undefined` if the row hasn't been loaded."
                        }]
                }
            },
            "getRowForItemId": {
                "complexType": {
                    "signature": "(itemId: string) => Promise<Row | undefined>",
                    "parameters": [{
                            "name": "itemId",
                            "type": "string",
                            "docs": "An ID of an item to return the row for."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "Row": {
                            "location": "import",
                            "path": "./lib/row",
                            "id": "src/components/scene-tree/lib/row.ts::Row",
                            "referenceLocation": "Row"
                        }
                    },
                    "return": "Promise<Row>"
                },
                "docs": {
                    "text": "Returns the row with the given id. If there is not a row\nmatching the id, returns `undefined`.",
                    "tags": [{
                            "name": "param",
                            "text": "itemId An ID of an item to return the row for."
                        }, {
                            "name": "returns",
                            "text": "A row, or `undefined` if a corresponding row doesn't exist"
                        }]
                }
            },
            "getRowForEvent": {
                "complexType": {
                    "signature": "(event: MouseEvent | PointerEvent) => Promise<Row>",
                    "parameters": [{
                            "name": "event",
                            "type": "MouseEvent | PointerEvent",
                            "docs": "A mouse or pointer event that originated from this component."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "Row": {
                            "location": "import",
                            "path": "./lib/row",
                            "id": "src/components/scene-tree/lib/row.ts::Row",
                            "referenceLocation": "Row"
                        },
                        "MouseEvent": {
                            "location": "global",
                            "id": "global::MouseEvent"
                        },
                        "PointerEvent": {
                            "location": "global",
                            "id": "global::PointerEvent"
                        },
                        "HTMLElement": {
                            "location": "global",
                            "id": "global::HTMLElement"
                        }
                    },
                    "return": "Promise<Row>"
                },
                "docs": {
                    "text": "Returns the row data from the given mouse or pointer event. The event must\noriginate from a `vertex-scene-tree-table-cell` contained by this element,\notherwise `undefined` is returned.",
                    "tags": [{
                            "name": "param",
                            "text": "event A mouse or pointer event that originated from this component."
                        }, {
                            "name": "returns",
                            "text": "A row, or `undefined` if the row hasn't been loaded."
                        }]
                }
            },
            "getRowAtClientY": {
                "complexType": {
                    "signature": "(clientY: number) => Promise<Row>",
                    "parameters": [{
                            "name": "clientY",
                            "type": "number",
                            "docs": "The vertical client position."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "Row": {
                            "location": "import",
                            "path": "./lib/row",
                            "id": "src/components/scene-tree/lib/row.ts::Row",
                            "referenceLocation": "Row"
                        }
                    },
                    "return": "Promise<Row>"
                },
                "docs": {
                    "text": "Returns the row data from the given vertical client position.",
                    "tags": [{
                            "name": "param",
                            "text": "clientY The vertical client position."
                        }, {
                            "name": "returns",
                            "text": "A row or `undefined` if the row hasn't been loaded."
                        }]
                }
            },
            "filterItems": {
                "complexType": {
                    "signature": "(term: string, options?: FilterTreeOptions) => Promise<void>",
                    "parameters": [{
                            "name": "term",
                            "type": "string",
                            "docs": "The filter term."
                        }, {
                            "name": "options",
                            "type": "FilterTreeOptions",
                            "docs": "The options to apply to the filter."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "FilterTreeOptions": {
                            "location": "import",
                            "path": "./lib/controller",
                            "id": "src/components/scene-tree/lib/controller.ts::FilterTreeOptions",
                            "referenceLocation": "FilterTreeOptions"
                        },
                        "FilterOptions": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::FilterOptions",
                            "referenceLocation": "FilterOptions"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Performs an async request that will filter the displayed items in the tree\nthat match the given term and options.",
                    "tags": [{
                            "name": "param",
                            "text": "term The filter term."
                        }, {
                            "name": "param",
                            "text": "options The options to apply to the filter."
                        }, {
                            "name": "returns",
                            "text": "A promise that completes when the request has completed. Note,\nitems are displayed asynchronously. So the displayed items may not reflect\nthe result of this filter when the promise completes."
                        }]
                }
            },
            "selectFilteredItems": {
                "complexType": {
                    "signature": "(term: string, options?: SceneTreeOperationOptions) => Promise<void>",
                    "parameters": [{
                            "name": "term",
                            "type": "string",
                            "docs": "The filter term."
                        }, {
                            "name": "options",
                            "type": "SceneTreeOperationOptions | undefined",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "SceneTreeOperationOptions": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::SceneTreeOperationOptions",
                            "referenceLocation": "SceneTreeOperationOptions"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Performs an async request that will select the filtered items in the tree\nthat match the given term.",
                    "tags": [{
                            "name": "param",
                            "text": "term The filter term."
                        }, {
                            "name": "returns",
                            "text": "A promise that completes when the request has completed."
                        }]
                }
            },
            "fetchMetadataKeys": {
                "complexType": {
                    "signature": "() => Promise<MetadataKey[]>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "MetadataKey": {
                            "location": "import",
                            "path": "./types",
                            "id": "src/components/scene-tree/types.ts::MetadataKey",
                            "referenceLocation": "MetadataKey"
                        }
                    },
                    "return": "Promise<string[]>"
                },
                "docs": {
                    "text": "Fetches the metadata keys that are available to the scene tree. Metadata\nkeys can be assigned to the scene tree using the `metadataKeys` property.\nThe scene tree will fetch this metadata and make these values available\nfor data binding.",
                    "tags": [{
                            "name": "returns",
                            "text": "A promise that resolves with the names of available keys."
                        }]
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "viewer",
                "methodName": "handleViewerChanged"
            }, {
                "propName": "controller",
                "methodName": "handleControllerChanged"
            }, {
                "propName": "metadataKeys",
                "methodName": "handleMetadataKeysChanged"
            }];
    }
    static get listeners() {
        return [{
                "name": "search",
                "method": "handleSearch",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "cellLoaded",
                "method": "handleCellLoaded",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
}
//# sourceMappingURL=scene-tree.js.map
