"use strict";
/*
 * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */
(self["webpackChunk_JUPYTERLAB_CORE_OUTPUT"] = self["webpackChunk_JUPYTERLAB_CORE_OUTPUT"] || []).push([["vendors-node_modules_lumino_widgets_dist_index_es6_js"],{

/***/ "../node_modules/@lumino/widgets/dist/index.es6.js":
/*!*********************************************************!*\
  !*** ../node_modules/@lumino/widgets/dist/index.es6.js ***!
  \*********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   AccordionLayout: () => (/* binding */ AccordionLayout),\n/* harmony export */   AccordionPanel: () => (/* binding */ AccordionPanel),\n/* harmony export */   BoxEngine: () => (/* binding */ BoxEngine),\n/* harmony export */   BoxLayout: () => (/* binding */ BoxLayout),\n/* harmony export */   BoxPanel: () => (/* binding */ BoxPanel),\n/* harmony export */   BoxSizer: () => (/* binding */ BoxSizer),\n/* harmony export */   CommandPalette: () => (/* binding */ CommandPalette),\n/* harmony export */   ContextMenu: () => (/* binding */ ContextMenu),\n/* harmony export */   DockLayout: () => (/* binding */ DockLayout),\n/* harmony export */   DockPanel: () => (/* binding */ DockPanel),\n/* harmony export */   FocusTracker: () => (/* binding */ FocusTracker),\n/* harmony export */   GridLayout: () => (/* binding */ GridLayout),\n/* harmony export */   Layout: () => (/* binding */ Layout),\n/* harmony export */   LayoutItem: () => (/* binding */ LayoutItem),\n/* harmony export */   Menu: () => (/* binding */ Menu),\n/* harmony export */   MenuBar: () => (/* binding */ MenuBar),\n/* harmony export */   Panel: () => (/* binding */ Panel),\n/* harmony export */   PanelLayout: () => (/* binding */ PanelLayout),\n/* harmony export */   ScrollBar: () => (/* binding */ ScrollBar),\n/* harmony export */   SingletonLayout: () => (/* binding */ SingletonLayout),\n/* harmony export */   SplitLayout: () => (/* binding */ SplitLayout),\n/* harmony export */   SplitPanel: () => (/* binding */ SplitPanel),\n/* harmony export */   StackedLayout: () => (/* binding */ StackedLayout),\n/* harmony export */   StackedPanel: () => (/* binding */ StackedPanel),\n/* harmony export */   TabBar: () => (/* binding */ TabBar),\n/* harmony export */   TabPanel: () => (/* binding */ TabPanel),\n/* harmony export */   Title: () => (/* binding */ Title),\n/* harmony export */   Widget: () => (/* binding */ Widget)\n/* harmony export */ });\n/* harmony import */ var _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @lumino/algorithm */ \"webpack/sharing/consume/default/@lumino/algorithm/@lumino/algorithm\");\n/* harmony import */ var _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lumino/coreutils */ \"webpack/sharing/consume/default/@lumino/coreutils/@lumino/coreutils\");\n/* harmony import */ var _lumino_coreutils__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @lumino/domutils */ \"webpack/sharing/consume/default/@lumino/domutils/@lumino/domutils\");\n/* harmony import */ var _lumino_domutils__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @lumino/messaging */ \"webpack/sharing/consume/default/@lumino/messaging/@lumino/messaging\");\n/* harmony import */ var _lumino_messaging__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_lumino_messaging__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _lumino_properties__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @lumino/properties */ \"webpack/sharing/consume/default/@lumino/properties/@lumino/properties\");\n/* harmony import */ var _lumino_properties__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_lumino_properties__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @lumino/signaling */ \"webpack/sharing/consume/default/@lumino/signaling/@lumino/signaling\");\n/* harmony import */ var _lumino_signaling__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_lumino_signaling__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _lumino_dragdrop__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @lumino/dragdrop */ \"webpack/sharing/consume/default/@lumino/dragdrop/@lumino/dragdrop\");\n/* harmony import */ var _lumino_dragdrop__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_lumino_dragdrop__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var _lumino_commands__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @lumino/commands */ \"webpack/sharing/consume/default/@lumino/commands/@lumino/commands\");\n/* harmony import */ var _lumino_commands__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_lumino_commands__WEBPACK_IMPORTED_MODULE_7__);\n/* harmony import */ var _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @lumino/virtualdom */ \"webpack/sharing/consume/default/@lumino/virtualdom/@lumino/virtualdom\");\n/* harmony import */ var _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__);\n/* harmony import */ var _lumino_disposable__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @lumino/disposable */ \"webpack/sharing/consume/default/@lumino/disposable/@lumino/disposable\");\n/* harmony import */ var _lumino_disposable__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(_lumino_disposable__WEBPACK_IMPORTED_MODULE_9__);\n/* harmony import */ var _lumino_keyboard__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @lumino/keyboard */ \"webpack/sharing/consume/default/@lumino/keyboard/@lumino/keyboard\");\n/* harmony import */ var _lumino_keyboard__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(_lumino_keyboard__WEBPACK_IMPORTED_MODULE_10__);\n\n\n\n\n\n\n\n\n\n\n\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A sizer object for use with the box engine layout functions.\n *\n * #### Notes\n * A box sizer holds the geometry information for an object along an\n * arbitrary layout orientation.\n *\n * For best performance, this class should be treated as a raw data\n * struct. It should not typically be subclassed.\n */\nclass BoxSizer {\n    constructor() {\n        /**\n         * The preferred size for the sizer.\n         *\n         * #### Notes\n         * The sizer will be given this initial size subject to its size\n         * bounds. The sizer will not deviate from this size unless such\n         * deviation is required to fit into the available layout space.\n         *\n         * There is no limit to this value, but it will be clamped to the\n         * bounds defined by {@link minSize} and {@link maxSize}.\n         *\n         * The default value is `0`.\n         */\n        this.sizeHint = 0;\n        /**\n         * The minimum size of the sizer.\n         *\n         * #### Notes\n         * The sizer will never be sized less than this value, even if\n         * it means the sizer will overflow the available layout space.\n         *\n         * It is assumed that this value lies in the range `[0, Infinity)`\n         * and that it is `<=` to {@link maxSize}. Failure to adhere to this\n         * constraint will yield undefined results.\n         *\n         * The default value is `0`.\n         */\n        this.minSize = 0;\n        /**\n         * The maximum size of the sizer.\n         *\n         * #### Notes\n         * The sizer will never be sized greater than this value, even if\n         * it means the sizer will underflow the available layout space.\n         *\n         * It is assumed that this value lies in the range `[0, Infinity]`\n         * and that it is `>=` to {@link minSize}. Failure to adhere to this\n         * constraint will yield undefined results.\n         *\n         * The default value is `Infinity`.\n         */\n        this.maxSize = Infinity;\n        /**\n         * The stretch factor for the sizer.\n         *\n         * #### Notes\n         * This controls how much the sizer stretches relative to its sibling\n         * sizers when layout space is distributed. A stretch factor of zero\n         * is special and will cause the sizer to only be resized after all\n         * other sizers with a stretch factor greater than zero have been\n         * resized to their limits.\n         *\n         * It is assumed that this value is an integer that lies in the range\n         * `[0, Infinity)`. Failure to adhere to this constraint will yield\n         * undefined results.\n         *\n         * The default value is `1`.\n         */\n        this.stretch = 1;\n        /**\n         * The computed size of the sizer.\n         *\n         * #### Notes\n         * This value is the output of a call to {@link BoxEngine.calc}. It represents\n         * the computed size for the object along the layout orientation,\n         * and will always lie in the range `[minSize, maxSize]`.\n         *\n         * This value is output only.\n         *\n         * Changing this value will have no effect.\n         */\n        this.size = 0;\n        /**\n         * An internal storage property for the layout algorithm.\n         *\n         * #### Notes\n         * This value is used as temporary storage by the layout algorithm.\n         *\n         * Changing this value will have no effect.\n         */\n        this.done = false;\n    }\n}\n/**\n * The namespace for the box engine layout functions.\n */\nvar BoxEngine;\n(function (BoxEngine) {\n    /**\n     * Calculate the optimal layout sizes for a sequence of box sizers.\n     *\n     * This distributes the available layout space among the box sizers\n     * according to the following algorithm:\n     *\n     * 1. Initialize the sizers's size to its size hint and compute the\n     *    sums for each of size hint, min size, and max size.\n     *\n     * 2. If the total size hint equals the available space, return.\n     *\n     * 3. If the available space is less than the total min size, set all\n     *    sizers to their min size and return.\n     *\n     * 4. If the available space is greater than the total max size, set\n     *    all sizers to their max size and return.\n     *\n     * 5. If the layout space is less than the total size hint, distribute\n     *    the negative delta as follows:\n     *\n     *    a. Shrink each sizer with a stretch factor greater than zero by\n     *       an amount proportional to the negative space and the sum of\n     *       stretch factors. If the sizer reaches its min size, remove\n     *       it and its stretch factor from the computation.\n     *\n     *    b. If after adjusting all stretch sizers there remains negative\n     *       space, distribute the space equally among the sizers with a\n     *       stretch factor of zero. If a sizer reaches its min size,\n     *       remove it from the computation.\n     *\n     * 6. If the layout space is greater than the total size hint,\n     *    distribute the positive delta as follows:\n     *\n     *    a. Expand each sizer with a stretch factor greater than zero by\n     *       an amount proportional to the postive space and the sum of\n     *       stretch factors. If the sizer reaches its max size, remove\n     *       it and its stretch factor from the computation.\n     *\n     *    b. If after adjusting all stretch sizers there remains positive\n     *       space, distribute the space equally among the sizers with a\n     *       stretch factor of zero. If a sizer reaches its max size,\n     *       remove it from the computation.\n     *\n     * 7. return\n     *\n     * @param sizers - The sizers for a particular layout line.\n     *\n     * @param space - The available layout space for the sizers.\n     *\n     * @returns The delta between the provided available space and the\n     *   actual consumed space. This value will be zero if the sizers\n     *   can be adjusted to fit, negative if the available space is too\n     *   small, and positive if the available space is too large.\n     *\n     * #### Notes\n     * The {@link BoxSizer.size} of each sizer is updated with the computed size.\n     *\n     * This function can be called at any time to recompute the layout for\n     * an existing sequence of sizers. The previously computed results will\n     * have no effect on the new output. It is therefore not necessary to\n     * create new sizer objects on each resize event.\n     */\n    function calc(sizers, space) {\n        // Bail early if there is nothing to do.\n        let count = sizers.length;\n        if (count === 0) {\n            return space;\n        }\n        // Setup the size and stretch counters.\n        let totalMin = 0;\n        let totalMax = 0;\n        let totalSize = 0;\n        let totalStretch = 0;\n        let stretchCount = 0;\n        // Setup the sizers and compute the totals.\n        for (let i = 0; i < count; ++i) {\n            let sizer = sizers[i];\n            let min = sizer.minSize;\n            let max = sizer.maxSize;\n            let hint = sizer.sizeHint;\n            sizer.done = false;\n            sizer.size = Math.max(min, Math.min(hint, max));\n            totalSize += sizer.size;\n            totalMin += min;\n            totalMax += max;\n            if (sizer.stretch > 0) {\n                totalStretch += sizer.stretch;\n                stretchCount++;\n            }\n        }\n        // If the space is equal to the total size, return early.\n        if (space === totalSize) {\n            return 0;\n        }\n        // If the space is less than the total min, minimize each sizer.\n        if (space <= totalMin) {\n            for (let i = 0; i < count; ++i) {\n                let sizer = sizers[i];\n                sizer.size = sizer.minSize;\n            }\n            return space - totalMin;\n        }\n        // If the space is greater than the total max, maximize each sizer.\n        if (space >= totalMax) {\n            for (let i = 0; i < count; ++i) {\n                let sizer = sizers[i];\n                sizer.size = sizer.maxSize;\n            }\n            return space - totalMax;\n        }\n        // The loops below perform sub-pixel precision sizing. A near zero\n        // value is used for compares instead of zero to ensure that the\n        // loop terminates when the subdivided space is reasonably small.\n        let nearZero = 0.01;\n        // A counter which is decremented each time a sizer is resized to\n        // its limit. This ensures the loops terminate even if there is\n        // space remaining to distribute.\n        let notDoneCount = count;\n        // Distribute negative delta space.\n        if (space < totalSize) {\n            // Shrink each stretchable sizer by an amount proportional to its\n            // stretch factor. If a sizer reaches its min size it's marked as\n            // done. The loop progresses in phases where each sizer is given\n            // a chance to consume its fair share for the pass, regardless of\n            // whether a sizer before it reached its limit. This continues\n            // until the stretchable sizers or the free space is exhausted.\n            let freeSpace = totalSize - space;\n            while (stretchCount > 0 && freeSpace > nearZero) {\n                let distSpace = freeSpace;\n                let distStretch = totalStretch;\n                for (let i = 0; i < count; ++i) {\n                    let sizer = sizers[i];\n                    if (sizer.done || sizer.stretch === 0) {\n                        continue;\n                    }\n                    let amt = (sizer.stretch * distSpace) / distStretch;\n                    if (sizer.size - amt <= sizer.minSize) {\n                        freeSpace -= sizer.size - sizer.minSize;\n                        totalStretch -= sizer.stretch;\n                        sizer.size = sizer.minSize;\n                        sizer.done = true;\n                        notDoneCount--;\n                        stretchCount--;\n                    }\n                    else {\n                        freeSpace -= amt;\n                        sizer.size -= amt;\n                    }\n                }\n            }\n            // Distribute any remaining space evenly among the non-stretchable\n            // sizers. This progresses in phases in the same manner as above.\n            while (notDoneCount > 0 && freeSpace > nearZero) {\n                let amt = freeSpace / notDoneCount;\n                for (let i = 0; i < count; ++i) {\n                    let sizer = sizers[i];\n                    if (sizer.done) {\n                        continue;\n                    }\n                    if (sizer.size - amt <= sizer.minSize) {\n                        freeSpace -= sizer.size - sizer.minSize;\n                        sizer.size = sizer.minSize;\n                        sizer.done = true;\n                        notDoneCount--;\n                    }\n                    else {\n                        freeSpace -= amt;\n                        sizer.size -= amt;\n                    }\n                }\n            }\n        }\n        // Distribute positive delta space.\n        else {\n            // Expand each stretchable sizer by an amount proportional to its\n            // stretch factor. If a sizer reaches its max size it's marked as\n            // done. The loop progresses in phases where each sizer is given\n            // a chance to consume its fair share for the pass, regardless of\n            // whether a sizer before it reached its limit. This continues\n            // until the stretchable sizers or the free space is exhausted.\n            let freeSpace = space - totalSize;\n            while (stretchCount > 0 && freeSpace > nearZero) {\n                let distSpace = freeSpace;\n                let distStretch = totalStretch;\n                for (let i = 0; i < count; ++i) {\n                    let sizer = sizers[i];\n                    if (sizer.done || sizer.stretch === 0) {\n                        continue;\n                    }\n                    let amt = (sizer.stretch * distSpace) / distStretch;\n                    if (sizer.size + amt >= sizer.maxSize) {\n                        freeSpace -= sizer.maxSize - sizer.size;\n                        totalStretch -= sizer.stretch;\n                        sizer.size = sizer.maxSize;\n                        sizer.done = true;\n                        notDoneCount--;\n                        stretchCount--;\n                    }\n                    else {\n                        freeSpace -= amt;\n                        sizer.size += amt;\n                    }\n                }\n            }\n            // Distribute any remaining space evenly among the non-stretchable\n            // sizers. This progresses in phases in the same manner as above.\n            while (notDoneCount > 0 && freeSpace > nearZero) {\n                let amt = freeSpace / notDoneCount;\n                for (let i = 0; i < count; ++i) {\n                    let sizer = sizers[i];\n                    if (sizer.done) {\n                        continue;\n                    }\n                    if (sizer.size + amt >= sizer.maxSize) {\n                        freeSpace -= sizer.maxSize - sizer.size;\n                        sizer.size = sizer.maxSize;\n                        sizer.done = true;\n                        notDoneCount--;\n                    }\n                    else {\n                        freeSpace -= amt;\n                        sizer.size += amt;\n                    }\n                }\n            }\n        }\n        // Indicate that the consumed space equals the available space.\n        return 0;\n    }\n    BoxEngine.calc = calc;\n    /**\n     * Adjust a sizer by a delta and update its neighbors accordingly.\n     *\n     * @param sizers - The sizers which should be adjusted.\n     *\n     * @param index - The index of the sizer to grow.\n     *\n     * @param delta - The amount to adjust the sizer, positive or negative.\n     *\n     * #### Notes\n     * This will adjust the indicated sizer by the specified amount, along\n     * with the sizes of the appropriate neighbors, subject to the limits\n     * specified by each of the sizers.\n     *\n     * This is useful when implementing box layouts where the boundaries\n     * between the sizers are interactively adjustable by the user.\n     */\n    function adjust(sizers, index, delta) {\n        // Bail early when there is nothing to do.\n        if (sizers.length === 0 || delta === 0) {\n            return;\n        }\n        // Dispatch to the proper implementation.\n        if (delta > 0) {\n            growSizer(sizers, index, delta);\n        }\n        else {\n            shrinkSizer(sizers, index, -delta);\n        }\n    }\n    BoxEngine.adjust = adjust;\n    /**\n     * Grow a sizer by a positive delta and adjust neighbors.\n     */\n    function growSizer(sizers, index, delta) {\n        // Compute how much the items to the left can expand.\n        let growLimit = 0;\n        for (let i = 0; i <= index; ++i) {\n            let sizer = sizers[i];\n            growLimit += sizer.maxSize - sizer.size;\n        }\n        // Compute how much the items to the right can shrink.\n        let shrinkLimit = 0;\n        for (let i = index + 1, n = sizers.length; i < n; ++i) {\n            let sizer = sizers[i];\n            shrinkLimit += sizer.size - sizer.minSize;\n        }\n        // Clamp the delta adjustment to the limits.\n        delta = Math.min(delta, growLimit, shrinkLimit);\n        // Grow the sizers to the left by the delta.\n        let grow = delta;\n        for (let i = index; i >= 0 && grow > 0; --i) {\n            let sizer = sizers[i];\n            let limit = sizer.maxSize - sizer.size;\n            if (limit >= grow) {\n                sizer.sizeHint = sizer.size + grow;\n                grow = 0;\n            }\n            else {\n                sizer.sizeHint = sizer.size + limit;\n                grow -= limit;\n            }\n        }\n        // Shrink the sizers to the right by the delta.\n        let shrink = delta;\n        for (let i = index + 1, n = sizers.length; i < n && shrink > 0; ++i) {\n            let sizer = sizers[i];\n            let limit = sizer.size - sizer.minSize;\n            if (limit >= shrink) {\n                sizer.sizeHint = sizer.size - shrink;\n                shrink = 0;\n            }\n            else {\n                sizer.sizeHint = sizer.size - limit;\n                shrink -= limit;\n            }\n        }\n    }\n    /**\n     * Shrink a sizer by a positive delta and adjust neighbors.\n     */\n    function shrinkSizer(sizers, index, delta) {\n        // Compute how much the items to the right can expand.\n        let growLimit = 0;\n        for (let i = index + 1, n = sizers.length; i < n; ++i) {\n            let sizer = sizers[i];\n            growLimit += sizer.maxSize - sizer.size;\n        }\n        // Compute how much the items to the left can shrink.\n        let shrinkLimit = 0;\n        for (let i = 0; i <= index; ++i) {\n            let sizer = sizers[i];\n            shrinkLimit += sizer.size - sizer.minSize;\n        }\n        // Clamp the delta adjustment to the limits.\n        delta = Math.min(delta, growLimit, shrinkLimit);\n        // Grow the sizers to the right by the delta.\n        let grow = delta;\n        for (let i = index + 1, n = sizers.length; i < n && grow > 0; ++i) {\n            let sizer = sizers[i];\n            let limit = sizer.maxSize - sizer.size;\n            if (limit >= grow) {\n                sizer.sizeHint = sizer.size + grow;\n                grow = 0;\n            }\n            else {\n                sizer.sizeHint = sizer.size + limit;\n                grow -= limit;\n            }\n        }\n        // Shrink the sizers to the left by the delta.\n        let shrink = delta;\n        for (let i = index; i >= 0 && shrink > 0; --i) {\n            let sizer = sizers[i];\n            let limit = sizer.size - sizer.minSize;\n            if (limit >= shrink) {\n                sizer.sizeHint = sizer.size - shrink;\n                shrink = 0;\n            }\n            else {\n                sizer.sizeHint = sizer.size - limit;\n                shrink -= limit;\n            }\n        }\n    }\n})(BoxEngine || (BoxEngine = {}));\n\n/**\n * An object which holds data related to an object's title.\n *\n * #### Notes\n * A title object is intended to hold the data necessary to display a\n * header for a particular object. A common example is the `TabPanel`,\n * which uses the widget title to populate the tab for a child widget.\n *\n * It is the responsibility of the owner to call the title disposal.\n */\nclass Title {\n    /**\n     * Construct a new title.\n     *\n     * @param options - The options for initializing the title.\n     */\n    constructor(options) {\n        this._label = '';\n        this._caption = '';\n        this._mnemonic = -1;\n        this._icon = undefined;\n        this._iconClass = '';\n        this._iconLabel = '';\n        this._className = '';\n        this._closable = false;\n        this._changed = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._isDisposed = false;\n        this.owner = options.owner;\n        if (options.label !== undefined) {\n            this._label = options.label;\n        }\n        if (options.mnemonic !== undefined) {\n            this._mnemonic = options.mnemonic;\n        }\n        if (options.icon !== undefined) {\n            this._icon = options.icon;\n        }\n        if (options.iconClass !== undefined) {\n            this._iconClass = options.iconClass;\n        }\n        if (options.iconLabel !== undefined) {\n            this._iconLabel = options.iconLabel;\n        }\n        if (options.caption !== undefined) {\n            this._caption = options.caption;\n        }\n        if (options.className !== undefined) {\n            this._className = options.className;\n        }\n        if (options.closable !== undefined) {\n            this._closable = options.closable;\n        }\n        this._dataset = options.dataset || {};\n    }\n    /**\n     * A signal emitted when the state of the title changes.\n     */\n    get changed() {\n        return this._changed;\n    }\n    /**\n     * Get the label for the title.\n     *\n     * #### Notes\n     * The default value is an empty string.\n     */\n    get label() {\n        return this._label;\n    }\n    /**\n     * Set the label for the title.\n     */\n    set label(value) {\n        if (this._label === value) {\n            return;\n        }\n        this._label = value;\n        this._changed.emit(undefined);\n    }\n    /**\n     * Get the mnemonic index for the title.\n     *\n     * #### Notes\n     * The default value is `-1`.\n     */\n    get mnemonic() {\n        return this._mnemonic;\n    }\n    /**\n     * Set the mnemonic index for the title.\n     */\n    set mnemonic(value) {\n        if (this._mnemonic === value) {\n            return;\n        }\n        this._mnemonic = value;\n        this._changed.emit(undefined);\n    }\n    /**\n     * Get the icon renderer for the title.\n     *\n     * #### Notes\n     * The default value is undefined.\n     */\n    get icon() {\n        return this._icon;\n    }\n    /**\n     * Set the icon renderer for the title.\n     *\n     * #### Notes\n     * A renderer is an object that supplies a render and unrender function.\n     */\n    set icon(value) {\n        if (this._icon === value) {\n            return;\n        }\n        this._icon = value;\n        this._changed.emit(undefined);\n    }\n    /**\n     * Get the icon class name for the title.\n     *\n     * #### Notes\n     * The default value is an empty string.\n     */\n    get iconClass() {\n        return this._iconClass;\n    }\n    /**\n     * Set the icon class name for the title.\n     *\n     * #### Notes\n     * Multiple class names can be separated with whitespace.\n     */\n    set iconClass(value) {\n        if (this._iconClass === value) {\n            return;\n        }\n        this._iconClass = value;\n        this._changed.emit(undefined);\n    }\n    /**\n     * Get the icon label for the title.\n     *\n     * #### Notes\n     * The default value is an empty string.\n     */\n    get iconLabel() {\n        return this._iconLabel;\n    }\n    /**\n     * Set the icon label for the title.\n     *\n     * #### Notes\n     * Multiple class names can be separated with whitespace.\n     */\n    set iconLabel(value) {\n        if (this._iconLabel === value) {\n            return;\n        }\n        this._iconLabel = value;\n        this._changed.emit(undefined);\n    }\n    /**\n     * Get the caption for the title.\n     *\n     * #### Notes\n     * The default value is an empty string.\n     */\n    get caption() {\n        return this._caption;\n    }\n    /**\n     * Set the caption for the title.\n     */\n    set caption(value) {\n        if (this._caption === value) {\n            return;\n        }\n        this._caption = value;\n        this._changed.emit(undefined);\n    }\n    /**\n     * Get the extra class name for the title.\n     *\n     * #### Notes\n     * The default value is an empty string.\n     */\n    get className() {\n        return this._className;\n    }\n    /**\n     * Set the extra class name for the title.\n     *\n     * #### Notes\n     * Multiple class names can be separated with whitespace.\n     */\n    set className(value) {\n        if (this._className === value) {\n            return;\n        }\n        this._className = value;\n        this._changed.emit(undefined);\n    }\n    /**\n     * Get the closable state for the title.\n     *\n     * #### Notes\n     * The default value is `false`.\n     */\n    get closable() {\n        return this._closable;\n    }\n    /**\n     * Set the closable state for the title.\n     *\n     * #### Notes\n     * This controls the presence of a close icon when applicable.\n     */\n    set closable(value) {\n        if (this._closable === value) {\n            return;\n        }\n        this._closable = value;\n        this._changed.emit(undefined);\n    }\n    /**\n     * Get the dataset for the title.\n     *\n     * #### Notes\n     * The default value is an empty dataset.\n     */\n    get dataset() {\n        return this._dataset;\n    }\n    /**\n     * Set the dataset for the title.\n     *\n     * #### Notes\n     * This controls the data attributes when applicable.\n     */\n    set dataset(value) {\n        if (this._dataset === value) {\n            return;\n        }\n        this._dataset = value;\n        this._changed.emit(undefined);\n    }\n    /**\n     * Test whether the title has been disposed.\n     */\n    get isDisposed() {\n        return this._isDisposed;\n    }\n    /**\n     * Dispose of the resources held by the title.\n     *\n     * #### Notes\n     * It is the responsibility of the owner to call the title disposal.\n     */\n    dispose() {\n        if (this.isDisposed) {\n            return;\n        }\n        this._isDisposed = true;\n        _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal.clearData(this);\n    }\n}\n\n/**\n * The base class of the lumino widget hierarchy.\n *\n * #### Notes\n * This class will typically be subclassed in order to create a useful\n * widget. However, it can be used directly to host externally created\n * content.\n */\nclass Widget {\n    /**\n     * Construct a new widget.\n     *\n     * @param options - The options for initializing the widget.\n     */\n    constructor(options = {}) {\n        this._flags = 0;\n        this._layout = null;\n        this._parent = null;\n        this._disposed = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._hiddenMode = Widget.HiddenMode.Display;\n        this.node = Private$j.createNode(options);\n        this.addClass('lm-Widget');\n    }\n    /**\n     * Dispose of the widget and its descendant widgets.\n     *\n     * #### Notes\n     * It is unsafe to use the widget after it has been disposed.\n     *\n     * All calls made to this method after the first are a no-op.\n     */\n    dispose() {\n        // Do nothing if the widget is already disposed.\n        if (this.isDisposed) {\n            return;\n        }\n        // Set the disposed flag and emit the disposed signal.\n        this.setFlag(Widget.Flag.IsDisposed);\n        this._disposed.emit(undefined);\n        // Remove or detach the widget if necessary.\n        if (this.parent) {\n            this.parent = null;\n        }\n        else if (this.isAttached) {\n            Widget.detach(this);\n        }\n        // Dispose of the widget layout.\n        if (this._layout) {\n            this._layout.dispose();\n            this._layout = null;\n        }\n        // Dispose the title\n        this.title.dispose();\n        // Clear the extra data associated with the widget.\n        _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal.clearData(this);\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.clearData(this);\n        _lumino_properties__WEBPACK_IMPORTED_MODULE_4__.AttachedProperty.clearData(this);\n    }\n    /**\n     * A signal emitted when the widget is disposed.\n     */\n    get disposed() {\n        return this._disposed;\n    }\n    /**\n     * Test whether the widget has been disposed.\n     */\n    get isDisposed() {\n        return this.testFlag(Widget.Flag.IsDisposed);\n    }\n    /**\n     * Test whether the widget's node is attached to the DOM.\n     */\n    get isAttached() {\n        return this.testFlag(Widget.Flag.IsAttached);\n    }\n    /**\n     * Test whether the widget is explicitly hidden.\n     */\n    get isHidden() {\n        return this.testFlag(Widget.Flag.IsHidden);\n    }\n    /**\n     * Test whether the widget is visible.\n     *\n     * #### Notes\n     * A widget is visible when it is attached to the DOM, is not\n     * explicitly hidden, and has no explicitly hidden ancestors.\n     */\n    get isVisible() {\n        return this.testFlag(Widget.Flag.IsVisible);\n    }\n    /**\n     * The title object for the widget.\n     *\n     * #### Notes\n     * The title object is used by some container widgets when displaying\n     * the widget alongside some title, such as a tab panel or side bar.\n     *\n     * Since not all widgets will use the title, it is created on demand.\n     *\n     * The `owner` property of the title is set to this widget.\n     */\n    get title() {\n        return Private$j.titleProperty.get(this);\n    }\n    /**\n     * Get the id of the widget's DOM node.\n     */\n    get id() {\n        return this.node.id;\n    }\n    /**\n     * Set the id of the widget's DOM node.\n     */\n    set id(value) {\n        this.node.id = value;\n    }\n    /**\n     * The dataset for the widget's DOM node.\n     */\n    get dataset() {\n        return this.node.dataset;\n    }\n    /**\n     * Get the method for hiding the widget.\n     */\n    get hiddenMode() {\n        return this._hiddenMode;\n    }\n    /**\n     * Set the method for hiding the widget.\n     */\n    set hiddenMode(value) {\n        if (this._hiddenMode === value) {\n            return;\n        }\n        if (this.isHidden) {\n            // Reset styles set by previous mode.\n            this._toggleHidden(false);\n        }\n        if (value == Widget.HiddenMode.Scale) {\n            this.node.style.willChange = 'transform';\n        }\n        else {\n            this.node.style.willChange = 'auto';\n        }\n        this._hiddenMode = value;\n        if (this.isHidden) {\n            // Set styles for new mode.\n            this._toggleHidden(true);\n        }\n    }\n    /**\n     * Get the parent of the widget.\n     */\n    get parent() {\n        return this._parent;\n    }\n    /**\n     * Set the parent of the widget.\n     *\n     * #### Notes\n     * Children are typically added to a widget by using a layout, which\n     * means user code will not normally set the parent widget directly.\n     *\n     * The widget will be automatically removed from its old parent.\n     *\n     * This is a no-op if there is no effective parent change.\n     */\n    set parent(value) {\n        if (this._parent === value) {\n            return;\n        }\n        if (value && this.contains(value)) {\n            throw new Error('Invalid parent widget.');\n        }\n        if (this._parent && !this._parent.isDisposed) {\n            let msg = new Widget.ChildMessage('child-removed', this);\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this._parent, msg);\n        }\n        this._parent = value;\n        if (this._parent && !this._parent.isDisposed) {\n            let msg = new Widget.ChildMessage('child-added', this);\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this._parent, msg);\n        }\n        if (!this.isDisposed) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this, Widget.Msg.ParentChanged);\n        }\n    }\n    /**\n     * Get the layout for the widget.\n     */\n    get layout() {\n        return this._layout;\n    }\n    /**\n     * Set the layout for the widget.\n     *\n     * #### Notes\n     * The layout is single-use only. It cannot be changed after the\n     * first assignment.\n     *\n     * The layout is disposed automatically when the widget is disposed.\n     */\n    set layout(value) {\n        if (this._layout === value) {\n            return;\n        }\n        if (this.testFlag(Widget.Flag.DisallowLayout)) {\n            throw new Error('Cannot set widget layout.');\n        }\n        if (this._layout) {\n            throw new Error('Cannot change widget layout.');\n        }\n        if (value.parent) {\n            throw new Error('Cannot change layout parent.');\n        }\n        this._layout = value;\n        value.parent = this;\n    }\n    /**\n     * Create an iterator over the widget's children.\n     *\n     * @returns A new iterator over the children of the widget.\n     *\n     * #### Notes\n     * The widget must have a populated layout in order to have children.\n     *\n     * If a layout is not installed, the returned iterator will be empty.\n     */\n    *children() {\n        if (this._layout) {\n            yield* this._layout;\n        }\n    }\n    /**\n     * Test whether a widget is a descendant of this widget.\n     *\n     * @param widget - The descendant widget of interest.\n     *\n     * @returns `true` if the widget is a descendant, `false` otherwise.\n     */\n    contains(widget) {\n        for (let value = widget; value; value = value._parent) {\n            if (value === this) {\n                return true;\n            }\n        }\n        return false;\n    }\n    /**\n     * Test whether the widget's DOM node has the given class name.\n     *\n     * @param name - The class name of interest.\n     *\n     * @returns `true` if the node has the class, `false` otherwise.\n     */\n    hasClass(name) {\n        return this.node.classList.contains(name);\n    }\n    /**\n     * Add a class name to the widget's DOM node.\n     *\n     * @param name - The class name to add to the node.\n     *\n     * #### Notes\n     * If the class name is already added to the node, this is a no-op.\n     *\n     * The class name must not contain whitespace.\n     */\n    addClass(name) {\n        this.node.classList.add(name);\n    }\n    /**\n     * Remove a class name from the widget's DOM node.\n     *\n     * @param name - The class name to remove from the node.\n     *\n     * #### Notes\n     * If the class name is not yet added to the node, this is a no-op.\n     *\n     * The class name must not contain whitespace.\n     */\n    removeClass(name) {\n        this.node.classList.remove(name);\n    }\n    /**\n     * Toggle a class name on the widget's DOM node.\n     *\n     * @param name - The class name to toggle on the node.\n     *\n     * @param force - Whether to force add the class (`true`) or force\n     *   remove the class (`false`). If not provided, the presence of\n     *   the class will be toggled from its current state.\n     *\n     * @returns `true` if the class is now present, `false` otherwise.\n     *\n     * #### Notes\n     * The class name must not contain whitespace.\n     */\n    toggleClass(name, force) {\n        if (force === true) {\n            this.node.classList.add(name);\n            return true;\n        }\n        if (force === false) {\n            this.node.classList.remove(name);\n            return false;\n        }\n        return this.node.classList.toggle(name);\n    }\n    /**\n     * Post an `'update-request'` message to the widget.\n     *\n     * #### Notes\n     * This is a simple convenience method for posting the message.\n     */\n    update() {\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.postMessage(this, Widget.Msg.UpdateRequest);\n    }\n    /**\n     * Post a `'fit-request'` message to the widget.\n     *\n     * #### Notes\n     * This is a simple convenience method for posting the message.\n     */\n    fit() {\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.postMessage(this, Widget.Msg.FitRequest);\n    }\n    /**\n     * Post an `'activate-request'` message to the widget.\n     *\n     * #### Notes\n     * This is a simple convenience method for posting the message.\n     */\n    activate() {\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.postMessage(this, Widget.Msg.ActivateRequest);\n    }\n    /**\n     * Send a `'close-request'` message to the widget.\n     *\n     * #### Notes\n     * This is a simple convenience method for sending the message.\n     */\n    close() {\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this, Widget.Msg.CloseRequest);\n    }\n    /**\n     * Show the widget and make it visible to its parent widget.\n     *\n     * #### Notes\n     * This causes the {@link isHidden} property to be `false`.\n     *\n     * If the widget is not explicitly hidden, this is a no-op.\n     */\n    show() {\n        if (!this.testFlag(Widget.Flag.IsHidden)) {\n            return;\n        }\n        if (this.isAttached && (!this.parent || this.parent.isVisible)) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this, Widget.Msg.BeforeShow);\n        }\n        this.clearFlag(Widget.Flag.IsHidden);\n        this._toggleHidden(false);\n        if (this.isAttached && (!this.parent || this.parent.isVisible)) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this, Widget.Msg.AfterShow);\n        }\n        if (this.parent) {\n            let msg = new Widget.ChildMessage('child-shown', this);\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.parent, msg);\n        }\n    }\n    /**\n     * Hide the widget and make it hidden to its parent widget.\n     *\n     * #### Notes\n     * This causes the {@link isHidden} property to be `true`.\n     *\n     * If the widget is explicitly hidden, this is a no-op.\n     */\n    hide() {\n        if (this.testFlag(Widget.Flag.IsHidden)) {\n            return;\n        }\n        if (this.isAttached && (!this.parent || this.parent.isVisible)) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this, Widget.Msg.BeforeHide);\n        }\n        this.setFlag(Widget.Flag.IsHidden);\n        this._toggleHidden(true);\n        if (this.isAttached && (!this.parent || this.parent.isVisible)) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this, Widget.Msg.AfterHide);\n        }\n        if (this.parent) {\n            let msg = new Widget.ChildMessage('child-hidden', this);\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.parent, msg);\n        }\n    }\n    /**\n     * Show or hide the widget according to a boolean value.\n     *\n     * @param hidden - `true` to hide the widget, or `false` to show it.\n     *\n     * #### Notes\n     * This is a convenience method for `hide()` and `show()`.\n     */\n    setHidden(hidden) {\n        if (hidden) {\n            this.hide();\n        }\n        else {\n            this.show();\n        }\n    }\n    /**\n     * Test whether the given widget flag is set.\n     *\n     * #### Notes\n     * This will not typically be called directly by user code.\n     */\n    testFlag(flag) {\n        return (this._flags & flag) !== 0;\n    }\n    /**\n     * Set the given widget flag.\n     *\n     * #### Notes\n     * This will not typically be called directly by user code.\n     */\n    setFlag(flag) {\n        this._flags |= flag;\n    }\n    /**\n     * Clear the given widget flag.\n     *\n     * #### Notes\n     * This will not typically be called directly by user code.\n     */\n    clearFlag(flag) {\n        this._flags &= ~flag;\n    }\n    /**\n     * Process a message sent to the widget.\n     *\n     * @param msg - The message sent to the widget.\n     *\n     * #### Notes\n     * Subclasses may reimplement this method as needed.\n     */\n    processMessage(msg) {\n        switch (msg.type) {\n            case 'resize':\n                this.notifyLayout(msg);\n                this.onResize(msg);\n                break;\n            case 'update-request':\n                this.notifyLayout(msg);\n                this.onUpdateRequest(msg);\n                break;\n            case 'fit-request':\n                this.notifyLayout(msg);\n                this.onFitRequest(msg);\n                break;\n            case 'before-show':\n                this.notifyLayout(msg);\n                this.onBeforeShow(msg);\n                break;\n            case 'after-show':\n                this.setFlag(Widget.Flag.IsVisible);\n                this.notifyLayout(msg);\n                this.onAfterShow(msg);\n                break;\n            case 'before-hide':\n                this.notifyLayout(msg);\n                this.onBeforeHide(msg);\n                break;\n            case 'after-hide':\n                this.clearFlag(Widget.Flag.IsVisible);\n                this.notifyLayout(msg);\n                this.onAfterHide(msg);\n                break;\n            case 'before-attach':\n                this.notifyLayout(msg);\n                this.onBeforeAttach(msg);\n                break;\n            case 'after-attach':\n                if (!this.isHidden && (!this.parent || this.parent.isVisible)) {\n                    this.setFlag(Widget.Flag.IsVisible);\n                }\n                this.setFlag(Widget.Flag.IsAttached);\n                this.notifyLayout(msg);\n                this.onAfterAttach(msg);\n                break;\n            case 'before-detach':\n                this.notifyLayout(msg);\n                this.onBeforeDetach(msg);\n                break;\n            case 'after-detach':\n                this.clearFlag(Widget.Flag.IsVisible);\n                this.clearFlag(Widget.Flag.IsAttached);\n                this.notifyLayout(msg);\n                this.onAfterDetach(msg);\n                break;\n            case 'activate-request':\n                this.notifyLayout(msg);\n                this.onActivateRequest(msg);\n                break;\n            case 'close-request':\n                this.notifyLayout(msg);\n                this.onCloseRequest(msg);\n                break;\n            case 'child-added':\n                this.notifyLayout(msg);\n                this.onChildAdded(msg);\n                break;\n            case 'child-removed':\n                this.notifyLayout(msg);\n                this.onChildRemoved(msg);\n                break;\n            default:\n                this.notifyLayout(msg);\n                break;\n        }\n    }\n    /**\n     * Invoke the message processing routine of the widget's layout.\n     *\n     * @param msg - The message to dispatch to the layout.\n     *\n     * #### Notes\n     * This is a no-op if the widget does not have a layout.\n     *\n     * This will not typically be called directly by user code.\n     */\n    notifyLayout(msg) {\n        if (this._layout) {\n            this._layout.processParentMessage(msg);\n        }\n    }\n    /**\n     * A message handler invoked on a `'close-request'` message.\n     *\n     * #### Notes\n     * The default implementation unparents or detaches the widget.\n     */\n    onCloseRequest(msg) {\n        if (this.parent) {\n            this.parent = null;\n        }\n        else if (this.isAttached) {\n            Widget.detach(this);\n        }\n    }\n    /**\n     * A message handler invoked on a `'resize'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onResize(msg) { }\n    /**\n     * A message handler invoked on an `'update-request'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onUpdateRequest(msg) { }\n    /**\n     * A message handler invoked on a `'fit-request'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onFitRequest(msg) { }\n    /**\n     * A message handler invoked on an `'activate-request'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onActivateRequest(msg) { }\n    /**\n     * A message handler invoked on a `'before-show'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onBeforeShow(msg) { }\n    /**\n     * A message handler invoked on an `'after-show'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onAfterShow(msg) { }\n    /**\n     * A message handler invoked on a `'before-hide'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onBeforeHide(msg) { }\n    /**\n     * A message handler invoked on an `'after-hide'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onAfterHide(msg) { }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onBeforeAttach(msg) { }\n    /**\n     * A message handler invoked on an `'after-attach'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onAfterAttach(msg) { }\n    /**\n     * A message handler invoked on a `'before-detach'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onBeforeDetach(msg) { }\n    /**\n     * A message handler invoked on an `'after-detach'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onAfterDetach(msg) { }\n    /**\n     * A message handler invoked on a `'child-added'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onChildAdded(msg) { }\n    /**\n     * A message handler invoked on a `'child-removed'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onChildRemoved(msg) { }\n    _toggleHidden(hidden) {\n        if (hidden) {\n            switch (this._hiddenMode) {\n                case Widget.HiddenMode.Display:\n                    this.addClass('lm-mod-hidden');\n                    break;\n                case Widget.HiddenMode.Scale:\n                    this.node.style.transform = 'scale(0)';\n                    this.node.setAttribute('aria-hidden', 'true');\n                    break;\n                case Widget.HiddenMode.ContentVisibility:\n                    // @ts-expect-error content-visibility unknown by DOM lib types\n                    this.node.style.contentVisibility = 'hidden';\n                    this.node.style.zIndex = '-1';\n                    break;\n            }\n        }\n        else {\n            switch (this._hiddenMode) {\n                case Widget.HiddenMode.Display:\n                    this.removeClass('lm-mod-hidden');\n                    break;\n                case Widget.HiddenMode.Scale:\n                    this.node.style.transform = '';\n                    this.node.removeAttribute('aria-hidden');\n                    break;\n                case Widget.HiddenMode.ContentVisibility:\n                    // @ts-expect-error content-visibility unknown by DOM lib types\n                    this.node.style.contentVisibility = '';\n                    this.node.style.zIndex = '';\n                    break;\n            }\n        }\n    }\n}\n/**\n * The namespace for the `Widget` class statics.\n */\n(function (Widget) {\n    (function (HiddenMode) {\n        /**\n         * Set a `lm-mod-hidden` CSS class to hide the widget using `display:none`\n         * CSS from the standard Lumino CSS.\n         */\n        HiddenMode[HiddenMode[\"Display\"] = 0] = \"Display\";\n        /**\n         * Hide the widget by setting the `transform` to `'scale(0)'`.\n         */\n        HiddenMode[HiddenMode[\"Scale\"] = 1] = \"Scale\";\n        /**\n         *Hide the widget by setting the `content-visibility` to `'hidden'`.\n         */\n        HiddenMode[HiddenMode[\"ContentVisibility\"] = 2] = \"ContentVisibility\";\n    })(Widget.HiddenMode || (Widget.HiddenMode = {}));\n    (function (Flag) {\n        /**\n         * The widget has been disposed.\n         */\n        Flag[Flag[\"IsDisposed\"] = 1] = \"IsDisposed\";\n        /**\n         * The widget is attached to the DOM.\n         */\n        Flag[Flag[\"IsAttached\"] = 2] = \"IsAttached\";\n        /**\n         * The widget is hidden.\n         */\n        Flag[Flag[\"IsHidden\"] = 4] = \"IsHidden\";\n        /**\n         * The widget is visible.\n         */\n        Flag[Flag[\"IsVisible\"] = 8] = \"IsVisible\";\n        /**\n         * A layout cannot be set on the widget.\n         */\n        Flag[Flag[\"DisallowLayout\"] = 16] = \"DisallowLayout\";\n    })(Widget.Flag || (Widget.Flag = {}));\n    (function (Msg) {\n        /**\n         * A singleton `'before-show'` message.\n         *\n         * #### Notes\n         * This message is sent to a widget before it becomes visible.\n         *\n         * This message is **not** sent when the widget is being attached.\n         */\n        Msg.BeforeShow = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.Message('before-show');\n        /**\n         * A singleton `'after-show'` message.\n         *\n         * #### Notes\n         * This message is sent to a widget after it becomes visible.\n         *\n         * This message is **not** sent when the widget is being attached.\n         */\n        Msg.AfterShow = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.Message('after-show');\n        /**\n         * A singleton `'before-hide'` message.\n         *\n         * #### Notes\n         * This message is sent to a widget before it becomes not-visible.\n         *\n         * This message is **not** sent when the widget is being detached.\n         */\n        Msg.BeforeHide = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.Message('before-hide');\n        /**\n         * A singleton `'after-hide'` message.\n         *\n         * #### Notes\n         * This message is sent to a widget after it becomes not-visible.\n         *\n         * This message is **not** sent when the widget is being detached.\n         */\n        Msg.AfterHide = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.Message('after-hide');\n        /**\n         * A singleton `'before-attach'` message.\n         *\n         * #### Notes\n         * This message is sent to a widget before it is attached.\n         */\n        Msg.BeforeAttach = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.Message('before-attach');\n        /**\n         * A singleton `'after-attach'` message.\n         *\n         * #### Notes\n         * This message is sent to a widget after it is attached.\n         */\n        Msg.AfterAttach = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.Message('after-attach');\n        /**\n         * A singleton `'before-detach'` message.\n         *\n         * #### Notes\n         * This message is sent to a widget before it is detached.\n         */\n        Msg.BeforeDetach = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.Message('before-detach');\n        /**\n         * A singleton `'after-detach'` message.\n         *\n         * #### Notes\n         * This message is sent to a widget after it is detached.\n         */\n        Msg.AfterDetach = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.Message('after-detach');\n        /**\n         * A singleton `'parent-changed'` message.\n         *\n         * #### Notes\n         * This message is sent to a widget when its parent has changed.\n         */\n        Msg.ParentChanged = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.Message('parent-changed');\n        /**\n         * A singleton conflatable `'update-request'` message.\n         *\n         * #### Notes\n         * This message can be dispatched to supporting widgets in order to\n         * update their content based on the current widget state. Not all\n         * widgets will respond to messages of this type.\n         *\n         * For widgets with a layout, this message will inform the layout to\n         * update the position and size of its child widgets.\n         */\n        Msg.UpdateRequest = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.ConflatableMessage('update-request');\n        /**\n         * A singleton conflatable `'fit-request'` message.\n         *\n         * #### Notes\n         * For widgets with a layout, this message will inform the layout to\n         * recalculate its size constraints to fit the space requirements of\n         * its child widgets, and to update their position and size. Not all\n         * layouts will respond to messages of this type.\n         */\n        Msg.FitRequest = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.ConflatableMessage('fit-request');\n        /**\n         * A singleton conflatable `'activate-request'` message.\n         *\n         * #### Notes\n         * This message should be dispatched to a widget when it should\n         * perform the actions necessary to activate the widget, which\n         * may include focusing its node or descendant node.\n         */\n        Msg.ActivateRequest = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.ConflatableMessage('activate-request');\n        /**\n         * A singleton conflatable `'close-request'` message.\n         *\n         * #### Notes\n         * This message should be dispatched to a widget when it should close\n         * and remove itself from the widget hierarchy.\n         */\n        Msg.CloseRequest = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.ConflatableMessage('close-request');\n    })(Widget.Msg || (Widget.Msg = {}));\n    /**\n     * A message class for child related messages.\n     */\n    class ChildMessage extends _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.Message {\n        /**\n         * Construct a new child message.\n         *\n         * @param type - The message type.\n         *\n         * @param child - The child widget for the message.\n         */\n        constructor(type, child) {\n            super(type);\n            this.child = child;\n        }\n    }\n    Widget.ChildMessage = ChildMessage;\n    /**\n     * A message class for `'resize'` messages.\n     */\n    class ResizeMessage extends _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.Message {\n        /**\n         * Construct a new resize message.\n         *\n         * @param width - The **offset width** of the widget, or `-1` if\n         *   the width is not known.\n         *\n         * @param height - The **offset height** of the widget, or `-1` if\n         *   the height is not known.\n         */\n        constructor(width, height) {\n            super('resize');\n            this.width = width;\n            this.height = height;\n        }\n    }\n    Widget.ResizeMessage = ResizeMessage;\n    /**\n     * The namespace for the `ResizeMessage` class statics.\n     */\n    (function (ResizeMessage) {\n        /**\n         * A singleton `'resize'` message with an unknown size.\n         */\n        ResizeMessage.UnknownSize = new ResizeMessage(-1, -1);\n    })(ResizeMessage = Widget.ResizeMessage || (Widget.ResizeMessage = {}));\n    /**\n     * Attach a widget to a host DOM node.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @param host - The DOM node to use as the widget's host.\n     *\n     * @param ref - The child of `host` to use as the reference element.\n     *   If this is provided, the widget will be inserted before this\n     *   node in the host. The default is `null`, which will cause the\n     *   widget to be added as the last child of the host.\n     *\n     * #### Notes\n     * This will throw an error if the widget is not a root widget, if\n     * the widget is already attached, or if the host is not attached\n     * to the DOM.\n     */\n    function attach(widget, host, ref = null) {\n        if (widget.parent) {\n            throw new Error('Cannot attach a child widget.');\n        }\n        if (widget.isAttached || widget.node.isConnected) {\n            throw new Error('Widget is already attached.');\n        }\n        if (!host.isConnected) {\n            throw new Error('Host is not attached.');\n        }\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeAttach);\n        host.insertBefore(widget.node, ref);\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterAttach);\n    }\n    Widget.attach = attach;\n    /**\n     * Detach the widget from its host DOM node.\n     *\n     * @param widget - The widget of interest.\n     *\n     * #### Notes\n     * This will throw an error if the widget is not a root widget,\n     * or if the widget is not attached to the DOM.\n     */\n    function detach(widget) {\n        if (widget.parent) {\n            throw new Error('Cannot detach a child widget.');\n        }\n        if (!widget.isAttached || !widget.node.isConnected) {\n            throw new Error('Widget is not attached.');\n        }\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeDetach);\n        widget.node.parentNode.removeChild(widget.node);\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterDetach);\n    }\n    Widget.detach = detach;\n})(Widget || (Widget = {}));\n/**\n * The namespace for the module implementation details.\n */\nvar Private$j;\n(function (Private) {\n    /**\n     * An attached property for the widget title object.\n     */\n    Private.titleProperty = new _lumino_properties__WEBPACK_IMPORTED_MODULE_4__.AttachedProperty({\n        name: 'title',\n        create: owner => new Title({ owner })\n    });\n    /**\n     * Create a DOM node for the given widget options.\n     */\n    function createNode(options) {\n        return options.node || document.createElement(options.tag || 'div');\n    }\n    Private.createNode = createNode;\n})(Private$j || (Private$j = {}));\n\n/**\n * An abstract base class for creating lumino layouts.\n *\n * #### Notes\n * A layout is used to add widgets to a parent and to arrange those\n * widgets within the parent's DOM node.\n *\n * This class implements the base functionality which is required of\n * nearly all layouts. It must be subclassed in order to be useful.\n *\n * Notably, this class does not define a uniform interface for adding\n * widgets to the layout. A subclass should define that API in a way\n * which is meaningful for its intended use.\n */\nclass Layout {\n    /**\n     * Construct a new layout.\n     *\n     * @param options - The options for initializing the layout.\n     */\n    constructor(options = {}) {\n        this._disposed = false;\n        this._parent = null;\n        this._fitPolicy = options.fitPolicy || 'set-min-size';\n    }\n    /**\n     * Dispose of the resources held by the layout.\n     *\n     * #### Notes\n     * This should be reimplemented to clear and dispose of the widgets.\n     *\n     * All reimplementations should call the superclass method.\n     *\n     * This method is called automatically when the parent is disposed.\n     */\n    dispose() {\n        this._parent = null;\n        this._disposed = true;\n        _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal.clearData(this);\n        _lumino_properties__WEBPACK_IMPORTED_MODULE_4__.AttachedProperty.clearData(this);\n    }\n    /**\n     * Test whether the layout is disposed.\n     */\n    get isDisposed() {\n        return this._disposed;\n    }\n    /**\n     * Get the parent widget of the layout.\n     */\n    get parent() {\n        return this._parent;\n    }\n    /**\n     * Set the parent widget of the layout.\n     *\n     * #### Notes\n     * This is set automatically when installing the layout on the parent\n     * widget. The parent widget should not be set directly by user code.\n     */\n    set parent(value) {\n        if (this._parent === value) {\n            return;\n        }\n        if (this._parent) {\n            throw new Error('Cannot change parent widget.');\n        }\n        if (value.layout !== this) {\n            throw new Error('Invalid parent widget.');\n        }\n        this._parent = value;\n        this.init();\n    }\n    /**\n     * Get the fit policy for the layout.\n     *\n     * #### Notes\n     * The fit policy controls the computed size constraints which are\n     * applied to the parent widget by the layout.\n     *\n     * Some layout implementations may ignore the fit policy.\n     */\n    get fitPolicy() {\n        return this._fitPolicy;\n    }\n    /**\n     * Set the fit policy for the layout.\n     *\n     * #### Notes\n     * The fit policy controls the computed size constraints which are\n     * applied to the parent widget by the layout.\n     *\n     * Some layout implementations may ignore the fit policy.\n     *\n     * Changing the fit policy will clear the current size constraint\n     * for the parent widget and then re-fit the parent.\n     */\n    set fitPolicy(value) {\n        // Bail if the policy does not change\n        if (this._fitPolicy === value) {\n            return;\n        }\n        // Update the internal policy.\n        this._fitPolicy = value;\n        // Clear the size constraints and schedule a fit of the parent.\n        if (this._parent) {\n            let style = this._parent.node.style;\n            style.minWidth = '';\n            style.minHeight = '';\n            style.maxWidth = '';\n            style.maxHeight = '';\n            this._parent.fit();\n        }\n    }\n    /**\n     * Process a message sent to the parent widget.\n     *\n     * @param msg - The message sent to the parent widget.\n     *\n     * #### Notes\n     * This method is called by the parent widget to process a message.\n     *\n     * Subclasses may reimplement this method as needed.\n     */\n    processParentMessage(msg) {\n        switch (msg.type) {\n            case 'resize':\n                this.onResize(msg);\n                break;\n            case 'update-request':\n                this.onUpdateRequest(msg);\n                break;\n            case 'fit-request':\n                this.onFitRequest(msg);\n                break;\n            case 'before-show':\n                this.onBeforeShow(msg);\n                break;\n            case 'after-show':\n                this.onAfterShow(msg);\n                break;\n            case 'before-hide':\n                this.onBeforeHide(msg);\n                break;\n            case 'after-hide':\n                this.onAfterHide(msg);\n                break;\n            case 'before-attach':\n                this.onBeforeAttach(msg);\n                break;\n            case 'after-attach':\n                this.onAfterAttach(msg);\n                break;\n            case 'before-detach':\n                this.onBeforeDetach(msg);\n                break;\n            case 'after-detach':\n                this.onAfterDetach(msg);\n                break;\n            case 'child-removed':\n                this.onChildRemoved(msg);\n                break;\n            case 'child-shown':\n                this.onChildShown(msg);\n                break;\n            case 'child-hidden':\n                this.onChildHidden(msg);\n                break;\n        }\n    }\n    /**\n     * Perform layout initialization which requires the parent widget.\n     *\n     * #### Notes\n     * This method is invoked immediately after the layout is installed\n     * on the parent widget.\n     *\n     * The default implementation reparents all of the widgets to the\n     * layout parent widget.\n     *\n     * Subclasses should reimplement this method and attach the child\n     * widget nodes to the parent widget's node.\n     */\n    init() {\n        for (const widget of this) {\n            widget.parent = this.parent;\n        }\n    }\n    /**\n     * A message handler invoked on a `'resize'` message.\n     *\n     * #### Notes\n     * The layout should ensure that its widgets are resized according\n     * to the specified layout space, and that they are sent a `'resize'`\n     * message if appropriate.\n     *\n     * The default implementation of this method sends an `UnknownSize`\n     * resize message to all widgets.\n     *\n     * This may be reimplemented by subclasses as needed.\n     */\n    onResize(msg) {\n        for (const widget of this) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.ResizeMessage.UnknownSize);\n        }\n    }\n    /**\n     * A message handler invoked on an `'update-request'` message.\n     *\n     * #### Notes\n     * The layout should ensure that its widgets are resized according\n     * to the available layout space, and that they are sent a `'resize'`\n     * message if appropriate.\n     *\n     * The default implementation of this method sends an `UnknownSize`\n     * resize message to all widgets.\n     *\n     * This may be reimplemented by subclasses as needed.\n     */\n    onUpdateRequest(msg) {\n        for (const widget of this) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.ResizeMessage.UnknownSize);\n        }\n    }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     *\n     * #### Notes\n     * The default implementation of this method forwards the message\n     * to all widgets. It assumes all widget nodes are attached to the\n     * parent widget node.\n     *\n     * This may be reimplemented by subclasses as needed.\n     */\n    onBeforeAttach(msg) {\n        for (const widget of this) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, msg);\n        }\n    }\n    /**\n     * A message handler invoked on an `'after-attach'` message.\n     *\n     * #### Notes\n     * The default implementation of this method forwards the message\n     * to all widgets. It assumes all widget nodes are attached to the\n     * parent widget node.\n     *\n     * This may be reimplemented by subclasses as needed.\n     */\n    onAfterAttach(msg) {\n        for (const widget of this) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, msg);\n        }\n    }\n    /**\n     * A message handler invoked on a `'before-detach'` message.\n     *\n     * #### Notes\n     * The default implementation of this method forwards the message\n     * to all widgets. It assumes all widget nodes are attached to the\n     * parent widget node.\n     *\n     * This may be reimplemented by subclasses as needed.\n     */\n    onBeforeDetach(msg) {\n        for (const widget of this) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, msg);\n        }\n    }\n    /**\n     * A message handler invoked on an `'after-detach'` message.\n     *\n     * #### Notes\n     * The default implementation of this method forwards the message\n     * to all widgets. It assumes all widget nodes are attached to the\n     * parent widget node.\n     *\n     * This may be reimplemented by subclasses as needed.\n     */\n    onAfterDetach(msg) {\n        for (const widget of this) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, msg);\n        }\n    }\n    /**\n     * A message handler invoked on a `'before-show'` message.\n     *\n     * #### Notes\n     * The default implementation of this method forwards the message to\n     * all non-hidden widgets. It assumes all widget nodes are attached\n     * to the parent widget node.\n     *\n     * This may be reimplemented by subclasses as needed.\n     */\n    onBeforeShow(msg) {\n        for (const widget of this) {\n            if (!widget.isHidden) {\n                _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, msg);\n            }\n        }\n    }\n    /**\n     * A message handler invoked on an `'after-show'` message.\n     *\n     * #### Notes\n     * The default implementation of this method forwards the message to\n     * all non-hidden widgets. It assumes all widget nodes are attached\n     * to the parent widget node.\n     *\n     * This may be reimplemented by subclasses as needed.\n     */\n    onAfterShow(msg) {\n        for (const widget of this) {\n            if (!widget.isHidden) {\n                _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, msg);\n            }\n        }\n    }\n    /**\n     * A message handler invoked on a `'before-hide'` message.\n     *\n     * #### Notes\n     * The default implementation of this method forwards the message to\n     * all non-hidden widgets. It assumes all widget nodes are attached\n     * to the parent widget node.\n     *\n     * This may be reimplemented by subclasses as needed.\n     */\n    onBeforeHide(msg) {\n        for (const widget of this) {\n            if (!widget.isHidden) {\n                _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, msg);\n            }\n        }\n    }\n    /**\n     * A message handler invoked on an `'after-hide'` message.\n     *\n     * #### Notes\n     * The default implementation of this method forwards the message to\n     * all non-hidden widgets. It assumes all widget nodes are attached\n     * to the parent widget node.\n     *\n     * This may be reimplemented by subclasses as needed.\n     */\n    onAfterHide(msg) {\n        for (const widget of this) {\n            if (!widget.isHidden) {\n                _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, msg);\n            }\n        }\n    }\n    /**\n     * A message handler invoked on a `'child-removed'` message.\n     *\n     * #### Notes\n     * This will remove the child widget from the layout.\n     *\n     * Subclasses should **not** typically reimplement this method.\n     */\n    onChildRemoved(msg) {\n        this.removeWidget(msg.child);\n    }\n    /**\n     * A message handler invoked on a `'fit-request'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onFitRequest(msg) { }\n    /**\n     * A message handler invoked on a `'child-shown'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onChildShown(msg) { }\n    /**\n     * A message handler invoked on a `'child-hidden'` message.\n     *\n     * #### Notes\n     * The default implementation of this handler is a no-op.\n     */\n    onChildHidden(msg) { }\n}\n/**\n * The namespace for the `Layout` class statics.\n */\n(function (Layout) {\n    /**\n     * Get the horizontal alignment for a widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @returns The horizontal alignment for the widget.\n     *\n     * #### Notes\n     * If the layout width allocated to a widget is larger than its max\n     * width, the horizontal alignment controls how the widget is placed\n     * within the extra horizontal space.\n     *\n     * If the allocated width is less than the widget's max width, the\n     * horizontal alignment has no effect.\n     *\n     * Some layout implementations may ignore horizontal alignment.\n     */\n    function getHorizontalAlignment(widget) {\n        return Private$i.horizontalAlignmentProperty.get(widget);\n    }\n    Layout.getHorizontalAlignment = getHorizontalAlignment;\n    /**\n     * Set the horizontal alignment for a widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @param value - The value for the horizontal alignment.\n     *\n     * #### Notes\n     * If the layout width allocated to a widget is larger than its max\n     * width, the horizontal alignment controls how the widget is placed\n     * within the extra horizontal space.\n     *\n     * If the allocated width is less than the widget's max width, the\n     * horizontal alignment has no effect.\n     *\n     * Some layout implementations may ignore horizontal alignment.\n     *\n     * Changing the horizontal alignment will post an `update-request`\n     * message to widget's parent, provided the parent has a layout\n     * installed.\n     */\n    function setHorizontalAlignment(widget, value) {\n        Private$i.horizontalAlignmentProperty.set(widget, value);\n    }\n    Layout.setHorizontalAlignment = setHorizontalAlignment;\n    /**\n     * Get the vertical alignment for a widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @returns The vertical alignment for the widget.\n     *\n     * #### Notes\n     * If the layout height allocated to a widget is larger than its max\n     * height, the vertical alignment controls how the widget is placed\n     * within the extra vertical space.\n     *\n     * If the allocated height is less than the widget's max height, the\n     * vertical alignment has no effect.\n     *\n     * Some layout implementations may ignore vertical alignment.\n     */\n    function getVerticalAlignment(widget) {\n        return Private$i.verticalAlignmentProperty.get(widget);\n    }\n    Layout.getVerticalAlignment = getVerticalAlignment;\n    /**\n     * Set the vertical alignment for a widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @param value - The value for the vertical alignment.\n     *\n     * #### Notes\n     * If the layout height allocated to a widget is larger than its max\n     * height, the vertical alignment controls how the widget is placed\n     * within the extra vertical space.\n     *\n     * If the allocated height is less than the widget's max height, the\n     * vertical alignment has no effect.\n     *\n     * Some layout implementations may ignore vertical alignment.\n     *\n     * Changing the horizontal alignment will post an `update-request`\n     * message to widget's parent, provided the parent has a layout\n     * installed.\n     */\n    function setVerticalAlignment(widget, value) {\n        Private$i.verticalAlignmentProperty.set(widget, value);\n    }\n    Layout.setVerticalAlignment = setVerticalAlignment;\n})(Layout || (Layout = {}));\n/**\n * An object which assists in the absolute layout of widgets.\n *\n * #### Notes\n * This class is useful when implementing a layout which arranges its\n * widgets using absolute positioning.\n *\n * This class is used by nearly all of the built-in lumino layouts.\n */\nclass LayoutItem {\n    /**\n     * Construct a new layout item.\n     *\n     * @param widget - The widget to be managed by the item.\n     *\n     * #### Notes\n     * The widget will be set to absolute positioning.\n     * The widget will use strict CSS containment.\n     */\n    constructor(widget) {\n        this._top = NaN;\n        this._left = NaN;\n        this._width = NaN;\n        this._height = NaN;\n        this._minWidth = 0;\n        this._minHeight = 0;\n        this._maxWidth = Infinity;\n        this._maxHeight = Infinity;\n        this._disposed = false;\n        this.widget = widget;\n        this.widget.node.style.position = 'absolute';\n        this.widget.node.style.contain = 'strict';\n    }\n    /**\n     * Dispose of the the layout item.\n     *\n     * #### Notes\n     * This will reset the positioning of the widget.\n     */\n    dispose() {\n        // Do nothing if the item is already disposed.\n        if (this._disposed) {\n            return;\n        }\n        // Mark the item as disposed.\n        this._disposed = true;\n        // Reset the widget style.\n        let style = this.widget.node.style;\n        style.position = '';\n        style.top = '';\n        style.left = '';\n        style.width = '';\n        style.height = '';\n        style.contain = '';\n    }\n    /**\n     * The computed minimum width of the widget.\n     *\n     * #### Notes\n     * This value can be updated by calling the `fit` method.\n     */\n    get minWidth() {\n        return this._minWidth;\n    }\n    /**\n     * The computed minimum height of the widget.\n     *\n     * #### Notes\n     * This value can be updated by calling the `fit` method.\n     */\n    get minHeight() {\n        return this._minHeight;\n    }\n    /**\n     * The computed maximum width of the widget.\n     *\n     * #### Notes\n     * This value can be updated by calling the `fit` method.\n     */\n    get maxWidth() {\n        return this._maxWidth;\n    }\n    /**\n     * The computed maximum height of the widget.\n     *\n     * #### Notes\n     * This value can be updated by calling the `fit` method.\n     */\n    get maxHeight() {\n        return this._maxHeight;\n    }\n    /**\n     * Whether the layout item is disposed.\n     */\n    get isDisposed() {\n        return this._disposed;\n    }\n    /**\n     * Whether the managed widget is hidden.\n     */\n    get isHidden() {\n        return this.widget.isHidden;\n    }\n    /**\n     * Whether the managed widget is visible.\n     */\n    get isVisible() {\n        return this.widget.isVisible;\n    }\n    /**\n     * Whether the managed widget is attached.\n     */\n    get isAttached() {\n        return this.widget.isAttached;\n    }\n    /**\n     * Update the computed size limits of the managed widget.\n     */\n    fit() {\n        let limits = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.sizeLimits(this.widget.node);\n        this._minWidth = limits.minWidth;\n        this._minHeight = limits.minHeight;\n        this._maxWidth = limits.maxWidth;\n        this._maxHeight = limits.maxHeight;\n    }\n    /**\n     * Update the position and size of the managed widget.\n     *\n     * @param left - The left edge position of the layout box.\n     *\n     * @param top - The top edge position of the layout box.\n     *\n     * @param width - The width of the layout box.\n     *\n     * @param height - The height of the layout box.\n     */\n    update(left, top, width, height) {\n        // Clamp the size to the computed size limits.\n        let clampW = Math.max(this._minWidth, Math.min(width, this._maxWidth));\n        let clampH = Math.max(this._minHeight, Math.min(height, this._maxHeight));\n        // Adjust the left edge for the horizontal alignment, if needed.\n        if (clampW < width) {\n            switch (Layout.getHorizontalAlignment(this.widget)) {\n                case 'left':\n                    break;\n                case 'center':\n                    left += (width - clampW) / 2;\n                    break;\n                case 'right':\n                    left += width - clampW;\n                    break;\n                default:\n                    throw 'unreachable';\n            }\n        }\n        // Adjust the top edge for the vertical alignment, if needed.\n        if (clampH < height) {\n            switch (Layout.getVerticalAlignment(this.widget)) {\n                case 'top':\n                    break;\n                case 'center':\n                    top += (height - clampH) / 2;\n                    break;\n                case 'bottom':\n                    top += height - clampH;\n                    break;\n                default:\n                    throw 'unreachable';\n            }\n        }\n        // Set up the resize variables.\n        let resized = false;\n        let style = this.widget.node.style;\n        // Update the top edge of the widget if needed.\n        if (this._top !== top) {\n            this._top = top;\n            style.top = `${top}px`;\n        }\n        // Update the left edge of the widget if needed.\n        if (this._left !== left) {\n            this._left = left;\n            style.left = `${left}px`;\n        }\n        // Update the width of the widget if needed.\n        if (this._width !== clampW) {\n            resized = true;\n            this._width = clampW;\n            style.width = `${clampW}px`;\n        }\n        // Update the height of the widget if needed.\n        if (this._height !== clampH) {\n            resized = true;\n            this._height = clampH;\n            style.height = `${clampH}px`;\n        }\n        // Send a resize message to the widget if needed.\n        if (resized) {\n            let msg = new Widget.ResizeMessage(clampW, clampH);\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.widget, msg);\n        }\n    }\n}\n/**\n * The namespace for the module implementation details.\n */\nvar Private$i;\n(function (Private) {\n    /**\n     * The attached property for a widget horizontal alignment.\n     */\n    Private.horizontalAlignmentProperty = new _lumino_properties__WEBPACK_IMPORTED_MODULE_4__.AttachedProperty({\n        name: 'horizontalAlignment',\n        create: () => 'center',\n        changed: onAlignmentChanged\n    });\n    /**\n     * The attached property for a widget vertical alignment.\n     */\n    Private.verticalAlignmentProperty = new _lumino_properties__WEBPACK_IMPORTED_MODULE_4__.AttachedProperty({\n        name: 'verticalAlignment',\n        create: () => 'top',\n        changed: onAlignmentChanged\n    });\n    /**\n     * The change handler for the attached alignment properties.\n     */\n    function onAlignmentChanged(child) {\n        if (child.parent && child.parent.layout) {\n            child.parent.update();\n        }\n    }\n})(Private$i || (Private$i = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A concrete layout implementation suitable for many use cases.\n *\n * #### Notes\n * This class is suitable as a base class for implementing a variety of\n * layouts, but can also be used directly with standard CSS to layout a\n * collection of widgets.\n */\nclass PanelLayout extends Layout {\n    constructor() {\n        super(...arguments);\n        this._widgets = [];\n    }\n    /**\n     * Dispose of the resources held by the layout.\n     *\n     * #### Notes\n     * This will clear and dispose all widgets in the layout.\n     *\n     * All reimplementations should call the superclass method.\n     *\n     * This method is called automatically when the parent is disposed.\n     */\n    dispose() {\n        while (this._widgets.length > 0) {\n            this._widgets.pop().dispose();\n        }\n        super.dispose();\n    }\n    /**\n     * A read-only array of the widgets in the layout.\n     */\n    get widgets() {\n        return this._widgets;\n    }\n    /**\n     * Create an iterator over the widgets in the layout.\n     *\n     * @returns A new iterator over the widgets in the layout.\n     */\n    *[Symbol.iterator]() {\n        yield* this._widgets;\n    }\n    /**\n     * Add a widget to the end of the layout.\n     *\n     * @param widget - The widget to add to the layout.\n     *\n     * #### Notes\n     * If the widget is already contained in the layout, it will be moved.\n     */\n    addWidget(widget) {\n        this.insertWidget(this._widgets.length, widget);\n    }\n    /**\n     * Insert a widget into the layout at the specified index.\n     *\n     * @param index - The index at which to insert the widget.\n     *\n     * @param widget - The widget to insert into the layout.\n     *\n     * #### Notes\n     * The index will be clamped to the bounds of the widgets.\n     *\n     * If the widget is already added to the layout, it will be moved.\n     *\n     * #### Undefined Behavior\n     * An `index` which is non-integral.\n     */\n    insertWidget(index, widget) {\n        // Remove the widget from its current parent. This is a no-op\n        // if the widget's parent is already the layout parent widget.\n        widget.parent = this.parent;\n        // Look up the current index of the widget.\n        let i = this._widgets.indexOf(widget);\n        // Clamp the insert index to the array bounds.\n        let j = Math.max(0, Math.min(index, this._widgets.length));\n        // If the widget is not in the array, insert it.\n        if (i === -1) {\n            // Insert the widget into the array.\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(this._widgets, j, widget);\n            // If the layout is parented, attach the widget to the DOM.\n            if (this.parent) {\n                this.attachWidget(j, widget);\n            }\n            // There is nothing more to do.\n            return;\n        }\n        // Otherwise, the widget exists in the array and should be moved.\n        // Adjust the index if the location is at the end of the array.\n        if (j === this._widgets.length) {\n            j--;\n        }\n        // Bail if there is no effective move.\n        if (i === j) {\n            return;\n        }\n        // Move the widget to the new location.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.move(this._widgets, i, j);\n        // If the layout is parented, move the widget in the DOM.\n        if (this.parent) {\n            this.moveWidget(i, j, widget);\n        }\n    }\n    /**\n     * Remove a widget from the layout.\n     *\n     * @param widget - The widget to remove from the layout.\n     *\n     * #### Notes\n     * A widget is automatically removed from the layout when its `parent`\n     * is set to `null`. This method should only be invoked directly when\n     * removing a widget from a layout which has yet to be installed on a\n     * parent widget.\n     *\n     * This method does *not* modify the widget's `parent`.\n     */\n    removeWidget(widget) {\n        this.removeWidgetAt(this._widgets.indexOf(widget));\n    }\n    /**\n     * Remove the widget at a given index from the layout.\n     *\n     * @param index - The index of the widget to remove.\n     *\n     * #### Notes\n     * A widget is automatically removed from the layout when its `parent`\n     * is set to `null`. This method should only be invoked directly when\n     * removing a widget from a layout which has yet to be installed on a\n     * parent widget.\n     *\n     * This method does *not* modify the widget's `parent`.\n     *\n     * #### Undefined Behavior\n     * An `index` which is non-integral.\n     */\n    removeWidgetAt(index) {\n        // Remove the widget from the array.\n        let widget = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(this._widgets, index);\n        // If the layout is parented, detach the widget from the DOM.\n        if (widget && this.parent) {\n            this.detachWidget(index, widget);\n        }\n    }\n    /**\n     * Perform layout initialization which requires the parent widget.\n     */\n    init() {\n        super.init();\n        let index = 0;\n        for (const widget of this) {\n            this.attachWidget(index++, widget);\n        }\n    }\n    /**\n     * Attach a widget to the parent's DOM node.\n     *\n     * @param index - The current index of the widget in the layout.\n     *\n     * @param widget - The widget to attach to the parent.\n     *\n     * #### Notes\n     * This method is called automatically by the panel layout at the\n     * appropriate time. It should not be called directly by user code.\n     *\n     * The default implementation adds the widgets's node to the parent's\n     * node at the proper location, and sends the appropriate attach\n     * messages to the widget if the parent is attached to the DOM.\n     *\n     * Subclasses may reimplement this method to control how the widget's\n     * node is added to the parent's node.\n     */\n    attachWidget(index, widget) {\n        // Look up the next sibling reference node.\n        let ref = this.parent.node.children[index];\n        // Send a `'before-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeAttach);\n        }\n        // Insert the widget's node before the sibling.\n        this.parent.node.insertBefore(widget.node, ref);\n        // Send an `'after-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterAttach);\n        }\n    }\n    /**\n     * Move a widget in the parent's DOM node.\n     *\n     * @param fromIndex - The previous index of the widget in the layout.\n     *\n     * @param toIndex - The current index of the widget in the layout.\n     *\n     * @param widget - The widget to move in the parent.\n     *\n     * #### Notes\n     * This method is called automatically by the panel layout at the\n     * appropriate time. It should not be called directly by user code.\n     *\n     * The default implementation moves the widget's node to the proper\n     * location in the parent's node and sends the appropriate attach and\n     * detach messages to the widget if the parent is attached to the DOM.\n     *\n     * Subclasses may reimplement this method to control how the widget's\n     * node is moved in the parent's node.\n     */\n    moveWidget(fromIndex, toIndex, widget) {\n        // Send a `'before-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeDetach);\n        }\n        // Remove the widget's node from the parent.\n        this.parent.node.removeChild(widget.node);\n        // Send an `'after-detach'` and  message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterDetach);\n        }\n        // Look up the next sibling reference node.\n        let ref = this.parent.node.children[toIndex];\n        // Send a `'before-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeAttach);\n        }\n        // Insert the widget's node before the sibling.\n        this.parent.node.insertBefore(widget.node, ref);\n        // Send an `'after-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterAttach);\n        }\n    }\n    /**\n     * Detach a widget from the parent's DOM node.\n     *\n     * @param index - The previous index of the widget in the layout.\n     *\n     * @param widget - The widget to detach from the parent.\n     *\n     * #### Notes\n     * This method is called automatically by the panel layout at the\n     * appropriate time. It should not be called directly by user code.\n     *\n     * The default implementation removes the widget's node from the\n     * parent's node, and sends the appropriate detach messages to the\n     * widget if the parent is attached to the DOM.\n     *\n     * Subclasses may reimplement this method to control how the widget's\n     * node is removed from the parent's node.\n     */\n    detachWidget(index, widget) {\n        // Send a `'before-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeDetach);\n        }\n        // Remove the widget's node from the parent.\n        this.parent.node.removeChild(widget.node);\n        // Send an `'after-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterDetach);\n        }\n    }\n}\n\n/*\n * Copyright (c) Jupyter Development Team.\n * Distributed under the terms of the Modified BSD License.\n */\nvar Utils;\n(function (Utils) {\n    /**\n     * Clamp a dimension value to an integer >= 0.\n     */\n    function clampDimension(value) {\n        return Math.max(0, Math.floor(value));\n    }\n    Utils.clampDimension = clampDimension;\n})(Utils || (Utils = {}));\nvar Utils$1 = Utils;\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A layout which arranges its widgets into resizable sections.\n */\nclass SplitLayout extends PanelLayout {\n    /**\n     * Construct a new split layout.\n     *\n     * @param options - The options for initializing the layout.\n     */\n    constructor(options) {\n        super();\n        this.widgetOffset = 0;\n        this._fixed = 0;\n        this._spacing = 4;\n        this._dirty = false;\n        this._hasNormedSizes = false;\n        this._sizers = [];\n        this._items = [];\n        this._handles = [];\n        this._box = null;\n        this._alignment = 'start';\n        this._orientation = 'horizontal';\n        this.renderer = options.renderer;\n        if (options.orientation !== undefined) {\n            this._orientation = options.orientation;\n        }\n        if (options.alignment !== undefined) {\n            this._alignment = options.alignment;\n        }\n        if (options.spacing !== undefined) {\n            this._spacing = Utils.clampDimension(options.spacing);\n        }\n    }\n    /**\n     * Dispose of the resources held by the layout.\n     */\n    dispose() {\n        // Dispose of the layout items.\n        for (const item of this._items) {\n            item.dispose();\n        }\n        // Clear the layout state.\n        this._box = null;\n        this._items.length = 0;\n        this._sizers.length = 0;\n        this._handles.length = 0;\n        // Dispose of the rest of the layout.\n        super.dispose();\n    }\n    /**\n     * Get the layout orientation for the split layout.\n     */\n    get orientation() {\n        return this._orientation;\n    }\n    /**\n     * Set the layout orientation for the split layout.\n     */\n    set orientation(value) {\n        if (this._orientation === value) {\n            return;\n        }\n        this._orientation = value;\n        if (!this.parent) {\n            return;\n        }\n        this.parent.dataset['orientation'] = value;\n        this.parent.fit();\n    }\n    /**\n     * Get the content alignment for the split layout.\n     *\n     * #### Notes\n     * This is the alignment of the widgets in the layout direction.\n     *\n     * The alignment has no effect if the widgets can expand  to fill the\n     * entire split layout.\n     */\n    get alignment() {\n        return this._alignment;\n    }\n    /**\n     * Set the content alignment for the split layout.\n     *\n     * #### Notes\n     * This is the alignment of the widgets in the layout direction.\n     *\n     * The alignment has no effect if the widgets can expand  to fill the\n     * entire split layout.\n     */\n    set alignment(value) {\n        if (this._alignment === value) {\n            return;\n        }\n        this._alignment = value;\n        if (!this.parent) {\n            return;\n        }\n        this.parent.dataset['alignment'] = value;\n        this.parent.update();\n    }\n    /**\n     * Get the inter-element spacing for the split layout.\n     */\n    get spacing() {\n        return this._spacing;\n    }\n    /**\n     * Set the inter-element spacing for the split layout.\n     */\n    set spacing(value) {\n        value = Utils.clampDimension(value);\n        if (this._spacing === value) {\n            return;\n        }\n        this._spacing = value;\n        if (!this.parent) {\n            return;\n        }\n        this.parent.fit();\n    }\n    /**\n     * A read-only array of the split handles in the layout.\n     */\n    get handles() {\n        return this._handles;\n    }\n    /**\n     * Get the absolute sizes of the widgets in the layout.\n     *\n     * @returns A new array of the absolute sizes of the widgets.\n     *\n     * This method **does not** measure the DOM nodes.\n     */\n    absoluteSizes() {\n        return this._sizers.map(sizer => sizer.size);\n    }\n    /**\n     * Get the relative sizes of the widgets in the layout.\n     *\n     * @returns A new array of the relative sizes of the widgets.\n     *\n     * #### Notes\n     * The returned sizes reflect the sizes of the widgets normalized\n     * relative to their siblings.\n     *\n     * This method **does not** measure the DOM nodes.\n     */\n    relativeSizes() {\n        return Private$h.normalize(this._sizers.map(sizer => sizer.size));\n    }\n    /**\n     * Set the relative sizes for the widgets in the layout.\n     *\n     * @param sizes - The relative sizes for the widgets in the panel.\n     * @param update - Update the layout after setting relative sizes.\n     * Default is True.\n     *\n     * #### Notes\n     * Extra values are ignored, too few will yield an undefined layout.\n     *\n     * The actual geometry of the DOM nodes is updated asynchronously.\n     */\n    setRelativeSizes(sizes, update = true) {\n        // Copy the sizes and pad with zeros as needed.\n        let n = this._sizers.length;\n        let temp = sizes.slice(0, n);\n        while (temp.length < n) {\n            temp.push(0);\n        }\n        // Normalize the padded sizes.\n        let normed = Private$h.normalize(temp);\n        // Apply the normalized sizes to the sizers.\n        for (let i = 0; i < n; ++i) {\n            let sizer = this._sizers[i];\n            sizer.sizeHint = normed[i];\n            sizer.size = normed[i];\n        }\n        // Set the flag indicating the sizes are normalized.\n        this._hasNormedSizes = true;\n        // Trigger an update of the parent widget.\n        if (update && this.parent) {\n            this.parent.update();\n        }\n    }\n    /**\n     * Move the offset position of a split handle.\n     *\n     * @param index - The index of the handle of the interest.\n     *\n     * @param position - The desired offset position of the handle.\n     *\n     * #### Notes\n     * The position is relative to the offset parent.\n     *\n     * This will move the handle as close as possible to the desired\n     * position. The sibling widgets will be adjusted as necessary.\n     */\n    moveHandle(index, position) {\n        // Bail if the index is invalid or the handle is hidden.\n        let handle = this._handles[index];\n        if (!handle || handle.classList.contains('lm-mod-hidden')) {\n            return;\n        }\n        // Compute the desired delta movement for the handle.\n        let delta;\n        if (this._orientation === 'horizontal') {\n            delta = position - handle.offsetLeft;\n        }\n        else {\n            delta = position - handle.offsetTop;\n        }\n        // Bail if there is no handle movement.\n        if (delta === 0) {\n            return;\n        }\n        // Prevent widget resizing unless needed.\n        for (let sizer of this._sizers) {\n            if (sizer.size > 0) {\n                sizer.sizeHint = sizer.size;\n            }\n        }\n        // Adjust the sizers to reflect the handle movement.\n        BoxEngine.adjust(this._sizers, index, delta);\n        // Update the layout of the widgets.\n        if (this.parent) {\n            this.parent.update();\n        }\n    }\n    /**\n     * Perform layout initialization which requires the parent widget.\n     */\n    init() {\n        this.parent.dataset['orientation'] = this.orientation;\n        this.parent.dataset['alignment'] = this.alignment;\n        super.init();\n    }\n    /**\n     * Attach a widget to the parent's DOM node.\n     *\n     * @param index - The current index of the widget in the layout.\n     *\n     * @param widget - The widget to attach to the parent.\n     *\n     * #### Notes\n     * This is a reimplementation of the superclass method.\n     */\n    attachWidget(index, widget) {\n        // Create the item, handle, and sizer for the new widget.\n        let item = new LayoutItem(widget);\n        let handle = Private$h.createHandle(this.renderer);\n        let average = Private$h.averageSize(this._sizers);\n        let sizer = Private$h.createSizer(average);\n        // Insert the item, handle, and sizer into the internal arrays.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(this._items, index, item);\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(this._sizers, index, sizer);\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(this._handles, index, handle);\n        // Send a `'before-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeAttach);\n        }\n        // Add the widget and handle nodes to the parent.\n        this.parent.node.appendChild(widget.node);\n        this.parent.node.appendChild(handle);\n        // Send an `'after-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterAttach);\n        }\n        // Post a fit request for the parent widget.\n        this.parent.fit();\n    }\n    /**\n     * Move a widget in the parent's DOM node.\n     *\n     * @param fromIndex - The previous index of the widget in the layout.\n     *\n     * @param toIndex - The current index of the widget in the layout.\n     *\n     * @param widget - The widget to move in the parent.\n     *\n     * #### Notes\n     * This is a reimplementation of the superclass method.\n     */\n    moveWidget(fromIndex, toIndex, widget) {\n        // Move the item, sizer, and handle for the widget.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.move(this._items, fromIndex, toIndex);\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.move(this._sizers, fromIndex, toIndex);\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.move(this._handles, fromIndex, toIndex);\n        // Post a fit request to the parent to show/hide last handle.\n        this.parent.fit();\n    }\n    /**\n     * Detach a widget from the parent's DOM node.\n     *\n     * @param index - The previous index of the widget in the layout.\n     *\n     * @param widget - The widget to detach from the parent.\n     *\n     * #### Notes\n     * This is a reimplementation of the superclass method.\n     */\n    detachWidget(index, widget) {\n        // Remove the item, handle, and sizer for the widget.\n        let item = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(this._items, index);\n        let handle = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(this._handles, index);\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(this._sizers, index);\n        // Send a `'before-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeDetach);\n        }\n        // Remove the widget and handle nodes from the parent.\n        this.parent.node.removeChild(widget.node);\n        this.parent.node.removeChild(handle);\n        // Send an `'after-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterDetach);\n        }\n        // Dispose of the layout item.\n        item.dispose();\n        // Post a fit request for the parent widget.\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'before-show'` message.\n     */\n    onBeforeShow(msg) {\n        super.onBeforeShow(msg);\n        this.parent.update();\n    }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     */\n    onBeforeAttach(msg) {\n        super.onBeforeAttach(msg);\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'child-shown'` message.\n     */\n    onChildShown(msg) {\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'child-hidden'` message.\n     */\n    onChildHidden(msg) {\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'resize'` message.\n     */\n    onResize(msg) {\n        if (this.parent.isVisible) {\n            this._update(msg.width, msg.height);\n        }\n    }\n    /**\n     * A message handler invoked on an `'update-request'` message.\n     */\n    onUpdateRequest(msg) {\n        if (this.parent.isVisible) {\n            this._update(-1, -1);\n        }\n    }\n    /**\n     * A message handler invoked on a `'fit-request'` message.\n     */\n    onFitRequest(msg) {\n        if (this.parent.isAttached) {\n            this._fit();\n        }\n    }\n    /**\n     * Update the item position.\n     *\n     * @param i Item index\n     * @param isHorizontal Whether the layout is horizontal or not\n     * @param left Left position in pixels\n     * @param top Top position in pixels\n     * @param height Item height\n     * @param width Item width\n     * @param size Item size\n     */\n    updateItemPosition(i, isHorizontal, left, top, height, width, size) {\n        const item = this._items[i];\n        if (item.isHidden) {\n            return;\n        }\n        // Fetch the style for the handle.\n        let handleStyle = this._handles[i].style;\n        // Update the widget and handle, and advance the relevant edge.\n        if (isHorizontal) {\n            left += this.widgetOffset;\n            item.update(left, top, size, height);\n            left += size;\n            handleStyle.top = `${top}px`;\n            handleStyle.left = `${left}px`;\n            handleStyle.width = `${this._spacing}px`;\n            handleStyle.height = `${height}px`;\n        }\n        else {\n            top += this.widgetOffset;\n            item.update(left, top, width, size);\n            top += size;\n            handleStyle.top = `${top}px`;\n            handleStyle.left = `${left}px`;\n            handleStyle.width = `${width}px`;\n            handleStyle.height = `${this._spacing}px`;\n        }\n    }\n    /**\n     * Fit the layout to the total size required by the widgets.\n     */\n    _fit() {\n        // Update the handles and track the visible widget count.\n        let nVisible = 0;\n        let lastHandleIndex = -1;\n        for (let i = 0, n = this._items.length; i < n; ++i) {\n            if (this._items[i].isHidden) {\n                this._handles[i].classList.add('lm-mod-hidden');\n            }\n            else {\n                this._handles[i].classList.remove('lm-mod-hidden');\n                lastHandleIndex = i;\n                nVisible++;\n            }\n        }\n        // Hide the handle for the last visible widget.\n        if (lastHandleIndex !== -1) {\n            this._handles[lastHandleIndex].classList.add('lm-mod-hidden');\n        }\n        // Update the fixed space for the visible items.\n        this._fixed =\n            this._spacing * Math.max(0, nVisible - 1) +\n                this.widgetOffset * this._items.length;\n        // Setup the computed minimum size.\n        let horz = this._orientation === 'horizontal';\n        let minW = horz ? this._fixed : 0;\n        let minH = horz ? 0 : this._fixed;\n        // Update the sizers and computed size limits.\n        for (let i = 0, n = this._items.length; i < n; ++i) {\n            // Fetch the item and corresponding box sizer.\n            let item = this._items[i];\n            let sizer = this._sizers[i];\n            // Prevent resizing unless necessary.\n            if (sizer.size > 0) {\n                sizer.sizeHint = sizer.size;\n            }\n            // If the item is hidden, it should consume zero size.\n            if (item.isHidden) {\n                sizer.minSize = 0;\n                sizer.maxSize = 0;\n                continue;\n            }\n            // Update the size limits for the item.\n            item.fit();\n            // Update the stretch factor.\n            sizer.stretch = SplitLayout.getStretch(item.widget);\n            // Update the sizer limits and computed min size.\n            if (horz) {\n                sizer.minSize = item.minWidth;\n                sizer.maxSize = item.maxWidth;\n                minW += item.minWidth;\n                minH = Math.max(minH, item.minHeight);\n            }\n            else {\n                sizer.minSize = item.minHeight;\n                sizer.maxSize = item.maxHeight;\n                minH += item.minHeight;\n                minW = Math.max(minW, item.minWidth);\n            }\n        }\n        // Update the box sizing and add it to the computed min size.\n        let box = (this._box = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.boxSizing(this.parent.node));\n        minW += box.horizontalSum;\n        minH += box.verticalSum;\n        // Update the parent's min size constraints.\n        let style = this.parent.node.style;\n        style.minWidth = `${minW}px`;\n        style.minHeight = `${minH}px`;\n        // Set the dirty flag to ensure only a single update occurs.\n        this._dirty = true;\n        // Notify the ancestor that it should fit immediately. This may\n        // cause a resize of the parent, fulfilling the required update.\n        if (this.parent.parent) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.parent.parent, Widget.Msg.FitRequest);\n        }\n        // If the dirty flag is still set, the parent was not resized.\n        // Trigger the required update on the parent widget immediately.\n        if (this._dirty) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.parent, Widget.Msg.UpdateRequest);\n        }\n    }\n    /**\n     * Update the layout position and size of the widgets.\n     *\n     * The parent offset dimensions should be `-1` if unknown.\n     */\n    _update(offsetWidth, offsetHeight) {\n        // Clear the dirty flag to indicate the update occurred.\n        this._dirty = false;\n        // Compute the visible item count.\n        let nVisible = 0;\n        for (let i = 0, n = this._items.length; i < n; ++i) {\n            nVisible += +!this._items[i].isHidden;\n        }\n        // Bail early if there are no visible items to layout.\n        if (nVisible === 0 && this.widgetOffset === 0) {\n            return;\n        }\n        // Measure the parent if the offset dimensions are unknown.\n        if (offsetWidth < 0) {\n            offsetWidth = this.parent.node.offsetWidth;\n        }\n        if (offsetHeight < 0) {\n            offsetHeight = this.parent.node.offsetHeight;\n        }\n        // Ensure the parent box sizing data is computed.\n        if (!this._box) {\n            this._box = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.boxSizing(this.parent.node);\n        }\n        // Compute the actual layout bounds adjusted for border and padding.\n        let top = this._box.paddingTop;\n        let left = this._box.paddingLeft;\n        let width = offsetWidth - this._box.horizontalSum;\n        let height = offsetHeight - this._box.verticalSum;\n        // Set up the variables for justification and alignment offset.\n        let extra = 0;\n        let offset = 0;\n        let horz = this._orientation === 'horizontal';\n        if (nVisible > 0) {\n            // Compute the adjusted layout space.\n            let space;\n            if (horz) {\n                // left += this.widgetOffset;\n                space = Math.max(0, width - this._fixed);\n            }\n            else {\n                // top += this.widgetOffset;\n                space = Math.max(0, height - this._fixed);\n            }\n            // Scale the size hints if they are normalized.\n            if (this._hasNormedSizes) {\n                for (let sizer of this._sizers) {\n                    sizer.sizeHint *= space;\n                }\n                this._hasNormedSizes = false;\n            }\n            // Distribute the layout space to the box sizers.\n            let delta = BoxEngine.calc(this._sizers, space);\n            // Account for alignment if there is extra layout space.\n            if (delta > 0) {\n                switch (this._alignment) {\n                    case 'start':\n                        break;\n                    case 'center':\n                        extra = 0;\n                        offset = delta / 2;\n                        break;\n                    case 'end':\n                        extra = 0;\n                        offset = delta;\n                        break;\n                    case 'justify':\n                        extra = delta / nVisible;\n                        offset = 0;\n                        break;\n                    default:\n                        throw 'unreachable';\n                }\n            }\n        }\n        // Layout the items using the computed box sizes.\n        for (let i = 0, n = this._items.length; i < n; ++i) {\n            // Fetch the item.\n            const item = this._items[i];\n            // Fetch the computed size for the widget.\n            const size = item.isHidden ? 0 : this._sizers[i].size + extra;\n            this.updateItemPosition(i, horz, horz ? left + offset : left, horz ? top : top + offset, height, width, size);\n            const fullOffset = this.widgetOffset +\n                (this._handles[i].classList.contains('lm-mod-hidden')\n                    ? 0\n                    : this._spacing);\n            if (horz) {\n                left += size + fullOffset;\n            }\n            else {\n                top += size + fullOffset;\n            }\n        }\n    }\n}\n/**\n * The namespace for the `SplitLayout` class statics.\n */\n(function (SplitLayout) {\n    /**\n     * Get the split layout stretch factor for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @returns The split layout stretch factor for the widget.\n     */\n    function getStretch(widget) {\n        return Private$h.stretchProperty.get(widget);\n    }\n    SplitLayout.getStretch = getStretch;\n    /**\n     * Set the split layout stretch factor for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @param value - The value for the stretch factor.\n     */\n    function setStretch(widget, value) {\n        Private$h.stretchProperty.set(widget, value);\n    }\n    SplitLayout.setStretch = setStretch;\n})(SplitLayout || (SplitLayout = {}));\n/**\n * The namespace for the module implementation details.\n */\nvar Private$h;\n(function (Private) {\n    /**\n     * The property descriptor for a widget stretch factor.\n     */\n    Private.stretchProperty = new _lumino_properties__WEBPACK_IMPORTED_MODULE_4__.AttachedProperty({\n        name: 'stretch',\n        create: () => 0,\n        coerce: (owner, value) => Math.max(0, Math.floor(value)),\n        changed: onChildSizingChanged\n    });\n    /**\n     * Create a new box sizer with the given size hint.\n     */\n    function createSizer(size) {\n        let sizer = new BoxSizer();\n        sizer.sizeHint = Math.floor(size);\n        return sizer;\n    }\n    Private.createSizer = createSizer;\n    /**\n     * Create a new split handle node using the given renderer.\n     */\n    function createHandle(renderer) {\n        let handle = renderer.createHandle();\n        handle.style.position = 'absolute';\n        // Do not use size containment to allow the handle to fill the available space\n        handle.style.contain = 'style';\n        return handle;\n    }\n    Private.createHandle = createHandle;\n    /**\n     * Compute the average size of an array of box sizers.\n     */\n    function averageSize(sizers) {\n        return sizers.reduce((v, s) => v + s.size, 0) / sizers.length || 0;\n    }\n    Private.averageSize = averageSize;\n    /**\n     * Normalize an array of values.\n     */\n    function normalize(values) {\n        let n = values.length;\n        if (n === 0) {\n            return [];\n        }\n        let sum = values.reduce((a, b) => a + Math.abs(b), 0);\n        return sum === 0 ? values.map(v => 1 / n) : values.map(v => v / sum);\n    }\n    Private.normalize = normalize;\n    /**\n     * The change handler for the attached sizing properties.\n     */\n    function onChildSizingChanged(child) {\n        if (child.parent && child.parent.layout instanceof SplitLayout) {\n            child.parent.fit();\n        }\n    }\n})(Private$h || (Private$h = {}));\n\n/*\n * Copyright (c) Jupyter Development Team.\n * Distributed under the terms of the Modified BSD License.\n */\n/**\n * A layout which arranges its widgets into collapsible resizable sections.\n */\nclass AccordionLayout extends SplitLayout {\n    /**\n     * Construct a new accordion layout.\n     *\n     * @param options - The options for initializing the layout.\n     *\n     * #### Notes\n     * The default orientation will be vertical.\n     *\n     * Titles must be rotated for horizontal accordion panel using CSS: see accordionpanel.css\n     */\n    constructor(options) {\n        super({ ...options, orientation: options.orientation || 'vertical' });\n        this._titles = [];\n        this.titleSpace = options.titleSpace || 22;\n    }\n    /**\n     * The section title height or width depending on the orientation.\n     */\n    get titleSpace() {\n        return this.widgetOffset;\n    }\n    set titleSpace(value) {\n        value = Utils$1.clampDimension(value);\n        if (this.widgetOffset === value) {\n            return;\n        }\n        this.widgetOffset = value;\n        if (!this.parent) {\n            return;\n        }\n        this.parent.fit();\n    }\n    /**\n     * A read-only array of the section titles in the panel.\n     */\n    get titles() {\n        return this._titles;\n    }\n    /**\n     * Dispose of the resources held by the layout.\n     */\n    dispose() {\n        if (this.isDisposed) {\n            return;\n        }\n        // Clear the layout state.\n        this._titles.length = 0;\n        // Dispose of the rest of the layout.\n        super.dispose();\n    }\n    updateTitle(index, widget) {\n        const oldTitle = this._titles[index];\n        const expanded = oldTitle.classList.contains('lm-mod-expanded');\n        const newTitle = Private$g.createTitle(this.renderer, widget.title, expanded);\n        this._titles[index] = newTitle;\n        // Add the title node to the parent before the widget.\n        this.parent.node.replaceChild(newTitle, oldTitle);\n    }\n    /**\n     * Insert a widget into the layout at the specified index.\n     *\n     * @param index - The index at which to insert the widget.\n     *\n     * @param widget - The widget to insert into the layout.\n     *\n     * #### Notes\n     * The index will be clamped to the bounds of the widgets.\n     *\n     * If the widget is already added to the layout, it will be moved.\n     *\n     * #### Undefined Behavior\n     * An `index` which is non-integral.\n     */\n    insertWidget(index, widget) {\n        if (!widget.id) {\n            widget.id = `id-${_lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__.UUID.uuid4()}`;\n        }\n        super.insertWidget(index, widget);\n    }\n    /**\n     * Attach a widget to the parent's DOM node.\n     *\n     * @param index - The current index of the widget in the layout.\n     *\n     * @param widget - The widget to attach to the parent.\n     */\n    attachWidget(index, widget) {\n        const title = Private$g.createTitle(this.renderer, widget.title);\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(this._titles, index, title);\n        // Add the title node to the parent before the widget.\n        this.parent.node.appendChild(title);\n        widget.node.setAttribute('role', 'region');\n        widget.node.setAttribute('aria-labelledby', title.id);\n        super.attachWidget(index, widget);\n    }\n    /**\n     * Move a widget in the parent's DOM node.\n     *\n     * @param fromIndex - The previous index of the widget in the layout.\n     *\n     * @param toIndex - The current index of the widget in the layout.\n     *\n     * @param widget - The widget to move in the parent.\n     */\n    moveWidget(fromIndex, toIndex, widget) {\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.move(this._titles, fromIndex, toIndex);\n        super.moveWidget(fromIndex, toIndex, widget);\n    }\n    /**\n     * Detach a widget from the parent's DOM node.\n     *\n     * @param index - The previous index of the widget in the layout.\n     *\n     * @param widget - The widget to detach from the parent.\n     *\n     * #### Notes\n     * This is a reimplementation of the superclass method.\n     */\n    detachWidget(index, widget) {\n        const title = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(this._titles, index);\n        this.parent.node.removeChild(title);\n        super.detachWidget(index, widget);\n    }\n    /**\n     * Update the item position.\n     *\n     * @param i Item index\n     * @param isHorizontal Whether the layout is horizontal or not\n     * @param left Left position in pixels\n     * @param top Top position in pixels\n     * @param height Item height\n     * @param width Item width\n     * @param size Item size\n     */\n    updateItemPosition(i, isHorizontal, left, top, height, width, size) {\n        const titleStyle = this._titles[i].style;\n        // Titles must be rotated for horizontal accordion panel using CSS: see accordionpanel.css\n        titleStyle.top = `${top}px`;\n        titleStyle.left = `${left}px`;\n        titleStyle.height = `${this.widgetOffset}px`;\n        if (isHorizontal) {\n            titleStyle.width = `${height}px`;\n        }\n        else {\n            titleStyle.width = `${width}px`;\n        }\n        super.updateItemPosition(i, isHorizontal, left, top, height, width, size);\n    }\n}\nvar Private$g;\n(function (Private) {\n    /**\n     * Create the title HTML element.\n     *\n     * @param renderer Accordion renderer\n     * @param data Widget title\n     * @returns Title HTML element\n     */\n    function createTitle(renderer, data, expanded = true) {\n        const title = renderer.createSectionTitle(data);\n        title.style.position = 'absolute';\n        title.style.contain = 'strict';\n        title.setAttribute('aria-label', `${data.label} Section`);\n        title.setAttribute('aria-expanded', expanded ? 'true' : 'false');\n        title.setAttribute('aria-controls', data.owner.id);\n        if (expanded) {\n            title.classList.add('lm-mod-expanded');\n        }\n        return title;\n    }\n    Private.createTitle = createTitle;\n})(Private$g || (Private$g = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A simple and convenient panel widget class.\n *\n * #### Notes\n * This class is suitable as a base class for implementing a variety of\n * convenience panel widgets, but can also be used directly with CSS to\n * arrange a collection of widgets.\n *\n * This class provides a convenience wrapper around a {@link PanelLayout}.\n */\nclass Panel extends Widget {\n    /**\n     * Construct a new panel.\n     *\n     * @param options - The options for initializing the panel.\n     */\n    constructor(options = {}) {\n        super();\n        this.addClass('lm-Panel');\n        this.layout = Private$f.createLayout(options);\n    }\n    /**\n     * A read-only array of the widgets in the panel.\n     */\n    get widgets() {\n        return this.layout.widgets;\n    }\n    /**\n     * Add a widget to the end of the panel.\n     *\n     * @param widget - The widget to add to the panel.\n     *\n     * #### Notes\n     * If the widget is already contained in the panel, it will be moved.\n     */\n    addWidget(widget) {\n        this.layout.addWidget(widget);\n    }\n    /**\n     * Insert a widget at the specified index.\n     *\n     * @param index - The index at which to insert the widget.\n     *\n     * @param widget - The widget to insert into to the panel.\n     *\n     * #### Notes\n     * If the widget is already contained in the panel, it will be moved.\n     */\n    insertWidget(index, widget) {\n        this.layout.insertWidget(index, widget);\n    }\n}\n/**\n * The namespace for the module implementation details.\n */\nvar Private$f;\n(function (Private) {\n    /**\n     * Create a panel layout for the given panel options.\n     */\n    function createLayout(options) {\n        return options.layout || new PanelLayout();\n    }\n    Private.createLayout = createLayout;\n})(Private$f || (Private$f = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A panel which arranges its widgets into resizable sections.\n *\n * #### Notes\n * This class provides a convenience wrapper around a {@link SplitLayout}.\n */\nclass SplitPanel extends Panel {\n    /**\n     * Construct a new split panel.\n     *\n     * @param options - The options for initializing the split panel.\n     */\n    constructor(options = {}) {\n        super({ layout: Private$e.createLayout(options) });\n        this._handleMoved = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._pressData = null;\n        this.addClass('lm-SplitPanel');\n    }\n    /**\n     * Dispose of the resources held by the panel.\n     */\n    dispose() {\n        this._releaseMouse();\n        super.dispose();\n    }\n    /**\n     * Get the layout orientation for the split panel.\n     */\n    get orientation() {\n        return this.layout.orientation;\n    }\n    /**\n     * Set the layout orientation for the split panel.\n     */\n    set orientation(value) {\n        this.layout.orientation = value;\n    }\n    /**\n     * Get the content alignment for the split panel.\n     *\n     * #### Notes\n     * This is the alignment of the widgets in the layout direction.\n     *\n     * The alignment has no effect if the widgets can expand to fill the\n     * entire split panel.\n     */\n    get alignment() {\n        return this.layout.alignment;\n    }\n    /**\n     * Set the content alignment for the split panel.\n     *\n     * #### Notes\n     * This is the alignment of the widgets in the layout direction.\n     *\n     * The alignment has no effect if the widgets can expand to fill the\n     * entire split panel.\n     */\n    set alignment(value) {\n        this.layout.alignment = value;\n    }\n    /**\n     * Get the inter-element spacing for the split panel.\n     */\n    get spacing() {\n        return this.layout.spacing;\n    }\n    /**\n     * Set the inter-element spacing for the split panel.\n     */\n    set spacing(value) {\n        this.layout.spacing = value;\n    }\n    /**\n     * The renderer used by the split panel.\n     */\n    get renderer() {\n        return this.layout.renderer;\n    }\n    /**\n     * A signal emitted when a split handle has moved.\n     */\n    get handleMoved() {\n        return this._handleMoved;\n    }\n    /**\n     * A read-only array of the split handles in the panel.\n     */\n    get handles() {\n        return this.layout.handles;\n    }\n    /**\n     * Get the relative sizes of the widgets in the panel.\n     *\n     * @returns A new array of the relative sizes of the widgets.\n     *\n     * #### Notes\n     * The returned sizes reflect the sizes of the widgets normalized\n     * relative to their siblings.\n     *\n     * This method **does not** measure the DOM nodes.\n     */\n    relativeSizes() {\n        return this.layout.relativeSizes();\n    }\n    /**\n     * Set the relative sizes for the widgets in the panel.\n     *\n     * @param sizes - The relative sizes for the widgets in the panel.\n     * @param update - Update the layout after setting relative sizes.\n     * Default is True.\n     *\n     * #### Notes\n     * Extra values are ignored, too few will yield an undefined layout.\n     *\n     * The actual geometry of the DOM nodes is updated asynchronously.\n     */\n    setRelativeSizes(sizes, update = true) {\n        this.layout.setRelativeSizes(sizes, update);\n    }\n    /**\n     * Handle the DOM events for the split panel.\n     *\n     * @param event - The DOM event sent to the panel.\n     *\n     * #### Notes\n     * This method implements the DOM `EventListener` interface and is\n     * called in response to events on the panel's DOM node. It should\n     * not be called directly by user code.\n     */\n    handleEvent(event) {\n        switch (event.type) {\n            case 'pointerdown':\n                this._evtPointerDown(event);\n                break;\n            case 'pointermove':\n                this._evtPointerMove(event);\n                break;\n            case 'pointerup':\n                this._evtPointerUp(event);\n                break;\n            case 'keydown':\n                this._evtKeyDown(event);\n                break;\n            case 'contextmenu':\n                event.preventDefault();\n                event.stopPropagation();\n                break;\n        }\n    }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     */\n    onBeforeAttach(msg) {\n        this.node.addEventListener('pointerdown', this);\n    }\n    /**\n     * A message handler invoked on an `'after-detach'` message.\n     */\n    onAfterDetach(msg) {\n        this.node.removeEventListener('pointerdown', this);\n        this._releaseMouse();\n    }\n    /**\n     * A message handler invoked on a `'child-added'` message.\n     */\n    onChildAdded(msg) {\n        msg.child.addClass('lm-SplitPanel-child');\n        this._releaseMouse();\n    }\n    /**\n     * A message handler invoked on a `'child-removed'` message.\n     */\n    onChildRemoved(msg) {\n        msg.child.removeClass('lm-SplitPanel-child');\n        this._releaseMouse();\n    }\n    /**\n     * Handle the `'keydown'` event for the split panel.\n     */\n    _evtKeyDown(event) {\n        // Stop input events during drag.\n        if (this._pressData) {\n            event.preventDefault();\n            event.stopPropagation();\n        }\n        // Release the mouse if `Escape` is pressed.\n        if (event.keyCode === 27) {\n            this._releaseMouse();\n        }\n    }\n    /**\n     * Handle the `'pointerdown'` event for the split panel.\n     */\n    _evtPointerDown(event) {\n        // Do nothing if the primary button is not pressed.\n        if (event.button !== 0) {\n            return;\n        }\n        // Find the handle which contains the target, if any.\n        let layout = this.layout;\n        let index = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(layout.handles, handle => {\n            return handle.contains(event.target);\n        });\n        // Bail early if the mouse press was not on a handle.\n        if (index === -1) {\n            return;\n        }\n        // Stop the event when a split handle is pressed.\n        event.preventDefault();\n        event.stopPropagation();\n        // Add the extra document listeners.\n        document.addEventListener('pointerup', this, true);\n        document.addEventListener('pointermove', this, true);\n        document.addEventListener('keydown', this, true);\n        document.addEventListener('contextmenu', this, true);\n        // Compute the offset delta for the handle press.\n        let delta;\n        let handle = layout.handles[index];\n        let rect = handle.getBoundingClientRect();\n        if (layout.orientation === 'horizontal') {\n            delta = event.clientX - rect.left;\n        }\n        else {\n            delta = event.clientY - rect.top;\n        }\n        // Override the cursor and store the press data.\n        let style = window.getComputedStyle(handle);\n        let override = _lumino_dragdrop__WEBPACK_IMPORTED_MODULE_6__.Drag.overrideCursor(style.cursor);\n        this._pressData = { index, delta, override };\n    }\n    /**\n     * Handle the `'pointermove'` event for the split panel.\n     */\n    _evtPointerMove(event) {\n        // Stop the event when dragging a split handle.\n        event.preventDefault();\n        event.stopPropagation();\n        // Compute the desired offset position for the handle.\n        let pos;\n        let layout = this.layout;\n        let rect = this.node.getBoundingClientRect();\n        if (layout.orientation === 'horizontal') {\n            pos = event.clientX - rect.left - this._pressData.delta;\n        }\n        else {\n            pos = event.clientY - rect.top - this._pressData.delta;\n        }\n        // Move the handle as close to the desired position as possible.\n        layout.moveHandle(this._pressData.index, pos);\n    }\n    /**\n     * Handle the `'pointerup'` event for the split panel.\n     */\n    _evtPointerUp(event) {\n        // Do nothing if the primary button is not released.\n        if (event.button !== 0) {\n            return;\n        }\n        // Stop the event when releasing a handle.\n        event.preventDefault();\n        event.stopPropagation();\n        // Finalize the mouse release.\n        this._releaseMouse();\n    }\n    /**\n     * Release the mouse grab for the split panel.\n     */\n    _releaseMouse() {\n        // Bail early if no drag is in progress.\n        if (!this._pressData) {\n            return;\n        }\n        // Clear the override cursor.\n        this._pressData.override.dispose();\n        this._pressData = null;\n        // Emit the handle moved signal.\n        this._handleMoved.emit();\n        // Remove the extra document listeners.\n        document.removeEventListener('keydown', this, true);\n        document.removeEventListener('pointerup', this, true);\n        document.removeEventListener('pointermove', this, true);\n        document.removeEventListener('contextmenu', this, true);\n    }\n}\n/**\n * The namespace for the `SplitPanel` class statics.\n */\n(function (SplitPanel) {\n    /**\n     * The default implementation of `IRenderer`.\n     */\n    class Renderer {\n        /**\n         * Create a new handle for use with a split panel.\n         *\n         * @returns A new handle element for a split panel.\n         */\n        createHandle() {\n            let handle = document.createElement('div');\n            handle.className = 'lm-SplitPanel-handle';\n            return handle;\n        }\n    }\n    SplitPanel.Renderer = Renderer;\n    /**\n     * The default `Renderer` instance.\n     */\n    SplitPanel.defaultRenderer = new Renderer();\n    /**\n     * Get the split panel stretch factor for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @returns The split panel stretch factor for the widget.\n     */\n    function getStretch(widget) {\n        return SplitLayout.getStretch(widget);\n    }\n    SplitPanel.getStretch = getStretch;\n    /**\n     * Set the split panel stretch factor for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @param value - The value for the stretch factor.\n     */\n    function setStretch(widget, value) {\n        SplitLayout.setStretch(widget, value);\n    }\n    SplitPanel.setStretch = setStretch;\n})(SplitPanel || (SplitPanel = {}));\n/**\n * The namespace for the module implementation details.\n */\nvar Private$e;\n(function (Private) {\n    /**\n     * Create a split layout for the given panel options.\n     */\n    function createLayout(options) {\n        return (options.layout ||\n            new SplitLayout({\n                renderer: options.renderer || SplitPanel.defaultRenderer,\n                orientation: options.orientation,\n                alignment: options.alignment,\n                spacing: options.spacing\n            }));\n    }\n    Private.createLayout = createLayout;\n})(Private$e || (Private$e = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/**\n * A panel which arranges its widgets into resizable sections separated by a title widget.\n *\n * #### Notes\n * This class provides a convenience wrapper around {@link AccordionLayout}.\n */\nclass AccordionPanel extends SplitPanel {\n    /**\n     * Construct a new accordion panel.\n     *\n     * @param options - The options for initializing the accordion panel.\n     */\n    constructor(options = {}) {\n        super({ ...options, layout: Private$d.createLayout(options) });\n        this._widgetSizesCache = new WeakMap();\n        this._expansionToggled = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this.addClass('lm-AccordionPanel');\n    }\n    /**\n     * The renderer used by the accordion panel.\n     */\n    get renderer() {\n        return this.layout.renderer;\n    }\n    /**\n     * The section title space.\n     *\n     * This is the height if the panel is vertical and the width if it is\n     * horizontal.\n     */\n    get titleSpace() {\n        return this.layout.titleSpace;\n    }\n    set titleSpace(value) {\n        this.layout.titleSpace = value;\n    }\n    /**\n     * A read-only array of the section titles in the panel.\n     */\n    get titles() {\n        return this.layout.titles;\n    }\n    /**\n     * A signal emitted when a widget of the AccordionPanel is collapsed or expanded.\n     */\n    get expansionToggled() {\n        return this._expansionToggled;\n    }\n    /**\n     * Add a widget to the end of the panel.\n     *\n     * @param widget - The widget to add to the panel.\n     *\n     * #### Notes\n     * If the widget is already contained in the panel, it will be moved.\n     */\n    addWidget(widget) {\n        super.addWidget(widget);\n        widget.title.changed.connect(this._onTitleChanged, this);\n    }\n    /**\n     * Collapse the widget at position `index`.\n     *\n     * #### Notes\n     * If no widget is found for `index`, this will bail.\n     *\n     * @param index Widget index\n     */\n    collapse(index) {\n        const widget = this.layout.widgets[index];\n        if (widget && !widget.isHidden) {\n            this._toggleExpansion(index);\n        }\n    }\n    /**\n     * Expand the widget at position `index`.\n     *\n     * #### Notes\n     * If no widget is found for `index`, this will bail.\n     *\n     * @param index Widget index\n     */\n    expand(index) {\n        const widget = this.layout.widgets[index];\n        if (widget && widget.isHidden) {\n            this._toggleExpansion(index);\n        }\n    }\n    /**\n     * Insert a widget at the specified index.\n     *\n     * @param index - The index at which to insert the widget.\n     *\n     * @param widget - The widget to insert into to the panel.\n     *\n     * #### Notes\n     * If the widget is already contained in the panel, it will be moved.\n     */\n    insertWidget(index, widget) {\n        super.insertWidget(index, widget);\n        widget.title.changed.connect(this._onTitleChanged, this);\n    }\n    /**\n     * Handle the DOM events for the accordion panel.\n     *\n     * @param event - The DOM event sent to the panel.\n     *\n     * #### Notes\n     * This method implements the DOM `EventListener` interface and is\n     * called in response to events on the panel's DOM node. It should\n     * not be called directly by user code.\n     */\n    handleEvent(event) {\n        super.handleEvent(event);\n        switch (event.type) {\n            case 'click':\n                this._evtClick(event);\n                break;\n            case 'keydown':\n                this._eventKeyDown(event);\n                break;\n        }\n    }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     */\n    onBeforeAttach(msg) {\n        this.node.addEventListener('click', this);\n        this.node.addEventListener('keydown', this);\n        super.onBeforeAttach(msg);\n    }\n    /**\n     * A message handler invoked on an `'after-detach'` message.\n     */\n    onAfterDetach(msg) {\n        super.onAfterDetach(msg);\n        this.node.removeEventListener('click', this);\n        this.node.removeEventListener('keydown', this);\n    }\n    /**\n     * Handle the `changed` signal of a title object.\n     */\n    _onTitleChanged(sender) {\n        const index = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(this.widgets, widget => {\n            return widget.contains(sender.owner);\n        });\n        if (index >= 0) {\n            this.layout.updateTitle(index, sender.owner);\n            this.update();\n        }\n    }\n    /**\n     * Compute the size of widgets in this panel on the title click event.\n     * On closing, the size of the widget is cached and we will try to expand\n     * the last opened widget.\n     * On opening, we will use the cached size if it is available to restore the\n     * widget.\n     * In both cases, if we can not compute the size of widgets, we will let\n     * `SplitLayout` decide.\n     *\n     * @param index - The index of widget to be opened of closed\n     *\n     * @returns Relative size of widgets in this panel, if this size can\n     * not be computed, return `undefined`\n     */\n    _computeWidgetSize(index) {\n        const layout = this.layout;\n        const widget = layout.widgets[index];\n        if (!widget) {\n            return undefined;\n        }\n        const isHidden = widget.isHidden;\n        const widgetSizes = layout.absoluteSizes();\n        const delta = (isHidden ? -1 : 1) * this.spacing;\n        const totalSize = widgetSizes.reduce((prev, curr) => prev + curr);\n        let newSize = [...widgetSizes];\n        if (!isHidden) {\n            // Hide the widget\n            const currentSize = widgetSizes[index];\n            this._widgetSizesCache.set(widget, currentSize);\n            newSize[index] = 0;\n            const widgetToCollapse = newSize.map(sz => sz > 0).lastIndexOf(true);\n            if (widgetToCollapse === -1) {\n                // All widget are closed, let the `SplitLayout` compute widget sizes.\n                return undefined;\n            }\n            newSize[widgetToCollapse] =\n                widgetSizes[widgetToCollapse] + currentSize + delta;\n        }\n        else {\n            // Show the widget\n            const previousSize = this._widgetSizesCache.get(widget);\n            if (!previousSize) {\n                // Previous size is unavailable, let the `SplitLayout` compute widget sizes.\n                return undefined;\n            }\n            newSize[index] += previousSize;\n            const widgetToCollapse = newSize\n                .map(sz => sz - previousSize > 0)\n                .lastIndexOf(true);\n            if (widgetToCollapse === -1) {\n                // Can not reduce the size of one widget, reduce all opened widgets\n                // proportionally with its size.\n                newSize.forEach((_, idx) => {\n                    if (idx !== index) {\n                        newSize[idx] -=\n                            (widgetSizes[idx] / totalSize) * (previousSize - delta);\n                    }\n                });\n            }\n            else {\n                newSize[widgetToCollapse] -= previousSize - delta;\n            }\n        }\n        return newSize.map(sz => sz / (totalSize + delta));\n    }\n    /**\n     * Handle the `'click'` event for the accordion panel\n     */\n    _evtClick(event) {\n        const target = event.target;\n        if (target) {\n            const index = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(this.titles, title => {\n                return title.contains(target);\n            });\n            if (index >= 0) {\n                event.preventDefault();\n                event.stopPropagation();\n                this._toggleExpansion(index);\n            }\n        }\n    }\n    /**\n     * Handle the `'keydown'` event for the accordion panel.\n     */\n    _eventKeyDown(event) {\n        if (event.defaultPrevented) {\n            return;\n        }\n        const target = event.target;\n        let handled = false;\n        if (target) {\n            const index = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(this.titles, title => {\n                return title.contains(target);\n            });\n            if (index >= 0) {\n                const keyCode = event.keyCode.toString();\n                // If Space or Enter is pressed on title, emulate click event\n                if (event.key.match(/Space|Enter/) || keyCode.match(/13|32/)) {\n                    target.click();\n                    handled = true;\n                }\n                else if (this.orientation === 'horizontal'\n                    ? event.key.match(/ArrowLeft|ArrowRight/) || keyCode.match(/37|39/)\n                    : event.key.match(/ArrowUp|ArrowDown/) || keyCode.match(/38|40/)) {\n                    // If Up or Down (for vertical) / Left or Right (for horizontal) is pressed on title, loop on titles\n                    const direction = event.key.match(/ArrowLeft|ArrowUp/) || keyCode.match(/37|38/)\n                        ? -1\n                        : 1;\n                    const length = this.titles.length;\n                    const newIndex = (index + length + direction) % length;\n                    this.titles[newIndex].focus();\n                    handled = true;\n                }\n                else if (event.key === 'End' || keyCode === '35') {\n                    // If End is pressed on title, focus on the last title\n                    this.titles[this.titles.length - 1].focus();\n                    handled = true;\n                }\n                else if (event.key === 'Home' || keyCode === '36') {\n                    // If Home is pressed on title, focus on the first title\n                    this.titles[0].focus();\n                    handled = true;\n                }\n            }\n            if (handled) {\n                event.preventDefault();\n            }\n        }\n    }\n    _toggleExpansion(index) {\n        const title = this.titles[index];\n        const widget = this.layout.widgets[index];\n        const newSize = this._computeWidgetSize(index);\n        if (newSize) {\n            this.setRelativeSizes(newSize, false);\n        }\n        if (widget.isHidden) {\n            title.classList.add('lm-mod-expanded');\n            title.setAttribute('aria-expanded', 'true');\n            widget.show();\n        }\n        else {\n            title.classList.remove('lm-mod-expanded');\n            title.setAttribute('aria-expanded', 'false');\n            widget.hide();\n        }\n        // Emit the expansion state signal.\n        this._expansionToggled.emit(index);\n    }\n}\n/**\n * The namespace for the `AccordionPanel` class statics.\n */\n(function (AccordionPanel) {\n    /**\n     * The default implementation of `IRenderer`.\n     */\n    class Renderer extends SplitPanel.Renderer {\n        constructor() {\n            super();\n            /**\n             * A selector which matches any title node in the accordion.\n             */\n            this.titleClassName = 'lm-AccordionPanel-title';\n            this._titleID = 0;\n            this._titleKeys = new WeakMap();\n            this._uuid = ++Renderer._nInstance;\n        }\n        /**\n         * Render the collapse indicator for a section title.\n         *\n         * @param data - The data to use for rendering the section title.\n         *\n         * @returns A element representing the collapse indicator.\n         */\n        createCollapseIcon(data) {\n            return document.createElement('span');\n        }\n        /**\n         * Render the element for a section title.\n         *\n         * @param data - The data to use for rendering the section title.\n         *\n         * @returns A element representing the section title.\n         */\n        createSectionTitle(data) {\n            const handle = document.createElement('h3');\n            handle.setAttribute('tabindex', '0');\n            handle.id = this.createTitleKey(data);\n            handle.className = this.titleClassName;\n            for (const aData in data.dataset) {\n                handle.dataset[aData] = data.dataset[aData];\n            }\n            const collapser = handle.appendChild(this.createCollapseIcon(data));\n            collapser.className = 'lm-AccordionPanel-titleCollapser';\n            const label = handle.appendChild(document.createElement('span'));\n            label.className = 'lm-AccordionPanel-titleLabel';\n            label.textContent = data.label;\n            label.title = data.caption || data.label;\n            return handle;\n        }\n        /**\n         * Create a unique render key for the title.\n         *\n         * @param data - The data to use for the title.\n         *\n         * @returns The unique render key for the title.\n         *\n         * #### Notes\n         * This method caches the key against the section title the first time\n         * the key is generated.\n         */\n        createTitleKey(data) {\n            let key = this._titleKeys.get(data);\n            if (key === undefined) {\n                key = `title-key-${this._uuid}-${this._titleID++}`;\n                this._titleKeys.set(data, key);\n            }\n            return key;\n        }\n    }\n    Renderer._nInstance = 0;\n    AccordionPanel.Renderer = Renderer;\n    /**\n     * The default `Renderer` instance.\n     */\n    AccordionPanel.defaultRenderer = new Renderer();\n})(AccordionPanel || (AccordionPanel = {}));\nvar Private$d;\n(function (Private) {\n    /**\n     * Create an accordion layout for the given panel options.\n     *\n     * @param options Panel options\n     * @returns Panel layout\n     */\n    function createLayout(options) {\n        return (options.layout ||\n            new AccordionLayout({\n                renderer: options.renderer || AccordionPanel.defaultRenderer,\n                orientation: options.orientation,\n                alignment: options.alignment,\n                spacing: options.spacing,\n                titleSpace: options.titleSpace\n            }));\n    }\n    Private.createLayout = createLayout;\n})(Private$d || (Private$d = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A layout which arranges its widgets in a single row or column.\n */\nclass BoxLayout extends PanelLayout {\n    /**\n     * Construct a new box layout.\n     *\n     * @param options - The options for initializing the layout.\n     */\n    constructor(options = {}) {\n        super();\n        this._fixed = 0;\n        this._spacing = 4;\n        this._dirty = false;\n        this._sizers = [];\n        this._items = [];\n        this._box = null;\n        this._alignment = 'start';\n        this._direction = 'top-to-bottom';\n        if (options.direction !== undefined) {\n            this._direction = options.direction;\n        }\n        if (options.alignment !== undefined) {\n            this._alignment = options.alignment;\n        }\n        if (options.spacing !== undefined) {\n            this._spacing = Utils$1.clampDimension(options.spacing);\n        }\n    }\n    /**\n     * Dispose of the resources held by the layout.\n     */\n    dispose() {\n        // Dispose of the layout items.\n        for (const item of this._items) {\n            item.dispose();\n        }\n        // Clear the layout state.\n        this._box = null;\n        this._items.length = 0;\n        this._sizers.length = 0;\n        // Dispose of the rest of the layout.\n        super.dispose();\n    }\n    /**\n     * Get the layout direction for the box layout.\n     */\n    get direction() {\n        return this._direction;\n    }\n    /**\n     * Set the layout direction for the box layout.\n     */\n    set direction(value) {\n        if (this._direction === value) {\n            return;\n        }\n        this._direction = value;\n        if (!this.parent) {\n            return;\n        }\n        this.parent.dataset['direction'] = value;\n        this.parent.fit();\n    }\n    /**\n     * Get the content alignment for the box layout.\n     *\n     * #### Notes\n     * This is the alignment of the widgets in the layout direction.\n     *\n     * The alignment has no effect if the widgets can expand to fill the\n     * entire box layout.\n     */\n    get alignment() {\n        return this._alignment;\n    }\n    /**\n     * Set the content alignment for the box layout.\n     *\n     * #### Notes\n     * This is the alignment of the widgets in the layout direction.\n     *\n     * The alignment has no effect if the widgets can expand to fill the\n     * entire box layout.\n     */\n    set alignment(value) {\n        if (this._alignment === value) {\n            return;\n        }\n        this._alignment = value;\n        if (!this.parent) {\n            return;\n        }\n        this.parent.dataset['alignment'] = value;\n        this.parent.update();\n    }\n    /**\n     * Get the inter-element spacing for the box layout.\n     */\n    get spacing() {\n        return this._spacing;\n    }\n    /**\n     * Set the inter-element spacing for the box layout.\n     */\n    set spacing(value) {\n        value = Utils$1.clampDimension(value);\n        if (this._spacing === value) {\n            return;\n        }\n        this._spacing = value;\n        if (!this.parent) {\n            return;\n        }\n        this.parent.fit();\n    }\n    /**\n     * Perform layout initialization which requires the parent widget.\n     */\n    init() {\n        this.parent.dataset['direction'] = this.direction;\n        this.parent.dataset['alignment'] = this.alignment;\n        super.init();\n    }\n    /**\n     * Attach a widget to the parent's DOM node.\n     *\n     * @param index - The current index of the widget in the layout.\n     *\n     * @param widget - The widget to attach to the parent.\n     *\n     * #### Notes\n     * This is a reimplementation of the superclass method.\n     */\n    attachWidget(index, widget) {\n        // Create and add a new layout item for the widget.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(this._items, index, new LayoutItem(widget));\n        // Create and add a new sizer for the widget.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(this._sizers, index, new BoxSizer());\n        // Send a `'before-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeAttach);\n        }\n        // Add the widget's node to the parent.\n        this.parent.node.appendChild(widget.node);\n        // Send an `'after-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterAttach);\n        }\n        // Post a fit request for the parent widget.\n        this.parent.fit();\n    }\n    /**\n     * Move a widget in the parent's DOM node.\n     *\n     * @param fromIndex - The previous index of the widget in the layout.\n     *\n     * @param toIndex - The current index of the widget in the layout.\n     *\n     * @param widget - The widget to move in the parent.\n     *\n     * #### Notes\n     * This is a reimplementation of the superclass method.\n     */\n    moveWidget(fromIndex, toIndex, widget) {\n        // Move the layout item for the widget.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.move(this._items, fromIndex, toIndex);\n        // Move the sizer for the widget.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.move(this._sizers, fromIndex, toIndex);\n        // Post an update request for the parent widget.\n        this.parent.update();\n    }\n    /**\n     * Detach a widget from the parent's DOM node.\n     *\n     * @param index - The previous index of the widget in the layout.\n     *\n     * @param widget - The widget to detach from the parent.\n     *\n     * #### Notes\n     * This is a reimplementation of the superclass method.\n     */\n    detachWidget(index, widget) {\n        // Remove the layout item for the widget.\n        let item = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(this._items, index);\n        // Remove the sizer for the widget.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(this._sizers, index);\n        // Send a `'before-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeDetach);\n        }\n        // Remove the widget's node from the parent.\n        this.parent.node.removeChild(widget.node);\n        // Send an `'after-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterDetach);\n        }\n        // Dispose of the layout item.\n        item.dispose();\n        // Post a fit request for the parent widget.\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'before-show'` message.\n     */\n    onBeforeShow(msg) {\n        super.onBeforeShow(msg);\n        this.parent.update();\n    }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     */\n    onBeforeAttach(msg) {\n        super.onBeforeAttach(msg);\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'child-shown'` message.\n     */\n    onChildShown(msg) {\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'child-hidden'` message.\n     */\n    onChildHidden(msg) {\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'resize'` message.\n     */\n    onResize(msg) {\n        if (this.parent.isVisible) {\n            this._update(msg.width, msg.height);\n        }\n    }\n    /**\n     * A message handler invoked on an `'update-request'` message.\n     */\n    onUpdateRequest(msg) {\n        if (this.parent.isVisible) {\n            this._update(-1, -1);\n        }\n    }\n    /**\n     * A message handler invoked on a `'fit-request'` message.\n     */\n    onFitRequest(msg) {\n        if (this.parent.isAttached) {\n            this._fit();\n        }\n    }\n    /**\n     * Fit the layout to the total size required by the widgets.\n     */\n    _fit() {\n        // Compute the visible item count.\n        let nVisible = 0;\n        for (let i = 0, n = this._items.length; i < n; ++i) {\n            nVisible += +!this._items[i].isHidden;\n        }\n        // Update the fixed space for the visible items.\n        this._fixed = this._spacing * Math.max(0, nVisible - 1);\n        // Setup the computed minimum size.\n        let horz = Private$c.isHorizontal(this._direction);\n        let minW = horz ? this._fixed : 0;\n        let minH = horz ? 0 : this._fixed;\n        // Update the sizers and computed minimum size.\n        for (let i = 0, n = this._items.length; i < n; ++i) {\n            // Fetch the item and corresponding box sizer.\n            let item = this._items[i];\n            let sizer = this._sizers[i];\n            // If the item is hidden, it should consume zero size.\n            if (item.isHidden) {\n                sizer.minSize = 0;\n                sizer.maxSize = 0;\n                continue;\n            }\n            // Update the size limits for the item.\n            item.fit();\n            // Update the size basis and stretch factor.\n            sizer.sizeHint = BoxLayout.getSizeBasis(item.widget);\n            sizer.stretch = BoxLayout.getStretch(item.widget);\n            // Update the sizer limits and computed min size.\n            if (horz) {\n                sizer.minSize = item.minWidth;\n                sizer.maxSize = item.maxWidth;\n                minW += item.minWidth;\n                minH = Math.max(minH, item.minHeight);\n            }\n            else {\n                sizer.minSize = item.minHeight;\n                sizer.maxSize = item.maxHeight;\n                minH += item.minHeight;\n                minW = Math.max(minW, item.minWidth);\n            }\n        }\n        // Update the box sizing and add it to the computed min size.\n        let box = (this._box = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.boxSizing(this.parent.node));\n        minW += box.horizontalSum;\n        minH += box.verticalSum;\n        // Update the parent's min size constraints.\n        let style = this.parent.node.style;\n        style.minWidth = `${minW}px`;\n        style.minHeight = `${minH}px`;\n        // Set the dirty flag to ensure only a single update occurs.\n        this._dirty = true;\n        // Notify the ancestor that it should fit immediately. This may\n        // cause a resize of the parent, fulfilling the required update.\n        if (this.parent.parent) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.parent.parent, Widget.Msg.FitRequest);\n        }\n        // If the dirty flag is still set, the parent was not resized.\n        // Trigger the required update on the parent widget immediately.\n        if (this._dirty) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.parent, Widget.Msg.UpdateRequest);\n        }\n    }\n    /**\n     * Update the layout position and size of the widgets.\n     *\n     * The parent offset dimensions should be `-1` if unknown.\n     */\n    _update(offsetWidth, offsetHeight) {\n        // Clear the dirty flag to indicate the update occurred.\n        this._dirty = false;\n        // Compute the visible item count.\n        let nVisible = 0;\n        for (let i = 0, n = this._items.length; i < n; ++i) {\n            nVisible += +!this._items[i].isHidden;\n        }\n        // Bail early if there are no visible items to layout.\n        if (nVisible === 0) {\n            return;\n        }\n        // Measure the parent if the offset dimensions are unknown.\n        if (offsetWidth < 0) {\n            offsetWidth = this.parent.node.offsetWidth;\n        }\n        if (offsetHeight < 0) {\n            offsetHeight = this.parent.node.offsetHeight;\n        }\n        // Ensure the parent box sizing data is computed.\n        if (!this._box) {\n            this._box = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.boxSizing(this.parent.node);\n        }\n        // Compute the layout area adjusted for border and padding.\n        let top = this._box.paddingTop;\n        let left = this._box.paddingLeft;\n        let width = offsetWidth - this._box.horizontalSum;\n        let height = offsetHeight - this._box.verticalSum;\n        // Distribute the layout space and adjust the start position.\n        let delta;\n        switch (this._direction) {\n            case 'left-to-right':\n                delta = BoxEngine.calc(this._sizers, Math.max(0, width - this._fixed));\n                break;\n            case 'top-to-bottom':\n                delta = BoxEngine.calc(this._sizers, Math.max(0, height - this._fixed));\n                break;\n            case 'right-to-left':\n                delta = BoxEngine.calc(this._sizers, Math.max(0, width - this._fixed));\n                left += width;\n                break;\n            case 'bottom-to-top':\n                delta = BoxEngine.calc(this._sizers, Math.max(0, height - this._fixed));\n                top += height;\n                break;\n            default:\n                throw 'unreachable';\n        }\n        // Setup the variables for justification and alignment offset.\n        let extra = 0;\n        let offset = 0;\n        // Account for alignment if there is extra layout space.\n        if (delta > 0) {\n            switch (this._alignment) {\n                case 'start':\n                    break;\n                case 'center':\n                    extra = 0;\n                    offset = delta / 2;\n                    break;\n                case 'end':\n                    extra = 0;\n                    offset = delta;\n                    break;\n                case 'justify':\n                    extra = delta / nVisible;\n                    offset = 0;\n                    break;\n                default:\n                    throw 'unreachable';\n            }\n        }\n        // Layout the items using the computed box sizes.\n        for (let i = 0, n = this._items.length; i < n; ++i) {\n            // Fetch the item.\n            let item = this._items[i];\n            // Ignore hidden items.\n            if (item.isHidden) {\n                continue;\n            }\n            // Fetch the computed size for the widget.\n            let size = this._sizers[i].size;\n            // Update the widget geometry and advance the relevant edge.\n            switch (this._direction) {\n                case 'left-to-right':\n                    item.update(left + offset, top, size + extra, height);\n                    left += size + extra + this._spacing;\n                    break;\n                case 'top-to-bottom':\n                    item.update(left, top + offset, width, size + extra);\n                    top += size + extra + this._spacing;\n                    break;\n                case 'right-to-left':\n                    item.update(left - offset - size - extra, top, size + extra, height);\n                    left -= size + extra + this._spacing;\n                    break;\n                case 'bottom-to-top':\n                    item.update(left, top - offset - size - extra, width, size + extra);\n                    top -= size + extra + this._spacing;\n                    break;\n                default:\n                    throw 'unreachable';\n            }\n        }\n    }\n}\n/**\n * The namespace for the `BoxLayout` class statics.\n */\n(function (BoxLayout) {\n    /**\n     * Get the box layout stretch factor for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @returns The box layout stretch factor for the widget.\n     */\n    function getStretch(widget) {\n        return Private$c.stretchProperty.get(widget);\n    }\n    BoxLayout.getStretch = getStretch;\n    /**\n     * Set the box layout stretch factor for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @param value - The value for the stretch factor.\n     */\n    function setStretch(widget, value) {\n        Private$c.stretchProperty.set(widget, value);\n    }\n    BoxLayout.setStretch = setStretch;\n    /**\n     * Get the box layout size basis for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @returns The box layout size basis for the widget.\n     */\n    function getSizeBasis(widget) {\n        return Private$c.sizeBasisProperty.get(widget);\n    }\n    BoxLayout.getSizeBasis = getSizeBasis;\n    /**\n     * Set the box layout size basis for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @param value - The value for the size basis.\n     */\n    function setSizeBasis(widget, value) {\n        Private$c.sizeBasisProperty.set(widget, value);\n    }\n    BoxLayout.setSizeBasis = setSizeBasis;\n})(BoxLayout || (BoxLayout = {}));\n/**\n * The namespace for the module implementation details.\n */\nvar Private$c;\n(function (Private) {\n    /**\n     * The property descriptor for a widget stretch factor.\n     */\n    Private.stretchProperty = new _lumino_properties__WEBPACK_IMPORTED_MODULE_4__.AttachedProperty({\n        name: 'stretch',\n        create: () => 0,\n        coerce: (owner, value) => Math.max(0, Math.floor(value)),\n        changed: onChildSizingChanged\n    });\n    /**\n     * The property descriptor for a widget size basis.\n     */\n    Private.sizeBasisProperty = new _lumino_properties__WEBPACK_IMPORTED_MODULE_4__.AttachedProperty({\n        name: 'sizeBasis',\n        create: () => 0,\n        coerce: (owner, value) => Math.max(0, Math.floor(value)),\n        changed: onChildSizingChanged\n    });\n    /**\n     * Test whether a direction has horizontal orientation.\n     */\n    function isHorizontal(dir) {\n        return dir === 'left-to-right' || dir === 'right-to-left';\n    }\n    Private.isHorizontal = isHorizontal;\n    /**\n     * Clamp a spacing value to an integer >= 0.\n     */\n    function clampSpacing(value) {\n        return Math.max(0, Math.floor(value));\n    }\n    Private.clampSpacing = clampSpacing;\n    /**\n     * The change handler for the attached sizing properties.\n     */\n    function onChildSizingChanged(child) {\n        if (child.parent && child.parent.layout instanceof BoxLayout) {\n            child.parent.fit();\n        }\n    }\n})(Private$c || (Private$c = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A panel which arranges its widgets in a single row or column.\n *\n * #### Notes\n * This class provides a convenience wrapper around a {@link BoxLayout}.\n */\nclass BoxPanel extends Panel {\n    /**\n     * Construct a new box panel.\n     *\n     * @param options - The options for initializing the box panel.\n     */\n    constructor(options = {}) {\n        super({ layout: Private$b.createLayout(options) });\n        this.addClass('lm-BoxPanel');\n    }\n    /**\n     * Get the layout direction for the box panel.\n     */\n    get direction() {\n        return this.layout.direction;\n    }\n    /**\n     * Set the layout direction for the box panel.\n     */\n    set direction(value) {\n        this.layout.direction = value;\n    }\n    /**\n     * Get the content alignment for the box panel.\n     *\n     * #### Notes\n     * This is the alignment of the widgets in the layout direction.\n     *\n     * The alignment has no effect if the widgets can expand to fill the\n     * entire box layout.\n     */\n    get alignment() {\n        return this.layout.alignment;\n    }\n    /**\n     * Set the content alignment for the box panel.\n     *\n     * #### Notes\n     * This is the alignment of the widgets in the layout direction.\n     *\n     * The alignment has no effect if the widgets can expand to fill the\n     * entire box layout.\n     */\n    set alignment(value) {\n        this.layout.alignment = value;\n    }\n    /**\n     * Get the inter-element spacing for the box panel.\n     */\n    get spacing() {\n        return this.layout.spacing;\n    }\n    /**\n     * Set the inter-element spacing for the box panel.\n     */\n    set spacing(value) {\n        this.layout.spacing = value;\n    }\n    /**\n     * A message handler invoked on a `'child-added'` message.\n     */\n    onChildAdded(msg) {\n        msg.child.addClass('lm-BoxPanel-child');\n    }\n    /**\n     * A message handler invoked on a `'child-removed'` message.\n     */\n    onChildRemoved(msg) {\n        msg.child.removeClass('lm-BoxPanel-child');\n    }\n}\n/**\n * The namespace for the `BoxPanel` class statics.\n */\n(function (BoxPanel) {\n    /**\n     * Get the box panel stretch factor for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @returns The box panel stretch factor for the widget.\n     */\n    function getStretch(widget) {\n        return BoxLayout.getStretch(widget);\n    }\n    BoxPanel.getStretch = getStretch;\n    /**\n     * Set the box panel stretch factor for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @param value - The value for the stretch factor.\n     */\n    function setStretch(widget, value) {\n        BoxLayout.setStretch(widget, value);\n    }\n    BoxPanel.setStretch = setStretch;\n    /**\n     * Get the box panel size basis for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @returns The box panel size basis for the widget.\n     */\n    function getSizeBasis(widget) {\n        return BoxLayout.getSizeBasis(widget);\n    }\n    BoxPanel.getSizeBasis = getSizeBasis;\n    /**\n     * Set the box panel size basis for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @param value - The value for the size basis.\n     */\n    function setSizeBasis(widget, value) {\n        BoxLayout.setSizeBasis(widget, value);\n    }\n    BoxPanel.setSizeBasis = setSizeBasis;\n})(BoxPanel || (BoxPanel = {}));\n/**\n * The namespace for the module implementation details.\n */\nvar Private$b;\n(function (Private) {\n    /**\n     * Create a box layout for the given panel options.\n     */\n    function createLayout(options) {\n        return options.layout || new BoxLayout(options);\n    }\n    Private.createLayout = createLayout;\n})(Private$b || (Private$b = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A widget which displays command items as a searchable palette.\n */\nclass CommandPalette extends Widget {\n    /**\n     * Construct a new command palette.\n     *\n     * @param options - The options for initializing the palette.\n     */\n    constructor(options) {\n        super({ node: Private$a.createNode() });\n        this._activeIndex = -1;\n        this._items = [];\n        this._results = null;\n        this.addClass('lm-CommandPalette');\n        this.setFlag(Widget.Flag.DisallowLayout);\n        this.commands = options.commands;\n        this.renderer = options.renderer || CommandPalette.defaultRenderer;\n        this.commands.commandChanged.connect(this._onGenericChange, this);\n        this.commands.keyBindingChanged.connect(this._onGenericChange, this);\n    }\n    /**\n     * Dispose of the resources held by the widget.\n     */\n    dispose() {\n        this._items.length = 0;\n        this._results = null;\n        super.dispose();\n    }\n    /**\n     * The command palette search node.\n     *\n     * #### Notes\n     * This is the node which contains the search-related elements.\n     */\n    get searchNode() {\n        return this.node.getElementsByClassName('lm-CommandPalette-search')[0];\n    }\n    /**\n     * The command palette input node.\n     *\n     * #### Notes\n     * This is the actual input node for the search area.\n     */\n    get inputNode() {\n        return this.node.getElementsByClassName('lm-CommandPalette-input')[0];\n    }\n    /**\n     * The command palette content node.\n     *\n     * #### Notes\n     * This is the node which holds the command item nodes.\n     *\n     * Modifying this node directly can lead to undefined behavior.\n     */\n    get contentNode() {\n        return this.node.getElementsByClassName('lm-CommandPalette-content')[0];\n    }\n    /**\n     * A read-only array of the command items in the palette.\n     */\n    get items() {\n        return this._items;\n    }\n    /**\n     * Add a command item to the command palette.\n     *\n     * @param options - The options for creating the command item.\n     *\n     * @returns The command item added to the palette.\n     */\n    addItem(options) {\n        // Create a new command item for the options.\n        let item = Private$a.createItem(this.commands, options);\n        // Add the item to the array.\n        this._items.push(item);\n        // Refresh the search results.\n        this.refresh();\n        // Return the item added to the palette.\n        return item;\n    }\n    /**\n     * Adds command items to the command palette.\n     *\n     * @param items - An array of options for creating each command item.\n     *\n     * @returns The command items added to the palette.\n     */\n    addItems(items) {\n        const newItems = items.map(item => Private$a.createItem(this.commands, item));\n        newItems.forEach(item => this._items.push(item));\n        this.refresh();\n        return newItems;\n    }\n    /**\n     * Remove an item from the command palette.\n     *\n     * @param item - The item to remove from the palette.\n     *\n     * #### Notes\n     * This is a no-op if the item is not in the palette.\n     */\n    removeItem(item) {\n        this.removeItemAt(this._items.indexOf(item));\n    }\n    /**\n     * Remove the item at a given index from the command palette.\n     *\n     * @param index - The index of the item to remove.\n     *\n     * #### Notes\n     * This is a no-op if the index is out of range.\n     */\n    removeItemAt(index) {\n        // Remove the item from the array.\n        let item = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(this._items, index);\n        // Bail if the index is out of range.\n        if (!item) {\n            return;\n        }\n        // Refresh the search results.\n        this.refresh();\n    }\n    /**\n     * Remove all items from the command palette.\n     */\n    clearItems() {\n        // Bail if there is nothing to remove.\n        if (this._items.length === 0) {\n            return;\n        }\n        // Clear the array of items.\n        this._items.length = 0;\n        // Refresh the search results.\n        this.refresh();\n    }\n    /**\n     * Clear the search results and schedule an update.\n     *\n     * #### Notes\n     * This should be called whenever the search results of the palette\n     * should be updated.\n     *\n     * This is typically called automatically by the palette as needed,\n     * but can be called manually if the input text is programatically\n     * changed.\n     *\n     * The rendered results are updated asynchronously.\n     */\n    refresh() {\n        this._results = null;\n        if (this.inputNode.value !== '') {\n            let clear = this.node.getElementsByClassName('lm-close-icon')[0];\n            clear.style.display = 'inherit';\n        }\n        else {\n            let clear = this.node.getElementsByClassName('lm-close-icon')[0];\n            clear.style.display = 'none';\n        }\n        this.update();\n    }\n    /**\n     * Handle the DOM events for the command palette.\n     *\n     * @param event - The DOM event sent to the command palette.\n     *\n     * #### Notes\n     * This method implements the DOM `EventListener` interface and is\n     * called in response to events on the command palette's DOM node.\n     * It should not be called directly by user code.\n     */\n    handleEvent(event) {\n        switch (event.type) {\n            case 'click':\n                this._evtClick(event);\n                break;\n            case 'keydown':\n                this._evtKeyDown(event);\n                break;\n            case 'input':\n                this.refresh();\n                break;\n            case 'focus':\n            case 'blur':\n                this._toggleFocused();\n                break;\n        }\n    }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     */\n    onBeforeAttach(msg) {\n        this.node.addEventListener('click', this);\n        this.node.addEventListener('keydown', this);\n        this.node.addEventListener('input', this);\n        this.node.addEventListener('focus', this, true);\n        this.node.addEventListener('blur', this, true);\n    }\n    /**\n     * A message handler invoked on an `'after-detach'` message.\n     */\n    onAfterDetach(msg) {\n        this.node.removeEventListener('click', this);\n        this.node.removeEventListener('keydown', this);\n        this.node.removeEventListener('input', this);\n        this.node.removeEventListener('focus', this, true);\n        this.node.removeEventListener('blur', this, true);\n    }\n    /**\n     * A message handler invoked on an `'after-show'` message.\n     */\n    onAfterShow(msg) {\n        this.update();\n        super.onAfterShow(msg);\n    }\n    /**\n     * A message handler invoked on an `'activate-request'` message.\n     */\n    onActivateRequest(msg) {\n        if (this.isAttached) {\n            let input = this.inputNode;\n            input.focus();\n            input.select();\n        }\n    }\n    /**\n     * A message handler invoked on an `'update-request'` message.\n     */\n    onUpdateRequest(msg) {\n        if (this.isHidden) {\n            return;\n        }\n        // Fetch the current query text and content node.\n        let query = this.inputNode.value;\n        let contentNode = this.contentNode;\n        // Ensure the search results are generated.\n        let results = this._results;\n        if (!results) {\n            // Generate and store the new search results.\n            results = this._results = Private$a.search(this._items, query);\n            // Reset the active index.\n            this._activeIndex = query\n                ? _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(results, Private$a.canActivate)\n                : -1;\n        }\n        // If there is no query and no results, clear the content.\n        if (!query && results.length === 0) {\n            _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.VirtualDOM.render(null, contentNode);\n            return;\n        }\n        // If the is a query but no results, render the empty message.\n        if (query && results.length === 0) {\n            let content = this.renderer.renderEmptyMessage({ query });\n            _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.VirtualDOM.render(content, contentNode);\n            return;\n        }\n        // Create the render content for the search results.\n        let renderer = this.renderer;\n        let activeIndex = this._activeIndex;\n        let content = new Array(results.length);\n        for (let i = 0, n = results.length; i < n; ++i) {\n            let result = results[i];\n            if (result.type === 'header') {\n                let indices = result.indices;\n                let category = result.category;\n                content[i] = renderer.renderHeader({ category, indices });\n            }\n            else {\n                let item = result.item;\n                let indices = result.indices;\n                let active = i === activeIndex;\n                content[i] = renderer.renderItem({ item, indices, active });\n            }\n        }\n        // Render the search result content.\n        _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.VirtualDOM.render(content, contentNode);\n        // Adjust the scroll position as needed.\n        if (activeIndex < 0 || activeIndex >= results.length) {\n            contentNode.scrollTop = 0;\n        }\n        else {\n            let element = contentNode.children[activeIndex];\n            _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.scrollIntoViewIfNeeded(contentNode, element);\n        }\n    }\n    /**\n     * Handle the `'click'` event for the command palette.\n     */\n    _evtClick(event) {\n        // Bail if the click is not the left button.\n        if (event.button !== 0) {\n            return;\n        }\n        // Clear input if the target is clear button\n        if (event.target.classList.contains('lm-close-icon')) {\n            this.inputNode.value = '';\n            this.refresh();\n            return;\n        }\n        // Find the index of the item which was clicked.\n        let index = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(this.contentNode.children, node => {\n            return node.contains(event.target);\n        });\n        // Bail if the click was not on an item.\n        if (index === -1) {\n            return;\n        }\n        // Kill the event when a content item is clicked.\n        event.preventDefault();\n        event.stopPropagation();\n        // Execute the item if possible.\n        this._execute(index);\n    }\n    /**\n     * Handle the `'keydown'` event for the command palette.\n     */\n    _evtKeyDown(event) {\n        if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {\n            return;\n        }\n        switch (event.keyCode) {\n            case 13: // Enter\n                event.preventDefault();\n                event.stopPropagation();\n                this._execute(this._activeIndex);\n                break;\n            case 38: // Up Arrow\n                event.preventDefault();\n                event.stopPropagation();\n                this._activatePreviousItem();\n                break;\n            case 40: // Down Arrow\n                event.preventDefault();\n                event.stopPropagation();\n                this._activateNextItem();\n                break;\n        }\n    }\n    /**\n     * Activate the next enabled command item.\n     */\n    _activateNextItem() {\n        // Bail if there are no search results.\n        if (!this._results || this._results.length === 0) {\n            return;\n        }\n        // Find the next enabled item index.\n        let ai = this._activeIndex;\n        let n = this._results.length;\n        let start = ai < n - 1 ? ai + 1 : 0;\n        let stop = start === 0 ? n - 1 : start - 1;\n        this._activeIndex = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(this._results, Private$a.canActivate, start, stop);\n        // Schedule an update of the items.\n        this.update();\n    }\n    /**\n     * Activate the previous enabled command item.\n     */\n    _activatePreviousItem() {\n        // Bail if there are no search results.\n        if (!this._results || this._results.length === 0) {\n            return;\n        }\n        // Find the previous enabled item index.\n        let ai = this._activeIndex;\n        let n = this._results.length;\n        let start = ai <= 0 ? n - 1 : ai - 1;\n        let stop = start === n - 1 ? 0 : start + 1;\n        this._activeIndex = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findLastIndex(this._results, Private$a.canActivate, start, stop);\n        // Schedule an update of the items.\n        this.update();\n    }\n    /**\n     * Execute the command item at the given index, if possible.\n     */\n    _execute(index) {\n        // Bail if there are no search results.\n        if (!this._results) {\n            return;\n        }\n        // Bail if the index is out of range.\n        let part = this._results[index];\n        if (!part) {\n            return;\n        }\n        // Update the search text if the item is a header.\n        if (part.type === 'header') {\n            let input = this.inputNode;\n            input.value = `${part.category.toLowerCase()} `;\n            input.focus();\n            this.refresh();\n            return;\n        }\n        // Bail if item is not enabled.\n        if (!part.item.isEnabled) {\n            return;\n        }\n        // Execute the item.\n        this.commands.execute(part.item.command, part.item.args);\n        // Clear the query text.\n        this.inputNode.value = '';\n        // Refresh the search results.\n        this.refresh();\n    }\n    /**\n     * Toggle the focused modifier based on the input node focus state.\n     */\n    _toggleFocused() {\n        let focused = document.activeElement === this.inputNode;\n        this.toggleClass('lm-mod-focused', focused);\n    }\n    /**\n     * A signal handler for generic command changes.\n     */\n    _onGenericChange() {\n        this.refresh();\n    }\n}\n/**\n * The namespace for the `CommandPalette` class statics.\n */\n(function (CommandPalette) {\n    /**\n     * The default implementation of `IRenderer`.\n     */\n    class Renderer {\n        /**\n         * Render the virtual element for a command palette header.\n         *\n         * @param data - The data to use for rendering the header.\n         *\n         * @returns A virtual element representing the header.\n         */\n        renderHeader(data) {\n            let content = this.formatHeader(data);\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.li({ className: 'lm-CommandPalette-header' }, content);\n        }\n        /**\n         * Render the virtual element for a command palette item.\n         *\n         * @param data - The data to use for rendering the item.\n         *\n         * @returns A virtual element representing the item.\n         */\n        renderItem(data) {\n            let className = this.createItemClass(data);\n            let dataset = this.createItemDataset(data);\n            if (data.item.isToggleable) {\n                return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.li({\n                    className,\n                    dataset,\n                    role: 'menuitemcheckbox',\n                    'aria-checked': `${data.item.isToggled}`\n                }, this.renderItemIcon(data), this.renderItemContent(data), this.renderItemShortcut(data));\n            }\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.li({\n                className,\n                dataset,\n                role: 'menuitem'\n            }, this.renderItemIcon(data), this.renderItemContent(data), this.renderItemShortcut(data));\n        }\n        /**\n         * Render the empty results message for a command palette.\n         *\n         * @param data - The data to use for rendering the message.\n         *\n         * @returns A virtual element representing the message.\n         */\n        renderEmptyMessage(data) {\n            let content = this.formatEmptyMessage(data);\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.li({ className: 'lm-CommandPalette-emptyMessage' }, content);\n        }\n        /**\n         * Render the icon for a command palette item.\n         *\n         * @param data - The data to use for rendering the icon.\n         *\n         * @returns A virtual element representing the icon.\n         */\n        renderItemIcon(data) {\n            let className = this.createIconClass(data);\n            // If data.item.icon is undefined, it will be ignored.\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className }, data.item.icon, data.item.iconLabel);\n        }\n        /**\n         * Render the content for a command palette item.\n         *\n         * @param data - The data to use for rendering the content.\n         *\n         * @returns A virtual element representing the content.\n         */\n        renderItemContent(data) {\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className: 'lm-CommandPalette-itemContent' }, this.renderItemLabel(data), this.renderItemCaption(data));\n        }\n        /**\n         * Render the label for a command palette item.\n         *\n         * @param data - The data to use for rendering the label.\n         *\n         * @returns A virtual element representing the label.\n         */\n        renderItemLabel(data) {\n            let content = this.formatItemLabel(data);\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className: 'lm-CommandPalette-itemLabel' }, content);\n        }\n        /**\n         * Render the caption for a command palette item.\n         *\n         * @param data - The data to use for rendering the caption.\n         *\n         * @returns A virtual element representing the caption.\n         */\n        renderItemCaption(data) {\n            let content = this.formatItemCaption(data);\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className: 'lm-CommandPalette-itemCaption' }, content);\n        }\n        /**\n         * Render the shortcut for a command palette item.\n         *\n         * @param data - The data to use for rendering the shortcut.\n         *\n         * @returns A virtual element representing the shortcut.\n         */\n        renderItemShortcut(data) {\n            let content = this.formatItemShortcut(data);\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className: 'lm-CommandPalette-itemShortcut' }, content);\n        }\n        /**\n         * Create the class name for the command palette item.\n         *\n         * @param data - The data to use for the class name.\n         *\n         * @returns The full class name for the command palette item.\n         */\n        createItemClass(data) {\n            // Set up the initial class name.\n            let name = 'lm-CommandPalette-item';\n            // Add the boolean state classes.\n            if (!data.item.isEnabled) {\n                name += ' lm-mod-disabled';\n            }\n            if (data.item.isToggled) {\n                name += ' lm-mod-toggled';\n            }\n            if (data.active) {\n                name += ' lm-mod-active';\n            }\n            // Add the extra class.\n            let extra = data.item.className;\n            if (extra) {\n                name += ` ${extra}`;\n            }\n            // Return the complete class name.\n            return name;\n        }\n        /**\n         * Create the dataset for the command palette item.\n         *\n         * @param data - The data to use for creating the dataset.\n         *\n         * @returns The dataset for the command palette item.\n         */\n        createItemDataset(data) {\n            return { ...data.item.dataset, command: data.item.command };\n        }\n        /**\n         * Create the class name for the command item icon.\n         *\n         * @param data - The data to use for the class name.\n         *\n         * @returns The full class name for the item icon.\n         */\n        createIconClass(data) {\n            let name = 'lm-CommandPalette-itemIcon';\n            let extra = data.item.iconClass;\n            return extra ? `${name} ${extra}` : name;\n        }\n        /**\n         * Create the render content for the header node.\n         *\n         * @param data - The data to use for the header content.\n         *\n         * @returns The content to add to the header node.\n         */\n        formatHeader(data) {\n            if (!data.indices || data.indices.length === 0) {\n                return data.category;\n            }\n            return _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.StringExt.highlight(data.category, data.indices, _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.mark);\n        }\n        /**\n         * Create the render content for the empty message node.\n         *\n         * @param data - The data to use for the empty message content.\n         *\n         * @returns The content to add to the empty message node.\n         */\n        formatEmptyMessage(data) {\n            return `No commands found that match '${data.query}'`;\n        }\n        /**\n         * Create the render content for the item shortcut node.\n         *\n         * @param data - The data to use for the shortcut content.\n         *\n         * @returns The content to add to the shortcut node.\n         */\n        formatItemShortcut(data) {\n            let kb = data.item.keyBinding;\n            return kb ? _lumino_commands__WEBPACK_IMPORTED_MODULE_7__.CommandRegistry.formatKeystroke(kb.keys) : null;\n        }\n        /**\n         * Create the render content for the item label node.\n         *\n         * @param data - The data to use for the label content.\n         *\n         * @returns The content to add to the label node.\n         */\n        formatItemLabel(data) {\n            if (!data.indices || data.indices.length === 0) {\n                return data.item.label;\n            }\n            return _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.StringExt.highlight(data.item.label, data.indices, _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.mark);\n        }\n        /**\n         * Create the render content for the item caption node.\n         *\n         * @param data - The data to use for the caption content.\n         *\n         * @returns The content to add to the caption node.\n         */\n        formatItemCaption(data) {\n            return data.item.caption;\n        }\n    }\n    CommandPalette.Renderer = Renderer;\n    /**\n     * The default `Renderer` instance.\n     */\n    CommandPalette.defaultRenderer = new Renderer();\n})(CommandPalette || (CommandPalette = {}));\n/**\n * The namespace for the module implementation details.\n */\nvar Private$a;\n(function (Private) {\n    /**\n     * Create the DOM node for a command palette.\n     */\n    function createNode() {\n        let node = document.createElement('div');\n        let search = document.createElement('div');\n        let wrapper = document.createElement('div');\n        let input = document.createElement('input');\n        let content = document.createElement('ul');\n        let clear = document.createElement('button');\n        search.className = 'lm-CommandPalette-search';\n        wrapper.className = 'lm-CommandPalette-wrapper';\n        input.className = 'lm-CommandPalette-input';\n        clear.className = 'lm-close-icon';\n        content.className = 'lm-CommandPalette-content';\n        content.setAttribute('role', 'menu');\n        input.spellcheck = false;\n        wrapper.appendChild(input);\n        wrapper.appendChild(clear);\n        search.appendChild(wrapper);\n        node.appendChild(search);\n        node.appendChild(content);\n        return node;\n    }\n    Private.createNode = createNode;\n    /**\n     * Create a new command item from a command registry and options.\n     */\n    function createItem(commands, options) {\n        return new CommandItem(commands, options);\n    }\n    Private.createItem = createItem;\n    /**\n     * Search an array of command items for fuzzy matches.\n     */\n    function search(items, query) {\n        // Fuzzy match the items for the query.\n        let scores = matchItems(items, query);\n        // Sort the items based on their score.\n        scores.sort(scoreCmp);\n        // Create the results for the search.\n        return createResults(scores);\n    }\n    Private.search = search;\n    /**\n     * Test whether a result item can be activated.\n     */\n    function canActivate(result) {\n        return result.type === 'item' && result.item.isEnabled;\n    }\n    Private.canActivate = canActivate;\n    /**\n     * Normalize a category for a command item.\n     */\n    function normalizeCategory(category) {\n        return category.trim().replace(/\\s+/g, ' ');\n    }\n    /**\n     * Normalize the query text for a fuzzy search.\n     */\n    function normalizeQuery(text) {\n        return text.replace(/\\s+/g, '').toLowerCase();\n    }\n    /**\n     * Perform a fuzzy match on an array of command items.\n     */\n    function matchItems(items, query) {\n        // Normalize the query text to lower case with no whitespace.\n        query = normalizeQuery(query);\n        // Create the array to hold the scores.\n        let scores = [];\n        // Iterate over the items and match against the query.\n        for (let i = 0, n = items.length; i < n; ++i) {\n            // Ignore items which are not visible.\n            let item = items[i];\n            if (!item.isVisible) {\n                continue;\n            }\n            // If the query is empty, all items are matched by default.\n            if (!query) {\n                scores.push({\n                    matchType: 3 /* MatchType.Default */,\n                    categoryIndices: null,\n                    labelIndices: null,\n                    score: 0,\n                    item\n                });\n                continue;\n            }\n            // Run the fuzzy search for the item and query.\n            let score = fuzzySearch(item, query);\n            // Ignore the item if it is not a match.\n            if (!score) {\n                continue;\n            }\n            // Penalize disabled items.\n            // TODO - push disabled items all the way down in sort cmp?\n            if (!item.isEnabled) {\n                score.score += 1000;\n            }\n            // Add the score to the results.\n            scores.push(score);\n        }\n        // Return the final array of scores.\n        return scores;\n    }\n    /**\n     * Perform a fuzzy search on a single command item.\n     */\n    function fuzzySearch(item, query) {\n        // Create the source text to be searched.\n        let category = item.category.toLowerCase();\n        let label = item.label.toLowerCase();\n        let source = `${category} ${label}`;\n        // Set up the match score and indices array.\n        let score = Infinity;\n        let indices = null;\n        // The regex for search word boundaries\n        let rgx = /\\b\\w/g;\n        // Search the source by word boundary.\n        // eslint-disable-next-line no-constant-condition\n        while (true) {\n            // Find the next word boundary in the source.\n            let rgxMatch = rgx.exec(source);\n            // Break if there is no more source context.\n            if (!rgxMatch) {\n                break;\n            }\n            // Run the string match on the relevant substring.\n            let match = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.StringExt.matchSumOfDeltas(source, query, rgxMatch.index);\n            // Break if there is no match.\n            if (!match) {\n                break;\n            }\n            // Update the match if the score is better.\n            if (match.score <= score) {\n                score = match.score;\n                indices = match.indices;\n            }\n        }\n        // Bail if there was no match.\n        if (!indices || score === Infinity) {\n            return null;\n        }\n        // Compute the pivot index between category and label text.\n        let pivot = category.length + 1;\n        // Find the slice index to separate matched indices.\n        let j = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.lowerBound(indices, pivot, (a, b) => a - b);\n        // Extract the matched category and label indices.\n        let categoryIndices = indices.slice(0, j);\n        let labelIndices = indices.slice(j);\n        // Adjust the label indices for the pivot offset.\n        for (let i = 0, n = labelIndices.length; i < n; ++i) {\n            labelIndices[i] -= pivot;\n        }\n        // Handle a pure label match.\n        if (categoryIndices.length === 0) {\n            return {\n                matchType: 0 /* MatchType.Label */,\n                categoryIndices: null,\n                labelIndices,\n                score,\n                item\n            };\n        }\n        // Handle a pure category match.\n        if (labelIndices.length === 0) {\n            return {\n                matchType: 1 /* MatchType.Category */,\n                categoryIndices,\n                labelIndices: null,\n                score,\n                item\n            };\n        }\n        // Handle a split match.\n        return {\n            matchType: 2 /* MatchType.Split */,\n            categoryIndices,\n            labelIndices,\n            score,\n            item\n        };\n    }\n    /**\n     * A sort comparison function for a match score.\n     */\n    function scoreCmp(a, b) {\n        // First compare based on the match type\n        let m1 = a.matchType - b.matchType;\n        if (m1 !== 0) {\n            return m1;\n        }\n        // Otherwise, compare based on the match score.\n        let d1 = a.score - b.score;\n        if (d1 !== 0) {\n            return d1;\n        }\n        // Find the match index based on the match type.\n        let i1 = 0;\n        let i2 = 0;\n        switch (a.matchType) {\n            case 0 /* MatchType.Label */:\n                i1 = a.labelIndices[0];\n                i2 = b.labelIndices[0];\n                break;\n            case 1 /* MatchType.Category */:\n            case 2 /* MatchType.Split */:\n                i1 = a.categoryIndices[0];\n                i2 = b.categoryIndices[0];\n                break;\n        }\n        // Compare based on the match index.\n        if (i1 !== i2) {\n            return i1 - i2;\n        }\n        // Otherwise, compare by category.\n        let d2 = a.item.category.localeCompare(b.item.category);\n        if (d2 !== 0) {\n            return d2;\n        }\n        // Otherwise, compare by rank.\n        let r1 = a.item.rank;\n        let r2 = b.item.rank;\n        if (r1 !== r2) {\n            return r1 < r2 ? -1 : 1; // Infinity safe\n        }\n        // Finally, compare by label.\n        return a.item.label.localeCompare(b.item.label);\n    }\n    /**\n     * Create the results from an array of sorted scores.\n     */\n    function createResults(scores) {\n        // Set up an array to track which scores have been visited.\n        let visited = new Array(scores.length);\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.fill(visited, false);\n        // Set up the search results array.\n        let results = [];\n        // Iterate over each score in the array.\n        for (let i = 0, n = scores.length; i < n; ++i) {\n            // Ignore a score which has already been processed.\n            if (visited[i]) {\n                continue;\n            }\n            // Extract the current item and indices.\n            let { item, categoryIndices } = scores[i];\n            // Extract the category for the current item.\n            let category = item.category;\n            // Add the header result for the category.\n            results.push({ type: 'header', category, indices: categoryIndices });\n            // Find the rest of the scores with the same category.\n            for (let j = i; j < n; ++j) {\n                // Ignore a score which has already been processed.\n                if (visited[j]) {\n                    continue;\n                }\n                // Extract the data for the current score.\n                let { item, labelIndices } = scores[j];\n                // Ignore an item with a different category.\n                if (item.category !== category) {\n                    continue;\n                }\n                // Create the item result for the score.\n                results.push({ type: 'item', item, indices: labelIndices });\n                // Mark the score as processed.\n                visited[j] = true;\n            }\n        }\n        // Return the final results.\n        return results;\n    }\n    /**\n     * A concrete implementation of `CommandPalette.IItem`.\n     */\n    class CommandItem {\n        /**\n         * Construct a new command item.\n         */\n        constructor(commands, options) {\n            this._commands = commands;\n            this.category = normalizeCategory(options.category);\n            this.command = options.command;\n            this.args = options.args || _lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__.JSONExt.emptyObject;\n            this.rank = options.rank !== undefined ? options.rank : Infinity;\n        }\n        /**\n         * The display label for the command item.\n         */\n        get label() {\n            return this._commands.label(this.command, this.args);\n        }\n        /**\n         * The icon renderer for the command item.\n         */\n        get icon() {\n            return this._commands.icon(this.command, this.args);\n        }\n        /**\n         * The icon class for the command item.\n         */\n        get iconClass() {\n            return this._commands.iconClass(this.command, this.args);\n        }\n        /**\n         * The icon label for the command item.\n         */\n        get iconLabel() {\n            return this._commands.iconLabel(this.command, this.args);\n        }\n        /**\n         * The display caption for the command item.\n         */\n        get caption() {\n            return this._commands.caption(this.command, this.args);\n        }\n        /**\n         * The extra class name for the command item.\n         */\n        get className() {\n            return this._commands.className(this.command, this.args);\n        }\n        /**\n         * The dataset for the command item.\n         */\n        get dataset() {\n            return this._commands.dataset(this.command, this.args);\n        }\n        /**\n         * Whether the command item is enabled.\n         */\n        get isEnabled() {\n            return this._commands.isEnabled(this.command, this.args);\n        }\n        /**\n         * Whether the command item is toggled.\n         */\n        get isToggled() {\n            return this._commands.isToggled(this.command, this.args);\n        }\n        /**\n         * Whether the command item is toggleable.\n         */\n        get isToggleable() {\n            return this._commands.isToggleable(this.command, this.args);\n        }\n        /**\n         * Whether the command item is visible.\n         */\n        get isVisible() {\n            return this._commands.isVisible(this.command, this.args);\n        }\n        /**\n         * The key binding for the command item.\n         */\n        get keyBinding() {\n            let { command, args } = this;\n            return (_lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findLastValue(this._commands.keyBindings, kb => {\n                return kb.command === command && _lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__.JSONExt.deepEqual(kb.args, args);\n            }) || null);\n        }\n    }\n})(Private$a || (Private$a = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A widget which displays items as a canonical menu.\n */\nclass Menu extends Widget {\n    /**\n     * Construct a new menu.\n     *\n     * @param options - The options for initializing the menu.\n     */\n    constructor(options) {\n        super({ node: Private$9.createNode() });\n        this._childIndex = -1;\n        this._activeIndex = -1;\n        this._openTimerID = 0;\n        this._closeTimerID = 0;\n        this._items = [];\n        this._childMenu = null;\n        this._parentMenu = null;\n        this._aboutToClose = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._menuRequested = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this.addClass('lm-Menu');\n        this.setFlag(Widget.Flag.DisallowLayout);\n        this.commands = options.commands;\n        this.renderer = options.renderer || Menu.defaultRenderer;\n    }\n    /**\n     * Dispose of the resources held by the menu.\n     */\n    dispose() {\n        this.close();\n        this._items.length = 0;\n        super.dispose();\n    }\n    /**\n     * A signal emitted just before the menu is closed.\n     *\n     * #### Notes\n     * This signal is emitted when the menu receives a `'close-request'`\n     * message, just before it removes itself from the DOM.\n     *\n     * This signal is not emitted if the menu is already detached from\n     * the DOM when it receives the `'close-request'` message.\n     */\n    get aboutToClose() {\n        return this._aboutToClose;\n    }\n    /**\n     * A signal emitted when a new menu is requested by the user.\n     *\n     * #### Notes\n     * This signal is emitted whenever the user presses the right or left\n     * arrow keys, and a submenu cannot be opened or closed in response.\n     *\n     * This signal is useful when implementing menu bars in order to open\n     * the next or previous menu in response to a user key press.\n     *\n     * This signal is only emitted for the root menu in a hierarchy.\n     */\n    get menuRequested() {\n        return this._menuRequested;\n    }\n    /**\n     * The parent menu of the menu.\n     *\n     * #### Notes\n     * This is `null` unless the menu is an open submenu.\n     */\n    get parentMenu() {\n        return this._parentMenu;\n    }\n    /**\n     * The child menu of the menu.\n     *\n     * #### Notes\n     * This is `null` unless the menu has an open submenu.\n     */\n    get childMenu() {\n        return this._childMenu;\n    }\n    /**\n     * The root menu of the menu hierarchy.\n     */\n    get rootMenu() {\n        // eslint-disable-next-line @typescript-eslint/no-this-alias\n        let menu = this;\n        while (menu._parentMenu) {\n            menu = menu._parentMenu;\n        }\n        return menu;\n    }\n    /**\n     * The leaf menu of the menu hierarchy.\n     */\n    get leafMenu() {\n        // eslint-disable-next-line @typescript-eslint/no-this-alias\n        let menu = this;\n        while (menu._childMenu) {\n            menu = menu._childMenu;\n        }\n        return menu;\n    }\n    /**\n     * The menu content node.\n     *\n     * #### Notes\n     * This is the node which holds the menu item nodes.\n     *\n     * Modifying this node directly can lead to undefined behavior.\n     */\n    get contentNode() {\n        return this.node.getElementsByClassName('lm-Menu-content')[0];\n    }\n    /**\n     * Get the currently active menu item.\n     */\n    get activeItem() {\n        return this._items[this._activeIndex] || null;\n    }\n    /**\n     * Set the currently active menu item.\n     *\n     * #### Notes\n     * If the item cannot be activated, the item will be set to `null`.\n     */\n    set activeItem(value) {\n        this.activeIndex = value ? this._items.indexOf(value) : -1;\n    }\n    /**\n     * Get the index of the currently active menu item.\n     *\n     * #### Notes\n     * This will be `-1` if no menu item is active.\n     */\n    get activeIndex() {\n        return this._activeIndex;\n    }\n    /**\n     * Set the index of the currently active menu item.\n     *\n     * #### Notes\n     * If the item cannot be activated, the index will be set to `-1`.\n     */\n    set activeIndex(value) {\n        // Adjust the value for an out of range index.\n        if (value < 0 || value >= this._items.length) {\n            value = -1;\n        }\n        // Ensure the item can be activated.\n        if (value !== -1 && !Private$9.canActivate(this._items[value])) {\n            value = -1;\n        }\n        // Bail if the index will not change.\n        if (this._activeIndex === value) {\n            return;\n        }\n        // Update the active index.\n        this._activeIndex = value;\n        // Make active element in focus\n        if (this._activeIndex >= 0 &&\n            this.contentNode.childNodes[this._activeIndex]) {\n            this.contentNode.childNodes[this._activeIndex].focus();\n        }\n        // schedule an update of the items.\n        this.update();\n    }\n    /**\n     * A read-only array of the menu items in the menu.\n     */\n    get items() {\n        return this._items;\n    }\n    /**\n     * Activate the next selectable item in the menu.\n     *\n     * #### Notes\n     * If no item is selectable, the index will be set to `-1`.\n     */\n    activateNextItem() {\n        let n = this._items.length;\n        let ai = this._activeIndex;\n        let start = ai < n - 1 ? ai + 1 : 0;\n        let stop = start === 0 ? n - 1 : start - 1;\n        this.activeIndex = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(this._items, Private$9.canActivate, start, stop);\n    }\n    /**\n     * Activate the previous selectable item in the menu.\n     *\n     * #### Notes\n     * If no item is selectable, the index will be set to `-1`.\n     */\n    activatePreviousItem() {\n        let n = this._items.length;\n        let ai = this._activeIndex;\n        let start = ai <= 0 ? n - 1 : ai - 1;\n        let stop = start === n - 1 ? 0 : start + 1;\n        this.activeIndex = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findLastIndex(this._items, Private$9.canActivate, start, stop);\n    }\n    /**\n     * Trigger the active menu item.\n     *\n     * #### Notes\n     * If the active item is a submenu, it will be opened and the first\n     * item will be activated.\n     *\n     * If the active item is a command, the command will be executed.\n     *\n     * If the menu is not attached, this is a no-op.\n     *\n     * If there is no active item, this is a no-op.\n     */\n    triggerActiveItem() {\n        // Bail if the menu is not attached.\n        if (!this.isAttached) {\n            return;\n        }\n        // Bail if there is no active item.\n        let item = this.activeItem;\n        if (!item) {\n            return;\n        }\n        // Cancel the pending timers.\n        this._cancelOpenTimer();\n        this._cancelCloseTimer();\n        // If the item is a submenu, open it.\n        if (item.type === 'submenu') {\n            this._openChildMenu(true);\n            return;\n        }\n        // Close the root menu before executing the command.\n        this.rootMenu.close();\n        // Execute the command for the item.\n        let { command, args } = item;\n        if (this.commands.isEnabled(command, args)) {\n            this.commands.execute(command, args);\n        }\n        else {\n            console.log(`Command '${command}' is disabled.`);\n        }\n    }\n    /**\n     * Add a menu item to the end of the menu.\n     *\n     * @param options - The options for creating the menu item.\n     *\n     * @returns The menu item added to the menu.\n     */\n    addItem(options) {\n        return this.insertItem(this._items.length, options);\n    }\n    /**\n     * Insert a menu item into the menu at the specified index.\n     *\n     * @param index - The index at which to insert the item.\n     *\n     * @param options - The options for creating the menu item.\n     *\n     * @returns The menu item added to the menu.\n     *\n     * #### Notes\n     * The index will be clamped to the bounds of the items.\n     */\n    insertItem(index, options) {\n        // Close the menu if it's attached.\n        if (this.isAttached) {\n            this.close();\n        }\n        // Reset the active index.\n        this.activeIndex = -1;\n        // Clamp the insert index to the array bounds.\n        let i = Math.max(0, Math.min(index, this._items.length));\n        // Create the item for the options.\n        let item = Private$9.createItem(this, options);\n        // Insert the item into the array.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(this._items, i, item);\n        // Schedule an update of the items.\n        this.update();\n        // Return the item added to the menu.\n        return item;\n    }\n    /**\n     * Remove an item from the menu.\n     *\n     * @param item - The item to remove from the menu.\n     *\n     * #### Notes\n     * This is a no-op if the item is not in the menu.\n     */\n    removeItem(item) {\n        this.removeItemAt(this._items.indexOf(item));\n    }\n    /**\n     * Remove the item at a given index from the menu.\n     *\n     * @param index - The index of the item to remove.\n     *\n     * #### Notes\n     * This is a no-op if the index is out of range.\n     */\n    removeItemAt(index) {\n        // Close the menu if it's attached.\n        if (this.isAttached) {\n            this.close();\n        }\n        // Reset the active index.\n        this.activeIndex = -1;\n        // Remove the item from the array.\n        let item = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(this._items, index);\n        // Bail if the index is out of range.\n        if (!item) {\n            return;\n        }\n        // Schedule an update of the items.\n        this.update();\n    }\n    /**\n     * Remove all menu items from the menu.\n     */\n    clearItems() {\n        // Close the menu if it's attached.\n        if (this.isAttached) {\n            this.close();\n        }\n        // Reset the active index.\n        this.activeIndex = -1;\n        // Bail if there is nothing to remove.\n        if (this._items.length === 0) {\n            return;\n        }\n        // Clear the items.\n        this._items.length = 0;\n        // Schedule an update of the items.\n        this.update();\n    }\n    /**\n     * Open the menu at the specified location.\n     *\n     * @param x - The client X coordinate of the menu location.\n     *\n     * @param y - The client Y coordinate of the menu location.\n     *\n     * @param options - The additional options for opening the menu.\n     *\n     * #### Notes\n     * The menu will be opened at the given location unless it will not\n     * fully fit on the screen. If it will not fit, it will be adjusted\n     * to fit naturally on the screen.\n     *\n     * This is a no-op if the menu is already attached to the DOM.\n     */\n    open(x, y, options = {}) {\n        // Bail early if the menu is already attached.\n        if (this.isAttached) {\n            return;\n        }\n        // Extract the position options.\n        let forceX = options.forceX || false;\n        let forceY = options.forceY || false;\n        // Open the menu as a root menu.\n        Private$9.openRootMenu(this, x, y, forceX, forceY);\n        // Activate the menu to accept keyboard input.\n        this.activate();\n    }\n    /**\n     * Handle the DOM events for the menu.\n     *\n     * @param event - The DOM event sent to the menu.\n     *\n     * #### Notes\n     * This method implements the DOM `EventListener` interface and is\n     * called in response to events on the menu's DOM nodes. It should\n     * not be called directly by user code.\n     */\n    handleEvent(event) {\n        switch (event.type) {\n            case 'keydown':\n                this._evtKeyDown(event);\n                break;\n            case 'mouseup':\n                this._evtMouseUp(event);\n                break;\n            case 'mousemove':\n                this._evtMouseMove(event);\n                break;\n            case 'mouseenter':\n                this._evtMouseEnter(event);\n                break;\n            case 'mouseleave':\n                this._evtMouseLeave(event);\n                break;\n            case 'mousedown':\n                this._evtMouseDown(event);\n                break;\n            case 'contextmenu':\n                event.preventDefault();\n                event.stopPropagation();\n                break;\n        }\n    }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     */\n    onBeforeAttach(msg) {\n        this.node.addEventListener('keydown', this);\n        this.node.addEventListener('mouseup', this);\n        this.node.addEventListener('mousemove', this);\n        this.node.addEventListener('mouseenter', this);\n        this.node.addEventListener('mouseleave', this);\n        this.node.addEventListener('contextmenu', this);\n        document.addEventListener('mousedown', this, true);\n    }\n    /**\n     * A message handler invoked on an `'after-detach'` message.\n     */\n    onAfterDetach(msg) {\n        this.node.removeEventListener('keydown', this);\n        this.node.removeEventListener('mouseup', this);\n        this.node.removeEventListener('mousemove', this);\n        this.node.removeEventListener('mouseenter', this);\n        this.node.removeEventListener('mouseleave', this);\n        this.node.removeEventListener('contextmenu', this);\n        document.removeEventListener('mousedown', this, true);\n    }\n    /**\n     * A message handler invoked on an `'activate-request'` message.\n     */\n    onActivateRequest(msg) {\n        if (this.isAttached) {\n            this.node.focus();\n        }\n    }\n    /**\n     * A message handler invoked on an `'update-request'` message.\n     */\n    onUpdateRequest(msg) {\n        let items = this._items;\n        let renderer = this.renderer;\n        let activeIndex = this._activeIndex;\n        let collapsedFlags = Private$9.computeCollapsed(items);\n        let content = new Array(items.length);\n        for (let i = 0, n = items.length; i < n; ++i) {\n            let item = items[i];\n            let active = i === activeIndex;\n            let collapsed = collapsedFlags[i];\n            content[i] = renderer.renderItem({\n                item,\n                active,\n                collapsed,\n                onfocus: () => {\n                    this.activeIndex = i;\n                }\n            });\n        }\n        _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.VirtualDOM.render(content, this.contentNode);\n    }\n    /**\n     * A message handler invoked on a `'close-request'` message.\n     */\n    onCloseRequest(msg) {\n        // Cancel the pending timers.\n        this._cancelOpenTimer();\n        this._cancelCloseTimer();\n        // Reset the active index.\n        this.activeIndex = -1;\n        // Close any open child menu.\n        let childMenu = this._childMenu;\n        if (childMenu) {\n            this._childIndex = -1;\n            this._childMenu = null;\n            childMenu._parentMenu = null;\n            childMenu.close();\n        }\n        // Remove this menu from its parent and activate the parent.\n        let parentMenu = this._parentMenu;\n        if (parentMenu) {\n            this._parentMenu = null;\n            parentMenu._childIndex = -1;\n            parentMenu._childMenu = null;\n            parentMenu.activate();\n        }\n        // Emit the `aboutToClose` signal if the menu is attached.\n        if (this.isAttached) {\n            this._aboutToClose.emit(undefined);\n        }\n        // Finish closing the menu.\n        super.onCloseRequest(msg);\n    }\n    /**\n     * Handle the `'keydown'` event for the menu.\n     *\n     * #### Notes\n     * This listener is attached to the menu node.\n     */\n    _evtKeyDown(event) {\n        // A menu handles all keydown events.\n        event.preventDefault();\n        event.stopPropagation();\n        // Fetch the key code for the event.\n        let kc = event.keyCode;\n        // Enter\n        if (kc === 13) {\n            this.triggerActiveItem();\n            return;\n        }\n        // Escape\n        if (kc === 27) {\n            this.close();\n            return;\n        }\n        // Left Arrow\n        if (kc === 37) {\n            if (this._parentMenu) {\n                this.close();\n            }\n            else {\n                this._menuRequested.emit('previous');\n            }\n            return;\n        }\n        // Up Arrow\n        if (kc === 38) {\n            this.activatePreviousItem();\n            return;\n        }\n        // Right Arrow\n        if (kc === 39) {\n            let item = this.activeItem;\n            if (item && item.type === 'submenu') {\n                this.triggerActiveItem();\n            }\n            else {\n                this.rootMenu._menuRequested.emit('next');\n            }\n            return;\n        }\n        // Down Arrow\n        if (kc === 40) {\n            this.activateNextItem();\n            return;\n        }\n        // Get the pressed key character.\n        let key = (0,_lumino_keyboard__WEBPACK_IMPORTED_MODULE_10__.getKeyboardLayout)().keyForKeydownEvent(event);\n        // Bail if the key is not valid.\n        if (!key) {\n            return;\n        }\n        // Search for the next best matching mnemonic item.\n        let start = this._activeIndex + 1;\n        let result = Private$9.findMnemonic(this._items, key, start);\n        // Handle the requested mnemonic based on the search results.\n        // If exactly one mnemonic is matched, that item is triggered.\n        // Otherwise, the next mnemonic is activated if available,\n        // followed by the auto mnemonic if available.\n        if (result.index !== -1 && !result.multiple) {\n            this.activeIndex = result.index;\n            this.triggerActiveItem();\n        }\n        else if (result.index !== -1) {\n            this.activeIndex = result.index;\n        }\n        else if (result.auto !== -1) {\n            this.activeIndex = result.auto;\n        }\n    }\n    /**\n     * Handle the `'mouseup'` event for the menu.\n     *\n     * #### Notes\n     * This listener is attached to the menu node.\n     */\n    _evtMouseUp(event) {\n        if (event.button !== 0) {\n            return;\n        }\n        event.preventDefault();\n        event.stopPropagation();\n        this.triggerActiveItem();\n    }\n    /**\n     * Handle the `'mousemove'` event for the menu.\n     *\n     * #### Notes\n     * This listener is attached to the menu node.\n     */\n    _evtMouseMove(event) {\n        // Hit test the item nodes for the item under the mouse.\n        let index = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(this.contentNode.children, node => {\n            return _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(node, event.clientX, event.clientY);\n        });\n        // Bail early if the mouse is already over the active index.\n        if (index === this._activeIndex) {\n            return;\n        }\n        // Update and coerce the active index.\n        this.activeIndex = index;\n        index = this.activeIndex;\n        // If the index is the current child index, cancel the timers.\n        if (index === this._childIndex) {\n            this._cancelOpenTimer();\n            this._cancelCloseTimer();\n            return;\n        }\n        // If a child menu is currently open, start the close timer.\n        if (this._childIndex !== -1) {\n            this._startCloseTimer();\n        }\n        // Cancel the open timer to give a full delay for opening.\n        this._cancelOpenTimer();\n        // Bail if the active item is not a valid submenu item.\n        let item = this.activeItem;\n        if (!item || item.type !== 'submenu' || !item.submenu) {\n            return;\n        }\n        // Start the open timer to open the active item submenu.\n        this._startOpenTimer();\n    }\n    /**\n     * Handle the `'mouseenter'` event for the menu.\n     *\n     * #### Notes\n     * This listener is attached to the menu node.\n     */\n    _evtMouseEnter(event) {\n        // Synchronize the active ancestor items.\n        for (let menu = this._parentMenu; menu; menu = menu._parentMenu) {\n            menu._cancelOpenTimer();\n            menu._cancelCloseTimer();\n            menu.activeIndex = menu._childIndex;\n        }\n    }\n    /**\n     * Handle the `'mouseleave'` event for the menu.\n     *\n     * #### Notes\n     * This listener is attached to the menu node.\n     */\n    _evtMouseLeave(event) {\n        // Cancel any pending submenu opening.\n        this._cancelOpenTimer();\n        // If there is no open child menu, just reset the active index.\n        if (!this._childMenu) {\n            this.activeIndex = -1;\n            return;\n        }\n        // If the mouse is over the child menu, cancel the close timer.\n        let { clientX, clientY } = event;\n        if (_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(this._childMenu.node, clientX, clientY)) {\n            this._cancelCloseTimer();\n            return;\n        }\n        // Otherwise, reset the active index and start the close timer.\n        this.activeIndex = -1;\n        this._startCloseTimer();\n    }\n    /**\n     * Handle the `'mousedown'` event for the menu.\n     *\n     * #### Notes\n     * This listener is attached to the document node.\n     */\n    _evtMouseDown(event) {\n        // Bail if the menu is not a root menu.\n        if (this._parentMenu) {\n            return;\n        }\n        // The mouse button which is pressed is irrelevant. If the press\n        // is not on a menu, the entire hierarchy is closed and the event\n        // is allowed to propagate. This allows other code to act on the\n        // event, such as focusing the clicked element.\n        if (Private$9.hitTestMenus(this, event.clientX, event.clientY)) {\n            event.preventDefault();\n            event.stopPropagation();\n        }\n        else {\n            this.close();\n        }\n    }\n    /**\n     * Open the child menu at the active index immediately.\n     *\n     * If a different child menu is already open, it will be closed,\n     * even if the active item is not a valid submenu.\n     */\n    _openChildMenu(activateFirst = false) {\n        // If the item is not a valid submenu, close the child menu.\n        let item = this.activeItem;\n        if (!item || item.type !== 'submenu' || !item.submenu) {\n            this._closeChildMenu();\n            return;\n        }\n        // Do nothing if the child menu will not change.\n        let submenu = item.submenu;\n        if (submenu === this._childMenu) {\n            return;\n        }\n        // Prior to any DOM modifications save window data\n        Menu.saveWindowData();\n        // Ensure the current child menu is closed.\n        this._closeChildMenu();\n        // Update the private child state.\n        this._childMenu = submenu;\n        this._childIndex = this._activeIndex;\n        // Set the parent menu reference for the child.\n        submenu._parentMenu = this;\n        // Ensure the menu is updated and lookup the item node.\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this, Widget.Msg.UpdateRequest);\n        let itemNode = this.contentNode.children[this._activeIndex];\n        // Open the submenu at the active node.\n        Private$9.openSubmenu(submenu, itemNode);\n        // Activate the first item if desired.\n        if (activateFirst) {\n            submenu.activeIndex = -1;\n            submenu.activateNextItem();\n        }\n        // Activate the child menu.\n        submenu.activate();\n    }\n    /**\n     * Close the child menu immediately.\n     *\n     * This is a no-op if a child menu is not open.\n     */\n    _closeChildMenu() {\n        if (this._childMenu) {\n            this._childMenu.close();\n        }\n    }\n    /**\n     * Start the open timer, unless it is already pending.\n     */\n    _startOpenTimer() {\n        if (this._openTimerID === 0) {\n            this._openTimerID = window.setTimeout(() => {\n                this._openTimerID = 0;\n                this._openChildMenu();\n            }, Private$9.TIMER_DELAY);\n        }\n    }\n    /**\n     * Start the close timer, unless it is already pending.\n     */\n    _startCloseTimer() {\n        if (this._closeTimerID === 0) {\n            this._closeTimerID = window.setTimeout(() => {\n                this._closeTimerID = 0;\n                this._closeChildMenu();\n            }, Private$9.TIMER_DELAY);\n        }\n    }\n    /**\n     * Cancel the open timer, if the timer is pending.\n     */\n    _cancelOpenTimer() {\n        if (this._openTimerID !== 0) {\n            clearTimeout(this._openTimerID);\n            this._openTimerID = 0;\n        }\n    }\n    /**\n     * Cancel the close timer, if the timer is pending.\n     */\n    _cancelCloseTimer() {\n        if (this._closeTimerID !== 0) {\n            clearTimeout(this._closeTimerID);\n            this._closeTimerID = 0;\n        }\n    }\n    /**\n     * Save window data used for menu positioning in transient cache.\n     *\n     * In order to avoid layout trashing it is recommended to invoke this\n     * method immediately prior to opening the menu and any DOM modifications\n     * (like closing previously visible menu, or adding a class to menu widget).\n     *\n     * The transient cache will be released upon `open()` call.\n     */\n    static saveWindowData() {\n        Private$9.saveWindowData();\n    }\n}\n/**\n * The namespace for the `Menu` class statics.\n */\n(function (Menu) {\n    /**\n     * The default implementation of `IRenderer`.\n     *\n     * #### Notes\n     * Subclasses are free to reimplement rendering methods as needed.\n     */\n    class Renderer {\n        /**\n         * Render the virtual element for a menu item.\n         *\n         * @param data - The data to use for rendering the item.\n         *\n         * @returns A virtual element representing the item.\n         */\n        renderItem(data) {\n            let className = this.createItemClass(data);\n            let dataset = this.createItemDataset(data);\n            let aria = this.createItemARIA(data);\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.li({\n                className,\n                dataset,\n                tabindex: '0',\n                onfocus: data.onfocus,\n                ...aria\n            }, this.renderIcon(data), this.renderLabel(data), this.renderShortcut(data), this.renderSubmenu(data));\n        }\n        /**\n         * Render the icon element for a menu item.\n         *\n         * @param data - The data to use for rendering the icon.\n         *\n         * @returns A virtual element representing the item icon.\n         */\n        renderIcon(data) {\n            let className = this.createIconClass(data);\n            // If data.item.icon is undefined, it will be ignored.\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className }, data.item.icon, data.item.iconLabel);\n        }\n        /**\n         * Render the label element for a menu item.\n         *\n         * @param data - The data to use for rendering the label.\n         *\n         * @returns A virtual element representing the item label.\n         */\n        renderLabel(data) {\n            let content = this.formatLabel(data);\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className: 'lm-Menu-itemLabel' }, content);\n        }\n        /**\n         * Render the shortcut element for a menu item.\n         *\n         * @param data - The data to use for rendering the shortcut.\n         *\n         * @returns A virtual element representing the item shortcut.\n         */\n        renderShortcut(data) {\n            let content = this.formatShortcut(data);\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className: 'lm-Menu-itemShortcut' }, content);\n        }\n        /**\n         * Render the submenu icon element for a menu item.\n         *\n         * @param data - The data to use for rendering the submenu icon.\n         *\n         * @returns A virtual element representing the submenu icon.\n         */\n        renderSubmenu(data) {\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className: 'lm-Menu-itemSubmenuIcon' });\n        }\n        /**\n         * Create the class name for the menu item.\n         *\n         * @param data - The data to use for the class name.\n         *\n         * @returns The full class name for the menu item.\n         */\n        createItemClass(data) {\n            // Setup the initial class name.\n            let name = 'lm-Menu-item';\n            // Add the boolean state classes.\n            if (!data.item.isEnabled) {\n                name += ' lm-mod-disabled';\n            }\n            if (data.item.isToggled) {\n                name += ' lm-mod-toggled';\n            }\n            if (!data.item.isVisible) {\n                name += ' lm-mod-hidden';\n            }\n            if (data.active) {\n                name += ' lm-mod-active';\n            }\n            if (data.collapsed) {\n                name += ' lm-mod-collapsed';\n            }\n            // Add the extra class.\n            let extra = data.item.className;\n            if (extra) {\n                name += ` ${extra}`;\n            }\n            // Return the complete class name.\n            return name;\n        }\n        /**\n         * Create the dataset for the menu item.\n         *\n         * @param data - The data to use for creating the dataset.\n         *\n         * @returns The dataset for the menu item.\n         */\n        createItemDataset(data) {\n            let result;\n            let { type, command, dataset } = data.item;\n            if (type === 'command') {\n                result = { ...dataset, type, command };\n            }\n            else {\n                result = { ...dataset, type };\n            }\n            return result;\n        }\n        /**\n         * Create the class name for the menu item icon.\n         *\n         * @param data - The data to use for the class name.\n         *\n         * @returns The full class name for the item icon.\n         */\n        createIconClass(data) {\n            let name = 'lm-Menu-itemIcon';\n            let extra = data.item.iconClass;\n            return extra ? `${name} ${extra}` : name;\n        }\n        /**\n         * Create the aria attributes for menu item.\n         *\n         * @param data - The data to use for the aria attributes.\n         *\n         * @returns The aria attributes object for the item.\n         */\n        createItemARIA(data) {\n            let aria = {};\n            switch (data.item.type) {\n                case 'separator':\n                    aria.role = 'presentation';\n                    break;\n                case 'submenu':\n                    aria['aria-haspopup'] = 'true';\n                    if (!data.item.isEnabled) {\n                        aria['aria-disabled'] = 'true';\n                    }\n                    break;\n                default:\n                    if (!data.item.isEnabled) {\n                        aria['aria-disabled'] = 'true';\n                    }\n                    aria.role = 'menuitem';\n            }\n            return aria;\n        }\n        /**\n         * Create the render content for the label node.\n         *\n         * @param data - The data to use for the label content.\n         *\n         * @returns The content to add to the label node.\n         */\n        formatLabel(data) {\n            // Fetch the label text and mnemonic index.\n            let { label, mnemonic } = data.item;\n            // If the index is out of range, do not modify the label.\n            if (mnemonic < 0 || mnemonic >= label.length) {\n                return label;\n            }\n            // Split the label into parts.\n            let prefix = label.slice(0, mnemonic);\n            let suffix = label.slice(mnemonic + 1);\n            let char = label[mnemonic];\n            // Wrap the mnemonic character in a span.\n            let span = _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.span({ className: 'lm-Menu-itemMnemonic' }, char);\n            // Return the content parts.\n            return [prefix, span, suffix];\n        }\n        /**\n         * Create the render content for the shortcut node.\n         *\n         * @param data - The data to use for the shortcut content.\n         *\n         * @returns The content to add to the shortcut node.\n         */\n        formatShortcut(data) {\n            let kb = data.item.keyBinding;\n            return kb ? _lumino_commands__WEBPACK_IMPORTED_MODULE_7__.CommandRegistry.formatKeystroke(kb.keys) : null;\n        }\n    }\n    Menu.Renderer = Renderer;\n    /**\n     * The default `Renderer` instance.\n     */\n    Menu.defaultRenderer = new Renderer();\n})(Menu || (Menu = {}));\n/**\n * The namespace for the module implementation details.\n */\nvar Private$9;\n(function (Private) {\n    /**\n     * The ms delay for opening and closing a submenu.\n     */\n    Private.TIMER_DELAY = 300;\n    /**\n     * The horizontal pixel overlap for an open submenu.\n     */\n    Private.SUBMENU_OVERLAP = 3;\n    let transientWindowDataCache = null;\n    let transientCacheCounter = 0;\n    function getWindowData() {\n        // if transient cache is in use, take one from it\n        if (transientCacheCounter > 0) {\n            transientCacheCounter--;\n            return transientWindowDataCache;\n        }\n        return _getWindowData();\n    }\n    /**\n     * Store window data in transient cache.\n     *\n     * The transient cache will be released upon `getWindowData()` call.\n     * If this function is called multiple times, the cache will be\n     * retained until as many calls to `getWindowData()` were made.\n     *\n     * Note: should be called before any DOM modifications.\n     */\n    function saveWindowData() {\n        transientWindowDataCache = _getWindowData();\n        transientCacheCounter++;\n    }\n    Private.saveWindowData = saveWindowData;\n    /**\n     * Create the DOM node for a menu.\n     */\n    function createNode() {\n        let node = document.createElement('div');\n        let content = document.createElement('ul');\n        content.className = 'lm-Menu-content';\n        node.appendChild(content);\n        content.setAttribute('role', 'menu');\n        node.tabIndex = 0;\n        return node;\n    }\n    Private.createNode = createNode;\n    /**\n     * Test whether a menu item can be activated.\n     */\n    function canActivate(item) {\n        return item.type !== 'separator' && item.isEnabled && item.isVisible;\n    }\n    Private.canActivate = canActivate;\n    /**\n     * Create a new menu item for an owner menu.\n     */\n    function createItem(owner, options) {\n        return new MenuItem(owner.commands, options);\n    }\n    Private.createItem = createItem;\n    /**\n     * Hit test a menu hierarchy starting at the given root.\n     */\n    function hitTestMenus(menu, x, y) {\n        for (let temp = menu; temp; temp = temp.childMenu) {\n            if (_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(temp.node, x, y)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    Private.hitTestMenus = hitTestMenus;\n    /**\n     * Compute which extra separator items should be collapsed.\n     */\n    function computeCollapsed(items) {\n        // Allocate the return array and fill it with `false`.\n        let result = new Array(items.length);\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.fill(result, false);\n        // Collapse the leading separators.\n        let k1 = 0;\n        let n = items.length;\n        for (; k1 < n; ++k1) {\n            let item = items[k1];\n            if (!item.isVisible) {\n                continue;\n            }\n            if (item.type !== 'separator') {\n                break;\n            }\n            result[k1] = true;\n        }\n        // Hide the trailing separators.\n        let k2 = n - 1;\n        for (; k2 >= 0; --k2) {\n            let item = items[k2];\n            if (!item.isVisible) {\n                continue;\n            }\n            if (item.type !== 'separator') {\n                break;\n            }\n            result[k2] = true;\n        }\n        // Hide the remaining consecutive separators.\n        let hide = false;\n        while (++k1 < k2) {\n            let item = items[k1];\n            if (!item.isVisible) {\n                continue;\n            }\n            if (item.type !== 'separator') {\n                hide = false;\n            }\n            else if (hide) {\n                result[k1] = true;\n            }\n            else {\n                hide = true;\n            }\n        }\n        // Return the resulting flags.\n        return result;\n    }\n    Private.computeCollapsed = computeCollapsed;\n    function _getWindowData() {\n        return {\n            pageXOffset: window.pageXOffset,\n            pageYOffset: window.pageYOffset,\n            clientWidth: document.documentElement.clientWidth,\n            clientHeight: document.documentElement.clientHeight\n        };\n    }\n    /**\n     * Open a menu as a root menu at the target location.\n     */\n    function openRootMenu(menu, x, y, forceX, forceY) {\n        // Get the current position and size of the main viewport.\n        const windowData = getWindowData();\n        let px = windowData.pageXOffset;\n        let py = windowData.pageYOffset;\n        let cw = windowData.clientWidth;\n        let ch = windowData.clientHeight;\n        // Ensure the menu is updated before attaching and measuring.\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(menu, Widget.Msg.UpdateRequest);\n        // Compute the maximum allowed height for the menu.\n        let maxHeight = ch - (forceY ? y : 0);\n        // Fetch common variables.\n        let node = menu.node;\n        let style = node.style;\n        // Clear the menu geometry and prepare it for measuring.\n        style.opacity = '0';\n        style.maxHeight = `${maxHeight}px`;\n        // Attach the menu to the document.\n        Widget.attach(menu, document.body);\n        // Measure the size of the menu.\n        let { width, height } = node.getBoundingClientRect();\n        // Adjust the X position of the menu to fit on-screen.\n        if (!forceX && x + width > px + cw) {\n            x = px + cw - width;\n        }\n        // Adjust the Y position of the menu to fit on-screen.\n        if (!forceY && y + height > py + ch) {\n            if (y > py + ch) {\n                y = py + ch - height;\n            }\n            else {\n                y = y - height;\n            }\n        }\n        // Update the position of the menu to the computed position.\n        style.transform = `translate(${Math.max(0, x)}px, ${Math.max(0, y)}px`;\n        // Finally, make the menu visible on the screen.\n        style.opacity = '1';\n    }\n    Private.openRootMenu = openRootMenu;\n    /**\n     * Open a menu as a submenu using an item node for positioning.\n     */\n    function openSubmenu(submenu, itemNode) {\n        // Get the current position and size of the main viewport.\n        const windowData = getWindowData();\n        let px = windowData.pageXOffset;\n        let py = windowData.pageYOffset;\n        let cw = windowData.clientWidth;\n        let ch = windowData.clientHeight;\n        // Ensure the menu is updated before opening.\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(submenu, Widget.Msg.UpdateRequest);\n        // Compute the maximum allowed height for the menu.\n        let maxHeight = ch;\n        // Fetch common variables.\n        let node = submenu.node;\n        let style = node.style;\n        // Clear the menu geometry and prepare it for measuring.\n        style.opacity = '0';\n        style.maxHeight = `${maxHeight}px`;\n        // Attach the menu to the document.\n        Widget.attach(submenu, document.body);\n        // Measure the size of the menu.\n        let { width, height } = node.getBoundingClientRect();\n        // Compute the box sizing for the menu.\n        let box = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.boxSizing(submenu.node);\n        // Get the bounding rect for the target item node.\n        let itemRect = itemNode.getBoundingClientRect();\n        // Compute the target X position.\n        let x = itemRect.right - Private.SUBMENU_OVERLAP;\n        // Adjust the X position to fit on the screen.\n        if (x + width > px + cw) {\n            x = itemRect.left + Private.SUBMENU_OVERLAP - width;\n        }\n        // Compute the target Y position.\n        let y = itemRect.top - box.borderTop - box.paddingTop;\n        // Adjust the Y position to fit on the screen.\n        if (y + height > py + ch) {\n            y = itemRect.bottom + box.borderBottom + box.paddingBottom - height;\n        }\n        // Update the position of the menu to the computed position.\n        style.transform = `translate(${Math.max(0, x)}px, ${Math.max(0, y)}px`;\n        // Finally, make the menu visible on the screen.\n        style.opacity = '1';\n    }\n    Private.openSubmenu = openSubmenu;\n    /**\n     * Find the best matching mnemonic item.\n     *\n     * The search starts at the given index and wraps around.\n     */\n    function findMnemonic(items, key, start) {\n        // Setup the result variables.\n        let index = -1;\n        let auto = -1;\n        let multiple = false;\n        // Normalize the key to upper case.\n        let upperKey = key.toUpperCase();\n        // Search the items from the given start index.\n        for (let i = 0, n = items.length; i < n; ++i) {\n            // Compute the wrapped index.\n            let k = (i + start) % n;\n            // Lookup the item\n            let item = items[k];\n            // Ignore items which cannot be activated.\n            if (!canActivate(item)) {\n                continue;\n            }\n            // Ignore items with an empty label.\n            let label = item.label;\n            if (label.length === 0) {\n                continue;\n            }\n            // Lookup the mnemonic index for the label.\n            let mn = item.mnemonic;\n            // Handle a valid mnemonic index.\n            if (mn >= 0 && mn < label.length) {\n                if (label[mn].toUpperCase() === upperKey) {\n                    if (index === -1) {\n                        index = k;\n                    }\n                    else {\n                        multiple = true;\n                    }\n                }\n                continue;\n            }\n            // Finally, handle the auto index if possible.\n            if (auto === -1 && label[0].toUpperCase() === upperKey) {\n                auto = k;\n            }\n        }\n        // Return the search results.\n        return { index, multiple, auto };\n    }\n    Private.findMnemonic = findMnemonic;\n    /**\n     * A concrete implementation of `Menu.IItem`.\n     */\n    class MenuItem {\n        /**\n         * Construct a new menu item.\n         */\n        constructor(commands, options) {\n            this._commands = commands;\n            this.type = options.type || 'command';\n            this.command = options.command || '';\n            this.args = options.args || _lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__.JSONExt.emptyObject;\n            this.submenu = options.submenu || null;\n        }\n        /**\n         * The display label for the menu item.\n         */\n        get label() {\n            if (this.type === 'command') {\n                return this._commands.label(this.command, this.args);\n            }\n            if (this.type === 'submenu' && this.submenu) {\n                return this.submenu.title.label;\n            }\n            return '';\n        }\n        /**\n         * The mnemonic index for the menu item.\n         */\n        get mnemonic() {\n            if (this.type === 'command') {\n                return this._commands.mnemonic(this.command, this.args);\n            }\n            if (this.type === 'submenu' && this.submenu) {\n                return this.submenu.title.mnemonic;\n            }\n            return -1;\n        }\n        /**\n         * The icon renderer for the menu item.\n         */\n        get icon() {\n            if (this.type === 'command') {\n                return this._commands.icon(this.command, this.args);\n            }\n            if (this.type === 'submenu' && this.submenu) {\n                return this.submenu.title.icon;\n            }\n            return undefined;\n        }\n        /**\n         * The icon class for the menu item.\n         */\n        get iconClass() {\n            if (this.type === 'command') {\n                return this._commands.iconClass(this.command, this.args);\n            }\n            if (this.type === 'submenu' && this.submenu) {\n                return this.submenu.title.iconClass;\n            }\n            return '';\n        }\n        /**\n         * The icon label for the menu item.\n         */\n        get iconLabel() {\n            if (this.type === 'command') {\n                return this._commands.iconLabel(this.command, this.args);\n            }\n            if (this.type === 'submenu' && this.submenu) {\n                return this.submenu.title.iconLabel;\n            }\n            return '';\n        }\n        /**\n         * The display caption for the menu item.\n         */\n        get caption() {\n            if (this.type === 'command') {\n                return this._commands.caption(this.command, this.args);\n            }\n            if (this.type === 'submenu' && this.submenu) {\n                return this.submenu.title.caption;\n            }\n            return '';\n        }\n        /**\n         * The extra class name for the menu item.\n         */\n        get className() {\n            if (this.type === 'command') {\n                return this._commands.className(this.command, this.args);\n            }\n            if (this.type === 'submenu' && this.submenu) {\n                return this.submenu.title.className;\n            }\n            return '';\n        }\n        /**\n         * The dataset for the menu item.\n         */\n        get dataset() {\n            if (this.type === 'command') {\n                return this._commands.dataset(this.command, this.args);\n            }\n            if (this.type === 'submenu' && this.submenu) {\n                return this.submenu.title.dataset;\n            }\n            return {};\n        }\n        /**\n         * Whether the menu item is enabled.\n         */\n        get isEnabled() {\n            if (this.type === 'command') {\n                return this._commands.isEnabled(this.command, this.args);\n            }\n            if (this.type === 'submenu') {\n                return this.submenu !== null;\n            }\n            return true;\n        }\n        /**\n         * Whether the menu item is toggled.\n         */\n        get isToggled() {\n            if (this.type === 'command') {\n                return this._commands.isToggled(this.command, this.args);\n            }\n            return false;\n        }\n        /**\n         * Whether the menu item is visible.\n         */\n        get isVisible() {\n            if (this.type === 'command') {\n                return this._commands.isVisible(this.command, this.args);\n            }\n            if (this.type === 'submenu') {\n                return this.submenu !== null;\n            }\n            return true;\n        }\n        /**\n         * The key binding for the menu item.\n         */\n        get keyBinding() {\n            if (this.type === 'command') {\n                let { command, args } = this;\n                return (_lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findLastValue(this._commands.keyBindings, kb => {\n                    return kb.command === command && _lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__.JSONExt.deepEqual(kb.args, args);\n                }) || null);\n            }\n            return null;\n        }\n    }\n})(Private$9 || (Private$9 = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * An object which implements a universal context menu.\n *\n * #### Notes\n * The items shown in the context menu are determined by CSS selector\n * matching against the DOM hierarchy at the site of the mouse click.\n * This is similar in concept to how keyboard shortcuts are matched\n * in the command registry.\n */\nclass ContextMenu {\n    /**\n     * Construct a new context menu.\n     *\n     * @param options - The options for initializing the menu.\n     */\n    constructor(options) {\n        this._groupByTarget = true;\n        this._idTick = 0;\n        this._items = [];\n        this._sortBySelector = true;\n        const { groupByTarget, sortBySelector, ...others } = options;\n        this.menu = new Menu(others);\n        this._groupByTarget = groupByTarget !== false;\n        this._sortBySelector = sortBySelector !== false;\n    }\n    /**\n     * Add an item to the context menu.\n     *\n     * @param options - The options for creating the item.\n     *\n     * @returns A disposable which will remove the item from the menu.\n     */\n    addItem(options) {\n        // Create an item from the given options.\n        let item = Private$8.createItem(options, this._idTick++);\n        // Add the item to the internal array.\n        this._items.push(item);\n        // Return a disposable which will remove the item.\n        return new _lumino_disposable__WEBPACK_IMPORTED_MODULE_9__.DisposableDelegate(() => {\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeFirstOf(this._items, item);\n        });\n    }\n    /**\n     * Open the context menu in response to a `'contextmenu'` event.\n     *\n     * @param event - The `'contextmenu'` event of interest.\n     *\n     * @returns `true` if the menu was opened, or `false` if no items\n     *   matched the event and the menu was not opened.\n     *\n     * #### Notes\n     * This method will populate the context menu with items which match\n     * the propagation path of the event, then open the menu at the mouse\n     * position indicated by the event.\n     */\n    open(event) {\n        // Prior to any DOM modifications update the window data.\n        Menu.saveWindowData();\n        // Clear the current contents of the context menu.\n        this.menu.clearItems();\n        // Bail early if there are no items to match.\n        if (this._items.length === 0) {\n            return false;\n        }\n        // Find the matching items for the event.\n        let items = Private$8.matchItems(this._items, event, this._groupByTarget, this._sortBySelector);\n        // Bail if there are no matching items.\n        if (!items || items.length === 0) {\n            return false;\n        }\n        // Add the filtered items to the menu.\n        for (const item of items) {\n            this.menu.addItem(item);\n        }\n        // Open the context menu at the current mouse position.\n        this.menu.open(event.clientX, event.clientY);\n        // Indicate success.\n        return true;\n    }\n}\n/**\n * The namespace for the module implementation details.\n */\nvar Private$8;\n(function (Private) {\n    /**\n     * Create a normalized context menu item from an options object.\n     */\n    function createItem(options, id) {\n        let selector = validateSelector(options.selector);\n        let rank = options.rank !== undefined ? options.rank : Infinity;\n        return { ...options, selector, rank, id };\n    }\n    Private.createItem = createItem;\n    /**\n     * Find the items which match a context menu event.\n     *\n     * The results are sorted by DOM level, specificity, and rank.\n     */\n    function matchItems(items, event, groupByTarget, sortBySelector) {\n        // Look up the target of the event.\n        let target = event.target;\n        // Bail if there is no target.\n        if (!target) {\n            return null;\n        }\n        // Look up the current target of the event.\n        let currentTarget = event.currentTarget;\n        // Bail if there is no current target.\n        if (!currentTarget) {\n            return null;\n        }\n        // There are some third party libraries that cause the `target` to\n        // be detached from the DOM before lumino can process the event.\n        // If that happens, search for a new target node by point. If that\n        // node is still dangling, bail.\n        if (!currentTarget.contains(target)) {\n            target = document.elementFromPoint(event.clientX, event.clientY);\n            if (!target || !currentTarget.contains(target)) {\n                return null;\n            }\n        }\n        // Set up the result array.\n        let result = [];\n        // Copy the items array to allow in-place modification.\n        let availableItems = items.slice();\n        // Walk up the DOM hierarchy searching for matches.\n        while (target !== null) {\n            // Set up the match array for this DOM level.\n            let matches = [];\n            // Search the remaining items for matches.\n            for (let i = 0, n = availableItems.length; i < n; ++i) {\n                // Fetch the item.\n                let item = availableItems[i];\n                // Skip items which are already consumed.\n                if (!item) {\n                    continue;\n                }\n                // Skip items which do not match the element.\n                if (!_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.Selector.matches(target, item.selector)) {\n                    continue;\n                }\n                // Add the matched item to the result for this DOM level.\n                matches.push(item);\n                // Mark the item as consumed.\n                availableItems[i] = null;\n            }\n            // Sort the matches for this level and add them to the results.\n            if (matches.length !== 0) {\n                if (groupByTarget) {\n                    matches.sort(sortBySelector ? itemCmp : itemCmpRank);\n                }\n                result.push(...matches);\n            }\n            // Stop searching at the limits of the DOM range.\n            if (target === currentTarget) {\n                break;\n            }\n            // Step to the parent DOM level.\n            target = target.parentElement;\n        }\n        if (!groupByTarget) {\n            result.sort(sortBySelector ? itemCmp : itemCmpRank);\n        }\n        // Return the matched and sorted results.\n        return result;\n    }\n    Private.matchItems = matchItems;\n    /**\n     * Validate the selector for a menu item.\n     *\n     * This returns the validated selector, or throws if the selector is\n     * invalid or contains commas.\n     */\n    function validateSelector(selector) {\n        if (selector.indexOf(',') !== -1) {\n            throw new Error(`Selector cannot contain commas: ${selector}`);\n        }\n        if (!_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.Selector.isValid(selector)) {\n            throw new Error(`Invalid selector: ${selector}`);\n        }\n        return selector;\n    }\n    /**\n     * A sort comparison function for a context menu item by ranks.\n     */\n    function itemCmpRank(a, b) {\n        // Sort based on rank.\n        let r1 = a.rank;\n        let r2 = b.rank;\n        if (r1 !== r2) {\n            return r1 < r2 ? -1 : 1; // Infinity-safe\n        }\n        // When all else fails, sort by item id.\n        return a.id - b.id;\n    }\n    /**\n     * A sort comparison function for a context menu item by selectors and ranks.\n     */\n    function itemCmp(a, b) {\n        // Sort first based on selector specificity.\n        let s1 = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.Selector.calculateSpecificity(a.selector);\n        let s2 = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.Selector.calculateSpecificity(b.selector);\n        if (s1 !== s2) {\n            return s2 - s1;\n        }\n        // If specificities are equal\n        return itemCmpRank(a, b);\n    }\n})(Private$8 || (Private$8 = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\nconst ARROW_KEYS = [\n    'ArrowLeft',\n    'ArrowUp',\n    'ArrowRight',\n    'ArrowDown',\n    'Home',\n    'End'\n];\n/**\n * A widget which displays titles as a single row or column of tabs.\n *\n * #### Notes\n * If CSS transforms are used to rotate nodes for vertically oriented\n * text, then tab dragging will not work correctly. The `tabsMovable`\n * property should be set to `false` when rotating nodes from CSS.\n */\nclass TabBar extends Widget {\n    /**\n     * Construct a new tab bar.\n     *\n     * @param options - The options for initializing the tab bar.\n     */\n    constructor(options = {}) {\n        super({ node: Private$7.createNode() });\n        this._currentIndex = -1;\n        this._titles = [];\n        this._titlesEditable = false;\n        this._previousTitle = null;\n        this._dragData = null;\n        this._addButtonEnabled = false;\n        this._tabMoved = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._currentChanged = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._addRequested = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._tabCloseRequested = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._tabDetachRequested = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._tabActivateRequested = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this.addClass('lm-TabBar');\n        this.contentNode.setAttribute('role', 'tablist');\n        this.setFlag(Widget.Flag.DisallowLayout);\n        this._document = options.document || document;\n        this.tabsMovable = options.tabsMovable || false;\n        this.titlesEditable = options.titlesEditable || false;\n        this.allowDeselect = options.allowDeselect || false;\n        this.addButtonEnabled = options.addButtonEnabled || false;\n        this.insertBehavior = options.insertBehavior || 'select-tab-if-needed';\n        this.name = options.name || '';\n        this.orientation = options.orientation || 'horizontal';\n        this.removeBehavior = options.removeBehavior || 'select-tab-after';\n        this.renderer = options.renderer || TabBar.defaultRenderer;\n    }\n    /**\n     * Dispose of the resources held by the widget.\n     */\n    dispose() {\n        this._releaseMouse();\n        this._titles.length = 0;\n        this._previousTitle = null;\n        super.dispose();\n    }\n    /**\n     * A signal emitted when the current tab is changed.\n     *\n     * #### Notes\n     * This signal is emitted when the currently selected tab is changed\n     * either through user or programmatic interaction.\n     *\n     * Notably, this signal is not emitted when the index of the current\n     * tab changes due to tabs being inserted, removed, or moved. It is\n     * only emitted when the actual current tab node is changed.\n     */\n    get currentChanged() {\n        return this._currentChanged;\n    }\n    /**\n     * A signal emitted when a tab is moved by the user.\n     *\n     * #### Notes\n     * This signal is emitted when a tab is moved by user interaction.\n     *\n     * This signal is not emitted when a tab is moved programmatically.\n     */\n    get tabMoved() {\n        return this._tabMoved;\n    }\n    /**\n     * A signal emitted when a tab is clicked by the user.\n     *\n     * #### Notes\n     * If the clicked tab is not the current tab, the clicked tab will be\n     * made current and the `currentChanged` signal will be emitted first.\n     *\n     * This signal is emitted even if the clicked tab is the current tab.\n     */\n    get tabActivateRequested() {\n        return this._tabActivateRequested;\n    }\n    /**\n     * A signal emitted when the tab bar add button is clicked.\n     */\n    get addRequested() {\n        return this._addRequested;\n    }\n    /**\n     * A signal emitted when a tab close icon is clicked.\n     *\n     * #### Notes\n     * This signal is not emitted unless the tab title is `closable`.\n     */\n    get tabCloseRequested() {\n        return this._tabCloseRequested;\n    }\n    /**\n     * A signal emitted when a tab is dragged beyond the detach threshold.\n     *\n     * #### Notes\n     * This signal is emitted when the user drags a tab with the mouse,\n     * and mouse is dragged beyond the detach threshold.\n     *\n     * The consumer of the signal should call `releaseMouse` and remove\n     * the tab in order to complete the detach.\n     *\n     * This signal is only emitted once per drag cycle.\n     */\n    get tabDetachRequested() {\n        return this._tabDetachRequested;\n    }\n    /**\n     * The document to use with the tab bar.\n     *\n     * The default is the global `document` instance.\n     */\n    get document() {\n        return this._document;\n    }\n    /**\n     * Whether the titles can be user-edited.\n     *\n     */\n    get titlesEditable() {\n        return this._titlesEditable;\n    }\n    /**\n     * Set whether titles can be user edited.\n     *\n     */\n    set titlesEditable(value) {\n        this._titlesEditable = value;\n    }\n    /**\n     * Get the currently selected title.\n     *\n     * #### Notes\n     * This will be `null` if no tab is selected.\n     */\n    get currentTitle() {\n        return this._titles[this._currentIndex] || null;\n    }\n    /**\n     * Set the currently selected title.\n     *\n     * #### Notes\n     * If the title does not exist, the title will be set to `null`.\n     */\n    set currentTitle(value) {\n        this.currentIndex = value ? this._titles.indexOf(value) : -1;\n    }\n    /**\n     * Get the index of the currently selected tab.\n     *\n     * #### Notes\n     * This will be `-1` if no tab is selected.\n     */\n    get currentIndex() {\n        return this._currentIndex;\n    }\n    /**\n     * Set the index of the currently selected tab.\n     *\n     * #### Notes\n     * If the value is out of range, the index will be set to `-1`.\n     */\n    set currentIndex(value) {\n        // Adjust for an out of range index.\n        if (value < 0 || value >= this._titles.length) {\n            value = -1;\n        }\n        // Bail early if the index will not change.\n        if (this._currentIndex === value) {\n            return;\n        }\n        // Look up the previous index and title.\n        let pi = this._currentIndex;\n        let pt = this._titles[pi] || null;\n        // Look up the current index and title.\n        let ci = value;\n        let ct = this._titles[ci] || null;\n        // Update the current index and previous title.\n        this._currentIndex = ci;\n        this._previousTitle = pt;\n        // Schedule an update of the tabs.\n        this.update();\n        // Emit the current changed signal.\n        this._currentChanged.emit({\n            previousIndex: pi,\n            previousTitle: pt,\n            currentIndex: ci,\n            currentTitle: ct\n        });\n    }\n    /**\n     * Get the name of the tab bar.\n     */\n    get name() {\n        return this._name;\n    }\n    /**\n     * Set the name of the tab bar.\n     */\n    set name(value) {\n        this._name = value;\n        if (value) {\n            this.contentNode.setAttribute('aria-label', value);\n        }\n        else {\n            this.contentNode.removeAttribute('aria-label');\n        }\n    }\n    /**\n     * Get the orientation of the tab bar.\n     *\n     * #### Notes\n     * This controls whether the tabs are arranged in a row or column.\n     */\n    get orientation() {\n        return this._orientation;\n    }\n    /**\n     * Set the orientation of the tab bar.\n     *\n     * #### Notes\n     * This controls whether the tabs are arranged in a row or column.\n     */\n    set orientation(value) {\n        // Do nothing if the orientation does not change.\n        if (this._orientation === value) {\n            return;\n        }\n        // Release the mouse before making any changes.\n        this._releaseMouse();\n        // Toggle the orientation values.\n        this._orientation = value;\n        this.dataset['orientation'] = value;\n        this.contentNode.setAttribute('aria-orientation', value);\n    }\n    /**\n     * Whether the add button is enabled.\n     */\n    get addButtonEnabled() {\n        return this._addButtonEnabled;\n    }\n    /**\n     * Set whether the add button is enabled.\n     */\n    set addButtonEnabled(value) {\n        // Do nothing if the value does not change.\n        if (this._addButtonEnabled === value) {\n            return;\n        }\n        this._addButtonEnabled = value;\n        if (value) {\n            this.addButtonNode.classList.remove('lm-mod-hidden');\n        }\n        else {\n            this.addButtonNode.classList.add('lm-mod-hidden');\n        }\n    }\n    /**\n     * A read-only array of the titles in the tab bar.\n     */\n    get titles() {\n        return this._titles;\n    }\n    /**\n     * The tab bar content node.\n     *\n     * #### Notes\n     * This is the node which holds the tab nodes.\n     *\n     * Modifying this node directly can lead to undefined behavior.\n     */\n    get contentNode() {\n        return this.node.getElementsByClassName('lm-TabBar-content')[0];\n    }\n    /**\n     * The tab bar add button node.\n     *\n     * #### Notes\n     * This is the node which holds the add button.\n     *\n     * Modifying this node directly can lead to undefined behavior.\n     */\n    get addButtonNode() {\n        return this.node.getElementsByClassName('lm-TabBar-addButton')[0];\n    }\n    /**\n     * Add a tab to the end of the tab bar.\n     *\n     * @param value - The title which holds the data for the tab,\n     *   or an options object to convert to a title.\n     *\n     * @returns The title object added to the tab bar.\n     *\n     * #### Notes\n     * If the title is already added to the tab bar, it will be moved.\n     */\n    addTab(value) {\n        return this.insertTab(this._titles.length, value);\n    }\n    /**\n     * Insert a tab into the tab bar at the specified index.\n     *\n     * @param index - The index at which to insert the tab.\n     *\n     * @param value - The title which holds the data for the tab,\n     *   or an options object to convert to a title.\n     *\n     * @returns The title object added to the tab bar.\n     *\n     * #### Notes\n     * The index will be clamped to the bounds of the tabs.\n     *\n     * If the title is already added to the tab bar, it will be moved.\n     */\n    insertTab(index, value) {\n        // Release the mouse before making any changes.\n        this._releaseMouse();\n        // Coerce the value to a title.\n        let title = Private$7.asTitle(value);\n        // Look up the index of the title.\n        let i = this._titles.indexOf(title);\n        // Clamp the insert index to the array bounds.\n        let j = Math.max(0, Math.min(index, this._titles.length));\n        // If the title is not in the array, insert it.\n        if (i === -1) {\n            // Insert the title into the array.\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(this._titles, j, title);\n            // Connect to the title changed signal.\n            title.changed.connect(this._onTitleChanged, this);\n            // Schedule an update of the tabs.\n            this.update();\n            // Adjust the current index for the insert.\n            this._adjustCurrentForInsert(j, title);\n            // Return the title added to the tab bar.\n            return title;\n        }\n        // Otherwise, the title exists in the array and should be moved.\n        // Adjust the index if the location is at the end of the array.\n        if (j === this._titles.length) {\n            j--;\n        }\n        // Bail if there is no effective move.\n        if (i === j) {\n            return title;\n        }\n        // Move the title to the new location.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.move(this._titles, i, j);\n        // Schedule an update of the tabs.\n        this.update();\n        // Adjust the current index for the move.\n        this._adjustCurrentForMove(i, j);\n        // Return the title added to the tab bar.\n        return title;\n    }\n    /**\n     * Remove a tab from the tab bar.\n     *\n     * @param title - The title for the tab to remove.\n     *\n     * #### Notes\n     * This is a no-op if the title is not in the tab bar.\n     */\n    removeTab(title) {\n        this.removeTabAt(this._titles.indexOf(title));\n    }\n    /**\n     * Remove the tab at a given index from the tab bar.\n     *\n     * @param index - The index of the tab to remove.\n     *\n     * #### Notes\n     * This is a no-op if the index is out of range.\n     */\n    removeTabAt(index) {\n        // Release the mouse before making any changes.\n        this._releaseMouse();\n        // Remove the title from the array.\n        let title = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(this._titles, index);\n        // Bail if the index is out of range.\n        if (!title) {\n            return;\n        }\n        // Disconnect from the title changed signal.\n        title.changed.disconnect(this._onTitleChanged, this);\n        // Clear the previous title if it's being removed.\n        if (title === this._previousTitle) {\n            this._previousTitle = null;\n        }\n        // Schedule an update of the tabs.\n        this.update();\n        // Adjust the current index for the remove.\n        this._adjustCurrentForRemove(index, title);\n    }\n    /**\n     * Remove all tabs from the tab bar.\n     */\n    clearTabs() {\n        // Bail if there is nothing to remove.\n        if (this._titles.length === 0) {\n            return;\n        }\n        // Release the mouse before making any changes.\n        this._releaseMouse();\n        // Disconnect from the title changed signals.\n        for (let title of this._titles) {\n            title.changed.disconnect(this._onTitleChanged, this);\n        }\n        // Get the current index and title.\n        let pi = this.currentIndex;\n        let pt = this.currentTitle;\n        // Reset the current index and previous title.\n        this._currentIndex = -1;\n        this._previousTitle = null;\n        // Clear the title array.\n        this._titles.length = 0;\n        // Schedule an update of the tabs.\n        this.update();\n        // If no tab was selected, there's nothing else to do.\n        if (pi === -1) {\n            return;\n        }\n        // Emit the current changed signal.\n        this._currentChanged.emit({\n            previousIndex: pi,\n            previousTitle: pt,\n            currentIndex: -1,\n            currentTitle: null\n        });\n    }\n    /**\n     * Release the mouse and restore the non-dragged tab positions.\n     *\n     * #### Notes\n     * This will cause the tab bar to stop handling mouse events and to\n     * restore the tabs to their non-dragged positions.\n     */\n    releaseMouse() {\n        this._releaseMouse();\n    }\n    /**\n     * Handle the DOM events for the tab bar.\n     *\n     * @param event - The DOM event sent to the tab bar.\n     *\n     * #### Notes\n     * This method implements the DOM `EventListener` interface and is\n     * called in response to events on the tab bar's DOM node.\n     *\n     * This should not be called directly by user code.\n     */\n    handleEvent(event) {\n        switch (event.type) {\n            case 'pointerdown':\n                this._evtPointerDown(event);\n                break;\n            case 'pointermove':\n                this._evtPointerMove(event);\n                break;\n            case 'pointerup':\n                this._evtPointerUp(event);\n                break;\n            case 'dblclick':\n                this._evtDblClick(event);\n                break;\n            case 'keydown':\n                event.eventPhase === Event.CAPTURING_PHASE\n                    ? this._evtKeyDownCapturing(event)\n                    : this._evtKeyDown(event);\n                break;\n            case 'contextmenu':\n                event.preventDefault();\n                event.stopPropagation();\n                break;\n        }\n    }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     */\n    onBeforeAttach(msg) {\n        this.node.addEventListener('pointerdown', this);\n        this.node.addEventListener('dblclick', this);\n        this.node.addEventListener('keydown', this);\n    }\n    /**\n     * A message handler invoked on an `'after-detach'` message.\n     */\n    onAfterDetach(msg) {\n        this.node.removeEventListener('pointerdown', this);\n        this.node.removeEventListener('dblclick', this);\n        this.node.removeEventListener('keydown', this);\n        this._releaseMouse();\n    }\n    /**\n     * A message handler invoked on an `'update-request'` message.\n     */\n    onUpdateRequest(msg) {\n        var _a;\n        let titles = this._titles;\n        let renderer = this.renderer;\n        let currentTitle = this.currentTitle;\n        let content = new Array(titles.length);\n        // Keep the tabindex=\"0\" attribute to the tab which handled it before the update.\n        // If the add button handles it, no need to do anything. If no element of the tab\n        // bar handles it, set it on the current or the first tab to ensure one element\n        // handles it after update.\n        const tabHandlingTabindex = (_a = this._getCurrentTabindex()) !== null && _a !== void 0 ? _a : (this._currentIndex > -1 ? this._currentIndex : 0);\n        for (let i = 0, n = titles.length; i < n; ++i) {\n            let title = titles[i];\n            let current = title === currentTitle;\n            let zIndex = current ? n : n - i - 1;\n            let tabIndex = tabHandlingTabindex === i ? 0 : -1;\n            content[i] = renderer.renderTab({ title, current, zIndex, tabIndex });\n        }\n        _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.VirtualDOM.render(content, this.contentNode);\n    }\n    /**\n     * Get the index of the tab which handles tabindex=\"0\".\n     * If the add button handles tabindex=\"0\", -1 is returned.\n     * If none of the previous handles tabindex=\"0\", null is returned.\n     */\n    _getCurrentTabindex() {\n        let index = null;\n        const elemTabindex = this.contentNode.querySelector('li[tabindex=\"0\"]');\n        if (elemTabindex) {\n            index = [...this.contentNode.children].indexOf(elemTabindex);\n        }\n        else if (this._addButtonEnabled &&\n            this.addButtonNode.getAttribute('tabindex') === '0') {\n            index = -1;\n        }\n        return index;\n    }\n    /**\n     * Handle the `'dblclick'` event for the tab bar.\n     */\n    _evtDblClick(event) {\n        // Do nothing if titles are not editable\n        if (!this.titlesEditable) {\n            return;\n        }\n        let tabs = this.contentNode.children;\n        // Find the index of the targeted tab.\n        let index = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(tabs, tab => {\n            return _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(tab, event.clientX, event.clientY);\n        });\n        // Do nothing if the press is not on a tab.\n        if (index === -1) {\n            return;\n        }\n        let title = this.titles[index];\n        let label = tabs[index].querySelector('.lm-TabBar-tabLabel');\n        if (label && label.contains(event.target)) {\n            let value = title.label || '';\n            // Clear the label element\n            let oldValue = label.innerHTML;\n            label.innerHTML = '';\n            let input = document.createElement('input');\n            input.classList.add('lm-TabBar-tabInput');\n            input.value = value;\n            label.appendChild(input);\n            let onblur = () => {\n                input.removeEventListener('blur', onblur);\n                label.innerHTML = oldValue;\n                this.node.addEventListener('keydown', this);\n            };\n            input.addEventListener('dblclick', (event) => event.stopPropagation());\n            input.addEventListener('blur', onblur);\n            input.addEventListener('keydown', (event) => {\n                if (event.key === 'Enter') {\n                    if (input.value !== '') {\n                        title.label = title.caption = input.value;\n                    }\n                    onblur();\n                }\n                else if (event.key === 'Escape') {\n                    onblur();\n                }\n            });\n            this.node.removeEventListener('keydown', this);\n            input.select();\n            input.focus();\n            if (label.children.length > 0) {\n                label.children[0].focus();\n            }\n        }\n    }\n    /**\n     * Handle the `'keydown'` event for the tab bar at capturing phase.\n     */\n    _evtKeyDownCapturing(event) {\n        if (event.eventPhase !== Event.CAPTURING_PHASE) {\n            return;\n        }\n        // Stop all input events during drag.\n        event.preventDefault();\n        event.stopPropagation();\n        // Release the mouse if `Escape` is pressed.\n        if (event.key === 'Escape') {\n            this._releaseMouse();\n        }\n    }\n    /**\n     * Handle the `'keydown'` event for the tab bar at target phase.\n     */\n    _evtKeyDown(event) {\n        var _a, _b, _c;\n        // Allow for navigation using tab key\n        if (event.key === 'Tab' || event.eventPhase === Event.CAPTURING_PHASE) {\n            return;\n        }\n        // Check if Enter or Spacebar key has been pressed and open that tab\n        if (event.key === 'Enter' ||\n            event.key === 'Spacebar' ||\n            event.key === ' ') {\n            // Get focus element that is in focus by the tab key\n            const focusedElement = document.activeElement;\n            // Test first if the focus is on the add button node\n            if (this.addButtonEnabled &&\n                this.addButtonNode.contains(focusedElement)) {\n                event.preventDefault();\n                event.stopPropagation();\n                this._addRequested.emit();\n            }\n            else {\n                const index = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(this.contentNode.children, tab => tab.contains(focusedElement));\n                if (index >= 0) {\n                    event.preventDefault();\n                    event.stopPropagation();\n                    this.currentIndex = index;\n                }\n            }\n            // Handle the arrow keys to switch tabs.\n        }\n        else if (ARROW_KEYS.includes(event.key)) {\n            // Create a list of all focusable elements in the tab bar.\n            const focusable = [...this.contentNode.children];\n            if (this.addButtonEnabled) {\n                focusable.push(this.addButtonNode);\n            }\n            // If the tab bar contains only one element, nothing to do.\n            if (focusable.length <= 1) {\n                return;\n            }\n            event.preventDefault();\n            event.stopPropagation();\n            // Get the current focused element.\n            let focusedIndex = focusable.indexOf(document.activeElement);\n            if (focusedIndex === -1) {\n                focusedIndex = this._currentIndex;\n            }\n            // Find the next element to focus on.\n            let nextFocused;\n            if ((event.key === 'ArrowRight' && this._orientation === 'horizontal') ||\n                (event.key === 'ArrowDown' && this._orientation === 'vertical')) {\n                nextFocused = (_a = focusable[focusedIndex + 1]) !== null && _a !== void 0 ? _a : focusable[0];\n            }\n            else if ((event.key === 'ArrowLeft' && this._orientation === 'horizontal') ||\n                (event.key === 'ArrowUp' && this._orientation === 'vertical')) {\n                nextFocused =\n                    (_b = focusable[focusedIndex - 1]) !== null && _b !== void 0 ? _b : focusable[focusable.length - 1];\n            }\n            else if (event.key === 'Home') {\n                nextFocused = focusable[0];\n            }\n            else if (event.key === 'End') {\n                nextFocused = focusable[focusable.length - 1];\n            }\n            // Change the focused element and the tabindex value.\n            if (nextFocused) {\n                (_c = focusable[focusedIndex]) === null || _c === void 0 ? void 0 : _c.setAttribute('tabindex', '-1');\n                nextFocused === null || nextFocused === void 0 ? void 0 : nextFocused.setAttribute('tabindex', '0');\n                nextFocused.focus();\n            }\n        }\n    }\n    /**\n     * Handle the `'pointerdown'` event for the tab bar.\n     */\n    _evtPointerDown(event) {\n        // Do nothing if it's not a left or middle mouse press.\n        if (event.button !== 0 && event.button !== 1) {\n            return;\n        }\n        // Do nothing if a drag is in progress.\n        if (this._dragData) {\n            return;\n        }\n        // Do nothing if a title editable input was clicked.\n        if (event.target.classList.contains('lm-TabBar-tabInput')) {\n            return;\n        }\n        // Check if the add button was clicked.\n        let addButtonClicked = this.addButtonEnabled &&\n            this.addButtonNode.contains(event.target);\n        // Lookup the tab nodes.\n        let tabs = this.contentNode.children;\n        // Find the index of the pressed tab.\n        let index = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(tabs, tab => {\n            return _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(tab, event.clientX, event.clientY);\n        });\n        // Do nothing if the press is not on a tab or the add button.\n        if (index === -1 && !addButtonClicked) {\n            return;\n        }\n        // Pressing on a tab stops the event propagation.\n        event.preventDefault();\n        event.stopPropagation();\n        // Initialize the non-measured parts of the drag data.\n        this._dragData = {\n            tab: tabs[index],\n            index: index,\n            pressX: event.clientX,\n            pressY: event.clientY,\n            tabPos: -1,\n            tabSize: -1,\n            tabPressPos: -1,\n            targetIndex: -1,\n            tabLayout: null,\n            contentRect: null,\n            override: null,\n            dragActive: false,\n            dragAborted: false,\n            detachRequested: false\n        };\n        // Add the document pointer up listener.\n        this.document.addEventListener('pointerup', this, true);\n        // Do nothing else if the middle button or add button is clicked.\n        if (event.button === 1 || addButtonClicked) {\n            return;\n        }\n        // Do nothing else if the close icon is clicked.\n        let icon = tabs[index].querySelector(this.renderer.closeIconSelector);\n        if (icon && icon.contains(event.target)) {\n            return;\n        }\n        // Add the extra listeners if the tabs are movable.\n        if (this.tabsMovable) {\n            this.document.addEventListener('pointermove', this, true);\n            this.document.addEventListener('keydown', this, true);\n            this.document.addEventListener('contextmenu', this, true);\n        }\n        // Update the current index as appropriate.\n        if (this.allowDeselect && this.currentIndex === index) {\n            this.currentIndex = -1;\n        }\n        else {\n            this.currentIndex = index;\n        }\n        // Do nothing else if there is no current tab.\n        if (this.currentIndex === -1) {\n            return;\n        }\n        // Emit the tab activate request signal.\n        this._tabActivateRequested.emit({\n            index: this.currentIndex,\n            title: this.currentTitle\n        });\n    }\n    /**\n     * Handle the `'pointermove'` event for the tab bar.\n     */\n    _evtPointerMove(event) {\n        // Do nothing if no drag is in progress.\n        let data = this._dragData;\n        if (!data) {\n            return;\n        }\n        // Suppress the event during a drag.\n        event.preventDefault();\n        event.stopPropagation();\n        // Lookup the tab nodes.\n        let tabs = this.contentNode.children;\n        // Bail early if the drag threshold has not been met.\n        if (!data.dragActive && !Private$7.dragExceeded(data, event)) {\n            return;\n        }\n        // Activate the drag if necessary.\n        if (!data.dragActive) {\n            // Fill in the rest of the drag data measurements.\n            let tabRect = data.tab.getBoundingClientRect();\n            if (this._orientation === 'horizontal') {\n                data.tabPos = data.tab.offsetLeft;\n                data.tabSize = tabRect.width;\n                data.tabPressPos = data.pressX - tabRect.left;\n            }\n            else {\n                data.tabPos = data.tab.offsetTop;\n                data.tabSize = tabRect.height;\n                data.tabPressPos = data.pressY - tabRect.top;\n            }\n            data.tabPressOffset = {\n                x: data.pressX - tabRect.left,\n                y: data.pressY - tabRect.top\n            };\n            data.tabLayout = Private$7.snapTabLayout(tabs, this._orientation);\n            data.contentRect = this.contentNode.getBoundingClientRect();\n            data.override = _lumino_dragdrop__WEBPACK_IMPORTED_MODULE_6__.Drag.overrideCursor('default');\n            // Add the dragging style classes.\n            data.tab.classList.add('lm-mod-dragging');\n            this.addClass('lm-mod-dragging');\n            // Mark the drag as active.\n            data.dragActive = true;\n        }\n        // Emit the detach requested signal if the threshold is exceeded.\n        if (!data.detachRequested && Private$7.detachExceeded(data, event)) {\n            // Only emit the signal once per drag cycle.\n            data.detachRequested = true;\n            // Setup the arguments for the signal.\n            let index = data.index;\n            let clientX = event.clientX;\n            let clientY = event.clientY;\n            let tab = tabs[index];\n            let title = this._titles[index];\n            // Emit the tab detach requested signal.\n            this._tabDetachRequested.emit({\n                index,\n                title,\n                tab,\n                clientX,\n                clientY,\n                offset: data.tabPressOffset\n            });\n            // Bail if the signal handler aborted the drag.\n            if (data.dragAborted) {\n                return;\n            }\n        }\n        // Update the positions of the tabs.\n        Private$7.layoutTabs(tabs, data, event, this._orientation);\n    }\n    /**\n     * Handle the `'pointerup'` event for the document.\n     */\n    _evtPointerUp(event) {\n        // Do nothing if it's not a left or middle mouse release.\n        if (event.button !== 0 && event.button !== 1) {\n            return;\n        }\n        // Do nothing if no drag is in progress.\n        const data = this._dragData;\n        if (!data) {\n            return;\n        }\n        // Stop the event propagation.\n        event.preventDefault();\n        event.stopPropagation();\n        // Remove the extra mouse event listeners.\n        this.document.removeEventListener('pointermove', this, true);\n        this.document.removeEventListener('pointerup', this, true);\n        this.document.removeEventListener('keydown', this, true);\n        this.document.removeEventListener('contextmenu', this, true);\n        // Handle a release when the drag is not active.\n        if (!data.dragActive) {\n            // Clear the drag data.\n            this._dragData = null;\n            // Handle clicking the add button.\n            let addButtonClicked = this.addButtonEnabled &&\n                this.addButtonNode.contains(event.target);\n            if (addButtonClicked) {\n                this._addRequested.emit(undefined);\n                return;\n            }\n            // Lookup the tab nodes.\n            let tabs = this.contentNode.children;\n            // Find the index of the released tab.\n            let index = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(tabs, tab => {\n                return _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(tab, event.clientX, event.clientY);\n            });\n            // Do nothing if the release is not on the original pressed tab.\n            if (index !== data.index) {\n                return;\n            }\n            // Ignore the release if the title is not closable.\n            let title = this._titles[index];\n            if (!title.closable) {\n                return;\n            }\n            // Emit the close requested signal if the middle button is released.\n            if (event.button === 1) {\n                this._tabCloseRequested.emit({ index, title });\n                return;\n            }\n            // Emit the close requested signal if the close icon was released.\n            let icon = tabs[index].querySelector(this.renderer.closeIconSelector);\n            if (icon && icon.contains(event.target)) {\n                this._tabCloseRequested.emit({ index, title });\n                return;\n            }\n            // Otherwise, there is nothing left to do.\n            return;\n        }\n        // Do nothing if the left button is not released.\n        if (event.button !== 0) {\n            return;\n        }\n        // Position the tab at its final resting position.\n        Private$7.finalizeTabPosition(data, this._orientation);\n        // Remove the dragging class from the tab so it can be transitioned.\n        data.tab.classList.remove('lm-mod-dragging');\n        // Parse the transition duration for releasing the tab.\n        let duration = Private$7.parseTransitionDuration(data.tab);\n        // Complete the release on a timer to allow the tab to transition.\n        setTimeout(() => {\n            // Do nothing if the drag has been aborted.\n            if (data.dragAborted) {\n                return;\n            }\n            // Clear the drag data reference.\n            this._dragData = null;\n            // Reset the positions of the tabs.\n            Private$7.resetTabPositions(this.contentNode.children, this._orientation);\n            // Clear the cursor grab.\n            data.override.dispose();\n            // Remove the remaining dragging style.\n            this.removeClass('lm-mod-dragging');\n            // If the tab was not moved, there is nothing else to do.\n            let i = data.index;\n            let j = data.targetIndex;\n            if (j === -1 || i === j) {\n                return;\n            }\n            // Move the title to the new locations.\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.move(this._titles, i, j);\n            // Adjust the current index for the move.\n            this._adjustCurrentForMove(i, j);\n            // Emit the tab moved signal.\n            this._tabMoved.emit({\n                fromIndex: i,\n                toIndex: j,\n                title: this._titles[j]\n            });\n            // Update the tabs immediately to prevent flicker.\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this, Widget.Msg.UpdateRequest);\n        }, duration);\n    }\n    /**\n     * Release the mouse and restore the non-dragged tab positions.\n     */\n    _releaseMouse() {\n        // Do nothing if no drag is in progress.\n        let data = this._dragData;\n        if (!data) {\n            return;\n        }\n        // Clear the drag data reference.\n        this._dragData = null;\n        // Remove the extra document event listeners.\n        this.document.removeEventListener('pointermove', this, true);\n        this.document.removeEventListener('pointerup', this, true);\n        this.document.removeEventListener('keydown', this, true);\n        this.document.removeEventListener('contextmenu', this, true);\n        // Indicate the drag has been aborted. This allows the mouse\n        // event handlers to return early when the drag is canceled.\n        data.dragAborted = true;\n        // If the drag is not active, there's nothing more to do.\n        if (!data.dragActive) {\n            return;\n        }\n        // Reset the tabs to their non-dragged positions.\n        Private$7.resetTabPositions(this.contentNode.children, this._orientation);\n        // Clear the cursor override.\n        data.override.dispose();\n        // Clear the dragging style classes.\n        data.tab.classList.remove('lm-mod-dragging');\n        this.removeClass('lm-mod-dragging');\n    }\n    /**\n     * Adjust the current index for a tab insert operation.\n     *\n     * This method accounts for the tab bar's insertion behavior when\n     * adjusting the current index and emitting the changed signal.\n     */\n    _adjustCurrentForInsert(i, title) {\n        // Lookup commonly used variables.\n        let ct = this.currentTitle;\n        let ci = this._currentIndex;\n        let bh = this.insertBehavior;\n        // TODO: do we need to do an update to update the aria-selected attribute?\n        // Handle the behavior where the new tab is always selected,\n        // or the behavior where the new tab is selected if needed.\n        if (bh === 'select-tab' || (bh === 'select-tab-if-needed' && ci === -1)) {\n            this._currentIndex = i;\n            this._previousTitle = ct;\n            this._currentChanged.emit({\n                previousIndex: ci,\n                previousTitle: ct,\n                currentIndex: i,\n                currentTitle: title\n            });\n            return;\n        }\n        // Otherwise, silently adjust the current index if needed.\n        if (ci >= i) {\n            this._currentIndex++;\n        }\n    }\n    /**\n     * Adjust the current index for a tab move operation.\n     *\n     * This method will not cause the actual current tab to change.\n     * It silently adjusts the index to account for the given move.\n     */\n    _adjustCurrentForMove(i, j) {\n        if (this._currentIndex === i) {\n            this._currentIndex = j;\n        }\n        else if (this._currentIndex < i && this._currentIndex >= j) {\n            this._currentIndex++;\n        }\n        else if (this._currentIndex > i && this._currentIndex <= j) {\n            this._currentIndex--;\n        }\n    }\n    /**\n     * Adjust the current index for a tab remove operation.\n     *\n     * This method accounts for the tab bar's remove behavior when\n     * adjusting the current index and emitting the changed signal.\n     */\n    _adjustCurrentForRemove(i, title) {\n        // Lookup commonly used variables.\n        let ci = this._currentIndex;\n        let bh = this.removeBehavior;\n        // Silently adjust the index if the current tab is not removed.\n        if (ci !== i) {\n            if (ci > i) {\n                this._currentIndex--;\n            }\n            return;\n        }\n        // TODO: do we need to do an update to adjust the aria-selected value?\n        // No tab gets selected if the tab bar is empty.\n        if (this._titles.length === 0) {\n            this._currentIndex = -1;\n            this._currentChanged.emit({\n                previousIndex: i,\n                previousTitle: title,\n                currentIndex: -1,\n                currentTitle: null\n            });\n            return;\n        }\n        // Handle behavior where the next sibling tab is selected.\n        if (bh === 'select-tab-after') {\n            this._currentIndex = Math.min(i, this._titles.length - 1);\n            this._currentChanged.emit({\n                previousIndex: i,\n                previousTitle: title,\n                currentIndex: this._currentIndex,\n                currentTitle: this.currentTitle\n            });\n            return;\n        }\n        // Handle behavior where the previous sibling tab is selected.\n        if (bh === 'select-tab-before') {\n            this._currentIndex = Math.max(0, i - 1);\n            this._currentChanged.emit({\n                previousIndex: i,\n                previousTitle: title,\n                currentIndex: this._currentIndex,\n                currentTitle: this.currentTitle\n            });\n            return;\n        }\n        // Handle behavior where the previous history tab is selected.\n        if (bh === 'select-previous-tab') {\n            if (this._previousTitle) {\n                this._currentIndex = this._titles.indexOf(this._previousTitle);\n                this._previousTitle = null;\n            }\n            else {\n                this._currentIndex = Math.min(i, this._titles.length - 1);\n            }\n            this._currentChanged.emit({\n                previousIndex: i,\n                previousTitle: title,\n                currentIndex: this._currentIndex,\n                currentTitle: this.currentTitle\n            });\n            return;\n        }\n        // Otherwise, no tab gets selected.\n        this._currentIndex = -1;\n        this._currentChanged.emit({\n            previousIndex: i,\n            previousTitle: title,\n            currentIndex: -1,\n            currentTitle: null\n        });\n    }\n    /**\n     * Handle the `changed` signal of a title object.\n     */\n    _onTitleChanged(sender) {\n        this.update();\n    }\n}\n/**\n * The namespace for the `TabBar` class statics.\n */\n(function (TabBar) {\n    /**\n     * The default implementation of `IRenderer`.\n     *\n     * #### Notes\n     * Subclasses are free to reimplement rendering methods as needed.\n     */\n    class Renderer {\n        constructor() {\n            /**\n             * A selector which matches the close icon node in a tab.\n             */\n            this.closeIconSelector = '.lm-TabBar-tabCloseIcon';\n            this._tabID = 0;\n            this._tabKeys = new WeakMap();\n            this._uuid = ++Renderer._nInstance;\n        }\n        /**\n         * Render the virtual element for a tab.\n         *\n         * @param data - The data to use for rendering the tab.\n         *\n         * @returns A virtual element representing the tab.\n         */\n        renderTab(data) {\n            let title = data.title.caption;\n            let key = this.createTabKey(data);\n            let id = key;\n            let style = this.createTabStyle(data);\n            let className = this.createTabClass(data);\n            let dataset = this.createTabDataset(data);\n            let aria = this.createTabARIA(data);\n            if (data.title.closable) {\n                return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.li({ id, key, className, title, style, dataset, ...aria }, this.renderIcon(data), this.renderLabel(data), this.renderCloseIcon(data));\n            }\n            else {\n                return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.li({ id, key, className, title, style, dataset, ...aria }, this.renderIcon(data), this.renderLabel(data));\n            }\n        }\n        /**\n         * Render the icon element for a tab.\n         *\n         * @param data - The data to use for rendering the tab.\n         *\n         * @returns A virtual element representing the tab icon.\n         */\n        renderIcon(data) {\n            const { title } = data;\n            let className = this.createIconClass(data);\n            // If title.icon is undefined, it will be ignored.\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className }, title.icon, title.iconLabel);\n        }\n        /**\n         * Render the label element for a tab.\n         *\n         * @param data - The data to use for rendering the tab.\n         *\n         * @returns A virtual element representing the tab label.\n         */\n        renderLabel(data) {\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className: 'lm-TabBar-tabLabel' }, data.title.label);\n        }\n        /**\n         * Render the close icon element for a tab.\n         *\n         * @param data - The data to use for rendering the tab.\n         *\n         * @returns A virtual element representing the tab close icon.\n         */\n        renderCloseIcon(data) {\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className: 'lm-TabBar-tabCloseIcon' });\n        }\n        /**\n         * Create a unique render key for the tab.\n         *\n         * @param data - The data to use for the tab.\n         *\n         * @returns The unique render key for the tab.\n         *\n         * #### Notes\n         * This method caches the key against the tab title the first time\n         * the key is generated. This enables efficient rendering of moved\n         * tabs and avoids subtle hover style artifacts.\n         */\n        createTabKey(data) {\n            let key = this._tabKeys.get(data.title);\n            if (key === undefined) {\n                key = `tab-key-${this._uuid}-${this._tabID++}`;\n                this._tabKeys.set(data.title, key);\n            }\n            return key;\n        }\n        /**\n         * Create the inline style object for a tab.\n         *\n         * @param data - The data to use for the tab.\n         *\n         * @returns The inline style data for the tab.\n         */\n        createTabStyle(data) {\n            return { zIndex: `${data.zIndex}` };\n        }\n        /**\n         * Create the class name for the tab.\n         *\n         * @param data - The data to use for the tab.\n         *\n         * @returns The full class name for the tab.\n         */\n        createTabClass(data) {\n            let name = 'lm-TabBar-tab';\n            if (data.title.className) {\n                name += ` ${data.title.className}`;\n            }\n            if (data.title.closable) {\n                name += ' lm-mod-closable';\n            }\n            if (data.current) {\n                name += ' lm-mod-current';\n            }\n            return name;\n        }\n        /**\n         * Create the dataset for a tab.\n         *\n         * @param data - The data to use for the tab.\n         *\n         * @returns The dataset for the tab.\n         */\n        createTabDataset(data) {\n            return data.title.dataset;\n        }\n        /**\n         * Create the ARIA attributes for a tab.\n         *\n         * @param data - The data to use for the tab.\n         *\n         * @returns The ARIA attributes for the tab.\n         */\n        createTabARIA(data) {\n            var _a;\n            return {\n                role: 'tab',\n                'aria-selected': data.current.toString(),\n                tabindex: `${(_a = data.tabIndex) !== null && _a !== void 0 ? _a : '-1'}`\n            };\n        }\n        /**\n         * Create the class name for the tab icon.\n         *\n         * @param data - The data to use for the tab.\n         *\n         * @returns The full class name for the tab icon.\n         */\n        createIconClass(data) {\n            let name = 'lm-TabBar-tabIcon';\n            let extra = data.title.iconClass;\n            return extra ? `${name} ${extra}` : name;\n        }\n    }\n    Renderer._nInstance = 0;\n    TabBar.Renderer = Renderer;\n    /**\n     * The default `Renderer` instance.\n     */\n    TabBar.defaultRenderer = new Renderer();\n    /**\n     * A selector which matches the add button node in the tab bar.\n     */\n    TabBar.addButtonSelector = '.lm-TabBar-addButton';\n})(TabBar || (TabBar = {}));\n/**\n * The namespace for the module implementation details.\n */\nvar Private$7;\n(function (Private) {\n    /**\n     * The start drag distance threshold.\n     */\n    Private.DRAG_THRESHOLD = 5;\n    /**\n     * The detach distance threshold.\n     */\n    Private.DETACH_THRESHOLD = 20;\n    /**\n     * Create the DOM node for a tab bar.\n     */\n    function createNode() {\n        let node = document.createElement('div');\n        let content = document.createElement('ul');\n        content.setAttribute('role', 'tablist');\n        content.className = 'lm-TabBar-content';\n        node.appendChild(content);\n        let add = document.createElement('div');\n        add.className = 'lm-TabBar-addButton lm-mod-hidden';\n        add.setAttribute('tabindex', '-1');\n        add.setAttribute('role', 'button');\n        node.appendChild(add);\n        return node;\n    }\n    Private.createNode = createNode;\n    /**\n     * Coerce a title or options into a real title.\n     */\n    function asTitle(value) {\n        return value instanceof Title ? value : new Title(value);\n    }\n    Private.asTitle = asTitle;\n    /**\n     * Parse the transition duration for a tab node.\n     */\n    function parseTransitionDuration(tab) {\n        let style = window.getComputedStyle(tab);\n        return 1000 * (parseFloat(style.transitionDuration) || 0);\n    }\n    Private.parseTransitionDuration = parseTransitionDuration;\n    /**\n     * Get a snapshot of the current tab layout values.\n     */\n    function snapTabLayout(tabs, orientation) {\n        let layout = new Array(tabs.length);\n        for (let i = 0, n = tabs.length; i < n; ++i) {\n            let node = tabs[i];\n            let style = window.getComputedStyle(node);\n            if (orientation === 'horizontal') {\n                layout[i] = {\n                    pos: node.offsetLeft,\n                    size: node.offsetWidth,\n                    margin: parseFloat(style.marginLeft) || 0\n                };\n            }\n            else {\n                layout[i] = {\n                    pos: node.offsetTop,\n                    size: node.offsetHeight,\n                    margin: parseFloat(style.marginTop) || 0\n                };\n            }\n        }\n        return layout;\n    }\n    Private.snapTabLayout = snapTabLayout;\n    /**\n     * Test if the event exceeds the drag threshold.\n     */\n    function dragExceeded(data, event) {\n        let dx = Math.abs(event.clientX - data.pressX);\n        let dy = Math.abs(event.clientY - data.pressY);\n        return dx >= Private.DRAG_THRESHOLD || dy >= Private.DRAG_THRESHOLD;\n    }\n    Private.dragExceeded = dragExceeded;\n    /**\n     * Test if the event exceeds the drag detach threshold.\n     */\n    function detachExceeded(data, event) {\n        let rect = data.contentRect;\n        return (event.clientX < rect.left - Private.DETACH_THRESHOLD ||\n            event.clientX >= rect.right + Private.DETACH_THRESHOLD ||\n            event.clientY < rect.top - Private.DETACH_THRESHOLD ||\n            event.clientY >= rect.bottom + Private.DETACH_THRESHOLD);\n    }\n    Private.detachExceeded = detachExceeded;\n    /**\n     * Update the relative tab positions and computed target index.\n     */\n    function layoutTabs(tabs, data, event, orientation) {\n        // Compute the orientation-sensitive values.\n        let pressPos;\n        let localPos;\n        let clientPos;\n        let clientSize;\n        if (orientation === 'horizontal') {\n            pressPos = data.pressX;\n            localPos = event.clientX - data.contentRect.left;\n            clientPos = event.clientX;\n            clientSize = data.contentRect.width;\n        }\n        else {\n            pressPos = data.pressY;\n            localPos = event.clientY - data.contentRect.top;\n            clientPos = event.clientY;\n            clientSize = data.contentRect.height;\n        }\n        // Compute the target data.\n        let targetIndex = data.index;\n        let targetPos = localPos - data.tabPressPos;\n        let targetEnd = targetPos + data.tabSize;\n        // Update the relative tab positions.\n        for (let i = 0, n = tabs.length; i < n; ++i) {\n            let pxPos;\n            let layout = data.tabLayout[i];\n            let threshold = layout.pos + (layout.size >> 1);\n            if (i < data.index && targetPos < threshold) {\n                pxPos = `${data.tabSize + data.tabLayout[i + 1].margin}px`;\n                targetIndex = Math.min(targetIndex, i);\n            }\n            else if (i > data.index && targetEnd > threshold) {\n                pxPos = `${-data.tabSize - layout.margin}px`;\n                targetIndex = Math.max(targetIndex, i);\n            }\n            else if (i === data.index) {\n                let ideal = clientPos - pressPos;\n                let limit = clientSize - (data.tabPos + data.tabSize);\n                pxPos = `${Math.max(-data.tabPos, Math.min(ideal, limit))}px`;\n            }\n            else {\n                pxPos = '';\n            }\n            if (orientation === 'horizontal') {\n                tabs[i].style.left = pxPos;\n            }\n            else {\n                tabs[i].style.top = pxPos;\n            }\n        }\n        // Update the computed target index.\n        data.targetIndex = targetIndex;\n    }\n    Private.layoutTabs = layoutTabs;\n    /**\n     * Position the drag tab at its final resting relative position.\n     */\n    function finalizeTabPosition(data, orientation) {\n        // Compute the orientation-sensitive client size.\n        let clientSize;\n        if (orientation === 'horizontal') {\n            clientSize = data.contentRect.width;\n        }\n        else {\n            clientSize = data.contentRect.height;\n        }\n        // Compute the ideal final tab position.\n        let ideal;\n        if (data.targetIndex === data.index) {\n            ideal = 0;\n        }\n        else if (data.targetIndex > data.index) {\n            let tgt = data.tabLayout[data.targetIndex];\n            ideal = tgt.pos + tgt.size - data.tabSize - data.tabPos;\n        }\n        else {\n            let tgt = data.tabLayout[data.targetIndex];\n            ideal = tgt.pos - data.tabPos;\n        }\n        // Compute the tab position limit.\n        let limit = clientSize - (data.tabPos + data.tabSize);\n        let final = Math.max(-data.tabPos, Math.min(ideal, limit));\n        // Set the final orientation-sensitive position.\n        if (orientation === 'horizontal') {\n            data.tab.style.left = `${final}px`;\n        }\n        else {\n            data.tab.style.top = `${final}px`;\n        }\n    }\n    Private.finalizeTabPosition = finalizeTabPosition;\n    /**\n     * Reset the relative positions of the given tabs.\n     */\n    function resetTabPositions(tabs, orientation) {\n        for (const tab of tabs) {\n            if (orientation === 'horizontal') {\n                tab.style.left = '';\n            }\n            else {\n                tab.style.top = '';\n            }\n        }\n    }\n    Private.resetTabPositions = resetTabPositions;\n})(Private$7 || (Private$7 = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A layout which provides a flexible docking arrangement.\n *\n * #### Notes\n * The consumer of this layout is responsible for handling all signals\n * from the generated tab bars and managing the visibility of widgets\n * and tab bars as needed.\n */\nclass DockLayout extends Layout {\n    /**\n     * Construct a new dock layout.\n     *\n     * @param options - The options for initializing the layout.\n     */\n    constructor(options) {\n        super();\n        this._spacing = 4;\n        this._dirty = false;\n        this._root = null;\n        this._box = null;\n        this._items = new Map();\n        this.renderer = options.renderer;\n        if (options.spacing !== undefined) {\n            this._spacing = Utils$1.clampDimension(options.spacing);\n        }\n        this._document = options.document || document;\n        this._hiddenMode =\n            options.hiddenMode !== undefined\n                ? options.hiddenMode\n                : Widget.HiddenMode.Display;\n    }\n    /**\n     * Dispose of the resources held by the layout.\n     *\n     * #### Notes\n     * This will clear and dispose all widgets in the layout.\n     */\n    dispose() {\n        // Get an iterator over the widgets in the layout.\n        let widgets = this[Symbol.iterator]();\n        // Dispose of the layout items.\n        this._items.forEach(item => {\n            item.dispose();\n        });\n        // Clear the layout state before disposing the widgets.\n        this._box = null;\n        this._root = null;\n        this._items.clear();\n        // Dispose of the widgets contained in the old layout root.\n        for (const widget of widgets) {\n            widget.dispose();\n        }\n        // Dispose of the base class.\n        super.dispose();\n    }\n    /**\n     * The method for hiding child widgets.\n     *\n     * #### Notes\n     * If there is only one child widget, `Display` hiding mode will be used\n     * regardless of this setting.\n     */\n    get hiddenMode() {\n        return this._hiddenMode;\n    }\n    set hiddenMode(v) {\n        if (this._hiddenMode === v) {\n            return;\n        }\n        this._hiddenMode = v;\n        for (const bar of this.tabBars()) {\n            if (bar.titles.length > 1) {\n                for (const title of bar.titles) {\n                    title.owner.hiddenMode = this._hiddenMode;\n                }\n            }\n        }\n    }\n    /**\n     * Get the inter-element spacing for the dock layout.\n     */\n    get spacing() {\n        return this._spacing;\n    }\n    /**\n     * Set the inter-element spacing for the dock layout.\n     */\n    set spacing(value) {\n        value = Utils$1.clampDimension(value);\n        if (this._spacing === value) {\n            return;\n        }\n        this._spacing = value;\n        if (!this.parent) {\n            return;\n        }\n        this.parent.fit();\n    }\n    /**\n     * Whether the dock layout is empty.\n     */\n    get isEmpty() {\n        return this._root === null;\n    }\n    /**\n     * Create an iterator over all widgets in the layout.\n     *\n     * @returns A new iterator over the widgets in the layout.\n     *\n     * #### Notes\n     * This iterator includes the generated tab bars.\n     */\n    [Symbol.iterator]() {\n        return this._root ? this._root.iterAllWidgets() : (0,_lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.empty)();\n    }\n    /**\n     * Create an iterator over the user widgets in the layout.\n     *\n     * @returns A new iterator over the user widgets in the layout.\n     *\n     * #### Notes\n     * This iterator does not include the generated tab bars.\n     */\n    widgets() {\n        return this._root ? this._root.iterUserWidgets() : (0,_lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.empty)();\n    }\n    /**\n     * Create an iterator over the selected widgets in the layout.\n     *\n     * @returns A new iterator over the selected user widgets.\n     *\n     * #### Notes\n     * This iterator yields the widgets corresponding to the current tab\n     * of each tab bar in the layout.\n     */\n    selectedWidgets() {\n        return this._root ? this._root.iterSelectedWidgets() : (0,_lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.empty)();\n    }\n    /**\n     * Create an iterator over the tab bars in the layout.\n     *\n     * @returns A new iterator over the tab bars in the layout.\n     *\n     * #### Notes\n     * This iterator does not include the user widgets.\n     */\n    tabBars() {\n        return this._root ? this._root.iterTabBars() : (0,_lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.empty)();\n    }\n    /**\n     * Create an iterator over the handles in the layout.\n     *\n     * @returns A new iterator over the handles in the layout.\n     */\n    handles() {\n        return this._root ? this._root.iterHandles() : (0,_lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.empty)();\n    }\n    /**\n     * Move a handle to the given offset position.\n     *\n     * @param handle - The handle to move.\n     *\n     * @param offsetX - The desired offset X position of the handle.\n     *\n     * @param offsetY - The desired offset Y position of the handle.\n     *\n     * #### Notes\n     * If the given handle is not contained in the layout, this is no-op.\n     *\n     * The handle will be moved as close as possible to the desired\n     * position without violating any of the layout constraints.\n     *\n     * Only one of the coordinates is used depending on the orientation\n     * of the handle. This method accepts both coordinates to make it\n     * easy to invoke from a mouse move event without needing to know\n     * the handle orientation.\n     */\n    moveHandle(handle, offsetX, offsetY) {\n        // Bail early if there is no root or if the handle is hidden.\n        let hidden = handle.classList.contains('lm-mod-hidden');\n        if (!this._root || hidden) {\n            return;\n        }\n        // Lookup the split node for the handle.\n        let data = this._root.findSplitNode(handle);\n        if (!data) {\n            return;\n        }\n        // Compute the desired delta movement for the handle.\n        let delta;\n        if (data.node.orientation === 'horizontal') {\n            delta = offsetX - handle.offsetLeft;\n        }\n        else {\n            delta = offsetY - handle.offsetTop;\n        }\n        // Bail if there is no handle movement.\n        if (delta === 0) {\n            return;\n        }\n        // Prevent sibling resizing unless needed.\n        data.node.holdSizes();\n        // Adjust the sizers to reflect the handle movement.\n        BoxEngine.adjust(data.node.sizers, data.index, delta);\n        // Update the layout of the widgets.\n        if (this.parent) {\n            this.parent.update();\n        }\n    }\n    /**\n     * Save the current configuration of the dock layout.\n     *\n     * @returns A new config object for the current layout state.\n     *\n     * #### Notes\n     * The return value can be provided to the `restoreLayout` method\n     * in order to restore the layout to its current configuration.\n     */\n    saveLayout() {\n        // Bail early if there is no root.\n        if (!this._root) {\n            return { main: null };\n        }\n        // Hold the current sizes in the layout tree.\n        this._root.holdAllSizes();\n        // Return the layout config.\n        return { main: this._root.createConfig() };\n    }\n    /**\n     * Restore the layout to a previously saved configuration.\n     *\n     * @param config - The layout configuration to restore.\n     *\n     * #### Notes\n     * Widgets which currently belong to the layout but which are not\n     * contained in the config will be unparented.\n     */\n    restoreLayout(config) {\n        // Create the widget set for validating the config.\n        let widgetSet = new Set();\n        // Normalize the main area config and collect the widgets.\n        let mainConfig;\n        if (config.main) {\n            mainConfig = Private$6.normalizeAreaConfig(config.main, widgetSet);\n        }\n        else {\n            mainConfig = null;\n        }\n        // Create iterators over the old content.\n        let oldWidgets = this.widgets();\n        let oldTabBars = this.tabBars();\n        let oldHandles = this.handles();\n        // Clear the root before removing the old content.\n        this._root = null;\n        // Unparent the old widgets which are not in the new config.\n        for (const widget of oldWidgets) {\n            if (!widgetSet.has(widget)) {\n                widget.parent = null;\n            }\n        }\n        // Dispose of the old tab bars.\n        for (const tabBar of oldTabBars) {\n            tabBar.dispose();\n        }\n        // Remove the old handles.\n        for (const handle of oldHandles) {\n            if (handle.parentNode) {\n                handle.parentNode.removeChild(handle);\n            }\n        }\n        // Reparent the new widgets to the current parent.\n        for (const widget of widgetSet) {\n            widget.parent = this.parent;\n        }\n        // Create the root node for the new config.\n        if (mainConfig) {\n            this._root = Private$6.realizeAreaConfig(mainConfig, {\n                // Ignoring optional `document` argument as we must reuse `this._document`\n                createTabBar: (document) => this._createTabBar(),\n                createHandle: () => this._createHandle()\n            }, this._document);\n        }\n        else {\n            this._root = null;\n        }\n        // If there is no parent, there is nothing more to do.\n        if (!this.parent) {\n            return;\n        }\n        // Attach the new widgets to the parent.\n        widgetSet.forEach(widget => {\n            this.attachWidget(widget);\n        });\n        // Post a fit request to the parent.\n        this.parent.fit();\n    }\n    /**\n     * Add a widget to the dock layout.\n     *\n     * @param widget - The widget to add to the dock layout.\n     *\n     * @param options - The additional options for adding the widget.\n     *\n     * #### Notes\n     * The widget will be moved if it is already contained in the layout.\n     *\n     * An error will be thrown if the reference widget is invalid.\n     */\n    addWidget(widget, options = {}) {\n        // Parse the options.\n        let ref = options.ref || null;\n        let mode = options.mode || 'tab-after';\n        // Find the tab node which holds the reference widget.\n        let refNode = null;\n        if (this._root && ref) {\n            refNode = this._root.findTabNode(ref);\n        }\n        // Throw an error if the reference widget is invalid.\n        if (ref && !refNode) {\n            throw new Error('Reference widget is not in the layout.');\n        }\n        // Reparent the widget to the current layout parent.\n        widget.parent = this.parent;\n        // Insert the widget according to the insert mode.\n        switch (mode) {\n            case 'tab-after':\n                this._insertTab(widget, ref, refNode, true);\n                break;\n            case 'tab-before':\n                this._insertTab(widget, ref, refNode, false);\n                break;\n            case 'split-top':\n                this._insertSplit(widget, ref, refNode, 'vertical', false);\n                break;\n            case 'split-left':\n                this._insertSplit(widget, ref, refNode, 'horizontal', false);\n                break;\n            case 'split-right':\n                this._insertSplit(widget, ref, refNode, 'horizontal', true);\n                break;\n            case 'split-bottom':\n                this._insertSplit(widget, ref, refNode, 'vertical', true);\n                break;\n            case 'merge-top':\n                this._insertSplit(widget, ref, refNode, 'vertical', false, true);\n                break;\n            case 'merge-left':\n                this._insertSplit(widget, ref, refNode, 'horizontal', false, true);\n                break;\n            case 'merge-right':\n                this._insertSplit(widget, ref, refNode, 'horizontal', true, true);\n                break;\n            case 'merge-bottom':\n                this._insertSplit(widget, ref, refNode, 'vertical', true, true);\n                break;\n        }\n        // Do nothing else if there is no parent widget.\n        if (!this.parent) {\n            return;\n        }\n        // Ensure the widget is attached to the parent widget.\n        this.attachWidget(widget);\n        // Post a fit request for the parent widget.\n        this.parent.fit();\n    }\n    /**\n     * Remove a widget from the layout.\n     *\n     * @param widget - The widget to remove from the layout.\n     *\n     * #### Notes\n     * A widget is automatically removed from the layout when its `parent`\n     * is set to `null`. This method should only be invoked directly when\n     * removing a widget from a layout which has yet to be installed on a\n     * parent widget.\n     *\n     * This method does *not* modify the widget's `parent`.\n     */\n    removeWidget(widget) {\n        // Remove the widget from its current layout location.\n        this._removeWidget(widget);\n        // Do nothing else if there is no parent widget.\n        if (!this.parent) {\n            return;\n        }\n        // Detach the widget from the parent widget.\n        this.detachWidget(widget);\n        // Post a fit request for the parent widget.\n        this.parent.fit();\n    }\n    /**\n     * Find the tab area which contains the given client position.\n     *\n     * @param clientX - The client X position of interest.\n     *\n     * @param clientY - The client Y position of interest.\n     *\n     * @returns The geometry of the tab area at the given position, or\n     *   `null` if there is no tab area at the given position.\n     */\n    hitTestTabAreas(clientX, clientY) {\n        // Bail early if hit testing cannot produce valid results.\n        if (!this._root || !this.parent || !this.parent.isVisible) {\n            return null;\n        }\n        // Ensure the parent box sizing data is computed.\n        if (!this._box) {\n            this._box = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.boxSizing(this.parent.node);\n        }\n        // Convert from client to local coordinates.\n        let rect = this.parent.node.getBoundingClientRect();\n        let x = clientX - rect.left - this._box.borderLeft;\n        let y = clientY - rect.top - this._box.borderTop;\n        // Find the tab layout node at the local position.\n        let tabNode = this._root.hitTestTabNodes(x, y);\n        // Bail if a tab layout node was not found.\n        if (!tabNode) {\n            return null;\n        }\n        // Extract the data from the tab node.\n        let { tabBar, top, left, width, height } = tabNode;\n        // Compute the right and bottom edges of the tab area.\n        let borderWidth = this._box.borderLeft + this._box.borderRight;\n        let borderHeight = this._box.borderTop + this._box.borderBottom;\n        let right = rect.width - borderWidth - (left + width);\n        let bottom = rect.height - borderHeight - (top + height);\n        // Return the hit test results.\n        return { tabBar, x, y, top, left, right, bottom, width, height };\n    }\n    /**\n     * Perform layout initialization which requires the parent widget.\n     */\n    init() {\n        // Perform superclass initialization.\n        super.init();\n        // Attach each widget to the parent.\n        for (const widget of this) {\n            this.attachWidget(widget);\n        }\n        // Attach each handle to the parent.\n        for (const handle of this.handles()) {\n            this.parent.node.appendChild(handle);\n        }\n        // Post a fit request for the parent widget.\n        this.parent.fit();\n    }\n    /**\n     * Attach the widget to the layout parent widget.\n     *\n     * @param widget - The widget to attach to the parent.\n     *\n     * #### Notes\n     * This is a no-op if the widget is already attached.\n     */\n    attachWidget(widget) {\n        // Do nothing if the widget is already attached.\n        if (this.parent.node === widget.node.parentNode) {\n            return;\n        }\n        // Create the layout item for the widget.\n        this._items.set(widget, new LayoutItem(widget));\n        // Send a `'before-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeAttach);\n        }\n        // Add the widget's node to the parent.\n        this.parent.node.appendChild(widget.node);\n        // Send an `'after-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterAttach);\n        }\n    }\n    /**\n     * Detach the widget from the layout parent widget.\n     *\n     * @param widget - The widget to detach from the parent.\n     *\n     * #### Notes\n     * This is a no-op if the widget is not attached.\n     */\n    detachWidget(widget) {\n        // Do nothing if the widget is not attached.\n        if (this.parent.node !== widget.node.parentNode) {\n            return;\n        }\n        // Send a `'before-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeDetach);\n        }\n        // Remove the widget's node from the parent.\n        this.parent.node.removeChild(widget.node);\n        // Send an `'after-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterDetach);\n        }\n        // Delete the layout item for the widget.\n        let item = this._items.get(widget);\n        if (item) {\n            this._items.delete(widget);\n            item.dispose();\n        }\n    }\n    /**\n     * A message handler invoked on a `'before-show'` message.\n     */\n    onBeforeShow(msg) {\n        super.onBeforeShow(msg);\n        this.parent.update();\n    }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     */\n    onBeforeAttach(msg) {\n        super.onBeforeAttach(msg);\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'child-shown'` message.\n     */\n    onChildShown(msg) {\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'child-hidden'` message.\n     */\n    onChildHidden(msg) {\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'resize'` message.\n     */\n    onResize(msg) {\n        if (this.parent.isVisible) {\n            this._update(msg.width, msg.height);\n        }\n    }\n    /**\n     * A message handler invoked on an `'update-request'` message.\n     */\n    onUpdateRequest(msg) {\n        if (this.parent.isVisible) {\n            this._update(-1, -1);\n        }\n    }\n    /**\n     * A message handler invoked on a `'fit-request'` message.\n     */\n    onFitRequest(msg) {\n        if (this.parent.isAttached) {\n            this._fit();\n        }\n    }\n    /**\n     * Remove the specified widget from the layout structure.\n     *\n     * #### Notes\n     * This is a no-op if the widget is not in the layout tree.\n     *\n     * This does not detach the widget from the parent node.\n     */\n    _removeWidget(widget) {\n        // Bail early if there is no layout root.\n        if (!this._root) {\n            return;\n        }\n        // Find the tab node which contains the given widget.\n        let tabNode = this._root.findTabNode(widget);\n        // Bail early if the tab node is not found.\n        if (!tabNode) {\n            return;\n        }\n        Private$6.removeAria(widget);\n        // If there are multiple tabs, just remove the widget's tab.\n        if (tabNode.tabBar.titles.length > 1) {\n            tabNode.tabBar.removeTab(widget.title);\n            if (this._hiddenMode === Widget.HiddenMode.Scale &&\n                tabNode.tabBar.titles.length == 1) {\n                const existingWidget = tabNode.tabBar.titles[0].owner;\n                existingWidget.hiddenMode = Widget.HiddenMode.Display;\n            }\n            return;\n        }\n        // Otherwise, the tab node needs to be removed...\n        // Dispose the tab bar.\n        tabNode.tabBar.dispose();\n        // Handle the case where the tab node is the root.\n        if (this._root === tabNode) {\n            this._root = null;\n            return;\n        }\n        // Otherwise, remove the tab node from its parent...\n        // Prevent widget resizing unless needed.\n        this._root.holdAllSizes();\n        // Clear the parent reference on the tab node.\n        let splitNode = tabNode.parent;\n        tabNode.parent = null;\n        // Remove the tab node from its parent split node.\n        let i = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeFirstOf(splitNode.children, tabNode);\n        let handle = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(splitNode.handles, i);\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(splitNode.sizers, i);\n        // Remove the handle from its parent DOM node.\n        if (handle.parentNode) {\n            handle.parentNode.removeChild(handle);\n        }\n        // If there are multiple children, just update the handles.\n        if (splitNode.children.length > 1) {\n            splitNode.syncHandles();\n            return;\n        }\n        // Otherwise, the split node also needs to be removed...\n        // Clear the parent reference on the split node.\n        let maybeParent = splitNode.parent;\n        splitNode.parent = null;\n        // Lookup the remaining child node and handle.\n        let childNode = splitNode.children[0];\n        let childHandle = splitNode.handles[0];\n        // Clear the split node data.\n        splitNode.children.length = 0;\n        splitNode.handles.length = 0;\n        splitNode.sizers.length = 0;\n        // Remove the child handle from its parent node.\n        if (childHandle.parentNode) {\n            childHandle.parentNode.removeChild(childHandle);\n        }\n        // Handle the case where the split node is the root.\n        if (this._root === splitNode) {\n            childNode.parent = null;\n            this._root = childNode;\n            return;\n        }\n        // Otherwise, move the child node to the parent node...\n        let parentNode = maybeParent;\n        // Lookup the index of the split node.\n        let j = parentNode.children.indexOf(splitNode);\n        // Handle the case where the child node is a tab node.\n        if (childNode instanceof Private$6.TabLayoutNode) {\n            childNode.parent = parentNode;\n            parentNode.children[j] = childNode;\n            return;\n        }\n        // Remove the split data from the parent.\n        let splitHandle = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(parentNode.handles, j);\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(parentNode.children, j);\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(parentNode.sizers, j);\n        // Remove the handle from its parent node.\n        if (splitHandle.parentNode) {\n            splitHandle.parentNode.removeChild(splitHandle);\n        }\n        // The child node and the split parent node will have the same\n        // orientation. Merge the grand-children with the parent node.\n        for (let i = 0, n = childNode.children.length; i < n; ++i) {\n            let gChild = childNode.children[i];\n            let gHandle = childNode.handles[i];\n            let gSizer = childNode.sizers[i];\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(parentNode.children, j + i, gChild);\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(parentNode.handles, j + i, gHandle);\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(parentNode.sizers, j + i, gSizer);\n            gChild.parent = parentNode;\n        }\n        // Clear the child node.\n        childNode.children.length = 0;\n        childNode.handles.length = 0;\n        childNode.sizers.length = 0;\n        childNode.parent = null;\n        // Sync the handles on the parent node.\n        parentNode.syncHandles();\n    }\n    /**\n     * Create the tab layout node to hold the widget.\n     */\n    _createTabNode(widget) {\n        let tabNode = new Private$6.TabLayoutNode(this._createTabBar());\n        tabNode.tabBar.addTab(widget.title);\n        Private$6.addAria(widget, tabNode.tabBar);\n        return tabNode;\n    }\n    /**\n     * Insert a widget next to an existing tab.\n     *\n     * #### Notes\n     * This does not attach the widget to the parent widget.\n     */\n    _insertTab(widget, ref, refNode, after) {\n        // Do nothing if the tab is inserted next to itself.\n        if (widget === ref) {\n            return;\n        }\n        // Create the root if it does not exist.\n        if (!this._root) {\n            let tabNode = new Private$6.TabLayoutNode(this._createTabBar());\n            tabNode.tabBar.addTab(widget.title);\n            this._root = tabNode;\n            Private$6.addAria(widget, tabNode.tabBar);\n            return;\n        }\n        // Use the first tab node as the ref node if needed.\n        if (!refNode) {\n            refNode = this._root.findFirstTabNode();\n        }\n        // If the widget is not contained in the ref node, ensure it is\n        // removed from the layout and hidden before being added again.\n        if (refNode.tabBar.titles.indexOf(widget.title) === -1) {\n            this._removeWidget(widget);\n            widget.hide();\n        }\n        // Lookup the target index for inserting the tab.\n        let index;\n        if (ref) {\n            index = refNode.tabBar.titles.indexOf(ref.title);\n        }\n        else {\n            index = refNode.tabBar.currentIndex;\n        }\n        // Using transform create an additional layer in the pixel pipeline\n        // to limit the number of layer, it is set only if there is more than one widget.\n        if (this._hiddenMode === Widget.HiddenMode.Scale) {\n            if (refNode.tabBar.titles.length === 0) {\n                // Singular tab should use display mode to limit number of layers.\n                widget.hiddenMode = Widget.HiddenMode.Display;\n            }\n            else if (refNode.tabBar.titles.length == 1) {\n                // If we are adding a second tab, switch the existing tab back to scale.\n                const existingWidget = refNode.tabBar.titles[0].owner;\n                existingWidget.hiddenMode = Widget.HiddenMode.Scale;\n            }\n            else {\n                // For the third and subsequent tabs no special action is needed.\n                widget.hiddenMode = Widget.HiddenMode.Scale;\n            }\n        }\n        else {\n            // For all other modes just propagate the current mode.\n            widget.hiddenMode = this._hiddenMode;\n        }\n        // Insert the widget's tab relative to the target index.\n        refNode.tabBar.insertTab(index + (after ? 1 : 0), widget.title);\n        Private$6.addAria(widget, refNode.tabBar);\n    }\n    /**\n     * Insert a widget as a new split area.\n     *\n     * #### Notes\n     * This does not attach the widget to the parent widget.\n     */\n    _insertSplit(widget, ref, refNode, orientation, after, merge = false) {\n        // Do nothing if there is no effective split.\n        if (widget === ref && refNode && refNode.tabBar.titles.length === 1) {\n            return;\n        }\n        // Ensure the widget is removed from the current layout.\n        this._removeWidget(widget);\n        // Set the root if it does not exist.\n        if (!this._root) {\n            this._root = this._createTabNode(widget);\n            return;\n        }\n        // If the ref node parent is null, split the root.\n        if (!refNode || !refNode.parent) {\n            // Ensure the root is split with the correct orientation.\n            let root = this._splitRoot(orientation);\n            // Determine the insert index for the new tab node.\n            let i = after ? root.children.length : 0;\n            // Normalize the split node.\n            root.normalizeSizes();\n            // Create the sizer for new tab node.\n            let sizer = Private$6.createSizer(refNode ? 1 : Private$6.GOLDEN_RATIO);\n            // Insert the tab node sized to the golden ratio.\n            let tabNode = this._createTabNode(widget);\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(root.children, i, tabNode);\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(root.sizers, i, sizer);\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(root.handles, i, this._createHandle());\n            tabNode.parent = root;\n            // Re-normalize the split node to maintain the ratios.\n            root.normalizeSizes();\n            // Finally, synchronize the visibility of the handles.\n            root.syncHandles();\n            return;\n        }\n        // Lookup the split node for the ref widget.\n        let splitNode = refNode.parent;\n        // If the split node already had the correct orientation,\n        // the widget can be inserted into the split node directly.\n        if (splitNode.orientation === orientation) {\n            // Find the index of the ref node.\n            let i = splitNode.children.indexOf(refNode);\n            // Conditionally reuse a tab layout found in the wanted position.\n            if (merge) {\n                let j = i + (after ? 1 : -1);\n                let sibling = splitNode.children[j];\n                if (sibling instanceof Private$6.TabLayoutNode) {\n                    this._insertTab(widget, null, sibling, true);\n                    ++sibling.tabBar.currentIndex;\n                    return;\n                }\n            }\n            // Normalize the split node.\n            splitNode.normalizeSizes();\n            // Consume half the space for the insert location.\n            let s = (splitNode.sizers[i].sizeHint /= 2);\n            // Insert the tab node sized to the other half.\n            let j = i + (after ? 1 : 0);\n            let tabNode = this._createTabNode(widget);\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(splitNode.children, j, tabNode);\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(splitNode.sizers, j, Private$6.createSizer(s));\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(splitNode.handles, j, this._createHandle());\n            tabNode.parent = splitNode;\n            // Finally, synchronize the visibility of the handles.\n            splitNode.syncHandles();\n            return;\n        }\n        // Remove the ref node from the split node.\n        let i = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeFirstOf(splitNode.children, refNode);\n        // Create a new normalized split node for the children.\n        let childNode = new Private$6.SplitLayoutNode(orientation);\n        childNode.normalized = true;\n        // Add the ref node sized to half the space.\n        childNode.children.push(refNode);\n        childNode.sizers.push(Private$6.createSizer(0.5));\n        childNode.handles.push(this._createHandle());\n        refNode.parent = childNode;\n        // Add the tab node sized to the other half.\n        let j = after ? 1 : 0;\n        let tabNode = this._createTabNode(widget);\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(childNode.children, j, tabNode);\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(childNode.sizers, j, Private$6.createSizer(0.5));\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(childNode.handles, j, this._createHandle());\n        tabNode.parent = childNode;\n        // Synchronize the visibility of the handles.\n        childNode.syncHandles();\n        // Finally, add the new child node to the original split node.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(splitNode.children, i, childNode);\n        childNode.parent = splitNode;\n    }\n    /**\n     * Ensure the root is a split node with the given orientation.\n     */\n    _splitRoot(orientation) {\n        // Bail early if the root already meets the requirements.\n        let oldRoot = this._root;\n        if (oldRoot instanceof Private$6.SplitLayoutNode) {\n            if (oldRoot.orientation === orientation) {\n                return oldRoot;\n            }\n        }\n        // Create a new root node with the specified orientation.\n        let newRoot = (this._root = new Private$6.SplitLayoutNode(orientation));\n        // Add the old root to the new root.\n        if (oldRoot) {\n            newRoot.children.push(oldRoot);\n            newRoot.sizers.push(Private$6.createSizer(0));\n            newRoot.handles.push(this._createHandle());\n            oldRoot.parent = newRoot;\n        }\n        // Return the new root as a convenience.\n        return newRoot;\n    }\n    /**\n     * Fit the layout to the total size required by the widgets.\n     */\n    _fit() {\n        // Set up the computed minimum size.\n        let minW = 0;\n        let minH = 0;\n        // Update the size limits for the layout tree.\n        if (this._root) {\n            let limits = this._root.fit(this._spacing, this._items);\n            minW = limits.minWidth;\n            minH = limits.minHeight;\n        }\n        // Update the box sizing and add it to the computed min size.\n        let box = (this._box = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.boxSizing(this.parent.node));\n        minW += box.horizontalSum;\n        minH += box.verticalSum;\n        // Update the parent's min size constraints.\n        let style = this.parent.node.style;\n        style.minWidth = `${minW}px`;\n        style.minHeight = `${minH}px`;\n        // Set the dirty flag to ensure only a single update occurs.\n        this._dirty = true;\n        // Notify the ancestor that it should fit immediately. This may\n        // cause a resize of the parent, fulfilling the required update.\n        if (this.parent.parent) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.parent.parent, Widget.Msg.FitRequest);\n        }\n        // If the dirty flag is still set, the parent was not resized.\n        // Trigger the required update on the parent widget immediately.\n        if (this._dirty) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.parent, Widget.Msg.UpdateRequest);\n        }\n    }\n    /**\n     * Update the layout position and size of the widgets.\n     *\n     * The parent offset dimensions should be `-1` if unknown.\n     */\n    _update(offsetWidth, offsetHeight) {\n        // Clear the dirty flag to indicate the update occurred.\n        this._dirty = false;\n        // Bail early if there is no root layout node.\n        if (!this._root) {\n            return;\n        }\n        // Measure the parent if the offset dimensions are unknown.\n        if (offsetWidth < 0) {\n            offsetWidth = this.parent.node.offsetWidth;\n        }\n        if (offsetHeight < 0) {\n            offsetHeight = this.parent.node.offsetHeight;\n        }\n        // Ensure the parent box sizing data is computed.\n        if (!this._box) {\n            this._box = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.boxSizing(this.parent.node);\n        }\n        // Compute the actual layout bounds adjusted for border and padding.\n        let x = this._box.paddingTop;\n        let y = this._box.paddingLeft;\n        let width = offsetWidth - this._box.horizontalSum;\n        let height = offsetHeight - this._box.verticalSum;\n        // Update the geometry of the layout tree.\n        this._root.update(x, y, width, height, this._spacing, this._items);\n    }\n    /**\n     * Create a new tab bar for use by the dock layout.\n     *\n     * #### Notes\n     * The tab bar will be attached to the parent if it exists.\n     */\n    _createTabBar() {\n        // Create the tab bar using the renderer.\n        let tabBar = this.renderer.createTabBar(this._document);\n        // Enforce necessary tab bar behavior.\n        tabBar.orientation = 'horizontal';\n        // Attach the tab bar to the parent if possible.\n        if (this.parent) {\n            this.attachWidget(tabBar);\n        }\n        // Return the initialized tab bar.\n        return tabBar;\n    }\n    /**\n     * Create a new handle for the dock layout.\n     *\n     * #### Notes\n     * The handle will be attached to the parent if it exists.\n     */\n    _createHandle() {\n        // Create the handle using the renderer.\n        let handle = this.renderer.createHandle();\n        // Initialize the handle layout behavior.\n        let style = handle.style;\n        style.position = 'absolute';\n        style.contain = 'strict';\n        style.top = '0';\n        style.left = '0';\n        style.width = '0';\n        style.height = '0';\n        // Attach the handle to the parent if it exists.\n        if (this.parent) {\n            this.parent.node.appendChild(handle);\n        }\n        // Return the initialized handle.\n        return handle;\n    }\n}\n/**\n * The namespace for the module implementation details.\n */\nvar Private$6;\n(function (Private) {\n    /**\n     * A fraction used for sizing root panels; ~= `1 / golden_ratio`.\n     */\n    Private.GOLDEN_RATIO = 0.618;\n    /**\n     * Create a box sizer with an initial size hint.\n     */\n    function createSizer(hint) {\n        let sizer = new BoxSizer();\n        sizer.sizeHint = hint;\n        sizer.size = hint;\n        return sizer;\n    }\n    Private.createSizer = createSizer;\n    /**\n     * Normalize an area config object and collect the visited widgets.\n     */\n    function normalizeAreaConfig(config, widgetSet) {\n        let result;\n        if (config.type === 'tab-area') {\n            result = normalizeTabAreaConfig(config, widgetSet);\n        }\n        else {\n            result = normalizeSplitAreaConfig(config, widgetSet);\n        }\n        return result;\n    }\n    Private.normalizeAreaConfig = normalizeAreaConfig;\n    /**\n     * Convert a normalized area config into a layout tree.\n     */\n    function realizeAreaConfig(config, renderer, document) {\n        let node;\n        if (config.type === 'tab-area') {\n            node = realizeTabAreaConfig(config, renderer, document);\n        }\n        else {\n            node = realizeSplitAreaConfig(config, renderer, document);\n        }\n        return node;\n    }\n    Private.realizeAreaConfig = realizeAreaConfig;\n    /**\n     * A layout node which holds the data for a tabbed area.\n     */\n    class TabLayoutNode {\n        /**\n         * Construct a new tab layout node.\n         *\n         * @param tabBar - The tab bar to use for the layout node.\n         */\n        constructor(tabBar) {\n            /**\n             * The parent of the layout node.\n             */\n            this.parent = null;\n            this._top = 0;\n            this._left = 0;\n            this._width = 0;\n            this._height = 0;\n            let tabSizer = new BoxSizer();\n            let widgetSizer = new BoxSizer();\n            tabSizer.stretch = 0;\n            widgetSizer.stretch = 1;\n            this.tabBar = tabBar;\n            this.sizers = [tabSizer, widgetSizer];\n        }\n        /**\n         * The most recent value for the `top` edge of the layout box.\n         */\n        get top() {\n            return this._top;\n        }\n        /**\n         * The most recent value for the `left` edge of the layout box.\n         */\n        get left() {\n            return this._left;\n        }\n        /**\n         * The most recent value for the `width` of the layout box.\n         */\n        get width() {\n            return this._width;\n        }\n        /**\n         * The most recent value for the `height` of the layout box.\n         */\n        get height() {\n            return this._height;\n        }\n        /**\n         * Create an iterator for all widgets in the layout tree.\n         */\n        *iterAllWidgets() {\n            yield this.tabBar;\n            yield* this.iterUserWidgets();\n        }\n        /**\n         * Create an iterator for the user widgets in the layout tree.\n         */\n        *iterUserWidgets() {\n            for (const title of this.tabBar.titles) {\n                yield title.owner;\n            }\n        }\n        /**\n         * Create an iterator for the selected widgets in the layout tree.\n         */\n        *iterSelectedWidgets() {\n            let title = this.tabBar.currentTitle;\n            if (title) {\n                yield title.owner;\n            }\n        }\n        /**\n         * Create an iterator for the tab bars in the layout tree.\n         */\n        *iterTabBars() {\n            yield this.tabBar;\n        }\n        /**\n         * Create an iterator for the handles in the layout tree.\n         */\n        // eslint-disable-next-line require-yield\n        *iterHandles() {\n            return;\n        }\n        /**\n         * Find the tab layout node which contains the given widget.\n         */\n        findTabNode(widget) {\n            return this.tabBar.titles.indexOf(widget.title) !== -1 ? this : null;\n        }\n        /**\n         * Find the split layout node which contains the given handle.\n         */\n        findSplitNode(handle) {\n            return null;\n        }\n        /**\n         * Find the first tab layout node in a layout tree.\n         */\n        findFirstTabNode() {\n            return this;\n        }\n        /**\n         * Find the tab layout node which contains the local point.\n         */\n        hitTestTabNodes(x, y) {\n            if (x < this._left || x >= this._left + this._width) {\n                return null;\n            }\n            if (y < this._top || y >= this._top + this._height) {\n                return null;\n            }\n            return this;\n        }\n        /**\n         * Create a configuration object for the layout tree.\n         */\n        createConfig() {\n            let widgets = this.tabBar.titles.map(title => title.owner);\n            let currentIndex = this.tabBar.currentIndex;\n            return { type: 'tab-area', widgets, currentIndex };\n        }\n        /**\n         * Recursively hold all of the sizes in the layout tree.\n         *\n         * This ignores the sizers of tab layout nodes.\n         */\n        holdAllSizes() {\n            return;\n        }\n        /**\n         * Fit the layout tree.\n         */\n        fit(spacing, items) {\n            // Set up the limit variables.\n            let minWidth = 0;\n            let minHeight = 0;\n            let maxWidth = Infinity;\n            let maxHeight = Infinity;\n            // Lookup the tab bar layout item.\n            let tabBarItem = items.get(this.tabBar);\n            // Lookup the widget layout item.\n            let current = this.tabBar.currentTitle;\n            let widgetItem = current ? items.get(current.owner) : undefined;\n            // Lookup the tab bar and widget sizers.\n            let [tabBarSizer, widgetSizer] = this.sizers;\n            // Update the tab bar limits.\n            if (tabBarItem) {\n                tabBarItem.fit();\n            }\n            // Update the widget limits.\n            if (widgetItem) {\n                widgetItem.fit();\n            }\n            // Update the results and sizer for the tab bar.\n            if (tabBarItem && !tabBarItem.isHidden) {\n                minWidth = Math.max(minWidth, tabBarItem.minWidth);\n                minHeight += tabBarItem.minHeight;\n                tabBarSizer.minSize = tabBarItem.minHeight;\n                tabBarSizer.maxSize = tabBarItem.maxHeight;\n            }\n            else {\n                tabBarSizer.minSize = 0;\n                tabBarSizer.maxSize = 0;\n            }\n            // Update the results and sizer for the current widget.\n            if (widgetItem && !widgetItem.isHidden) {\n                minWidth = Math.max(minWidth, widgetItem.minWidth);\n                minHeight += widgetItem.minHeight;\n                widgetSizer.minSize = widgetItem.minHeight;\n                widgetSizer.maxSize = Infinity;\n            }\n            else {\n                widgetSizer.minSize = 0;\n                widgetSizer.maxSize = Infinity;\n            }\n            // Return the computed size limits for the layout node.\n            return { minWidth, minHeight, maxWidth, maxHeight };\n        }\n        /**\n         * Update the layout tree.\n         */\n        update(left, top, width, height, spacing, items) {\n            // Update the layout box values.\n            this._top = top;\n            this._left = left;\n            this._width = width;\n            this._height = height;\n            // Lookup the tab bar layout item.\n            let tabBarItem = items.get(this.tabBar);\n            // Lookup the widget layout item.\n            let current = this.tabBar.currentTitle;\n            let widgetItem = current ? items.get(current.owner) : undefined;\n            // Distribute the layout space to the sizers.\n            BoxEngine.calc(this.sizers, height);\n            // Update the tab bar item using the computed size.\n            if (tabBarItem && !tabBarItem.isHidden) {\n                let size = this.sizers[0].size;\n                tabBarItem.update(left, top, width, size);\n                top += size;\n            }\n            // Layout the widget using the computed size.\n            if (widgetItem && !widgetItem.isHidden) {\n                let size = this.sizers[1].size;\n                widgetItem.update(left, top, width, size);\n            }\n        }\n    }\n    Private.TabLayoutNode = TabLayoutNode;\n    /**\n     * A layout node which holds the data for a split area.\n     */\n    class SplitLayoutNode {\n        /**\n         * Construct a new split layout node.\n         *\n         * @param orientation - The orientation of the node.\n         */\n        constructor(orientation) {\n            /**\n             * The parent of the layout node.\n             */\n            this.parent = null;\n            /**\n             * Whether the sizers have been normalized.\n             */\n            this.normalized = false;\n            /**\n             * The child nodes for the split node.\n             */\n            this.children = [];\n            /**\n             * The box sizers for the layout children.\n             */\n            this.sizers = [];\n            /**\n             * The handles for the layout children.\n             */\n            this.handles = [];\n            this.orientation = orientation;\n        }\n        /**\n         * Create an iterator for all widgets in the layout tree.\n         */\n        *iterAllWidgets() {\n            for (const child of this.children) {\n                yield* child.iterAllWidgets();\n            }\n        }\n        /**\n         * Create an iterator for the user widgets in the layout tree.\n         */\n        *iterUserWidgets() {\n            for (const child of this.children) {\n                yield* child.iterUserWidgets();\n            }\n        }\n        /**\n         * Create an iterator for the selected widgets in the layout tree.\n         */\n        *iterSelectedWidgets() {\n            for (const child of this.children) {\n                yield* child.iterSelectedWidgets();\n            }\n        }\n        /**\n         * Create an iterator for the tab bars in the layout tree.\n         */\n        *iterTabBars() {\n            for (const child of this.children) {\n                yield* child.iterTabBars();\n            }\n        }\n        /**\n         * Create an iterator for the handles in the layout tree.\n         */\n        *iterHandles() {\n            yield* this.handles;\n            for (const child of this.children) {\n                yield* child.iterHandles();\n            }\n        }\n        /**\n         * Find the tab layout node which contains the given widget.\n         */\n        findTabNode(widget) {\n            for (let i = 0, n = this.children.length; i < n; ++i) {\n                let result = this.children[i].findTabNode(widget);\n                if (result) {\n                    return result;\n                }\n            }\n            return null;\n        }\n        /**\n         * Find the split layout node which contains the given handle.\n         */\n        findSplitNode(handle) {\n            let index = this.handles.indexOf(handle);\n            if (index !== -1) {\n                return { index, node: this };\n            }\n            for (let i = 0, n = this.children.length; i < n; ++i) {\n                let result = this.children[i].findSplitNode(handle);\n                if (result) {\n                    return result;\n                }\n            }\n            return null;\n        }\n        /**\n         * Find the first tab layout node in a layout tree.\n         */\n        findFirstTabNode() {\n            if (this.children.length === 0) {\n                return null;\n            }\n            return this.children[0].findFirstTabNode();\n        }\n        /**\n         * Find the tab layout node which contains the local point.\n         */\n        hitTestTabNodes(x, y) {\n            for (let i = 0, n = this.children.length; i < n; ++i) {\n                let result = this.children[i].hitTestTabNodes(x, y);\n                if (result) {\n                    return result;\n                }\n            }\n            return null;\n        }\n        /**\n         * Create a configuration object for the layout tree.\n         */\n        createConfig() {\n            let orientation = this.orientation;\n            let sizes = this.createNormalizedSizes();\n            let children = this.children.map(child => child.createConfig());\n            return { type: 'split-area', orientation, children, sizes };\n        }\n        /**\n         * Sync the visibility and orientation of the handles.\n         */\n        syncHandles() {\n            this.handles.forEach((handle, i) => {\n                handle.setAttribute('data-orientation', this.orientation);\n                if (i === this.handles.length - 1) {\n                    handle.classList.add('lm-mod-hidden');\n                }\n                else {\n                    handle.classList.remove('lm-mod-hidden');\n                }\n            });\n        }\n        /**\n         * Hold the current sizes of the box sizers.\n         *\n         * This sets the size hint of each sizer to its current size.\n         */\n        holdSizes() {\n            for (const sizer of this.sizers) {\n                sizer.sizeHint = sizer.size;\n            }\n        }\n        /**\n         * Recursively hold all of the sizes in the layout tree.\n         *\n         * This ignores the sizers of tab layout nodes.\n         */\n        holdAllSizes() {\n            for (const child of this.children) {\n                child.holdAllSizes();\n            }\n            this.holdSizes();\n        }\n        /**\n         * Normalize the sizes of the split layout node.\n         */\n        normalizeSizes() {\n            // Bail early if the sizers are empty.\n            let n = this.sizers.length;\n            if (n === 0) {\n                return;\n            }\n            // Hold the current sizes of the sizers.\n            this.holdSizes();\n            // Compute the sum of the sizes.\n            let sum = this.sizers.reduce((v, sizer) => v + sizer.sizeHint, 0);\n            // Normalize the sizes based on the sum.\n            if (sum === 0) {\n                for (const sizer of this.sizers) {\n                    sizer.size = sizer.sizeHint = 1 / n;\n                }\n            }\n            else {\n                for (const sizer of this.sizers) {\n                    sizer.size = sizer.sizeHint /= sum;\n                }\n            }\n            // Mark the sizes as normalized.\n            this.normalized = true;\n        }\n        /**\n         * Snap the normalized sizes of the split layout node.\n         */\n        createNormalizedSizes() {\n            // Bail early if the sizers are empty.\n            let n = this.sizers.length;\n            if (n === 0) {\n                return [];\n            }\n            // Grab the current sizes of the sizers.\n            let sizes = this.sizers.map(sizer => sizer.size);\n            // Compute the sum of the sizes.\n            let sum = sizes.reduce((v, size) => v + size, 0);\n            // Normalize the sizes based on the sum.\n            if (sum === 0) {\n                for (let i = sizes.length - 1; i > -1; i--) {\n                    sizes[i] = 1 / n;\n                }\n            }\n            else {\n                for (let i = sizes.length - 1; i > -1; i--) {\n                    sizes[i] /= sum;\n                }\n            }\n            // Return the normalized sizes.\n            return sizes;\n        }\n        /**\n         * Fit the layout tree.\n         */\n        fit(spacing, items) {\n            // Compute the required fixed space.\n            let horizontal = this.orientation === 'horizontal';\n            let fixed = Math.max(0, this.children.length - 1) * spacing;\n            // Set up the limit variables.\n            let minWidth = horizontal ? fixed : 0;\n            let minHeight = horizontal ? 0 : fixed;\n            let maxWidth = Infinity;\n            let maxHeight = Infinity;\n            // Fit the children and update the limits.\n            for (let i = 0, n = this.children.length; i < n; ++i) {\n                let limits = this.children[i].fit(spacing, items);\n                if (horizontal) {\n                    minHeight = Math.max(minHeight, limits.minHeight);\n                    minWidth += limits.minWidth;\n                    this.sizers[i].minSize = limits.minWidth;\n                }\n                else {\n                    minWidth = Math.max(minWidth, limits.minWidth);\n                    minHeight += limits.minHeight;\n                    this.sizers[i].minSize = limits.minHeight;\n                }\n            }\n            // Return the computed limits for the layout node.\n            return { minWidth, minHeight, maxWidth, maxHeight };\n        }\n        /**\n         * Update the layout tree.\n         */\n        update(left, top, width, height, spacing, items) {\n            // Compute the available layout space.\n            let horizontal = this.orientation === 'horizontal';\n            let fixed = Math.max(0, this.children.length - 1) * spacing;\n            let space = Math.max(0, (horizontal ? width : height) - fixed);\n            // De-normalize the sizes if needed.\n            if (this.normalized) {\n                for (const sizer of this.sizers) {\n                    sizer.sizeHint *= space;\n                }\n                this.normalized = false;\n            }\n            // Distribute the layout space to the sizers.\n            BoxEngine.calc(this.sizers, space);\n            // Update the geometry of the child nodes and handles.\n            for (let i = 0, n = this.children.length; i < n; ++i) {\n                let child = this.children[i];\n                let size = this.sizers[i].size;\n                let handleStyle = this.handles[i].style;\n                if (horizontal) {\n                    child.update(left, top, size, height, spacing, items);\n                    left += size;\n                    handleStyle.top = `${top}px`;\n                    handleStyle.left = `${left}px`;\n                    handleStyle.width = `${spacing}px`;\n                    handleStyle.height = `${height}px`;\n                    left += spacing;\n                }\n                else {\n                    child.update(left, top, width, size, spacing, items);\n                    top += size;\n                    handleStyle.top = `${top}px`;\n                    handleStyle.left = `${left}px`;\n                    handleStyle.width = `${width}px`;\n                    handleStyle.height = `${spacing}px`;\n                    top += spacing;\n                }\n            }\n        }\n    }\n    Private.SplitLayoutNode = SplitLayoutNode;\n    function addAria(widget, tabBar) {\n        widget.node.setAttribute('role', 'tabpanel');\n        let renderer = tabBar.renderer;\n        if (renderer instanceof TabBar.Renderer) {\n            let tabId = renderer.createTabKey({\n                title: widget.title,\n                current: false,\n                zIndex: 0\n            });\n            widget.node.setAttribute('aria-labelledby', tabId);\n        }\n    }\n    Private.addAria = addAria;\n    function removeAria(widget) {\n        widget.node.removeAttribute('role');\n        widget.node.removeAttribute('aria-labelledby');\n    }\n    Private.removeAria = removeAria;\n    /**\n     * Normalize a tab area config and collect the visited widgets.\n     */\n    function normalizeTabAreaConfig(config, widgetSet) {\n        // Bail early if there is no content.\n        if (config.widgets.length === 0) {\n            return null;\n        }\n        // Setup the filtered widgets array.\n        let widgets = [];\n        // Filter the config for unique widgets.\n        for (const widget of config.widgets) {\n            if (!widgetSet.has(widget)) {\n                widgetSet.add(widget);\n                widgets.push(widget);\n            }\n        }\n        // Bail if there are no effective widgets.\n        if (widgets.length === 0) {\n            return null;\n        }\n        // Normalize the current index.\n        let index = config.currentIndex;\n        if (index !== -1 && (index < 0 || index >= widgets.length)) {\n            index = 0;\n        }\n        // Return a normalized config object.\n        return { type: 'tab-area', widgets, currentIndex: index };\n    }\n    /**\n     * Normalize a split area config and collect the visited widgets.\n     */\n    function normalizeSplitAreaConfig(config, widgetSet) {\n        // Set up the result variables.\n        let orientation = config.orientation;\n        let children = [];\n        let sizes = [];\n        // Normalize the config children.\n        for (let i = 0, n = config.children.length; i < n; ++i) {\n            // Normalize the child config.\n            let child = normalizeAreaConfig(config.children[i], widgetSet);\n            // Ignore an empty child.\n            if (!child) {\n                continue;\n            }\n            // Add the child or hoist its content as appropriate.\n            if (child.type === 'tab-area' || child.orientation !== orientation) {\n                children.push(child);\n                sizes.push(Math.abs(config.sizes[i] || 0));\n            }\n            else {\n                children.push(...child.children);\n                sizes.push(...child.sizes);\n            }\n        }\n        // Bail if there are no effective children.\n        if (children.length === 0) {\n            return null;\n        }\n        // If there is only one effective child, return that child.\n        if (children.length === 1) {\n            return children[0];\n        }\n        // Return a normalized config object.\n        return { type: 'split-area', orientation, children, sizes };\n    }\n    /**\n     * Convert a normalized tab area config into a layout tree.\n     */\n    function realizeTabAreaConfig(config, renderer, document) {\n        // Create the tab bar for the layout node.\n        let tabBar = renderer.createTabBar(document);\n        // Hide each widget and add it to the tab bar.\n        for (const widget of config.widgets) {\n            widget.hide();\n            tabBar.addTab(widget.title);\n            Private.addAria(widget, tabBar);\n        }\n        // Set the current index of the tab bar.\n        tabBar.currentIndex = config.currentIndex;\n        // Return the new tab layout node.\n        return new TabLayoutNode(tabBar);\n    }\n    /**\n     * Convert a normalized split area config into a layout tree.\n     */\n    function realizeSplitAreaConfig(config, renderer, document) {\n        // Create the split layout node.\n        let node = new SplitLayoutNode(config.orientation);\n        // Add each child to the layout node.\n        config.children.forEach((child, i) => {\n            // Create the child data for the layout node.\n            let childNode = realizeAreaConfig(child, renderer, document);\n            let sizer = createSizer(config.sizes[i]);\n            let handle = renderer.createHandle();\n            // Add the child data to the layout node.\n            node.children.push(childNode);\n            node.handles.push(handle);\n            node.sizers.push(sizer);\n            // Update the parent for the child node.\n            childNode.parent = node;\n        });\n        // Synchronize the handle state for the layout node.\n        node.syncHandles();\n        // Normalize the sizes for the layout node.\n        node.normalizeSizes();\n        // Return the new layout node.\n        return node;\n    }\n})(Private$6 || (Private$6 = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A widget which provides a flexible docking area for widgets.\n */\nclass DockPanel extends Widget {\n    /**\n     * Construct a new dock panel.\n     *\n     * @param options - The options for initializing the panel.\n     */\n    constructor(options = {}) {\n        super();\n        this._drag = null;\n        this._tabsMovable = true;\n        this._tabsConstrained = false;\n        this._addButtonEnabled = false;\n        this._pressData = null;\n        this._layoutModified = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._addRequested = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this.addClass('lm-DockPanel');\n        this._document = options.document || document;\n        this._mode = options.mode || 'multiple-document';\n        this._renderer = options.renderer || DockPanel.defaultRenderer;\n        this._edges = options.edges || Private$5.DEFAULT_EDGES;\n        if (options.tabsMovable !== undefined) {\n            this._tabsMovable = options.tabsMovable;\n        }\n        if (options.tabsConstrained !== undefined) {\n            this._tabsConstrained = options.tabsConstrained;\n        }\n        if (options.addButtonEnabled !== undefined) {\n            this._addButtonEnabled = options.addButtonEnabled;\n        }\n        // Toggle the CSS mode attribute.\n        this.dataset['mode'] = this._mode;\n        // Create the delegate renderer for the layout.\n        let renderer = {\n            createTabBar: () => this._createTabBar(),\n            createHandle: () => this._createHandle()\n        };\n        // Set up the dock layout for the panel.\n        this.layout = new DockLayout({\n            document: this._document,\n            renderer,\n            spacing: options.spacing,\n            hiddenMode: options.hiddenMode\n        });\n        // Set up the overlay drop indicator.\n        this.overlay = options.overlay || new DockPanel.Overlay();\n        this.node.appendChild(this.overlay.node);\n    }\n    /**\n     * Dispose of the resources held by the panel.\n     */\n    dispose() {\n        // Ensure the mouse is released.\n        this._releaseMouse();\n        // Hide the overlay.\n        this.overlay.hide(0);\n        // Cancel a drag if one is in progress.\n        if (this._drag) {\n            this._drag.dispose();\n        }\n        // Dispose of the base class.\n        super.dispose();\n    }\n    /**\n     * The method for hiding widgets.\n     */\n    get hiddenMode() {\n        return this.layout.hiddenMode;\n    }\n    /**\n     * Set the method for hiding widgets.\n     */\n    set hiddenMode(v) {\n        this.layout.hiddenMode = v;\n    }\n    /**\n     * A signal emitted when the layout configuration is modified.\n     *\n     * #### Notes\n     * This signal is emitted whenever the current layout configuration\n     * may have changed.\n     *\n     * This signal is emitted asynchronously in a collapsed fashion, so\n     * that multiple synchronous modifications results in only a single\n     * emit of the signal.\n     */\n    get layoutModified() {\n        return this._layoutModified;\n    }\n    /**\n     * A signal emitted when the add button on a tab bar is clicked.\n     *\n     */\n    get addRequested() {\n        return this._addRequested;\n    }\n    /**\n     * The renderer used by the dock panel.\n     */\n    get renderer() {\n        return this.layout.renderer;\n    }\n    /**\n     * Get the spacing between the widgets.\n     */\n    get spacing() {\n        return this.layout.spacing;\n    }\n    /**\n     * Set the spacing between the widgets.\n     */\n    set spacing(value) {\n        this.layout.spacing = value;\n    }\n    /**\n     * Get the mode for the dock panel.\n     */\n    get mode() {\n        return this._mode;\n    }\n    /**\n     * Set the mode for the dock panel.\n     *\n     * #### Notes\n     * Changing the mode is a destructive operation with respect to the\n     * panel's layout configuration. If layout state must be preserved,\n     * save the current layout config before changing the mode.\n     */\n    set mode(value) {\n        // Bail early if the mode does not change.\n        if (this._mode === value) {\n            return;\n        }\n        // Update the internal mode.\n        this._mode = value;\n        // Toggle the CSS mode attribute.\n        this.dataset['mode'] = value;\n        // Get the layout for the panel.\n        let layout = this.layout;\n        // Configure the layout for the specified mode.\n        switch (value) {\n            case 'multiple-document':\n                for (const tabBar of layout.tabBars()) {\n                    tabBar.show();\n                }\n                break;\n            case 'single-document':\n                layout.restoreLayout(Private$5.createSingleDocumentConfig(this));\n                break;\n            default:\n                throw 'unreachable';\n        }\n        // Schedule an emit of the layout modified signal.\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.postMessage(this, Private$5.LayoutModified);\n    }\n    /**\n     * Whether the tabs can be dragged / moved at runtime.\n     */\n    get tabsMovable() {\n        return this._tabsMovable;\n    }\n    /**\n     * Enable / Disable draggable / movable tabs.\n     */\n    set tabsMovable(value) {\n        this._tabsMovable = value;\n        for (const tabBar of this.tabBars()) {\n            tabBar.tabsMovable = value;\n        }\n    }\n    /**\n     * Whether the tabs are constrained to their source dock panel\n     */\n    get tabsConstrained() {\n        return this._tabsConstrained;\n    }\n    /**\n     * Constrain/Allow tabs to be dragged outside of this dock panel\n     */\n    set tabsConstrained(value) {\n        this._tabsConstrained = value;\n    }\n    /**\n     * Whether the add buttons for each tab bar are enabled.\n     */\n    get addButtonEnabled() {\n        return this._addButtonEnabled;\n    }\n    /**\n     * Set whether the add buttons for each tab bar are enabled.\n     */\n    set addButtonEnabled(value) {\n        this._addButtonEnabled = value;\n        for (const tabBar of this.tabBars()) {\n            tabBar.addButtonEnabled = value;\n        }\n    }\n    /**\n     * Whether the dock panel is empty.\n     */\n    get isEmpty() {\n        return this.layout.isEmpty;\n    }\n    /**\n     * Create an iterator over the user widgets in the panel.\n     *\n     * @returns A new iterator over the user widgets in the panel.\n     *\n     * #### Notes\n     * This iterator does not include the generated tab bars.\n     */\n    *widgets() {\n        yield* this.layout.widgets();\n    }\n    /**\n     * Create an iterator over the selected widgets in the panel.\n     *\n     * @returns A new iterator over the selected user widgets.\n     *\n     * #### Notes\n     * This iterator yields the widgets corresponding to the current tab\n     * of each tab bar in the panel.\n     */\n    *selectedWidgets() {\n        yield* this.layout.selectedWidgets();\n    }\n    /**\n     * Create an iterator over the tab bars in the panel.\n     *\n     * @returns A new iterator over the tab bars in the panel.\n     *\n     * #### Notes\n     * This iterator does not include the user widgets.\n     */\n    *tabBars() {\n        yield* this.layout.tabBars();\n    }\n    /**\n     * Create an iterator over the handles in the panel.\n     *\n     * @returns A new iterator over the handles in the panel.\n     */\n    *handles() {\n        yield* this.layout.handles();\n    }\n    /**\n     * Select a specific widget in the dock panel.\n     *\n     * @param widget - The widget of interest.\n     *\n     * #### Notes\n     * This will make the widget the current widget in its tab area.\n     */\n    selectWidget(widget) {\n        // Find the tab bar which contains the widget.\n        let tabBar = (0,_lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.find)(this.tabBars(), bar => {\n            return bar.titles.indexOf(widget.title) !== -1;\n        });\n        // Throw an error if no tab bar is found.\n        if (!tabBar) {\n            throw new Error('Widget is not contained in the dock panel.');\n        }\n        // Ensure the widget is the current widget.\n        tabBar.currentTitle = widget.title;\n    }\n    /**\n     * Activate a specified widget in the dock panel.\n     *\n     * @param widget - The widget of interest.\n     *\n     * #### Notes\n     * This will select and activate the given widget.\n     */\n    activateWidget(widget) {\n        this.selectWidget(widget);\n        widget.activate();\n    }\n    /**\n     * Save the current layout configuration of the dock panel.\n     *\n     * @returns A new config object for the current layout state.\n     *\n     * #### Notes\n     * The return value can be provided to the `restoreLayout` method\n     * in order to restore the layout to its current configuration.\n     */\n    saveLayout() {\n        return this.layout.saveLayout();\n    }\n    /**\n     * Restore the layout to a previously saved configuration.\n     *\n     * @param config - The layout configuration to restore.\n     *\n     * #### Notes\n     * Widgets which currently belong to the layout but which are not\n     * contained in the config will be unparented.\n     *\n     * The dock panel automatically reverts to `'multiple-document'`\n     * mode when a layout config is restored.\n     */\n    restoreLayout(config) {\n        // Reset the mode.\n        this._mode = 'multiple-document';\n        // Restore the layout.\n        this.layout.restoreLayout(config);\n        // Flush the message loop on IE and Edge to prevent flicker.\n        if (_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.Platform.IS_EDGE || _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.Platform.IS_IE) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.flush();\n        }\n        // Schedule an emit of the layout modified signal.\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.postMessage(this, Private$5.LayoutModified);\n    }\n    /**\n     * Add a widget to the dock panel.\n     *\n     * @param widget - The widget to add to the dock panel.\n     *\n     * @param options - The additional options for adding the widget.\n     *\n     * #### Notes\n     * If the panel is in single document mode, the options are ignored\n     * and the widget is always added as tab in the hidden tab bar.\n     */\n    addWidget(widget, options = {}) {\n        // Add the widget to the layout.\n        if (this._mode === 'single-document') {\n            this.layout.addWidget(widget);\n        }\n        else {\n            this.layout.addWidget(widget, options);\n        }\n        // Schedule an emit of the layout modified signal.\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.postMessage(this, Private$5.LayoutModified);\n    }\n    /**\n     * Process a message sent to the widget.\n     *\n     * @param msg - The message sent to the widget.\n     */\n    processMessage(msg) {\n        if (msg.type === 'layout-modified') {\n            this._layoutModified.emit(undefined);\n        }\n        else {\n            super.processMessage(msg);\n        }\n    }\n    /**\n     * Handle the DOM events for the dock panel.\n     *\n     * @param event - The DOM event sent to the panel.\n     *\n     * #### Notes\n     * This method implements the DOM `EventListener` interface and is\n     * called in response to events on the panel's DOM node. It should\n     * not be called directly by user code.\n     */\n    handleEvent(event) {\n        switch (event.type) {\n            case 'lm-dragenter':\n                this._evtDragEnter(event);\n                break;\n            case 'lm-dragleave':\n                this._evtDragLeave(event);\n                break;\n            case 'lm-dragover':\n                this._evtDragOver(event);\n                break;\n            case 'lm-drop':\n                this._evtDrop(event);\n                break;\n            case 'pointerdown':\n                this._evtPointerDown(event);\n                break;\n            case 'pointermove':\n                this._evtPointerMove(event);\n                break;\n            case 'pointerup':\n                this._evtPointerUp(event);\n                break;\n            case 'keydown':\n                this._evtKeyDown(event);\n                break;\n            case 'contextmenu':\n                event.preventDefault();\n                event.stopPropagation();\n                break;\n        }\n    }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     */\n    onBeforeAttach(msg) {\n        this.node.addEventListener('lm-dragenter', this);\n        this.node.addEventListener('lm-dragleave', this);\n        this.node.addEventListener('lm-dragover', this);\n        this.node.addEventListener('lm-drop', this);\n        this.node.addEventListener('pointerdown', this);\n    }\n    /**\n     * A message handler invoked on an `'after-detach'` message.\n     */\n    onAfterDetach(msg) {\n        this.node.removeEventListener('lm-dragenter', this);\n        this.node.removeEventListener('lm-dragleave', this);\n        this.node.removeEventListener('lm-dragover', this);\n        this.node.removeEventListener('lm-drop', this);\n        this.node.removeEventListener('pointerdown', this);\n        this._releaseMouse();\n    }\n    /**\n     * A message handler invoked on a `'child-added'` message.\n     */\n    onChildAdded(msg) {\n        // Ignore the generated tab bars.\n        if (Private$5.isGeneratedTabBarProperty.get(msg.child)) {\n            return;\n        }\n        // Add the widget class to the child.\n        msg.child.addClass('lm-DockPanel-widget');\n    }\n    /**\n     * A message handler invoked on a `'child-removed'` message.\n     */\n    onChildRemoved(msg) {\n        // Ignore the generated tab bars.\n        if (Private$5.isGeneratedTabBarProperty.get(msg.child)) {\n            return;\n        }\n        // Remove the widget class from the child.\n        msg.child.removeClass('lm-DockPanel-widget');\n        // Schedule an emit of the layout modified signal.\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.postMessage(this, Private$5.LayoutModified);\n    }\n    /**\n     * Handle the `'lm-dragenter'` event for the dock panel.\n     */\n    _evtDragEnter(event) {\n        // If the factory mime type is present, mark the event as\n        // handled in order to get the rest of the drag events.\n        if (event.mimeData.hasData('application/vnd.lumino.widget-factory')) {\n            event.preventDefault();\n            event.stopPropagation();\n        }\n    }\n    /**\n     * Handle the `'lm-dragleave'` event for the dock panel.\n     */\n    _evtDragLeave(event) {\n        // Mark the event as handled.\n        event.preventDefault();\n        if (this._tabsConstrained && event.source !== this)\n            return;\n        event.stopPropagation();\n        // The new target might be a descendant, so we might still handle the drop.\n        // Hide asynchronously so that if a lm-dragover event bubbles up to us, the\n        // hide is cancelled by the lm-dragover handler's show overlay logic.\n        this.overlay.hide(1);\n    }\n    /**\n     * Handle the `'lm-dragover'` event for the dock panel.\n     */\n    _evtDragOver(event) {\n        // Mark the event as handled.\n        event.preventDefault();\n        // Show the drop indicator overlay and update the drop\n        // action based on the drop target zone under the mouse.\n        if ((this._tabsConstrained && event.source !== this) ||\n            this._showOverlay(event.clientX, event.clientY) === 'invalid') {\n            event.dropAction = 'none';\n        }\n        else {\n            event.stopPropagation();\n            event.dropAction = event.proposedAction;\n        }\n    }\n    /**\n     * Handle the `'lm-drop'` event for the dock panel.\n     */\n    _evtDrop(event) {\n        // Mark the event as handled.\n        event.preventDefault();\n        // Hide the drop indicator overlay.\n        this.overlay.hide(0);\n        // Bail if the proposed action is to do nothing.\n        if (event.proposedAction === 'none') {\n            event.dropAction = 'none';\n            return;\n        }\n        // Find the drop target under the mouse.\n        let { clientX, clientY } = event;\n        let { zone, target } = Private$5.findDropTarget(this, clientX, clientY, this._edges);\n        // Bail if the drop zone is invalid.\n        if ((this._tabsConstrained && event.source !== this) ||\n            zone === 'invalid') {\n            event.dropAction = 'none';\n            return;\n        }\n        // Bail if the factory mime type has invalid data.\n        let mimeData = event.mimeData;\n        let factory = mimeData.getData('application/vnd.lumino.widget-factory');\n        if (typeof factory !== 'function') {\n            event.dropAction = 'none';\n            return;\n        }\n        // Bail if the factory does not produce a widget.\n        let widget = factory();\n        if (!(widget instanceof Widget)) {\n            event.dropAction = 'none';\n            return;\n        }\n        // Bail if the widget is an ancestor of the dock panel.\n        if (widget.contains(this)) {\n            event.dropAction = 'none';\n            return;\n        }\n        // Find the reference widget for the drop target.\n        let ref = target ? Private$5.getDropRef(target.tabBar) : null;\n        // Add the widget according to the indicated drop zone.\n        switch (zone) {\n            case 'root-all':\n                this.addWidget(widget);\n                break;\n            case 'root-top':\n                this.addWidget(widget, { mode: 'split-top' });\n                break;\n            case 'root-left':\n                this.addWidget(widget, { mode: 'split-left' });\n                break;\n            case 'root-right':\n                this.addWidget(widget, { mode: 'split-right' });\n                break;\n            case 'root-bottom':\n                this.addWidget(widget, { mode: 'split-bottom' });\n                break;\n            case 'widget-all':\n                this.addWidget(widget, { mode: 'tab-after', ref });\n                break;\n            case 'widget-top':\n                this.addWidget(widget, { mode: 'split-top', ref });\n                break;\n            case 'widget-left':\n                this.addWidget(widget, { mode: 'split-left', ref });\n                break;\n            case 'widget-right':\n                this.addWidget(widget, { mode: 'split-right', ref });\n                break;\n            case 'widget-bottom':\n                this.addWidget(widget, { mode: 'split-bottom', ref });\n                break;\n            case 'widget-tab':\n                this.addWidget(widget, { mode: 'tab-after', ref });\n                break;\n            default:\n                throw 'unreachable';\n        }\n        // Accept the proposed drop action.\n        event.dropAction = event.proposedAction;\n        // Stop propagation if we have not bailed so far.\n        event.stopPropagation();\n        // Activate the dropped widget.\n        this.activateWidget(widget);\n    }\n    /**\n     * Handle the `'keydown'` event for the dock panel.\n     */\n    _evtKeyDown(event) {\n        // Stop input events during drag.\n        event.preventDefault();\n        event.stopPropagation();\n        // Release the mouse if `Escape` is pressed.\n        if (event.keyCode === 27) {\n            // Finalize the mouse release.\n            this._releaseMouse();\n            // Schedule an emit of the layout modified signal.\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.postMessage(this, Private$5.LayoutModified);\n        }\n    }\n    /**\n     * Handle the `'pointerdown'` event for the dock panel.\n     */\n    _evtPointerDown(event) {\n        // Do nothing if the left mouse button is not pressed.\n        if (event.button !== 0) {\n            return;\n        }\n        // Find the handle which contains the mouse target, if any.\n        let layout = this.layout;\n        let target = event.target;\n        let handle = (0,_lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.find)(layout.handles(), handle => handle.contains(target));\n        if (!handle) {\n            return;\n        }\n        // Stop the event when a handle is pressed.\n        event.preventDefault();\n        event.stopPropagation();\n        // Add the extra document listeners.\n        this._document.addEventListener('keydown', this, true);\n        this._document.addEventListener('pointerup', this, true);\n        this._document.addEventListener('pointermove', this, true);\n        this._document.addEventListener('contextmenu', this, true);\n        // Compute the offset deltas for the handle press.\n        let rect = handle.getBoundingClientRect();\n        let deltaX = event.clientX - rect.left;\n        let deltaY = event.clientY - rect.top;\n        // Override the cursor and store the press data.\n        let style = window.getComputedStyle(handle);\n        let override = _lumino_dragdrop__WEBPACK_IMPORTED_MODULE_6__.Drag.overrideCursor(style.cursor, this._document);\n        this._pressData = { handle, deltaX, deltaY, override };\n    }\n    /**\n     * Handle the `'pointermove'` event for the dock panel.\n     */\n    _evtPointerMove(event) {\n        // Bail early if no drag is in progress.\n        if (!this._pressData) {\n            return;\n        }\n        // Stop the event when dragging a handle.\n        event.preventDefault();\n        event.stopPropagation();\n        // Compute the desired offset position for the handle.\n        let rect = this.node.getBoundingClientRect();\n        let xPos = event.clientX - rect.left - this._pressData.deltaX;\n        let yPos = event.clientY - rect.top - this._pressData.deltaY;\n        // Set the handle as close to the desired position as possible.\n        let layout = this.layout;\n        layout.moveHandle(this._pressData.handle, xPos, yPos);\n    }\n    /**\n     * Handle the `'pointerup'` event for the dock panel.\n     */\n    _evtPointerUp(event) {\n        // Do nothing if the left mouse button is not released.\n        if (event.button !== 0) {\n            return;\n        }\n        // Stop the event when releasing a handle.\n        event.preventDefault();\n        event.stopPropagation();\n        // Finalize the mouse release.\n        this._releaseMouse();\n        // Schedule an emit of the layout modified signal.\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.postMessage(this, Private$5.LayoutModified);\n    }\n    /**\n     * Release the mouse grab for the dock panel.\n     */\n    _releaseMouse() {\n        // Bail early if no drag is in progress.\n        if (!this._pressData) {\n            return;\n        }\n        // Clear the override cursor.\n        this._pressData.override.dispose();\n        this._pressData = null;\n        // Remove the extra document listeners.\n        this._document.removeEventListener('keydown', this, true);\n        this._document.removeEventListener('pointerup', this, true);\n        this._document.removeEventListener('pointermove', this, true);\n        this._document.removeEventListener('contextmenu', this, true);\n    }\n    /**\n     * Show the overlay indicator at the given client position.\n     *\n     * Returns the drop zone at the specified client position.\n     *\n     * #### Notes\n     * If the position is not over a valid zone, the overlay is hidden.\n     */\n    _showOverlay(clientX, clientY) {\n        // Find the dock target for the given client position.\n        let { zone, target } = Private$5.findDropTarget(this, clientX, clientY, this._edges);\n        // If the drop zone is invalid, hide the overlay and bail.\n        if (zone === 'invalid') {\n            this.overlay.hide(100);\n            return zone;\n        }\n        // Setup the variables needed to compute the overlay geometry.\n        let top;\n        let left;\n        let right;\n        let bottom;\n        let box = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.boxSizing(this.node); // TODO cache this?\n        let rect = this.node.getBoundingClientRect();\n        // Compute the overlay geometry based on the dock zone.\n        switch (zone) {\n            case 'root-all':\n                top = box.paddingTop;\n                left = box.paddingLeft;\n                right = box.paddingRight;\n                bottom = box.paddingBottom;\n                break;\n            case 'root-top':\n                top = box.paddingTop;\n                left = box.paddingLeft;\n                right = box.paddingRight;\n                bottom = rect.height * Private$5.GOLDEN_RATIO;\n                break;\n            case 'root-left':\n                top = box.paddingTop;\n                left = box.paddingLeft;\n                right = rect.width * Private$5.GOLDEN_RATIO;\n                bottom = box.paddingBottom;\n                break;\n            case 'root-right':\n                top = box.paddingTop;\n                left = rect.width * Private$5.GOLDEN_RATIO;\n                right = box.paddingRight;\n                bottom = box.paddingBottom;\n                break;\n            case 'root-bottom':\n                top = rect.height * Private$5.GOLDEN_RATIO;\n                left = box.paddingLeft;\n                right = box.paddingRight;\n                bottom = box.paddingBottom;\n                break;\n            case 'widget-all':\n                top = target.top;\n                left = target.left;\n                right = target.right;\n                bottom = target.bottom;\n                break;\n            case 'widget-top':\n                top = target.top;\n                left = target.left;\n                right = target.right;\n                bottom = target.bottom + target.height / 2;\n                break;\n            case 'widget-left':\n                top = target.top;\n                left = target.left;\n                right = target.right + target.width / 2;\n                bottom = target.bottom;\n                break;\n            case 'widget-right':\n                top = target.top;\n                left = target.left + target.width / 2;\n                right = target.right;\n                bottom = target.bottom;\n                break;\n            case 'widget-bottom':\n                top = target.top + target.height / 2;\n                left = target.left;\n                right = target.right;\n                bottom = target.bottom;\n                break;\n            case 'widget-tab': {\n                const tabHeight = target.tabBar.node.getBoundingClientRect().height;\n                top = target.top;\n                left = target.left;\n                right = target.right;\n                bottom = target.bottom + target.height - tabHeight;\n                break;\n            }\n            default:\n                throw 'unreachable';\n        }\n        // Show the overlay with the computed geometry.\n        this.overlay.show({ top, left, right, bottom });\n        // Finally, return the computed drop zone.\n        return zone;\n    }\n    /**\n     * Create a new tab bar for use by the panel.\n     */\n    _createTabBar() {\n        // Create the tab bar.\n        let tabBar = this._renderer.createTabBar(this._document);\n        // Set the generated tab bar property for the tab bar.\n        Private$5.isGeneratedTabBarProperty.set(tabBar, true);\n        // Hide the tab bar when in single document mode.\n        if (this._mode === 'single-document') {\n            tabBar.hide();\n        }\n        // Enforce necessary tab bar behavior.\n        // TODO do we really want to enforce *all* of these?\n        tabBar.tabsMovable = this._tabsMovable;\n        tabBar.allowDeselect = false;\n        tabBar.addButtonEnabled = this._addButtonEnabled;\n        tabBar.removeBehavior = 'select-previous-tab';\n        tabBar.insertBehavior = 'select-tab-if-needed';\n        // Connect the signal handlers for the tab bar.\n        tabBar.tabMoved.connect(this._onTabMoved, this);\n        tabBar.currentChanged.connect(this._onCurrentChanged, this);\n        tabBar.tabCloseRequested.connect(this._onTabCloseRequested, this);\n        tabBar.tabDetachRequested.connect(this._onTabDetachRequested, this);\n        tabBar.tabActivateRequested.connect(this._onTabActivateRequested, this);\n        tabBar.addRequested.connect(this._onTabAddRequested, this);\n        // Return the initialized tab bar.\n        return tabBar;\n    }\n    /**\n     * Create a new handle for use by the panel.\n     */\n    _createHandle() {\n        return this._renderer.createHandle();\n    }\n    /**\n     * Handle the `tabMoved` signal from a tab bar.\n     */\n    _onTabMoved() {\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.postMessage(this, Private$5.LayoutModified);\n    }\n    /**\n     * Handle the `currentChanged` signal from a tab bar.\n     */\n    _onCurrentChanged(sender, args) {\n        // Extract the previous and current title from the args.\n        let { previousTitle, currentTitle } = args;\n        // Hide the previous widget.\n        if (previousTitle) {\n            previousTitle.owner.hide();\n        }\n        // Show the current widget.\n        if (currentTitle) {\n            currentTitle.owner.show();\n        }\n        // Flush the message loop on IE and Edge to prevent flicker.\n        if (_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.Platform.IS_EDGE || _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.Platform.IS_IE) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.flush();\n        }\n        // Schedule an emit of the layout modified signal.\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.postMessage(this, Private$5.LayoutModified);\n    }\n    /**\n     * Handle the `addRequested` signal from a tab bar.\n     */\n    _onTabAddRequested(sender) {\n        this._addRequested.emit(sender);\n    }\n    /**\n     * Handle the `tabActivateRequested` signal from a tab bar.\n     */\n    _onTabActivateRequested(sender, args) {\n        args.title.owner.activate();\n    }\n    /**\n     * Handle the `tabCloseRequested` signal from a tab bar.\n     */\n    _onTabCloseRequested(sender, args) {\n        args.title.owner.close();\n    }\n    /**\n     * Handle the `tabDetachRequested` signal from a tab bar.\n     */\n    _onTabDetachRequested(sender, args) {\n        // Do nothing if a drag is already in progress.\n        if (this._drag) {\n            return;\n        }\n        // Release the tab bar's hold on the mouse.\n        sender.releaseMouse();\n        // Extract the data from the args.\n        let { title, tab, clientX, clientY, offset } = args;\n        // Setup the mime data for the drag operation.\n        let mimeData = new _lumino_coreutils__WEBPACK_IMPORTED_MODULE_1__.MimeData();\n        let factory = () => title.owner;\n        mimeData.setData('application/vnd.lumino.widget-factory', factory);\n        // Create the drag image for the drag operation.\n        let dragImage = tab.cloneNode(true);\n        if (offset) {\n            dragImage.style.top = `-${offset.y}px`;\n            dragImage.style.left = `-${offset.x}px`;\n        }\n        // Create the drag object to manage the drag-drop operation.\n        this._drag = new _lumino_dragdrop__WEBPACK_IMPORTED_MODULE_6__.Drag({\n            document: this._document,\n            mimeData,\n            dragImage,\n            proposedAction: 'move',\n            supportedActions: 'move',\n            source: this\n        });\n        // Hide the tab node in the original tab.\n        tab.classList.add('lm-mod-hidden');\n        let cleanup = () => {\n            this._drag = null;\n            tab.classList.remove('lm-mod-hidden');\n        };\n        // Start the drag operation and cleanup when done.\n        this._drag.start(clientX, clientY).then(cleanup);\n    }\n}\n/**\n * The namespace for the `DockPanel` class statics.\n */\n(function (DockPanel) {\n    /**\n     * A concrete implementation of `IOverlay`.\n     *\n     * This is the default overlay implementation for a dock panel.\n     */\n    class Overlay {\n        /**\n         * Construct a new overlay.\n         */\n        constructor() {\n            this._timer = -1;\n            this._hidden = true;\n            this.node = document.createElement('div');\n            this.node.classList.add('lm-DockPanel-overlay');\n            this.node.classList.add('lm-mod-hidden');\n            this.node.style.position = 'absolute';\n            this.node.style.contain = 'strict';\n        }\n        /**\n         * Show the overlay using the given overlay geometry.\n         *\n         * @param geo - The desired geometry for the overlay.\n         */\n        show(geo) {\n            // Update the position of the overlay.\n            let style = this.node.style;\n            style.top = `${geo.top}px`;\n            style.left = `${geo.left}px`;\n            style.right = `${geo.right}px`;\n            style.bottom = `${geo.bottom}px`;\n            // Clear any pending hide timer.\n            clearTimeout(this._timer);\n            this._timer = -1;\n            // If the overlay is already visible, we're done.\n            if (!this._hidden) {\n                return;\n            }\n            // Clear the hidden flag.\n            this._hidden = false;\n            // Finally, show the overlay.\n            this.node.classList.remove('lm-mod-hidden');\n        }\n        /**\n         * Hide the overlay node.\n         *\n         * @param delay - The delay (in ms) before hiding the overlay.\n         *   A delay value <= 0 will hide the overlay immediately.\n         */\n        hide(delay) {\n            // Do nothing if the overlay is already hidden.\n            if (this._hidden) {\n                return;\n            }\n            // Hide immediately if the delay is <= 0.\n            if (delay <= 0) {\n                clearTimeout(this._timer);\n                this._timer = -1;\n                this._hidden = true;\n                this.node.classList.add('lm-mod-hidden');\n                return;\n            }\n            // Do nothing if a hide is already pending.\n            if (this._timer !== -1) {\n                return;\n            }\n            // Otherwise setup the hide timer.\n            this._timer = window.setTimeout(() => {\n                this._timer = -1;\n                this._hidden = true;\n                this.node.classList.add('lm-mod-hidden');\n            }, delay);\n        }\n    }\n    DockPanel.Overlay = Overlay;\n    /**\n     * The default implementation of `IRenderer`.\n     */\n    class Renderer {\n        /**\n         * Create a new tab bar for use with a dock panel.\n         *\n         * @returns A new tab bar for a dock panel.\n         */\n        createTabBar(document) {\n            let bar = new TabBar({ document });\n            bar.addClass('lm-DockPanel-tabBar');\n            return bar;\n        }\n        /**\n         * Create a new handle node for use with a dock panel.\n         *\n         * @returns A new handle node for a dock panel.\n         */\n        createHandle() {\n            let handle = document.createElement('div');\n            handle.className = 'lm-DockPanel-handle';\n            return handle;\n        }\n    }\n    DockPanel.Renderer = Renderer;\n    /**\n     * The default `Renderer` instance.\n     */\n    DockPanel.defaultRenderer = new Renderer();\n})(DockPanel || (DockPanel = {}));\n/**\n * The namespace for the module implementation details.\n */\nvar Private$5;\n(function (Private) {\n    /**\n     * A fraction used for sizing root panels; ~= `1 / golden_ratio`.\n     */\n    Private.GOLDEN_RATIO = 0.618;\n    /**\n     * The default sizes for the edge drop zones, in pixels.\n     */\n    Private.DEFAULT_EDGES = {\n        /**\n         * The size of the top edge dock zone for the root panel, in pixels.\n         * This is different from the others to distinguish between the top\n         * tab bar and the top root zone.\n         */\n        top: 12,\n        /**\n         * The size of the edge dock zone for the root panel, in pixels.\n         */\n        right: 40,\n        /**\n         * The size of the edge dock zone for the root panel, in pixels.\n         */\n        bottom: 40,\n        /**\n         * The size of the edge dock zone for the root panel, in pixels.\n         */\n        left: 40\n    };\n    /**\n     * A singleton `'layout-modified'` conflatable message.\n     */\n    Private.LayoutModified = new _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.ConflatableMessage('layout-modified');\n    /**\n     * An attached property used to track generated tab bars.\n     */\n    Private.isGeneratedTabBarProperty = new _lumino_properties__WEBPACK_IMPORTED_MODULE_4__.AttachedProperty({\n        name: 'isGeneratedTabBar',\n        create: () => false\n    });\n    /**\n     * Create a single document config for the widgets in a dock panel.\n     */\n    function createSingleDocumentConfig(panel) {\n        // Return an empty config if the panel is empty.\n        if (panel.isEmpty) {\n            return { main: null };\n        }\n        // Get a flat array of the widgets in the panel.\n        let widgets = Array.from(panel.widgets());\n        // Get the first selected widget in the panel.\n        let selected = panel.selectedWidgets().next().value;\n        // Compute the current index for the new config.\n        let currentIndex = selected ? widgets.indexOf(selected) : -1;\n        // Return the single document config.\n        return { main: { type: 'tab-area', widgets, currentIndex } };\n    }\n    Private.createSingleDocumentConfig = createSingleDocumentConfig;\n    /**\n     * Find the drop target at the given client position.\n     */\n    function findDropTarget(panel, clientX, clientY, edges) {\n        // Bail if the mouse is not over the dock panel.\n        if (!_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(panel.node, clientX, clientY)) {\n            return { zone: 'invalid', target: null };\n        }\n        // Look up the layout for the panel.\n        let layout = panel.layout;\n        // If the layout is empty, indicate the entire root drop zone.\n        if (layout.isEmpty) {\n            return { zone: 'root-all', target: null };\n        }\n        // Test the edge zones when in multiple document mode.\n        if (panel.mode === 'multiple-document') {\n            // Get the client rect for the dock panel.\n            let panelRect = panel.node.getBoundingClientRect();\n            // Compute the distance to each edge of the panel.\n            let pl = clientX - panelRect.left + 1;\n            let pt = clientY - panelRect.top + 1;\n            let pr = panelRect.right - clientX;\n            let pb = panelRect.bottom - clientY;\n            // Find the minimum distance to an edge.\n            let pd = Math.min(pt, pr, pb, pl);\n            // Return a root zone if the mouse is within an edge.\n            switch (pd) {\n                case pt:\n                    if (pt < edges.top) {\n                        return { zone: 'root-top', target: null };\n                    }\n                    break;\n                case pr:\n                    if (pr < edges.right) {\n                        return { zone: 'root-right', target: null };\n                    }\n                    break;\n                case pb:\n                    if (pb < edges.bottom) {\n                        return { zone: 'root-bottom', target: null };\n                    }\n                    break;\n                case pl:\n                    if (pl < edges.left) {\n                        return { zone: 'root-left', target: null };\n                    }\n                    break;\n                default:\n                    throw 'unreachable';\n            }\n        }\n        // Hit test the dock layout at the given client position.\n        let target = layout.hitTestTabAreas(clientX, clientY);\n        // Bail if no target area was found.\n        if (!target) {\n            return { zone: 'invalid', target: null };\n        }\n        // Return the whole tab area when in single document mode.\n        if (panel.mode === 'single-document') {\n            return { zone: 'widget-all', target };\n        }\n        // Compute the distance to each edge of the tab area.\n        let al = target.x - target.left + 1;\n        let at = target.y - target.top + 1;\n        let ar = target.left + target.width - target.x;\n        let ab = target.top + target.height - target.y;\n        const tabHeight = target.tabBar.node.getBoundingClientRect().height;\n        if (at < tabHeight) {\n            return { zone: 'widget-tab', target };\n        }\n        // Get the X and Y edge sizes for the area.\n        let rx = Math.round(target.width / 3);\n        let ry = Math.round(target.height / 3);\n        // If the mouse is not within an edge, indicate the entire area.\n        if (al > rx && ar > rx && at > ry && ab > ry) {\n            return { zone: 'widget-all', target };\n        }\n        // Scale the distances by the slenderness ratio.\n        al /= rx;\n        at /= ry;\n        ar /= rx;\n        ab /= ry;\n        // Find the minimum distance to the area edge.\n        let ad = Math.min(al, at, ar, ab);\n        // Find the widget zone for the area edge.\n        let zone;\n        switch (ad) {\n            case al:\n                zone = 'widget-left';\n                break;\n            case at:\n                zone = 'widget-top';\n                break;\n            case ar:\n                zone = 'widget-right';\n                break;\n            case ab:\n                zone = 'widget-bottom';\n                break;\n            default:\n                throw 'unreachable';\n        }\n        // Return the final drop target.\n        return { zone, target };\n    }\n    Private.findDropTarget = findDropTarget;\n    /**\n     * Get the drop reference widget for a tab bar.\n     */\n    function getDropRef(tabBar) {\n        if (tabBar.titles.length === 0) {\n            return null;\n        }\n        if (tabBar.currentTitle) {\n            return tabBar.currentTitle.owner;\n        }\n        return tabBar.titles[tabBar.titles.length - 1].owner;\n    }\n    Private.getDropRef = getDropRef;\n})(Private$5 || (Private$5 = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A class which tracks focus among a set of widgets.\n *\n * This class is useful when code needs to keep track of the most\n * recently focused widget(s) among a set of related widgets.\n */\nclass FocusTracker {\n    constructor() {\n        this._counter = 0;\n        this._widgets = [];\n        this._activeWidget = null;\n        this._currentWidget = null;\n        this._numbers = new Map();\n        this._nodes = new Map();\n        this._activeChanged = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._currentChanged = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n    }\n    /**\n     * Dispose of the resources held by the tracker.\n     */\n    dispose() {\n        // Do nothing if the tracker is already disposed.\n        if (this._counter < 0) {\n            return;\n        }\n        // Mark the tracker as disposed.\n        this._counter = -1;\n        // Clear the connections for the tracker.\n        _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal.clearData(this);\n        // Remove all event listeners.\n        for (const widget of this._widgets) {\n            widget.node.removeEventListener('focus', this, true);\n            widget.node.removeEventListener('blur', this, true);\n        }\n        // Clear the internal data structures.\n        this._activeWidget = null;\n        this._currentWidget = null;\n        this._nodes.clear();\n        this._numbers.clear();\n        this._widgets.length = 0;\n    }\n    /**\n     * A signal emitted when the current widget has changed.\n     */\n    get currentChanged() {\n        return this._currentChanged;\n    }\n    /**\n     * A signal emitted when the active widget has changed.\n     */\n    get activeChanged() {\n        return this._activeChanged;\n    }\n    /**\n     * A flag indicating whether the tracker is disposed.\n     */\n    get isDisposed() {\n        return this._counter < 0;\n    }\n    /**\n     * The current widget in the tracker.\n     *\n     * #### Notes\n     * The current widget is the widget among the tracked widgets which\n     * has the *descendant node* which has most recently been focused.\n     *\n     * The current widget will not be updated if the node loses focus. It\n     * will only be updated when a different tracked widget gains focus.\n     *\n     * If the current widget is removed from the tracker, the previous\n     * current widget will be restored.\n     *\n     * This behavior is intended to follow a user's conceptual model of\n     * a semantically \"current\" widget, where the \"last thing of type X\"\n     * to be interacted with is the \"current instance of X\", regardless\n     * of whether that instance still has focus.\n     */\n    get currentWidget() {\n        return this._currentWidget;\n    }\n    /**\n     * The active widget in the tracker.\n     *\n     * #### Notes\n     * The active widget is the widget among the tracked widgets which\n     * has the *descendant node* which is currently focused.\n     */\n    get activeWidget() {\n        return this._activeWidget;\n    }\n    /**\n     * A read only array of the widgets being tracked.\n     */\n    get widgets() {\n        return this._widgets;\n    }\n    /**\n     * Get the focus number for a particular widget in the tracker.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @returns The focus number for the given widget, or `-1` if the\n     *   widget has not had focus since being added to the tracker, or\n     *   is not contained by the tracker.\n     *\n     * #### Notes\n     * The focus number indicates the relative order in which the widgets\n     * have gained focus. A widget with a larger number has gained focus\n     * more recently than a widget with a smaller number.\n     *\n     * The `currentWidget` will always have the largest focus number.\n     *\n     * All widgets start with a focus number of `-1`, which indicates that\n     * the widget has not been focused since being added to the tracker.\n     */\n    focusNumber(widget) {\n        let n = this._numbers.get(widget);\n        return n === undefined ? -1 : n;\n    }\n    /**\n     * Test whether the focus tracker contains a given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @returns `true` if the widget is tracked, `false` otherwise.\n     */\n    has(widget) {\n        return this._numbers.has(widget);\n    }\n    /**\n     * Add a widget to the focus tracker.\n     *\n     * @param widget - The widget of interest.\n     *\n     * #### Notes\n     * A widget will be automatically removed from the tracker if it\n     * is disposed after being added.\n     *\n     * If the widget is already tracked, this is a no-op.\n     */\n    add(widget) {\n        // Do nothing if the widget is already tracked.\n        if (this._numbers.has(widget)) {\n            return;\n        }\n        // Test whether the widget has focus.\n        let focused = widget.node.contains(document.activeElement);\n        // Set up the initial focus number.\n        let n = focused ? this._counter++ : -1;\n        // Add the widget to the internal data structures.\n        this._widgets.push(widget);\n        this._numbers.set(widget, n);\n        this._nodes.set(widget.node, widget);\n        // Set up the event listeners. The capturing phase must be used\n        // since the 'focus' and 'blur' events don't bubble and Firefox\n        // doesn't support the 'focusin' or 'focusout' events.\n        widget.node.addEventListener('focus', this, true);\n        widget.node.addEventListener('blur', this, true);\n        // Connect the disposed signal handler.\n        widget.disposed.connect(this._onWidgetDisposed, this);\n        // Set the current and active widgets if needed.\n        if (focused) {\n            this._setWidgets(widget, widget);\n        }\n    }\n    /**\n     * Remove a widget from the focus tracker.\n     *\n     * #### Notes\n     * If the widget is the `currentWidget`, the previous current widget\n     * will become the new `currentWidget`.\n     *\n     * A widget will be automatically removed from the tracker if it\n     * is disposed after being added.\n     *\n     * If the widget is not tracked, this is a no-op.\n     */\n    remove(widget) {\n        // Bail early if the widget is not tracked.\n        if (!this._numbers.has(widget)) {\n            return;\n        }\n        // Disconnect the disposed signal handler.\n        widget.disposed.disconnect(this._onWidgetDisposed, this);\n        // Remove the event listeners.\n        widget.node.removeEventListener('focus', this, true);\n        widget.node.removeEventListener('blur', this, true);\n        // Remove the widget from the internal data structures.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeFirstOf(this._widgets, widget);\n        this._nodes.delete(widget.node);\n        this._numbers.delete(widget);\n        // Bail early if the widget is not the current widget.\n        if (this._currentWidget !== widget) {\n            return;\n        }\n        // Filter the widgets for those which have had focus.\n        let valid = this._widgets.filter(w => this._numbers.get(w) !== -1);\n        // Get the valid widget with the max focus number.\n        let previous = (0,_lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.max)(valid, (first, second) => {\n            let a = this._numbers.get(first);\n            let b = this._numbers.get(second);\n            return a - b;\n        }) || null;\n        // Set the current and active widgets.\n        this._setWidgets(previous, null);\n    }\n    /**\n     * Handle the DOM events for the focus tracker.\n     *\n     * @param event - The DOM event sent to the panel.\n     *\n     * #### Notes\n     * This method implements the DOM `EventListener` interface and is\n     * called in response to events on the tracked nodes. It should\n     * not be called directly by user code.\n     */\n    handleEvent(event) {\n        switch (event.type) {\n            case 'focus':\n                this._evtFocus(event);\n                break;\n            case 'blur':\n                this._evtBlur(event);\n                break;\n        }\n    }\n    /**\n     * Set the current and active widgets for the tracker.\n     */\n    _setWidgets(current, active) {\n        // Swap the current widget.\n        let oldCurrent = this._currentWidget;\n        this._currentWidget = current;\n        // Swap the active widget.\n        let oldActive = this._activeWidget;\n        this._activeWidget = active;\n        // Emit the `currentChanged` signal if needed.\n        if (oldCurrent !== current) {\n            this._currentChanged.emit({ oldValue: oldCurrent, newValue: current });\n        }\n        // Emit the `activeChanged` signal if needed.\n        if (oldActive !== active) {\n            this._activeChanged.emit({ oldValue: oldActive, newValue: active });\n        }\n    }\n    /**\n     * Handle the `'focus'` event for a tracked widget.\n     */\n    _evtFocus(event) {\n        // Find the widget which gained focus, which is known to exist.\n        let widget = this._nodes.get(event.currentTarget);\n        // Update the focus number if necessary.\n        if (widget !== this._currentWidget) {\n            this._numbers.set(widget, this._counter++);\n        }\n        // Set the current and active widgets.\n        this._setWidgets(widget, widget);\n    }\n    /**\n     * Handle the `'blur'` event for a tracked widget.\n     */\n    _evtBlur(event) {\n        // Find the widget which lost focus, which is known to exist.\n        let widget = this._nodes.get(event.currentTarget);\n        // Get the node which being focused after this blur.\n        let focusTarget = event.relatedTarget;\n        // If no other node is being focused, clear the active widget.\n        if (!focusTarget) {\n            this._setWidgets(this._currentWidget, null);\n            return;\n        }\n        // Bail if the focus widget is not changing.\n        if (widget.node.contains(focusTarget)) {\n            return;\n        }\n        // If no tracked widget is being focused, clear the active widget.\n        if (!(0,_lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.find)(this._widgets, w => w.node.contains(focusTarget))) {\n            this._setWidgets(this._currentWidget, null);\n            return;\n        }\n    }\n    /**\n     * Handle the `disposed` signal for a tracked widget.\n     */\n    _onWidgetDisposed(sender) {\n        this.remove(sender);\n    }\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A layout which arranges its widgets in a grid.\n */\nclass GridLayout extends Layout {\n    /**\n     * Construct a new grid layout.\n     *\n     * @param options - The options for initializing the layout.\n     */\n    constructor(options = {}) {\n        super(options);\n        this._dirty = false;\n        this._rowSpacing = 4;\n        this._columnSpacing = 4;\n        this._items = [];\n        this._rowStarts = [];\n        this._columnStarts = [];\n        this._rowSizers = [new BoxSizer()];\n        this._columnSizers = [new BoxSizer()];\n        this._box = null;\n        if (options.rowCount !== undefined) {\n            Private$4.reallocSizers(this._rowSizers, options.rowCount);\n        }\n        if (options.columnCount !== undefined) {\n            Private$4.reallocSizers(this._columnSizers, options.columnCount);\n        }\n        if (options.rowSpacing !== undefined) {\n            this._rowSpacing = Private$4.clampValue(options.rowSpacing);\n        }\n        if (options.columnSpacing !== undefined) {\n            this._columnSpacing = Private$4.clampValue(options.columnSpacing);\n        }\n    }\n    /**\n     * Dispose of the resources held by the layout.\n     */\n    dispose() {\n        // Dispose of the widgets and layout items.\n        for (const item of this._items) {\n            let widget = item.widget;\n            item.dispose();\n            widget.dispose();\n        }\n        // Clear the layout state.\n        this._box = null;\n        this._items.length = 0;\n        this._rowStarts.length = 0;\n        this._rowSizers.length = 0;\n        this._columnStarts.length = 0;\n        this._columnSizers.length = 0;\n        // Dispose of the rest of the layout.\n        super.dispose();\n    }\n    /**\n     * Get the number of rows in the layout.\n     */\n    get rowCount() {\n        return this._rowSizers.length;\n    }\n    /**\n     * Set the number of rows in the layout.\n     *\n     * #### Notes\n     * The minimum row count is `1`.\n     */\n    set rowCount(value) {\n        // Do nothing if the row count does not change.\n        if (value === this.rowCount) {\n            return;\n        }\n        // Reallocate the row sizers.\n        Private$4.reallocSizers(this._rowSizers, value);\n        // Schedule a fit of the parent.\n        if (this.parent) {\n            this.parent.fit();\n        }\n    }\n    /**\n     * Get the number of columns in the layout.\n     */\n    get columnCount() {\n        return this._columnSizers.length;\n    }\n    /**\n     * Set the number of columns in the layout.\n     *\n     * #### Notes\n     * The minimum column count is `1`.\n     */\n    set columnCount(value) {\n        // Do nothing if the column count does not change.\n        if (value === this.columnCount) {\n            return;\n        }\n        // Reallocate the column sizers.\n        Private$4.reallocSizers(this._columnSizers, value);\n        // Schedule a fit of the parent.\n        if (this.parent) {\n            this.parent.fit();\n        }\n    }\n    /**\n     * Get the row spacing for the layout.\n     */\n    get rowSpacing() {\n        return this._rowSpacing;\n    }\n    /**\n     * Set the row spacing for the layout.\n     */\n    set rowSpacing(value) {\n        // Clamp the spacing to the allowed range.\n        value = Private$4.clampValue(value);\n        // Bail if the spacing does not change\n        if (this._rowSpacing === value) {\n            return;\n        }\n        // Update the internal spacing.\n        this._rowSpacing = value;\n        // Schedule a fit of the parent.\n        if (this.parent) {\n            this.parent.fit();\n        }\n    }\n    /**\n     * Get the column spacing for the layout.\n     */\n    get columnSpacing() {\n        return this._columnSpacing;\n    }\n    /**\n     * Set the col spacing for the layout.\n     */\n    set columnSpacing(value) {\n        // Clamp the spacing to the allowed range.\n        value = Private$4.clampValue(value);\n        // Bail if the spacing does not change\n        if (this._columnSpacing === value) {\n            return;\n        }\n        // Update the internal spacing.\n        this._columnSpacing = value;\n        // Schedule a fit of the parent.\n        if (this.parent) {\n            this.parent.fit();\n        }\n    }\n    /**\n     * Get the stretch factor for a specific row.\n     *\n     * @param index - The row index of interest.\n     *\n     * @returns The stretch factor for the row.\n     *\n     * #### Notes\n     * This returns `-1` if the index is out of range.\n     */\n    rowStretch(index) {\n        let sizer = this._rowSizers[index];\n        return sizer ? sizer.stretch : -1;\n    }\n    /**\n     * Set the stretch factor for a specific row.\n     *\n     * @param index - The row index of interest.\n     *\n     * @param value - The stretch factor for the row.\n     *\n     * #### Notes\n     * This is a no-op if the index is out of range.\n     */\n    setRowStretch(index, value) {\n        // Look up the row sizer.\n        let sizer = this._rowSizers[index];\n        // Bail if the index is out of range.\n        if (!sizer) {\n            return;\n        }\n        // Clamp the value to the allowed range.\n        value = Private$4.clampValue(value);\n        // Bail if the stretch does not change.\n        if (sizer.stretch === value) {\n            return;\n        }\n        // Update the sizer stretch.\n        sizer.stretch = value;\n        // Schedule an update of the parent.\n        if (this.parent) {\n            this.parent.update();\n        }\n    }\n    /**\n     * Get the stretch factor for a specific column.\n     *\n     * @param index - The column index of interest.\n     *\n     * @returns The stretch factor for the column.\n     *\n     * #### Notes\n     * This returns `-1` if the index is out of range.\n     */\n    columnStretch(index) {\n        let sizer = this._columnSizers[index];\n        return sizer ? sizer.stretch : -1;\n    }\n    /**\n     * Set the stretch factor for a specific column.\n     *\n     * @param index - The column index of interest.\n     *\n     * @param value - The stretch factor for the column.\n     *\n     * #### Notes\n     * This is a no-op if the index is out of range.\n     */\n    setColumnStretch(index, value) {\n        // Look up the column sizer.\n        let sizer = this._columnSizers[index];\n        // Bail if the index is out of range.\n        if (!sizer) {\n            return;\n        }\n        // Clamp the value to the allowed range.\n        value = Private$4.clampValue(value);\n        // Bail if the stretch does not change.\n        if (sizer.stretch === value) {\n            return;\n        }\n        // Update the sizer stretch.\n        sizer.stretch = value;\n        // Schedule an update of the parent.\n        if (this.parent) {\n            this.parent.update();\n        }\n    }\n    /**\n     * Create an iterator over the widgets in the layout.\n     *\n     * @returns A new iterator over the widgets in the layout.\n     */\n    *[Symbol.iterator]() {\n        for (const item of this._items) {\n            yield item.widget;\n        }\n    }\n    /**\n     * Add a widget to the grid layout.\n     *\n     * @param widget - The widget to add to the layout.\n     *\n     * #### Notes\n     * If the widget is already contained in the layout, this is no-op.\n     */\n    addWidget(widget) {\n        // Look up the index for the widget.\n        let i = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(this._items, it => it.widget === widget);\n        // Bail if the widget is already in the layout.\n        if (i !== -1) {\n            return;\n        }\n        // Add the widget to the layout.\n        this._items.push(new LayoutItem(widget));\n        // Attach the widget to the parent.\n        if (this.parent) {\n            this.attachWidget(widget);\n        }\n    }\n    /**\n     * Remove a widget from the grid layout.\n     *\n     * @param widget - The widget to remove from the layout.\n     *\n     * #### Notes\n     * A widget is automatically removed from the layout when its `parent`\n     * is set to `null`. This method should only be invoked directly when\n     * removing a widget from a layout which has yet to be installed on a\n     * parent widget.\n     *\n     * This method does *not* modify the widget's `parent`.\n     */\n    removeWidget(widget) {\n        // Look up the index for the widget.\n        let i = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(this._items, it => it.widget === widget);\n        // Bail if the widget is not in the layout.\n        if (i === -1) {\n            return;\n        }\n        // Remove the widget from the layout.\n        let item = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(this._items, i);\n        // Detach the widget from the parent.\n        if (this.parent) {\n            this.detachWidget(widget);\n        }\n        // Dispose the layout item.\n        item.dispose();\n    }\n    /**\n     * Perform layout initialization which requires the parent widget.\n     */\n    init() {\n        super.init();\n        for (const widget of this) {\n            this.attachWidget(widget);\n        }\n    }\n    /**\n     * Attach a widget to the parent's DOM node.\n     *\n     * @param widget - The widget to attach to the parent.\n     */\n    attachWidget(widget) {\n        // Send a `'before-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeAttach);\n        }\n        // Add the widget's node to the parent.\n        this.parent.node.appendChild(widget.node);\n        // Send an `'after-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterAttach);\n        }\n        // Post a fit request for the parent widget.\n        this.parent.fit();\n    }\n    /**\n     * Detach a widget from the parent's DOM node.\n     *\n     * @param widget - The widget to detach from the parent.\n     */\n    detachWidget(widget) {\n        // Send a `'before-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeDetach);\n        }\n        // Remove the widget's node from the parent.\n        this.parent.node.removeChild(widget.node);\n        // Send an `'after-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterDetach);\n        }\n        // Post a fit request for the parent widget.\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'before-show'` message.\n     */\n    onBeforeShow(msg) {\n        super.onBeforeShow(msg);\n        this.parent.update();\n    }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     */\n    onBeforeAttach(msg) {\n        super.onBeforeAttach(msg);\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'child-shown'` message.\n     */\n    onChildShown(msg) {\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'child-hidden'` message.\n     */\n    onChildHidden(msg) {\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'resize'` message.\n     */\n    onResize(msg) {\n        if (this.parent.isVisible) {\n            this._update(msg.width, msg.height);\n        }\n    }\n    /**\n     * A message handler invoked on an `'update-request'` message.\n     */\n    onUpdateRequest(msg) {\n        if (this.parent.isVisible) {\n            this._update(-1, -1);\n        }\n    }\n    /**\n     * A message handler invoked on a `'fit-request'` message.\n     */\n    onFitRequest(msg) {\n        if (this.parent.isAttached) {\n            this._fit();\n        }\n    }\n    /**\n     * Fit the layout to the total size required by the widgets.\n     */\n    _fit() {\n        // Reset the min sizes of the sizers.\n        for (let i = 0, n = this.rowCount; i < n; ++i) {\n            this._rowSizers[i].minSize = 0;\n        }\n        for (let i = 0, n = this.columnCount; i < n; ++i) {\n            this._columnSizers[i].minSize = 0;\n        }\n        // Filter for the visible layout items.\n        let items = this._items.filter(it => !it.isHidden);\n        // Fit the layout items.\n        for (let i = 0, n = items.length; i < n; ++i) {\n            items[i].fit();\n        }\n        // Get the max row and column index.\n        let maxRow = this.rowCount - 1;\n        let maxCol = this.columnCount - 1;\n        // Sort the items by row span.\n        items.sort(Private$4.rowSpanCmp);\n        // Update the min sizes of the row sizers.\n        for (let i = 0, n = items.length; i < n; ++i) {\n            // Fetch the item.\n            let item = items[i];\n            // Get the row bounds for the item.\n            let config = GridLayout.getCellConfig(item.widget);\n            let r1 = Math.min(config.row, maxRow);\n            let r2 = Math.min(config.row + config.rowSpan - 1, maxRow);\n            // Distribute the minimum height to the sizers as needed.\n            Private$4.distributeMin(this._rowSizers, r1, r2, item.minHeight);\n        }\n        // Sort the items by column span.\n        items.sort(Private$4.columnSpanCmp);\n        // Update the min sizes of the column sizers.\n        for (let i = 0, n = items.length; i < n; ++i) {\n            // Fetch the item.\n            let item = items[i];\n            // Get the column bounds for the item.\n            let config = GridLayout.getCellConfig(item.widget);\n            let c1 = Math.min(config.column, maxCol);\n            let c2 = Math.min(config.column + config.columnSpan - 1, maxCol);\n            // Distribute the minimum width to the sizers as needed.\n            Private$4.distributeMin(this._columnSizers, c1, c2, item.minWidth);\n        }\n        // If no size constraint is needed, just update the parent.\n        if (this.fitPolicy === 'set-no-constraint') {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.parent, Widget.Msg.UpdateRequest);\n            return;\n        }\n        // Set up the computed min size.\n        let minH = maxRow * this._rowSpacing;\n        let minW = maxCol * this._columnSpacing;\n        // Add the sizer minimums to the computed min size.\n        for (let i = 0, n = this.rowCount; i < n; ++i) {\n            minH += this._rowSizers[i].minSize;\n        }\n        for (let i = 0, n = this.columnCount; i < n; ++i) {\n            minW += this._columnSizers[i].minSize;\n        }\n        // Update the box sizing and add it to the computed min size.\n        let box = (this._box = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.boxSizing(this.parent.node));\n        minW += box.horizontalSum;\n        minH += box.verticalSum;\n        // Update the parent's min size constraints.\n        let style = this.parent.node.style;\n        style.minWidth = `${minW}px`;\n        style.minHeight = `${minH}px`;\n        // Set the dirty flag to ensure only a single update occurs.\n        this._dirty = true;\n        // Notify the ancestor that it should fit immediately. This may\n        // cause a resize of the parent, fulfilling the required update.\n        if (this.parent.parent) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.parent.parent, Widget.Msg.FitRequest);\n        }\n        // If the dirty flag is still set, the parent was not resized.\n        // Trigger the required update on the parent widget immediately.\n        if (this._dirty) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.parent, Widget.Msg.UpdateRequest);\n        }\n    }\n    /**\n     * Update the layout position and size of the widgets.\n     *\n     * The parent offset dimensions should be `-1` if unknown.\n     */\n    _update(offsetWidth, offsetHeight) {\n        // Clear the dirty flag to indicate the update occurred.\n        this._dirty = false;\n        // Measure the parent if the offset dimensions are unknown.\n        if (offsetWidth < 0) {\n            offsetWidth = this.parent.node.offsetWidth;\n        }\n        if (offsetHeight < 0) {\n            offsetHeight = this.parent.node.offsetHeight;\n        }\n        // Ensure the parent box sizing data is computed.\n        if (!this._box) {\n            this._box = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.boxSizing(this.parent.node);\n        }\n        // Compute the layout area adjusted for border and padding.\n        let top = this._box.paddingTop;\n        let left = this._box.paddingLeft;\n        let width = offsetWidth - this._box.horizontalSum;\n        let height = offsetHeight - this._box.verticalSum;\n        // Get the max row and column index.\n        let maxRow = this.rowCount - 1;\n        let maxCol = this.columnCount - 1;\n        // Compute the total fixed row and column space.\n        let fixedRowSpace = maxRow * this._rowSpacing;\n        let fixedColSpace = maxCol * this._columnSpacing;\n        // Distribute the available space to the box sizers.\n        BoxEngine.calc(this._rowSizers, Math.max(0, height - fixedRowSpace));\n        BoxEngine.calc(this._columnSizers, Math.max(0, width - fixedColSpace));\n        // Update the row start positions.\n        for (let i = 0, pos = top, n = this.rowCount; i < n; ++i) {\n            this._rowStarts[i] = pos;\n            pos += this._rowSizers[i].size + this._rowSpacing;\n        }\n        // Update the column start positions.\n        for (let i = 0, pos = left, n = this.columnCount; i < n; ++i) {\n            this._columnStarts[i] = pos;\n            pos += this._columnSizers[i].size + this._columnSpacing;\n        }\n        // Update the geometry of the layout items.\n        for (let i = 0, n = this._items.length; i < n; ++i) {\n            // Fetch the item.\n            let item = this._items[i];\n            // Ignore hidden items.\n            if (item.isHidden) {\n                continue;\n            }\n            // Fetch the cell bounds for the widget.\n            let config = GridLayout.getCellConfig(item.widget);\n            let r1 = Math.min(config.row, maxRow);\n            let c1 = Math.min(config.column, maxCol);\n            let r2 = Math.min(config.row + config.rowSpan - 1, maxRow);\n            let c2 = Math.min(config.column + config.columnSpan - 1, maxCol);\n            // Compute the cell geometry.\n            let x = this._columnStarts[c1];\n            let y = this._rowStarts[r1];\n            let w = this._columnStarts[c2] + this._columnSizers[c2].size - x;\n            let h = this._rowStarts[r2] + this._rowSizers[r2].size - y;\n            // Update the geometry of the layout item.\n            item.update(x, y, w, h);\n        }\n    }\n}\n/**\n * The namespace for the `GridLayout` class statics.\n */\n(function (GridLayout) {\n    /**\n     * Get the cell config for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @returns The cell config for the widget.\n     */\n    function getCellConfig(widget) {\n        return Private$4.cellConfigProperty.get(widget);\n    }\n    GridLayout.getCellConfig = getCellConfig;\n    /**\n     * Set the cell config for the given widget.\n     *\n     * @param widget - The widget of interest.\n     *\n     * @param value - The value for the cell config.\n     */\n    function setCellConfig(widget, value) {\n        Private$4.cellConfigProperty.set(widget, Private$4.normalizeConfig(value));\n    }\n    GridLayout.setCellConfig = setCellConfig;\n})(GridLayout || (GridLayout = {}));\n/**\n * The namespace for the module implementation details.\n */\nvar Private$4;\n(function (Private) {\n    /**\n     * The property descriptor for the widget cell config.\n     */\n    Private.cellConfigProperty = new _lumino_properties__WEBPACK_IMPORTED_MODULE_4__.AttachedProperty({\n        name: 'cellConfig',\n        create: () => ({ row: 0, column: 0, rowSpan: 1, columnSpan: 1 }),\n        changed: onChildCellConfigChanged\n    });\n    /**\n     * Normalize a partial cell config object.\n     */\n    function normalizeConfig(config) {\n        let row = Math.max(0, Math.floor(config.row || 0));\n        let column = Math.max(0, Math.floor(config.column || 0));\n        let rowSpan = Math.max(1, Math.floor(config.rowSpan || 0));\n        let columnSpan = Math.max(1, Math.floor(config.columnSpan || 0));\n        return { row, column, rowSpan, columnSpan };\n    }\n    Private.normalizeConfig = normalizeConfig;\n    /**\n     * Clamp a value to an integer >= 0.\n     */\n    function clampValue(value) {\n        return Math.max(0, Math.floor(value));\n    }\n    Private.clampValue = clampValue;\n    /**\n     * A sort comparison function for row spans.\n     */\n    function rowSpanCmp(a, b) {\n        let c1 = Private.cellConfigProperty.get(a.widget);\n        let c2 = Private.cellConfigProperty.get(b.widget);\n        return c1.rowSpan - c2.rowSpan;\n    }\n    Private.rowSpanCmp = rowSpanCmp;\n    /**\n     * A sort comparison function for column spans.\n     */\n    function columnSpanCmp(a, b) {\n        let c1 = Private.cellConfigProperty.get(a.widget);\n        let c2 = Private.cellConfigProperty.get(b.widget);\n        return c1.columnSpan - c2.columnSpan;\n    }\n    Private.columnSpanCmp = columnSpanCmp;\n    /**\n     * Reallocate the box sizers for the given grid dimensions.\n     */\n    function reallocSizers(sizers, count) {\n        // Coerce the count to the valid range.\n        count = Math.max(1, Math.floor(count));\n        // Add the missing sizers.\n        while (sizers.length < count) {\n            sizers.push(new BoxSizer());\n        }\n        // Remove the extra sizers.\n        if (sizers.length > count) {\n            sizers.length = count;\n        }\n    }\n    Private.reallocSizers = reallocSizers;\n    /**\n     * Distribute a min size constraint across a range of sizers.\n     */\n    function distributeMin(sizers, i1, i2, minSize) {\n        // Sanity check the indices.\n        if (i2 < i1) {\n            return;\n        }\n        // Handle the simple case of no cell span.\n        if (i1 === i2) {\n            let sizer = sizers[i1];\n            sizer.minSize = Math.max(sizer.minSize, minSize);\n            return;\n        }\n        // Compute the total current min size of the span.\n        let totalMin = 0;\n        for (let i = i1; i <= i2; ++i) {\n            totalMin += sizers[i].minSize;\n        }\n        // Do nothing if the total is greater than the required.\n        if (totalMin >= minSize) {\n            return;\n        }\n        // Compute the portion of the space to allocate to each sizer.\n        let portion = (minSize - totalMin) / (i2 - i1 + 1);\n        // Add the portion to each sizer.\n        for (let i = i1; i <= i2; ++i) {\n            sizers[i].minSize += portion;\n        }\n    }\n    Private.distributeMin = distributeMin;\n    /**\n     * The change handler for the child cell config property.\n     */\n    function onChildCellConfigChanged(child) {\n        if (child.parent && child.parent.layout instanceof GridLayout) {\n            child.parent.fit();\n        }\n    }\n})(Private$4 || (Private$4 = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A widget which displays menus as a canonical menu bar.\n */\nclass MenuBar extends Widget {\n    /**\n     * Construct a new menu bar.\n     *\n     * @param options - The options for initializing the menu bar.\n     */\n    constructor(options = {}) {\n        super({ node: Private$3.createNode() });\n        // Track the index of the item that is currently focused or hovered. -1 means nothing focused or hovered.\n        this._activeIndex = -1;\n        // Track which item can be focused using the TAB key. Unlike _activeIndex will\n        // always point to a menuitem. Whenever you update this value, it's important\n        // to follow it with an \"update-request\" message so that the `tabindex`\n        // attribute on each menubar item gets properly updated.\n        this._tabFocusIndex = 0;\n        this._menus = [];\n        this._childMenu = null;\n        this._overflowMenu = null;\n        this._menuItemSizes = [];\n        this._overflowIndex = -1;\n        this.addClass('lm-MenuBar');\n        this.setFlag(Widget.Flag.DisallowLayout);\n        this.renderer = options.renderer || MenuBar.defaultRenderer;\n        this._forceItemsPosition = options.forceItemsPosition || {\n            forceX: true,\n            forceY: true\n        };\n        this._overflowMenuOptions = options.overflowMenuOptions || {\n            isVisible: true\n        };\n    }\n    /**\n     * Dispose of the resources held by the widget.\n     */\n    dispose() {\n        this._closeChildMenu();\n        this._menus.length = 0;\n        super.dispose();\n    }\n    /**\n     * The child menu of the menu bar.\n     *\n     * #### Notes\n     * This will be `null` if the menu bar does not have an open menu.\n     */\n    get childMenu() {\n        return this._childMenu;\n    }\n    /**\n     * The overflow index of the menu bar.\n     */\n    get overflowIndex() {\n        return this._overflowIndex;\n    }\n    /**\n     * The overflow menu of the menu bar.\n     */\n    get overflowMenu() {\n        return this._overflowMenu;\n    }\n    /**\n     * Get the menu bar content node.\n     *\n     * #### Notes\n     * This is the node which holds the menu title nodes.\n     *\n     * Modifying this node directly can lead to undefined behavior.\n     */\n    get contentNode() {\n        return this.node.getElementsByClassName('lm-MenuBar-content')[0];\n    }\n    /**\n     * Get the currently active menu.\n     */\n    get activeMenu() {\n        return this._menus[this._activeIndex] || null;\n    }\n    /**\n     * Set the currently active menu.\n     *\n     * #### Notes\n     * If the menu does not exist, the menu will be set to `null`.\n     */\n    set activeMenu(value) {\n        this.activeIndex = value ? this._menus.indexOf(value) : -1;\n    }\n    /**\n     * Get the index of the currently active menu.\n     *\n     * #### Notes\n     * This will be `-1` if no menu is active.\n     */\n    get activeIndex() {\n        return this._activeIndex;\n    }\n    /**\n     * Set the index of the currently active menu.\n     *\n     * #### Notes\n     * If the menu cannot be activated, the index will be set to `-1`.\n     */\n    set activeIndex(value) {\n        // Adjust the value for an out of range index.\n        if (value < 0 || value >= this._menus.length) {\n            value = -1;\n        }\n        // An empty menu cannot be active\n        if (value > -1 && this._menus[value].items.length === 0) {\n            value = -1;\n        }\n        // Bail early if the index will not change.\n        if (this._activeIndex === value) {\n            return;\n        }\n        // Update the active index.\n        this._activeIndex = value;\n        // Schedule an update of the items.\n        this.update();\n    }\n    /**\n     * A read-only array of the menus in the menu bar.\n     */\n    get menus() {\n        return this._menus;\n    }\n    /**\n     * Open the active menu and activate its first menu item.\n     *\n     * #### Notes\n     * If there is no active menu, this is a no-op.\n     */\n    openActiveMenu() {\n        // Bail early if there is no active item.\n        if (this._activeIndex === -1) {\n            return;\n        }\n        // Open the child menu.\n        this._openChildMenu();\n        // Activate the first item in the child menu.\n        if (this._childMenu) {\n            this._childMenu.activeIndex = -1;\n            this._childMenu.activateNextItem();\n        }\n    }\n    /**\n     * Add a menu to the end of the menu bar.\n     *\n     * @param menu - The menu to add to the menu bar.\n     *\n     * #### Notes\n     * If the menu is already added to the menu bar, it will be moved.\n     */\n    addMenu(menu, update = true) {\n        this.insertMenu(this._menus.length, menu, update);\n    }\n    /**\n     * Insert a menu into the menu bar at the specified index.\n     *\n     * @param index - The index at which to insert the menu.\n     *\n     * @param menu - The menu to insert into the menu bar.\n     *\n     * #### Notes\n     * The index will be clamped to the bounds of the menus.\n     *\n     * If the menu is already added to the menu bar, it will be moved.\n     */\n    insertMenu(index, menu, update = true) {\n        // Close the child menu before making changes.\n        this._closeChildMenu();\n        // Look up the index of the menu.\n        let i = this._menus.indexOf(menu);\n        // Clamp the insert index to the array bounds.\n        let j = Math.max(0, Math.min(index, this._menus.length));\n        // If the menu is not in the array, insert it.\n        if (i === -1) {\n            // Insert the menu into the array.\n            _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(this._menus, j, menu);\n            // Add the styling class to the menu.\n            menu.addClass('lm-MenuBar-menu');\n            // Connect to the menu signals.\n            menu.aboutToClose.connect(this._onMenuAboutToClose, this);\n            menu.menuRequested.connect(this._onMenuMenuRequested, this);\n            menu.title.changed.connect(this._onTitleChanged, this);\n            // Schedule an update of the items.\n            if (update) {\n                this.update();\n            }\n            // There is nothing more to do.\n            return;\n        }\n        // Otherwise, the menu exists in the array and should be moved.\n        // Adjust the index if the location is at the end of the array.\n        if (j === this._menus.length) {\n            j--;\n        }\n        // Bail if there is no effective move.\n        if (i === j) {\n            return;\n        }\n        // Move the menu to the new locations.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.move(this._menus, i, j);\n        // Schedule an update of the items.\n        if (update) {\n            this.update();\n        }\n    }\n    /**\n     * Remove a menu from the menu bar.\n     *\n     * @param menu - The menu to remove from the menu bar.\n     *\n     * #### Notes\n     * This is a no-op if the menu is not in the menu bar.\n     */\n    removeMenu(menu, update = true) {\n        this.removeMenuAt(this._menus.indexOf(menu), update);\n    }\n    /**\n     * Remove the menu at a given index from the menu bar.\n     *\n     * @param index - The index of the menu to remove.\n     *\n     * #### Notes\n     * This is a no-op if the index is out of range.\n     */\n    removeMenuAt(index, update = true) {\n        // Close the child menu before making changes.\n        this._closeChildMenu();\n        // Remove the menu from the array.\n        let menu = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(this._menus, index);\n        // Bail if the index is out of range.\n        if (!menu) {\n            return;\n        }\n        // Disconnect from the menu signals.\n        menu.aboutToClose.disconnect(this._onMenuAboutToClose, this);\n        menu.menuRequested.disconnect(this._onMenuMenuRequested, this);\n        menu.title.changed.disconnect(this._onTitleChanged, this);\n        // Remove the styling class from the menu.\n        menu.removeClass('lm-MenuBar-menu');\n        // Schedule an update of the items.\n        if (update) {\n            this.update();\n        }\n    }\n    /**\n     * Remove all menus from the menu bar.\n     */\n    clearMenus() {\n        // Bail if there is nothing to remove.\n        if (this._menus.length === 0) {\n            return;\n        }\n        // Close the child menu before making changes.\n        this._closeChildMenu();\n        // Disconnect from the menu signals and remove the styling class.\n        for (let menu of this._menus) {\n            menu.aboutToClose.disconnect(this._onMenuAboutToClose, this);\n            menu.menuRequested.disconnect(this._onMenuMenuRequested, this);\n            menu.title.changed.disconnect(this._onTitleChanged, this);\n            menu.removeClass('lm-MenuBar-menu');\n        }\n        // Clear the menus array.\n        this._menus.length = 0;\n        // Schedule an update of the items.\n        this.update();\n    }\n    /**\n     * Handle the DOM events for the menu bar.\n     *\n     * @param event - The DOM event sent to the menu bar.\n     *\n     * #### Notes\n     * This method implements the DOM `EventListener` interface and is\n     * called in response to events on the menu bar's DOM nodes. It\n     * should not be called directly by user code.\n     */\n    handleEvent(event) {\n        switch (event.type) {\n            case 'keydown':\n                this._evtKeyDown(event);\n                break;\n            case 'mousedown':\n                this._evtMouseDown(event);\n                break;\n            case 'mousemove':\n                this._evtMouseMove(event);\n                break;\n            case 'focusout':\n                this._evtFocusOut(event);\n                break;\n            case 'contextmenu':\n                event.preventDefault();\n                event.stopPropagation();\n                break;\n        }\n    }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     */\n    onBeforeAttach(msg) {\n        this.node.addEventListener('keydown', this);\n        this.node.addEventListener('mousedown', this);\n        this.node.addEventListener('mousemove', this);\n        this.node.addEventListener('focusout', this);\n        this.node.addEventListener('contextmenu', this);\n    }\n    /**\n     * A message handler invoked on an `'after-detach'` message.\n     */\n    onAfterDetach(msg) {\n        this.node.removeEventListener('keydown', this);\n        this.node.removeEventListener('mousedown', this);\n        this.node.removeEventListener('mousemove', this);\n        this.node.removeEventListener('focusout', this);\n        this.node.removeEventListener('contextmenu', this);\n        this._closeChildMenu();\n    }\n    /**\n     * A message handler invoked on an `'activate-request'` message.\n     */\n    onActivateRequest(msg) {\n        if (this.isAttached) {\n            this._focusItemAt(0);\n        }\n    }\n    /**\n     * A message handler invoked on a `'resize'` message.\n     */\n    onResize(msg) {\n        this.update();\n        super.onResize(msg);\n    }\n    /**\n     * A message handler invoked on an `'update-request'` message.\n     */\n    onUpdateRequest(msg) {\n        var _a;\n        let menus = this._menus;\n        let renderer = this.renderer;\n        let activeIndex = this._activeIndex;\n        let tabFocusIndex = this._tabFocusIndex >= 0 && this._tabFocusIndex < menus.length\n            ? this._tabFocusIndex\n            : 0;\n        let length = this._overflowIndex > -1 ? this._overflowIndex : menus.length;\n        let totalMenuSize = 0;\n        let isVisible = false;\n        // Check that the overflow menu doesn't count\n        length = this._overflowMenu !== null ? length - 1 : length;\n        let content = new Array(length);\n        // Render visible menus\n        for (let i = 0; i < length; ++i) {\n            content[i] = renderer.renderItem({\n                title: menus[i].title,\n                active: i === activeIndex,\n                tabbable: i === tabFocusIndex,\n                disabled: menus[i].items.length === 0,\n                onfocus: () => {\n                    this._tabFocusIndex = i;\n                    this.activeIndex = i;\n                }\n            });\n            // Calculate size of current menu\n            totalMenuSize += this._menuItemSizes[i];\n            // Check if overflow menu is already rendered\n            if (menus[i].title.label === this._overflowMenuOptions.title) {\n                isVisible = true;\n                length--;\n            }\n        }\n        // Render overflow menu if needed and active\n        if (this._overflowMenuOptions.isVisible) {\n            if (this._overflowIndex > -1 && !isVisible) {\n                // Create overflow menu\n                if (this._overflowMenu === null) {\n                    const overflowMenuTitle = (_a = this._overflowMenuOptions.title) !== null && _a !== void 0 ? _a : '...';\n                    this._overflowMenu = new Menu({ commands: new _lumino_commands__WEBPACK_IMPORTED_MODULE_7__.CommandRegistry() });\n                    this._overflowMenu.title.label = overflowMenuTitle;\n                    this._overflowMenu.title.mnemonic = 0;\n                    this.addMenu(this._overflowMenu, false);\n                }\n                // Move menus to overflow menu\n                for (let i = menus.length - 2; i >= length; i--) {\n                    const submenu = this.menus[i];\n                    submenu.title.mnemonic = 0;\n                    this._overflowMenu.insertItem(0, {\n                        type: 'submenu',\n                        submenu: submenu\n                    });\n                    this.removeMenu(submenu, false);\n                }\n                content[length] = renderer.renderItem({\n                    title: this._overflowMenu.title,\n                    active: length === activeIndex && menus[length].items.length !== 0,\n                    tabbable: length === tabFocusIndex,\n                    disabled: menus[length].items.length === 0,\n                    onfocus: () => {\n                        this._tabFocusIndex = length;\n                        this.activeIndex = length;\n                    }\n                });\n                length++;\n            }\n            else if (this._overflowMenu !== null) {\n                // Remove submenus from overflow menu\n                let overflowMenuItems = this._overflowMenu.items;\n                let screenSize = this.node.offsetWidth;\n                let n = this._overflowMenu.items.length;\n                for (let i = 0; i < n; ++i) {\n                    let index = menus.length - 1 - i;\n                    if (screenSize - totalMenuSize > this._menuItemSizes[index]) {\n                        let menu = overflowMenuItems[0].submenu;\n                        this._overflowMenu.removeItemAt(0);\n                        this.insertMenu(length, menu, false);\n                        content[length] = renderer.renderItem({\n                            title: menu.title,\n                            active: false,\n                            tabbable: length === tabFocusIndex,\n                            disabled: menus[length].items.length === 0,\n                            onfocus: () => {\n                                this._tabFocusIndex = length;\n                                this.activeIndex = length;\n                            }\n                        });\n                        length++;\n                    }\n                }\n                if (this._overflowMenu.items.length === 0) {\n                    this.removeMenu(this._overflowMenu, false);\n                    content.pop();\n                    this._overflowMenu = null;\n                    this._overflowIndex = -1;\n                }\n            }\n        }\n        _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.VirtualDOM.render(content, this.contentNode);\n        this._updateOverflowIndex();\n    }\n    /**\n     * Calculate and update the current overflow index.\n     */\n    _updateOverflowIndex() {\n        if (!this._overflowMenuOptions.isVisible) {\n            return;\n        }\n        // Get elements visible in the main menu bar\n        const itemMenus = this.contentNode.childNodes;\n        let screenSize = this.node.offsetWidth;\n        let totalMenuSize = 0;\n        let index = -1;\n        let n = itemMenus.length;\n        if (this._menuItemSizes.length == 0) {\n            // Check if it is the first resize and get info about menu items sizes\n            for (let i = 0; i < n; i++) {\n                let item = itemMenus[i];\n                // Add sizes to array\n                totalMenuSize += item.offsetWidth;\n                this._menuItemSizes.push(item.offsetWidth);\n                if (totalMenuSize > screenSize && index === -1) {\n                    index = i;\n                }\n            }\n        }\n        else {\n            // Calculate current menu size\n            for (let i = 0; i < this._menuItemSizes.length; i++) {\n                totalMenuSize += this._menuItemSizes[i];\n                if (totalMenuSize > screenSize) {\n                    index = i;\n                    break;\n                }\n            }\n        }\n        this._overflowIndex = index;\n    }\n    /**\n     * Handle the `'keydown'` event for the menu bar.\n     *\n     * #### Notes\n     * All keys are trapped except the tab key that is ignored.\n     */\n    _evtKeyDown(event) {\n        // Fetch the key code for the event.\n        let kc = event.keyCode;\n        // Reset the active index on tab, but do not trap the tab key.\n        if (kc === 9) {\n            this.activeIndex = -1;\n            return;\n        }\n        // A menu bar handles all other keydown events.\n        event.preventDefault();\n        event.stopPropagation();\n        // Enter, Space, Up Arrow, Down Arrow\n        if (kc === 13 || kc === 32 || kc === 38 || kc === 40) {\n            // The active index may have changed (for example, user hovers over an\n            // item with the mouse), so be sure to use the focus index.\n            this.activeIndex = this._tabFocusIndex;\n            if (this.activeIndex !== this._tabFocusIndex) {\n                // Bail if the setter refused to set activeIndex to tabFocusIndex\n                // because it means that the item at tabFocusIndex cannot be opened (for\n                // example, it has an empty menu)\n                return;\n            }\n            this.openActiveMenu();\n            return;\n        }\n        // Escape\n        if (kc === 27) {\n            this._closeChildMenu();\n            this._focusItemAt(this.activeIndex);\n            return;\n        }\n        // Left or Right Arrow\n        if (kc === 37 || kc === 39) {\n            let direction = kc === 37 ? -1 : 1;\n            let start = this._tabFocusIndex + direction;\n            let n = this._menus.length;\n            for (let i = 0; i < n; i++) {\n                let index = (n + start + direction * i) % n;\n                if (this._menus[index].items.length) {\n                    this._focusItemAt(index);\n                    return;\n                }\n            }\n            return;\n        }\n        // Get the pressed key character.\n        let key = (0,_lumino_keyboard__WEBPACK_IMPORTED_MODULE_10__.getKeyboardLayout)().keyForKeydownEvent(event);\n        // Bail if the key is not valid.\n        if (!key) {\n            return;\n        }\n        // Search for the next best matching mnemonic item.\n        let start = this._activeIndex + 1;\n        let result = Private$3.findMnemonic(this._menus, key, start);\n        // Handle the requested mnemonic based on the search results.\n        // If exactly one mnemonic is matched, that menu is opened.\n        // Otherwise, the next mnemonic is activated if available,\n        // followed by the auto mnemonic if available.\n        if (result.index !== -1 && !result.multiple) {\n            this.activeIndex = result.index;\n            this.openActiveMenu();\n        }\n        else if (result.index !== -1) {\n            this.activeIndex = result.index;\n            this._focusItemAt(this.activeIndex);\n        }\n        else if (result.auto !== -1) {\n            this.activeIndex = result.auto;\n            this._focusItemAt(this.activeIndex);\n        }\n    }\n    /**\n     * Handle the `'mousedown'` event for the menu bar.\n     */\n    _evtMouseDown(event) {\n        // Bail if the mouse press was not on the menu bar. This can occur\n        // when the document listener is installed for an active menu bar.\n        if (!_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(this.node, event.clientX, event.clientY)) {\n            return;\n        }\n        // Stop the propagation of the event. Immediate propagation is\n        // also stopped so that an open menu does not handle the event.\n        event.stopPropagation();\n        event.stopImmediatePropagation();\n        // Check if the mouse is over one of the menu items.\n        let index = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(this.contentNode.children, node => {\n            return _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(node, event.clientX, event.clientY);\n        });\n        // If the press was not on an item, close the child menu.\n        if (index === -1) {\n            this._closeChildMenu();\n            return;\n        }\n        // If the press was not the left mouse button, do nothing further.\n        if (event.button !== 0) {\n            return;\n        }\n        // Otherwise, toggle the open state of the child menu.\n        if (this._childMenu) {\n            this._closeChildMenu();\n            this.activeIndex = index;\n        }\n        else {\n            // If we don't call preventDefault() here, then the item in the menu\n            // bar will take focus over the menu that is being opened.\n            event.preventDefault();\n            const position = this._positionForMenu(index);\n            Menu.saveWindowData();\n            // Begin DOM modifications.\n            this.activeIndex = index;\n            this._openChildMenu(position);\n        }\n    }\n    /**\n     * Handle the `'mousemove'` event for the menu bar.\n     */\n    _evtMouseMove(event) {\n        // Check if the mouse is over one of the menu items.\n        let index = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.findFirstIndex(this.contentNode.children, node => {\n            return _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(node, event.clientX, event.clientY);\n        });\n        // Bail early if the active index will not change.\n        if (index === this._activeIndex) {\n            return;\n        }\n        // Bail early if a child menu is open and the mouse is not over\n        // an item. This allows the child menu to be kept open when the\n        // mouse is over the empty part of the menu bar.\n        if (index === -1 && this._childMenu) {\n            return;\n        }\n        // Get position for the new menu >before< updating active index.\n        const position = index >= 0 && this._childMenu ? this._positionForMenu(index) : null;\n        // Before any modification, update window data.\n        Menu.saveWindowData();\n        // Begin DOM modifications.\n        // Update the active index to the hovered item.\n        this.activeIndex = index;\n        // Open the new menu if a menu is already open.\n        if (position) {\n            this._openChildMenu(position);\n        }\n    }\n    /**\n     * Find initial position for the menu based on menubar item position.\n     *\n     * NOTE: this should be called before updating active index to avoid\n     * an additional layout and style invalidation as changing active\n     * index modifies DOM.\n     */\n    _positionForMenu(index) {\n        let itemNode = this.contentNode.children[index];\n        let { left, bottom } = itemNode.getBoundingClientRect();\n        return {\n            top: bottom,\n            left\n        };\n    }\n    /**\n     * Handle the `'focusout'` event for the menu bar.\n     */\n    _evtFocusOut(event) {\n        // Reset the active index if there is no open menu and the menubar is losing focus.\n        if (!this._childMenu && !this.node.contains(event.relatedTarget)) {\n            this.activeIndex = -1;\n        }\n    }\n    /**\n     * Focus an item in the menu bar.\n     *\n     * #### Notes\n     * Does not open the associated menu.\n     */\n    _focusItemAt(index) {\n        const itemNode = this.contentNode.childNodes[index];\n        if (itemNode) {\n            itemNode.focus();\n        }\n    }\n    /**\n     * Open the child menu at the active index immediately.\n     *\n     * If a different child menu is already open, it will be closed,\n     * even if there is no active menu.\n     */\n    _openChildMenu(options = {}) {\n        // If there is no active menu, close the current menu.\n        let newMenu = this.activeMenu;\n        if (!newMenu) {\n            this._closeChildMenu();\n            return;\n        }\n        // Bail if there is no effective menu change.\n        let oldMenu = this._childMenu;\n        if (oldMenu === newMenu) {\n            return;\n        }\n        // Swap the internal menu reference.\n        this._childMenu = newMenu;\n        // Close the current menu, or setup for the new menu.\n        if (oldMenu) {\n            oldMenu.close();\n        }\n        else {\n            document.addEventListener('mousedown', this, true);\n        }\n        // Update the tab focus index and ensure the menu bar is updated.\n        this._tabFocusIndex = this.activeIndex;\n        _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this, Widget.Msg.UpdateRequest);\n        // Get the positioning data for the new menu.\n        let { left, top } = options;\n        if (typeof left === 'undefined' || typeof top === 'undefined') {\n            ({ left, top } = this._positionForMenu(this._activeIndex));\n        }\n        // Begin DOM modifications\n        if (!oldMenu) {\n            // Continue setup for new menu\n            this.addClass('lm-mod-active');\n        }\n        // Open the new menu at the computed location.\n        if (newMenu.items.length > 0) {\n            newMenu.open(left, top, this._forceItemsPosition);\n        }\n    }\n    /**\n     * Close the child menu immediately.\n     *\n     * This is a no-op if a child menu is not open.\n     */\n    _closeChildMenu() {\n        // Bail if no child menu is open.\n        if (!this._childMenu) {\n            return;\n        }\n        // Remove the active class from the menu bar.\n        this.removeClass('lm-mod-active');\n        // Remove the document listeners.\n        document.removeEventListener('mousedown', this, true);\n        // Clear the internal menu reference.\n        let menu = this._childMenu;\n        this._childMenu = null;\n        // Close the menu.\n        menu.close();\n        // Reset the active index.\n        this.activeIndex = -1;\n    }\n    /**\n     * Handle the `aboutToClose` signal of a menu.\n     */\n    _onMenuAboutToClose(sender) {\n        // Bail if the sender is not the child menu.\n        if (sender !== this._childMenu) {\n            return;\n        }\n        // Remove the active class from the menu bar.\n        this.removeClass('lm-mod-active');\n        // Remove the document listeners.\n        document.removeEventListener('mousedown', this, true);\n        // Clear the internal menu reference.\n        this._childMenu = null;\n        // Reset the active index.\n        this.activeIndex = -1;\n    }\n    /**\n     * Handle the `menuRequested` signal of a child menu.\n     */\n    _onMenuMenuRequested(sender, args) {\n        // Bail if the sender is not the child menu.\n        if (sender !== this._childMenu) {\n            return;\n        }\n        // Look up the active index and menu count.\n        let i = this._activeIndex;\n        let n = this._menus.length;\n        // Active the next requested index.\n        switch (args) {\n            case 'next':\n                this.activeIndex = i === n - 1 ? 0 : i + 1;\n                break;\n            case 'previous':\n                this.activeIndex = i === 0 ? n - 1 : i - 1;\n                break;\n        }\n        // Open the active menu.\n        this.openActiveMenu();\n    }\n    /**\n     * Handle the `changed` signal of a title object.\n     */\n    _onTitleChanged() {\n        this.update();\n    }\n}\n/**\n * The namespace for the `MenuBar` class statics.\n */\n(function (MenuBar) {\n    /**\n     * The default implementation of `IRenderer`.\n     *\n     * #### Notes\n     * Subclasses are free to reimplement rendering methods as needed.\n     */\n    class Renderer {\n        /**\n         * Render the virtual element for a menu bar item.\n         *\n         * @param data - The data to use for rendering the item.\n         *\n         * @returns A virtual element representing the item.\n         */\n        renderItem(data) {\n            let className = this.createItemClass(data);\n            let dataset = this.createItemDataset(data);\n            let aria = this.createItemARIA(data);\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.li({\n                className,\n                dataset,\n                ...(data.disabled ? {} : { tabindex: data.tabbable ? '0' : '-1' }),\n                onfocus: data.onfocus,\n                ...aria\n            }, this.renderIcon(data), this.renderLabel(data));\n        }\n        /**\n         * Render the icon element for a menu bar item.\n         *\n         * @param data - The data to use for rendering the icon.\n         *\n         * @returns A virtual element representing the item icon.\n         */\n        renderIcon(data) {\n            let className = this.createIconClass(data);\n            // If data.title.icon is undefined, it will be ignored.\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className }, data.title.icon, data.title.iconLabel);\n        }\n        /**\n         * Render the label element for a menu item.\n         *\n         * @param data - The data to use for rendering the label.\n         *\n         * @returns A virtual element representing the item label.\n         */\n        renderLabel(data) {\n            let content = this.formatLabel(data);\n            return _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.div({ className: 'lm-MenuBar-itemLabel' }, content);\n        }\n        /**\n         * Create the class name for the menu bar item.\n         *\n         * @param data - The data to use for the class name.\n         *\n         * @returns The full class name for the menu item.\n         */\n        createItemClass(data) {\n            let name = 'lm-MenuBar-item';\n            if (data.title.className) {\n                name += ` ${data.title.className}`;\n            }\n            if (data.active && !data.disabled) {\n                name += ' lm-mod-active';\n            }\n            return name;\n        }\n        /**\n         * Create the dataset for a menu bar item.\n         *\n         * @param data - The data to use for the item.\n         *\n         * @returns The dataset for the menu bar item.\n         */\n        createItemDataset(data) {\n            return data.title.dataset;\n        }\n        /**\n         * Create the aria attributes for menu bar item.\n         *\n         * @param data - The data to use for the aria attributes.\n         *\n         * @returns The aria attributes object for the item.\n         */\n        createItemARIA(data) {\n            return {\n                role: 'menuitem',\n                'aria-haspopup': 'true',\n                'aria-disabled': data.disabled ? 'true' : 'false'\n            };\n        }\n        /**\n         * Create the class name for the menu bar item icon.\n         *\n         * @param data - The data to use for the class name.\n         *\n         * @returns The full class name for the item icon.\n         */\n        createIconClass(data) {\n            let name = 'lm-MenuBar-itemIcon';\n            let extra = data.title.iconClass;\n            return extra ? `${name} ${extra}` : name;\n        }\n        /**\n         * Create the render content for the label node.\n         *\n         * @param data - The data to use for the label content.\n         *\n         * @returns The content to add to the label node.\n         */\n        formatLabel(data) {\n            // Fetch the label text and mnemonic index.\n            let { label, mnemonic } = data.title;\n            // If the index is out of range, do not modify the label.\n            if (mnemonic < 0 || mnemonic >= label.length) {\n                return label;\n            }\n            // Split the label into parts.\n            let prefix = label.slice(0, mnemonic);\n            let suffix = label.slice(mnemonic + 1);\n            let char = label[mnemonic];\n            // Wrap the mnemonic character in a span.\n            let span = _lumino_virtualdom__WEBPACK_IMPORTED_MODULE_8__.h.span({ className: 'lm-MenuBar-itemMnemonic' }, char);\n            // Return the content parts.\n            return [prefix, span, suffix];\n        }\n    }\n    MenuBar.Renderer = Renderer;\n    /**\n     * The default `Renderer` instance.\n     */\n    MenuBar.defaultRenderer = new Renderer();\n})(MenuBar || (MenuBar = {}));\n/**\n * The namespace for the module implementation details.\n */\nvar Private$3;\n(function (Private) {\n    /**\n     * Create the DOM node for a menu bar.\n     */\n    function createNode() {\n        let node = document.createElement('div');\n        let content = document.createElement('ul');\n        content.className = 'lm-MenuBar-content';\n        node.appendChild(content);\n        content.setAttribute('role', 'menubar');\n        return node;\n    }\n    Private.createNode = createNode;\n    /**\n     * Find the best matching mnemonic item.\n     *\n     * The search starts at the given index and wraps around.\n     */\n    function findMnemonic(menus, key, start) {\n        // Setup the result variables.\n        let index = -1;\n        let auto = -1;\n        let multiple = false;\n        // Normalize the key to upper case.\n        let upperKey = key.toUpperCase();\n        // Search the items from the given start index.\n        for (let i = 0, n = menus.length; i < n; ++i) {\n            // Compute the wrapped index.\n            let k = (i + start) % n;\n            // Look up the menu title.\n            let title = menus[k].title;\n            // Ignore titles with an empty label.\n            if (title.label.length === 0) {\n                continue;\n            }\n            // Look up the mnemonic index for the label.\n            let mn = title.mnemonic;\n            // Handle a valid mnemonic index.\n            if (mn >= 0 && mn < title.label.length) {\n                if (title.label[mn].toUpperCase() === upperKey) {\n                    if (index === -1) {\n                        index = k;\n                    }\n                    else {\n                        multiple = true;\n                    }\n                }\n                continue;\n            }\n            // Finally, handle the auto index if possible.\n            if (auto === -1 && title.label[0].toUpperCase() === upperKey) {\n                auto = k;\n            }\n        }\n        // Return the search results.\n        return { index, multiple, auto };\n    }\n    Private.findMnemonic = findMnemonic;\n})(Private$3 || (Private$3 = {}));\n\n/**\n * A widget which implements a canonical scroll bar.\n */\nclass ScrollBar extends Widget {\n    /**\n     * Construct a new scroll bar.\n     *\n     * @param options - The options for initializing the scroll bar.\n     */\n    constructor(options = {}) {\n        super({ node: Private$2.createNode() });\n        /**\n         * A timeout callback for repeating the mouse press.\n         */\n        this._onRepeat = () => {\n            // Clear the repeat timer id.\n            this._repeatTimer = -1;\n            // Bail if the mouse has been released.\n            if (!this._pressData) {\n                return;\n            }\n            // Look up the part that was pressed.\n            let part = this._pressData.part;\n            // Bail if the thumb was pressed.\n            if (part === 'thumb') {\n                return;\n            }\n            // Schedule the timer for another repeat.\n            this._repeatTimer = window.setTimeout(this._onRepeat, 20);\n            // Get the current mouse position.\n            let mouseX = this._pressData.mouseX;\n            let mouseY = this._pressData.mouseY;\n            // Handle a decrement button repeat.\n            if (part === 'decrement') {\n                // Bail if the mouse is not over the button.\n                if (!_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(this.decrementNode, mouseX, mouseY)) {\n                    return;\n                }\n                // Emit the step requested signal.\n                this._stepRequested.emit('decrement');\n                // Finished.\n                return;\n            }\n            // Handle an increment button repeat.\n            if (part === 'increment') {\n                // Bail if the mouse is not over the button.\n                if (!_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(this.incrementNode, mouseX, mouseY)) {\n                    return;\n                }\n                // Emit the step requested signal.\n                this._stepRequested.emit('increment');\n                // Finished.\n                return;\n            }\n            // Handle a track repeat.\n            if (part === 'track') {\n                // Bail if the mouse is not over the track.\n                if (!_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(this.trackNode, mouseX, mouseY)) {\n                    return;\n                }\n                // Fetch the thumb node.\n                let thumbNode = this.thumbNode;\n                // Bail if the mouse is over the thumb.\n                if (_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.hitTest(thumbNode, mouseX, mouseY)) {\n                    return;\n                }\n                // Fetch the client rect for the thumb.\n                let thumbRect = thumbNode.getBoundingClientRect();\n                // Determine the direction for the page request.\n                let dir;\n                if (this._orientation === 'horizontal') {\n                    dir = mouseX < thumbRect.left ? 'decrement' : 'increment';\n                }\n                else {\n                    dir = mouseY < thumbRect.top ? 'decrement' : 'increment';\n                }\n                // Emit the page requested signal.\n                this._pageRequested.emit(dir);\n                // Finished.\n                return;\n            }\n        };\n        this._value = 0;\n        this._page = 10;\n        this._maximum = 100;\n        this._repeatTimer = -1;\n        this._pressData = null;\n        this._thumbMoved = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._stepRequested = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._pageRequested = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this.addClass('lm-ScrollBar');\n        this.setFlag(Widget.Flag.DisallowLayout);\n        // Set the orientation.\n        this._orientation = options.orientation || 'vertical';\n        this.dataset['orientation'] = this._orientation;\n        // Parse the rest of the options.\n        if (options.maximum !== undefined) {\n            this._maximum = Math.max(0, options.maximum);\n        }\n        if (options.page !== undefined) {\n            this._page = Math.max(0, options.page);\n        }\n        if (options.value !== undefined) {\n            this._value = Math.max(0, Math.min(options.value, this._maximum));\n        }\n    }\n    /**\n     * A signal emitted when the user moves the scroll thumb.\n     *\n     * #### Notes\n     * The payload is the current value of the scroll bar.\n     */\n    get thumbMoved() {\n        return this._thumbMoved;\n    }\n    /**\n     * A signal emitted when the user clicks a step button.\n     *\n     * #### Notes\n     * The payload is whether a decrease or increase is requested.\n     */\n    get stepRequested() {\n        return this._stepRequested;\n    }\n    /**\n     * A signal emitted when the user clicks the scroll track.\n     *\n     * #### Notes\n     * The payload is whether a decrease or increase is requested.\n     */\n    get pageRequested() {\n        return this._pageRequested;\n    }\n    /**\n     * Get the orientation of the scroll bar.\n     */\n    get orientation() {\n        return this._orientation;\n    }\n    /**\n     * Set the orientation of the scroll bar.\n     */\n    set orientation(value) {\n        // Do nothing if the orientation does not change.\n        if (this._orientation === value) {\n            return;\n        }\n        // Release the mouse before making changes.\n        this._releaseMouse();\n        // Update the internal orientation.\n        this._orientation = value;\n        this.dataset['orientation'] = value;\n        // Schedule an update the scroll bar.\n        this.update();\n    }\n    /**\n     * Get the current value of the scroll bar.\n     */\n    get value() {\n        return this._value;\n    }\n    /**\n     * Set the current value of the scroll bar.\n     *\n     * #### Notes\n     * The value will be clamped to the range `[0, maximum]`.\n     */\n    set value(value) {\n        // Clamp the value to the allowable range.\n        value = Math.max(0, Math.min(value, this._maximum));\n        // Do nothing if the value does not change.\n        if (this._value === value) {\n            return;\n        }\n        // Update the internal value.\n        this._value = value;\n        // Schedule an update the scroll bar.\n        this.update();\n    }\n    /**\n     * Get the page size of the scroll bar.\n     *\n     * #### Notes\n     * The page size is the amount of visible content in the scrolled\n     * region, expressed in data units. It determines the size of the\n     * scroll bar thumb.\n     */\n    get page() {\n        return this._page;\n    }\n    /**\n     * Set the page size of the scroll bar.\n     *\n     * #### Notes\n     * The page size will be clamped to the range `[0, Infinity]`.\n     */\n    set page(value) {\n        // Clamp the page size to the allowable range.\n        value = Math.max(0, value);\n        // Do nothing if the value does not change.\n        if (this._page === value) {\n            return;\n        }\n        // Update the internal page size.\n        this._page = value;\n        // Schedule an update the scroll bar.\n        this.update();\n    }\n    /**\n     * Get the maximum value of the scroll bar.\n     */\n    get maximum() {\n        return this._maximum;\n    }\n    /**\n     * Set the maximum value of the scroll bar.\n     *\n     * #### Notes\n     * The max size will be clamped to the range `[0, Infinity]`.\n     */\n    set maximum(value) {\n        // Clamp the value to the allowable range.\n        value = Math.max(0, value);\n        // Do nothing if the value does not change.\n        if (this._maximum === value) {\n            return;\n        }\n        // Update the internal values.\n        this._maximum = value;\n        // Clamp the current value to the new range.\n        this._value = Math.min(this._value, value);\n        // Schedule an update the scroll bar.\n        this.update();\n    }\n    /**\n     * The scroll bar decrement button node.\n     *\n     * #### Notes\n     * Modifying this node directly can lead to undefined behavior.\n     */\n    get decrementNode() {\n        return this.node.getElementsByClassName('lm-ScrollBar-button')[0];\n    }\n    /**\n     * The scroll bar increment button node.\n     *\n     * #### Notes\n     * Modifying this node directly can lead to undefined behavior.\n     */\n    get incrementNode() {\n        return this.node.getElementsByClassName('lm-ScrollBar-button')[1];\n    }\n    /**\n     * The scroll bar track node.\n     *\n     * #### Notes\n     * Modifying this node directly can lead to undefined behavior.\n     */\n    get trackNode() {\n        return this.node.getElementsByClassName('lm-ScrollBar-track')[0];\n    }\n    /**\n     * The scroll bar thumb node.\n     *\n     * #### Notes\n     * Modifying this node directly can lead to undefined behavior.\n     */\n    get thumbNode() {\n        return this.node.getElementsByClassName('lm-ScrollBar-thumb')[0];\n    }\n    /**\n     * Handle the DOM events for the scroll bar.\n     *\n     * @param event - The DOM event sent to the scroll bar.\n     *\n     * #### Notes\n     * This method implements the DOM `EventListener` interface and is\n     * called in response to events on the scroll bar's DOM node.\n     *\n     * This should not be called directly by user code.\n     */\n    handleEvent(event) {\n        switch (event.type) {\n            case 'mousedown':\n                this._evtMouseDown(event);\n                break;\n            case 'mousemove':\n                this._evtMouseMove(event);\n                break;\n            case 'mouseup':\n                this._evtMouseUp(event);\n                break;\n            case 'keydown':\n                this._evtKeyDown(event);\n                break;\n            case 'contextmenu':\n                event.preventDefault();\n                event.stopPropagation();\n                break;\n        }\n    }\n    /**\n     * A method invoked on a 'before-attach' message.\n     */\n    onBeforeAttach(msg) {\n        this.node.addEventListener('mousedown', this);\n        this.update();\n    }\n    /**\n     * A method invoked on an 'after-detach' message.\n     */\n    onAfterDetach(msg) {\n        this.node.removeEventListener('mousedown', this);\n        this._releaseMouse();\n    }\n    /**\n     * A method invoked on an 'update-request' message.\n     */\n    onUpdateRequest(msg) {\n        // Convert the value and page into percentages.\n        let value = (this._value * 100) / this._maximum;\n        let page = (this._page * 100) / (this._page + this._maximum);\n        // Clamp the value and page to the relevant range.\n        value = Math.max(0, Math.min(value, 100));\n        page = Math.max(0, Math.min(page, 100));\n        // Fetch the thumb style.\n        let thumbStyle = this.thumbNode.style;\n        // Update the thumb style for the current orientation.\n        if (this._orientation === 'horizontal') {\n            thumbStyle.top = '';\n            thumbStyle.height = '';\n            thumbStyle.left = `${value}%`;\n            thumbStyle.width = `${page}%`;\n            thumbStyle.transform = `translate(${-value}%, 0%)`;\n        }\n        else {\n            thumbStyle.left = '';\n            thumbStyle.width = '';\n            thumbStyle.top = `${value}%`;\n            thumbStyle.height = `${page}%`;\n            thumbStyle.transform = `translate(0%, ${-value}%)`;\n        }\n    }\n    /**\n     * Handle the `'keydown'` event for the scroll bar.\n     */\n    _evtKeyDown(event) {\n        // Stop all input events during drag.\n        event.preventDefault();\n        event.stopPropagation();\n        // Ignore anything except the `Escape` key.\n        if (event.keyCode !== 27) {\n            return;\n        }\n        // Fetch the previous scroll value.\n        let value = this._pressData ? this._pressData.value : -1;\n        // Release the mouse.\n        this._releaseMouse();\n        // Restore the old scroll value if possible.\n        if (value !== -1) {\n            this._moveThumb(value);\n        }\n    }\n    /**\n     * Handle the `'mousedown'` event for the scroll bar.\n     */\n    _evtMouseDown(event) {\n        // Do nothing if it's not a left mouse press.\n        if (event.button !== 0) {\n            return;\n        }\n        // Send an activate request to the scroll bar. This can be\n        // used by message hooks to activate something relevant.\n        this.activate();\n        // Do nothing if the mouse is already captured.\n        if (this._pressData) {\n            return;\n        }\n        // Find the pressed scroll bar part.\n        let part = Private$2.findPart(this, event.target);\n        // Do nothing if the part is not of interest.\n        if (!part) {\n            return;\n        }\n        // Stop the event propagation.\n        event.preventDefault();\n        event.stopPropagation();\n        // Override the mouse cursor.\n        let override = _lumino_dragdrop__WEBPACK_IMPORTED_MODULE_6__.Drag.overrideCursor('default');\n        // Set up the press data.\n        this._pressData = {\n            part,\n            override,\n            delta: -1,\n            value: -1,\n            mouseX: event.clientX,\n            mouseY: event.clientY\n        };\n        // Add the extra event listeners.\n        document.addEventListener('mousemove', this, true);\n        document.addEventListener('mouseup', this, true);\n        document.addEventListener('keydown', this, true);\n        document.addEventListener('contextmenu', this, true);\n        // Handle a thumb press.\n        if (part === 'thumb') {\n            // Fetch the thumb node.\n            let thumbNode = this.thumbNode;\n            // Fetch the client rect for the thumb.\n            let thumbRect = thumbNode.getBoundingClientRect();\n            // Update the press data delta for the current orientation.\n            if (this._orientation === 'horizontal') {\n                this._pressData.delta = event.clientX - thumbRect.left;\n            }\n            else {\n                this._pressData.delta = event.clientY - thumbRect.top;\n            }\n            // Add the active class to the thumb node.\n            thumbNode.classList.add('lm-mod-active');\n            // Store the current value in the press data.\n            this._pressData.value = this._value;\n            // Finished.\n            return;\n        }\n        // Handle a track press.\n        if (part === 'track') {\n            // Fetch the client rect for the thumb.\n            let thumbRect = this.thumbNode.getBoundingClientRect();\n            // Determine the direction for the page request.\n            let dir;\n            if (this._orientation === 'horizontal') {\n                dir = event.clientX < thumbRect.left ? 'decrement' : 'increment';\n            }\n            else {\n                dir = event.clientY < thumbRect.top ? 'decrement' : 'increment';\n            }\n            // Start the repeat timer.\n            this._repeatTimer = window.setTimeout(this._onRepeat, 350);\n            // Emit the page requested signal.\n            this._pageRequested.emit(dir);\n            // Finished.\n            return;\n        }\n        // Handle a decrement button press.\n        if (part === 'decrement') {\n            // Add the active class to the decrement node.\n            this.decrementNode.classList.add('lm-mod-active');\n            // Start the repeat timer.\n            this._repeatTimer = window.setTimeout(this._onRepeat, 350);\n            // Emit the step requested signal.\n            this._stepRequested.emit('decrement');\n            // Finished.\n            return;\n        }\n        // Handle an increment button press.\n        if (part === 'increment') {\n            // Add the active class to the increment node.\n            this.incrementNode.classList.add('lm-mod-active');\n            // Start the repeat timer.\n            this._repeatTimer = window.setTimeout(this._onRepeat, 350);\n            // Emit the step requested signal.\n            this._stepRequested.emit('increment');\n            // Finished.\n            return;\n        }\n    }\n    /**\n     * Handle the `'mousemove'` event for the scroll bar.\n     */\n    _evtMouseMove(event) {\n        // Do nothing if no drag is in progress.\n        if (!this._pressData) {\n            return;\n        }\n        // Stop the event propagation.\n        event.preventDefault();\n        event.stopPropagation();\n        // Update the mouse position.\n        this._pressData.mouseX = event.clientX;\n        this._pressData.mouseY = event.clientY;\n        // Bail if the thumb is not being dragged.\n        if (this._pressData.part !== 'thumb') {\n            return;\n        }\n        // Get the client rect for the thumb and track.\n        let thumbRect = this.thumbNode.getBoundingClientRect();\n        let trackRect = this.trackNode.getBoundingClientRect();\n        // Fetch the scroll geometry based on the orientation.\n        let trackPos;\n        let trackSpan;\n        if (this._orientation === 'horizontal') {\n            trackPos = event.clientX - trackRect.left - this._pressData.delta;\n            trackSpan = trackRect.width - thumbRect.width;\n        }\n        else {\n            trackPos = event.clientY - trackRect.top - this._pressData.delta;\n            trackSpan = trackRect.height - thumbRect.height;\n        }\n        // Compute the desired value from the scroll geometry.\n        let value = trackSpan === 0 ? 0 : (trackPos * this._maximum) / trackSpan;\n        // Move the thumb to the computed value.\n        this._moveThumb(value);\n    }\n    /**\n     * Handle the `'mouseup'` event for the scroll bar.\n     */\n    _evtMouseUp(event) {\n        // Do nothing if it's not a left mouse release.\n        if (event.button !== 0) {\n            return;\n        }\n        // Stop the event propagation.\n        event.preventDefault();\n        event.stopPropagation();\n        // Release the mouse.\n        this._releaseMouse();\n    }\n    /**\n     * Release the mouse and restore the node states.\n     */\n    _releaseMouse() {\n        // Bail if there is no press data.\n        if (!this._pressData) {\n            return;\n        }\n        // Clear the repeat timer.\n        clearTimeout(this._repeatTimer);\n        this._repeatTimer = -1;\n        // Clear the press data.\n        this._pressData.override.dispose();\n        this._pressData = null;\n        // Remove the extra event listeners.\n        document.removeEventListener('mousemove', this, true);\n        document.removeEventListener('mouseup', this, true);\n        document.removeEventListener('keydown', this, true);\n        document.removeEventListener('contextmenu', this, true);\n        // Remove the active classes from the nodes.\n        this.thumbNode.classList.remove('lm-mod-active');\n        this.decrementNode.classList.remove('lm-mod-active');\n        this.incrementNode.classList.remove('lm-mod-active');\n    }\n    /**\n     * Move the thumb to the specified position.\n     */\n    _moveThumb(value) {\n        // Clamp the value to the allowed range.\n        value = Math.max(0, Math.min(value, this._maximum));\n        // Bail if the value does not change.\n        if (this._value === value) {\n            return;\n        }\n        // Update the internal value.\n        this._value = value;\n        // Schedule an update of the scroll bar.\n        this.update();\n        // Emit the thumb moved signal.\n        this._thumbMoved.emit(value);\n    }\n}\n/**\n * The namespace for the module implementation details.\n */\nvar Private$2;\n(function (Private) {\n    /**\n     * Create the DOM node for a scroll bar.\n     */\n    function createNode() {\n        let node = document.createElement('div');\n        let decrement = document.createElement('div');\n        let increment = document.createElement('div');\n        let track = document.createElement('div');\n        let thumb = document.createElement('div');\n        decrement.className = 'lm-ScrollBar-button';\n        increment.className = 'lm-ScrollBar-button';\n        decrement.dataset['action'] = 'decrement';\n        increment.dataset['action'] = 'increment';\n        track.className = 'lm-ScrollBar-track';\n        thumb.className = 'lm-ScrollBar-thumb';\n        track.appendChild(thumb);\n        node.appendChild(decrement);\n        node.appendChild(track);\n        node.appendChild(increment);\n        return node;\n    }\n    Private.createNode = createNode;\n    /**\n     * Find the scroll bar part which contains the given target.\n     */\n    function findPart(scrollBar, target) {\n        // Test the thumb.\n        if (scrollBar.thumbNode.contains(target)) {\n            return 'thumb';\n        }\n        // Test the track.\n        if (scrollBar.trackNode.contains(target)) {\n            return 'track';\n        }\n        // Test the decrement button.\n        if (scrollBar.decrementNode.contains(target)) {\n            return 'decrement';\n        }\n        // Test the increment button.\n        if (scrollBar.incrementNode.contains(target)) {\n            return 'increment';\n        }\n        // Indicate no match.\n        return null;\n    }\n    Private.findPart = findPart;\n})(Private$2 || (Private$2 = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A concrete layout implementation which holds a single widget.\n *\n * #### Notes\n * This class is useful for creating simple container widgets which\n * hold a single child. The child should be positioned with CSS.\n */\nclass SingletonLayout extends Layout {\n    constructor() {\n        super(...arguments);\n        this._widget = null;\n    }\n    /**\n     * Dispose of the resources held by the layout.\n     */\n    dispose() {\n        if (this._widget) {\n            let widget = this._widget;\n            this._widget = null;\n            widget.dispose();\n        }\n        super.dispose();\n    }\n    /**\n     * Get the child widget for the layout.\n     */\n    get widget() {\n        return this._widget;\n    }\n    /**\n     * Set the child widget for the layout.\n     *\n     * #### Notes\n     * Setting the child widget will cause the old child widget to be\n     * automatically disposed. If that is not desired, set the parent\n     * of the old child to `null` before assigning a new child.\n     */\n    set widget(widget) {\n        // Remove the widget from its current parent. This is a no-op\n        // if the widget's parent is already the layout parent widget.\n        if (widget) {\n            widget.parent = this.parent;\n        }\n        // Bail early if the widget does not change.\n        if (this._widget === widget) {\n            return;\n        }\n        // Dispose of the old child widget.\n        if (this._widget) {\n            this._widget.dispose();\n        }\n        // Update the internal widget.\n        this._widget = widget;\n        // Attach the new child widget if needed.\n        if (this.parent && widget) {\n            this.attachWidget(widget);\n        }\n    }\n    /**\n     * Create an iterator over the widgets in the layout.\n     *\n     * @returns A new iterator over the widgets in the layout.\n     */\n    *[Symbol.iterator]() {\n        if (this._widget) {\n            yield this._widget;\n        }\n    }\n    /**\n     * Remove a widget from the layout.\n     *\n     * @param widget - The widget to remove from the layout.\n     *\n     * #### Notes\n     * A widget is automatically removed from the layout when its `parent`\n     * is set to `null`. This method should only be invoked directly when\n     * removing a widget from a layout which has yet to be installed on a\n     * parent widget.\n     *\n     * This method does *not* modify the widget's `parent`.\n     */\n    removeWidget(widget) {\n        // Bail early if the widget does not exist in the layout.\n        if (this._widget !== widget) {\n            return;\n        }\n        // Clear the internal widget.\n        this._widget = null;\n        // If the layout is parented, detach the widget from the DOM.\n        if (this.parent) {\n            this.detachWidget(widget);\n        }\n    }\n    /**\n     * Perform layout initialization which requires the parent widget.\n     */\n    init() {\n        super.init();\n        for (const widget of this) {\n            this.attachWidget(widget);\n        }\n    }\n    /**\n     * Attach a widget to the parent's DOM node.\n     *\n     * @param index - The current index of the widget in the layout.\n     *\n     * @param widget - The widget to attach to the parent.\n     *\n     * #### Notes\n     * This method is called automatically by the single layout at the\n     * appropriate time. It should not be called directly by user code.\n     *\n     * The default implementation adds the widgets's node to the parent's\n     * node at the proper location, and sends the appropriate attach\n     * messages to the widget if the parent is attached to the DOM.\n     *\n     * Subclasses may reimplement this method to control how the widget's\n     * node is added to the parent's node.\n     */\n    attachWidget(widget) {\n        // Send a `'before-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeAttach);\n        }\n        // Add the widget's node to the parent.\n        this.parent.node.appendChild(widget.node);\n        // Send an `'after-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterAttach);\n        }\n    }\n    /**\n     * Detach a widget from the parent's DOM node.\n     *\n     * @param widget - The widget to detach from the parent.\n     *\n     * #### Notes\n     * This method is called automatically by the single layout at the\n     * appropriate time. It should not be called directly by user code.\n     *\n     * The default implementation removes the widget's node from the\n     * parent's node, and sends the appropriate detach messages to the\n     * widget if the parent is attached to the DOM.\n     *\n     * Subclasses may reimplement this method to control how the widget's\n     * node is removed from the parent's node.\n     */\n    detachWidget(widget) {\n        // Send a `'before-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeDetach);\n        }\n        // Remove the widget's node from the parent.\n        this.parent.node.removeChild(widget.node);\n        // Send an `'after-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterDetach);\n        }\n    }\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A layout where visible widgets are stacked atop one another.\n *\n * #### Notes\n * The Z-order of the visible widgets follows their layout order.\n */\nclass StackedLayout extends PanelLayout {\n    constructor(options = {}) {\n        super(options);\n        this._dirty = false;\n        this._items = [];\n        this._box = null;\n        this._hiddenMode =\n            options.hiddenMode !== undefined\n                ? options.hiddenMode\n                : Widget.HiddenMode.Display;\n    }\n    /**\n     * The method for hiding widgets.\n     *\n     * #### Notes\n     * If there is only one child widget, `Display` hiding mode will be used\n     * regardless of this setting.\n     */\n    get hiddenMode() {\n        return this._hiddenMode;\n    }\n    /**\n     * Set the method for hiding widgets.\n     *\n     * #### Notes\n     * If there is only one child widget, `Display` hiding mode will be used\n     * regardless of this setting.\n     */\n    set hiddenMode(v) {\n        if (this._hiddenMode === v) {\n            return;\n        }\n        this._hiddenMode = v;\n        if (this.widgets.length > 1) {\n            this.widgets.forEach(w => {\n                w.hiddenMode = this._hiddenMode;\n            });\n        }\n    }\n    /**\n     * Dispose of the resources held by the layout.\n     */\n    dispose() {\n        // Dispose of the layout items.\n        for (const item of this._items) {\n            item.dispose();\n        }\n        // Clear the layout state.\n        this._box = null;\n        this._items.length = 0;\n        // Dispose of the rest of the layout.\n        super.dispose();\n    }\n    /**\n     * Attach a widget to the parent's DOM node.\n     *\n     * @param index - The current index of the widget in the layout.\n     *\n     * @param widget - The widget to attach to the parent.\n     *\n     * #### Notes\n     * This is a reimplementation of the superclass method.\n     */\n    attachWidget(index, widget) {\n        // Using transform create an additional layer in the pixel pipeline\n        // to limit the number of layer, it is set only if there is more than one widget.\n        if (this._hiddenMode === Widget.HiddenMode.Scale &&\n            this._items.length > 0) {\n            if (this._items.length === 1) {\n                this.widgets[0].hiddenMode = Widget.HiddenMode.Scale;\n            }\n            widget.hiddenMode = Widget.HiddenMode.Scale;\n        }\n        else {\n            widget.hiddenMode = Widget.HiddenMode.Display;\n        }\n        // Create and add a new layout item for the widget.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.insert(this._items, index, new LayoutItem(widget));\n        // Send a `'before-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeAttach);\n        }\n        // Add the widget's node to the parent.\n        this.parent.node.appendChild(widget.node);\n        // Send an `'after-attach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterAttach);\n        }\n        // Post a fit request for the parent widget.\n        this.parent.fit();\n    }\n    /**\n     * Move a widget in the parent's DOM node.\n     *\n     * @param fromIndex - The previous index of the widget in the layout.\n     *\n     * @param toIndex - The current index of the widget in the layout.\n     *\n     * @param widget - The widget to move in the parent.\n     *\n     * #### Notes\n     * This is a reimplementation of the superclass method.\n     */\n    moveWidget(fromIndex, toIndex, widget) {\n        // Move the layout item for the widget.\n        _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.move(this._items, fromIndex, toIndex);\n        // Post an update request for the parent widget.\n        this.parent.update();\n    }\n    /**\n     * Detach a widget from the parent's DOM node.\n     *\n     * @param index - The previous index of the widget in the layout.\n     *\n     * @param widget - The widget to detach from the parent.\n     *\n     * #### Notes\n     * This is a reimplementation of the superclass method.\n     */\n    detachWidget(index, widget) {\n        // Remove the layout item for the widget.\n        let item = _lumino_algorithm__WEBPACK_IMPORTED_MODULE_0__.ArrayExt.removeAt(this._items, index);\n        // Send a `'before-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.BeforeDetach);\n        }\n        // Remove the widget's node from the parent.\n        this.parent.node.removeChild(widget.node);\n        // Send an `'after-detach'` message if the parent is attached.\n        if (this.parent.isAttached) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(widget, Widget.Msg.AfterDetach);\n        }\n        // Reset the z-index for the widget.\n        item.widget.node.style.zIndex = '';\n        // Reset the hidden mode for the widget.\n        if (this._hiddenMode === Widget.HiddenMode.Scale) {\n            widget.hiddenMode = Widget.HiddenMode.Display;\n            // Reset the hidden mode for the first widget if necessary.\n            if (this._items.length === 1) {\n                this._items[0].widget.hiddenMode = Widget.HiddenMode.Display;\n            }\n        }\n        // Dispose of the layout item.\n        item.dispose();\n        // Post a fit request for the parent widget.\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'before-show'` message.\n     */\n    onBeforeShow(msg) {\n        super.onBeforeShow(msg);\n        this.parent.update();\n    }\n    /**\n     * A message handler invoked on a `'before-attach'` message.\n     */\n    onBeforeAttach(msg) {\n        super.onBeforeAttach(msg);\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'child-shown'` message.\n     */\n    onChildShown(msg) {\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'child-hidden'` message.\n     */\n    onChildHidden(msg) {\n        this.parent.fit();\n    }\n    /**\n     * A message handler invoked on a `'resize'` message.\n     */\n    onResize(msg) {\n        if (this.parent.isVisible) {\n            this._update(msg.width, msg.height);\n        }\n    }\n    /**\n     * A message handler invoked on an `'update-request'` message.\n     */\n    onUpdateRequest(msg) {\n        if (this.parent.isVisible) {\n            this._update(-1, -1);\n        }\n    }\n    /**\n     * A message handler invoked on a `'fit-request'` message.\n     */\n    onFitRequest(msg) {\n        if (this.parent.isAttached) {\n            this._fit();\n        }\n    }\n    /**\n     * Fit the layout to the total size required by the widgets.\n     */\n    _fit() {\n        // Set up the computed minimum size.\n        let minW = 0;\n        let minH = 0;\n        // Update the computed minimum size.\n        for (let i = 0, n = this._items.length; i < n; ++i) {\n            // Fetch the item.\n            let item = this._items[i];\n            // Ignore hidden items.\n            if (item.isHidden) {\n                continue;\n            }\n            // Update the size limits for the item.\n            item.fit();\n            // Update the computed minimum size.\n            minW = Math.max(minW, item.minWidth);\n            minH = Math.max(minH, item.minHeight);\n        }\n        // Update the box sizing and add it to the computed min size.\n        let box = (this._box = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.boxSizing(this.parent.node));\n        minW += box.horizontalSum;\n        minH += box.verticalSum;\n        // Update the parent's min size constraints.\n        let style = this.parent.node.style;\n        style.minWidth = `${minW}px`;\n        style.minHeight = `${minH}px`;\n        // Set the dirty flag to ensure only a single update occurs.\n        this._dirty = true;\n        // Notify the ancestor that it should fit immediately. This may\n        // cause a resize of the parent, fulfilling the required update.\n        if (this.parent.parent) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.parent.parent, Widget.Msg.FitRequest);\n        }\n        // If the dirty flag is still set, the parent was not resized.\n        // Trigger the required update on the parent widget immediately.\n        if (this._dirty) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.sendMessage(this.parent, Widget.Msg.UpdateRequest);\n        }\n    }\n    /**\n     * Update the layout position and size of the widgets.\n     *\n     * The parent offset dimensions should be `-1` if unknown.\n     */\n    _update(offsetWidth, offsetHeight) {\n        // Clear the dirty flag to indicate the update occurred.\n        this._dirty = false;\n        // Compute the visible item count.\n        let nVisible = 0;\n        for (let i = 0, n = this._items.length; i < n; ++i) {\n            nVisible += +!this._items[i].isHidden;\n        }\n        // Bail early if there are no visible items to layout.\n        if (nVisible === 0) {\n            return;\n        }\n        // Measure the parent if the offset dimensions are unknown.\n        if (offsetWidth < 0) {\n            offsetWidth = this.parent.node.offsetWidth;\n        }\n        if (offsetHeight < 0) {\n            offsetHeight = this.parent.node.offsetHeight;\n        }\n        // Ensure the parent box sizing data is computed.\n        if (!this._box) {\n            this._box = _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.ElementExt.boxSizing(this.parent.node);\n        }\n        // Compute the actual layout bounds adjusted for border and padding.\n        let top = this._box.paddingTop;\n        let left = this._box.paddingLeft;\n        let width = offsetWidth - this._box.horizontalSum;\n        let height = offsetHeight - this._box.verticalSum;\n        // Update the widget stacking order and layout geometry.\n        for (let i = 0, n = this._items.length; i < n; ++i) {\n            // Fetch the item.\n            let item = this._items[i];\n            // Ignore hidden items.\n            if (item.isHidden) {\n                continue;\n            }\n            // Set the z-index for the widget.\n            item.widget.node.style.zIndex = `${i}`;\n            // Update the item geometry.\n            item.update(left, top, width, height);\n        }\n    }\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A panel where visible widgets are stacked atop one another.\n *\n * #### Notes\n * This class provides a convenience wrapper around a {@link StackedLayout}.\n */\nclass StackedPanel extends Panel {\n    /**\n     * Construct a new stacked panel.\n     *\n     * @param options - The options for initializing the panel.\n     */\n    constructor(options = {}) {\n        super({ layout: Private$1.createLayout(options) });\n        this._widgetRemoved = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this.addClass('lm-StackedPanel');\n    }\n    /**\n     * The method for hiding widgets.\n     *\n     * #### Notes\n     * If there is only one child widget, `Display` hiding mode will be used\n     * regardless of this setting.\n     */\n    get hiddenMode() {\n        return this.layout.hiddenMode;\n    }\n    /**\n     * Set the method for hiding widgets.\n     *\n     * #### Notes\n     * If there is only one child widget, `Display` hiding mode will be used\n     * regardless of this setting.\n     */\n    set hiddenMode(v) {\n        this.layout.hiddenMode = v;\n    }\n    /**\n     * A signal emitted when a widget is removed from a stacked panel.\n     */\n    get widgetRemoved() {\n        return this._widgetRemoved;\n    }\n    /**\n     * A message handler invoked on a `'child-added'` message.\n     */\n    onChildAdded(msg) {\n        msg.child.addClass('lm-StackedPanel-child');\n    }\n    /**\n     * A message handler invoked on a `'child-removed'` message.\n     */\n    onChildRemoved(msg) {\n        msg.child.removeClass('lm-StackedPanel-child');\n        this._widgetRemoved.emit(msg.child);\n    }\n}\n/**\n * The namespace for the module implementation details.\n */\nvar Private$1;\n(function (Private) {\n    /**\n     * Create a stacked layout for the given panel options.\n     */\n    function createLayout(options) {\n        return options.layout || new StackedLayout();\n    }\n    Private.createLayout = createLayout;\n})(Private$1 || (Private$1 = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * A widget which combines a `TabBar` and a `StackedPanel`.\n *\n * #### Notes\n * This is a simple panel which handles the common case of a tab bar\n * placed next to a content area. The selected tab controls the widget\n * which is shown in the content area.\n *\n * For use cases which require more control than is provided by this\n * panel, the `TabBar` widget may be used independently.\n */\nclass TabPanel extends Widget {\n    /**\n     * Construct a new tab panel.\n     *\n     * @param options - The options for initializing the tab panel.\n     */\n    constructor(options = {}) {\n        super();\n        this._currentChanged = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this._addRequested = new _lumino_signaling__WEBPACK_IMPORTED_MODULE_5__.Signal(this);\n        this.addClass('lm-TabPanel');\n        // Create the tab bar and stacked panel.\n        this.tabBar = new TabBar(options);\n        this.tabBar.addClass('lm-TabPanel-tabBar');\n        this.stackedPanel = new StackedPanel();\n        this.stackedPanel.addClass('lm-TabPanel-stackedPanel');\n        // Connect the tab bar signal handlers.\n        this.tabBar.tabMoved.connect(this._onTabMoved, this);\n        this.tabBar.currentChanged.connect(this._onCurrentChanged, this);\n        this.tabBar.tabCloseRequested.connect(this._onTabCloseRequested, this);\n        this.tabBar.tabActivateRequested.connect(this._onTabActivateRequested, this);\n        this.tabBar.addRequested.connect(this._onTabAddRequested, this);\n        // Connect the stacked panel signal handlers.\n        this.stackedPanel.widgetRemoved.connect(this._onWidgetRemoved, this);\n        // Get the data related to the placement.\n        this._tabPlacement = options.tabPlacement || 'top';\n        let direction = Private.directionFromPlacement(this._tabPlacement);\n        let orientation = Private.orientationFromPlacement(this._tabPlacement);\n        // Configure the tab bar for the placement.\n        this.tabBar.orientation = orientation;\n        this.tabBar.dataset['placement'] = this._tabPlacement;\n        // Create the box layout.\n        let layout = new BoxLayout({ direction, spacing: 0 });\n        // Set the stretch factors for the child widgets.\n        BoxLayout.setStretch(this.tabBar, 0);\n        BoxLayout.setStretch(this.stackedPanel, 1);\n        // Add the child widgets to the layout.\n        layout.addWidget(this.tabBar);\n        layout.addWidget(this.stackedPanel);\n        // Install the layout on the tab panel.\n        this.layout = layout;\n    }\n    /**\n     * A signal emitted when the current tab is changed.\n     *\n     * #### Notes\n     * This signal is emitted when the currently selected tab is changed\n     * either through user or programmatic interaction.\n     *\n     * Notably, this signal is not emitted when the index of the current\n     * tab changes due to tabs being inserted, removed, or moved. It is\n     * only emitted when the actual current tab node is changed.\n     */\n    get currentChanged() {\n        return this._currentChanged;\n    }\n    /**\n     * Get the index of the currently selected tab.\n     *\n     * #### Notes\n     * This will be `-1` if no tab is selected.\n     */\n    get currentIndex() {\n        return this.tabBar.currentIndex;\n    }\n    /**\n     * Set the index of the currently selected tab.\n     *\n     * #### Notes\n     * If the index is out of range, it will be set to `-1`.\n     */\n    set currentIndex(value) {\n        this.tabBar.currentIndex = value;\n    }\n    /**\n     * Get the currently selected widget.\n     *\n     * #### Notes\n     * This will be `null` if there is no selected tab.\n     */\n    get currentWidget() {\n        let title = this.tabBar.currentTitle;\n        return title ? title.owner : null;\n    }\n    /**\n     * Set the currently selected widget.\n     *\n     * #### Notes\n     * If the widget is not in the panel, it will be set to `null`.\n     */\n    set currentWidget(value) {\n        this.tabBar.currentTitle = value ? value.title : null;\n    }\n    /**\n     * Get the whether the tabs are movable by the user.\n     *\n     * #### Notes\n     * Tabs can always be moved programmatically.\n     */\n    get tabsMovable() {\n        return this.tabBar.tabsMovable;\n    }\n    /**\n     * Set the whether the tabs are movable by the user.\n     *\n     * #### Notes\n     * Tabs can always be moved programmatically.\n     */\n    set tabsMovable(value) {\n        this.tabBar.tabsMovable = value;\n    }\n    /**\n     * Get the whether the add button is enabled.\n     *\n     */\n    get addButtonEnabled() {\n        return this.tabBar.addButtonEnabled;\n    }\n    /**\n     * Set the whether the add button is enabled.\n     *\n     */\n    set addButtonEnabled(value) {\n        this.tabBar.addButtonEnabled = value;\n    }\n    /**\n     * Get the tab placement for the tab panel.\n     *\n     * #### Notes\n     * This controls the position of the tab bar relative to the content.\n     */\n    get tabPlacement() {\n        return this._tabPlacement;\n    }\n    /**\n     * Set the tab placement for the tab panel.\n     *\n     * #### Notes\n     * This controls the position of the tab bar relative to the content.\n     */\n    set tabPlacement(value) {\n        // Bail if the placement does not change.\n        if (this._tabPlacement === value) {\n            return;\n        }\n        // Update the internal value.\n        this._tabPlacement = value;\n        // Get the values related to the placement.\n        let direction = Private.directionFromPlacement(value);\n        let orientation = Private.orientationFromPlacement(value);\n        // Configure the tab bar for the placement.\n        this.tabBar.orientation = orientation;\n        this.tabBar.dataset['placement'] = value;\n        // Update the layout direction.\n        this.layout.direction = direction;\n    }\n    /**\n     * A signal emitted when the add button on a tab bar is clicked.\n     *\n     */\n    get addRequested() {\n        return this._addRequested;\n    }\n    /**\n     * A read-only array of the widgets in the panel.\n     */\n    get widgets() {\n        return this.stackedPanel.widgets;\n    }\n    /**\n     * Add a widget to the end of the tab panel.\n     *\n     * @param widget - The widget to add to the tab panel.\n     *\n     * #### Notes\n     * If the widget is already contained in the panel, it will be moved.\n     *\n     * The widget's `title` is used to populate the tab.\n     */\n    addWidget(widget) {\n        this.insertWidget(this.widgets.length, widget);\n    }\n    /**\n     * Insert a widget into the tab panel at a specified index.\n     *\n     * @param index - The index at which to insert the widget.\n     *\n     * @param widget - The widget to insert into to the tab panel.\n     *\n     * #### Notes\n     * If the widget is already contained in the panel, it will be moved.\n     *\n     * The widget's `title` is used to populate the tab.\n     */\n    insertWidget(index, widget) {\n        if (widget !== this.currentWidget) {\n            widget.hide();\n        }\n        this.stackedPanel.insertWidget(index, widget);\n        this.tabBar.insertTab(index, widget.title);\n        widget.node.setAttribute('role', 'tabpanel');\n        let renderer = this.tabBar.renderer;\n        if (renderer instanceof TabBar.Renderer) {\n            let tabId = renderer.createTabKey({\n                title: widget.title,\n                current: false,\n                zIndex: 0\n            });\n            widget.node.setAttribute('aria-labelledby', tabId);\n        }\n    }\n    /**\n     * Handle the `currentChanged` signal from the tab bar.\n     */\n    _onCurrentChanged(sender, args) {\n        // Extract the previous and current title from the args.\n        let { previousIndex, previousTitle, currentIndex, currentTitle } = args;\n        // Extract the widgets from the titles.\n        let previousWidget = previousTitle ? previousTitle.owner : null;\n        let currentWidget = currentTitle ? currentTitle.owner : null;\n        // Hide the previous widget.\n        if (previousWidget) {\n            previousWidget.hide();\n        }\n        // Show the current widget.\n        if (currentWidget) {\n            currentWidget.show();\n        }\n        // Emit the `currentChanged` signal for the tab panel.\n        this._currentChanged.emit({\n            previousIndex,\n            previousWidget,\n            currentIndex,\n            currentWidget\n        });\n        // Flush the message loop on IE and Edge to prevent flicker.\n        if (_lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.Platform.IS_EDGE || _lumino_domutils__WEBPACK_IMPORTED_MODULE_2__.Platform.IS_IE) {\n            _lumino_messaging__WEBPACK_IMPORTED_MODULE_3__.MessageLoop.flush();\n        }\n    }\n    /**\n     * Handle the `tabAddRequested` signal from the tab bar.\n     */\n    _onTabAddRequested(sender, args) {\n        this._addRequested.emit(sender);\n    }\n    /**\n     * Handle the `tabActivateRequested` signal from the tab bar.\n     */\n    _onTabActivateRequested(sender, args) {\n        args.title.owner.activate();\n    }\n    /**\n     * Handle the `tabCloseRequested` signal from the tab bar.\n     */\n    _onTabCloseRequested(sender, args) {\n        args.title.owner.close();\n    }\n    /**\n     * Handle the `tabMoved` signal from the tab bar.\n     */\n    _onTabMoved(sender, args) {\n        this.stackedPanel.insertWidget(args.toIndex, args.title.owner);\n    }\n    /**\n     * Handle the `widgetRemoved` signal from the stacked panel.\n     */\n    _onWidgetRemoved(sender, widget) {\n        widget.node.removeAttribute('role');\n        widget.node.removeAttribute('aria-labelledby');\n        this.tabBar.removeTab(widget.title);\n    }\n}\n/**\n * The namespace for the module implementation details.\n */\nvar Private;\n(function (Private) {\n    /**\n     * Convert a tab placement to tab bar orientation.\n     */\n    function orientationFromPlacement(plc) {\n        return placementToOrientationMap[plc];\n    }\n    Private.orientationFromPlacement = orientationFromPlacement;\n    /**\n     * Convert a tab placement to a box layout direction.\n     */\n    function directionFromPlacement(plc) {\n        return placementToDirectionMap[plc];\n    }\n    Private.directionFromPlacement = directionFromPlacement;\n    /**\n     * A mapping of tab placement to tab bar orientation.\n     */\n    const placementToOrientationMap = {\n        top: 'horizontal',\n        left: 'vertical',\n        right: 'vertical',\n        bottom: 'horizontal'\n    };\n    /**\n     * A mapping of tab placement to box layout direction.\n     */\n    const placementToDirectionMap = {\n        top: 'top-to-bottom',\n        left: 'left-to-right',\n        right: 'right-to-left',\n        bottom: 'bottom-to-top'\n    };\n})(Private || (Private = {}));\n\n\n//# sourceMappingURL=index.es6.js.map\n\n\n//# sourceURL=webpack://_JUPYTERLAB.CORE_OUTPUT/../node_modules/@lumino/widgets/dist/index.es6.js?");

/***/ })

}]);