{"version":3,"file":"inert.min.js","sources":["../src/inert.js"],"sourcesContent":["/**\n * This work is licensed under the W3C Software and Document License\n * (http://www.w3.org/Consortium/Legal/2015/copyright-software-and-document).\n */\n\n(function() {\n // Return early if we're not running inside of the browser.\n if (typeof window === 'undefined') {\n return;\n }\n\n // Convenience function for converting NodeLists.\n /** @type {typeof Array.prototype.slice} */\n const slice = Array.prototype.slice;\n\n /**\n * IE has a non-standard name for \"matches\".\n * @type {typeof Element.prototype.matches}\n */\n const matches =\n Element.prototype.matches || Element.prototype.msMatchesSelector;\n\n /** @type {string} */\n const _focusableElementsString = ['a[href]',\n 'area[href]',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n 'button:not([disabled])',\n 'details',\n 'summary',\n 'iframe',\n 'object',\n 'embed',\n '[contenteditable]'].join(',');\n\n /**\n * `InertRoot` manages a single inert subtree, i.e. a DOM subtree whose root element has an `inert`\n * attribute.\n *\n * Its main functions are:\n *\n * - to create and maintain a set of managed `InertNode`s, including when mutations occur in the\n * subtree. The `makeSubtreeUnfocusable()` method handles collecting `InertNode`s via registering\n * each focusable node in the subtree with the singleton `InertManager` which manages all known\n * focusable nodes within inert subtrees. `InertManager` ensures that a single `InertNode`\n * instance exists for each focusable node which has at least one inert root as an ancestor.\n *\n * - to notify all managed `InertNode`s when this subtree stops being inert (i.e. when the `inert`\n * attribute is removed from the root node). This is handled in the destructor, which calls the\n * `deregister` method on `InertManager` for each managed inert node.\n */\n class InertRoot {\n /**\n * @param {!HTMLElement} rootElement The HTMLElement at the root of the inert subtree.\n * @param {!InertManager} inertManager The global singleton InertManager object.\n */\n constructor(rootElement, inertManager) {\n /** @type {!InertManager} */\n this._inertManager = inertManager;\n\n /** @type {!HTMLElement} */\n this._rootElement = rootElement;\n\n /**\n * @type {!Set}\n * All managed focusable nodes in this InertRoot's subtree.\n */\n this._managedNodes = new Set();\n\n // Make the subtree hidden from assistive technology\n if (this._rootElement.hasAttribute('aria-hidden')) {\n /** @type {?string} */\n this._savedAriaHidden = this._rootElement.getAttribute('aria-hidden');\n } else {\n this._savedAriaHidden = null;\n }\n this._rootElement.setAttribute('aria-hidden', 'true');\n\n // Make all focusable elements in the subtree unfocusable and add them to _managedNodes\n this._makeSubtreeUnfocusable(this._rootElement);\n\n // Watch for:\n // - any additions in the subtree: make them unfocusable too\n // - any removals from the subtree: remove them from this inert root's managed nodes\n // - attribute changes: if `tabindex` is added, or removed from an intrinsically focusable\n // element, make that node a managed node.\n this._observer = new MutationObserver(this._onMutation.bind(this));\n this._observer.observe(this._rootElement, {attributes: true, childList: true, subtree: true});\n }\n\n /**\n * Call this whenever this object is about to become obsolete. This unwinds all of the state\n * stored in this object and updates the state of all of the managed nodes.\n */\n destructor() {\n this._observer.disconnect();\n\n if (this._rootElement) {\n if (this._savedAriaHidden !== null) {\n this._rootElement.setAttribute('aria-hidden', this._savedAriaHidden);\n } else {\n this._rootElement.removeAttribute('aria-hidden');\n }\n }\n\n this._managedNodes.forEach(function(inertNode) {\n this._unmanageNode(inertNode.node);\n }, this);\n\n // Note we cast the nulls to the ANY type here because:\n // 1) We want the class properties to be declared as non-null, or else we\n // need even more casts throughout this code. All bets are off if an\n // instance has been destroyed and a method is called.\n // 2) We don't want to cast \"this\", because we want type-aware optimizations\n // to know which properties we're setting.\n this._observer = /** @type {?} */ (null);\n this._rootElement = /** @type {?} */ (null);\n this._managedNodes = /** @type {?} */ (null);\n this._inertManager = /** @type {?} */ (null);\n }\n\n /**\n * @return {!Set} A copy of this InertRoot's managed nodes set.\n */\n get managedNodes() {\n return new Set(this._managedNodes);\n }\n\n /** @return {boolean} */\n get hasSavedAriaHidden() {\n return this._savedAriaHidden !== null;\n }\n\n /** @param {?string} ariaHidden */\n set savedAriaHidden(ariaHidden) {\n this._savedAriaHidden = ariaHidden;\n }\n\n /** @return {?string} */\n get savedAriaHidden() {\n return this._savedAriaHidden;\n }\n\n /**\n * @param {!Node} startNode\n */\n _makeSubtreeUnfocusable(startNode) {\n composedTreeWalk(startNode, (node) => this._visitNode(node));\n\n let activeElement = document.activeElement;\n\n if (!document.body.contains(startNode)) {\n // startNode may be in shadow DOM, so find its nearest shadowRoot to get the activeElement.\n let node = startNode;\n /** @type {!ShadowRoot|undefined} */\n let root = undefined;\n while (node) {\n if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n root = /** @type {!ShadowRoot} */ (node);\n break;\n }\n node = node.parentNode;\n }\n if (root) {\n activeElement = root.activeElement;\n }\n }\n if (startNode.contains(activeElement)) {\n activeElement.blur();\n // In IE11, if an element is already focused, and then set to tabindex=-1\n // calling blur() will not actually move the focus.\n // To work around this we call focus() on the body instead.\n if (activeElement === document.activeElement) {\n document.body.focus();\n }\n }\n }\n\n /**\n * @param {!Node} node\n */\n _visitNode(node) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return;\n }\n const element = /** @type {!HTMLElement} */ (node);\n\n // If a descendant inert root becomes un-inert, its descendants will still be inert because of\n // this inert root, so all of its managed nodes need to be adopted by this InertRoot.\n if (element !== this._rootElement && element.hasAttribute('inert')) {\n this._adoptInertRoot(element);\n }\n\n if (matches.call(element, _focusableElementsString) || element.hasAttribute('tabindex')) {\n this._manageNode(element);\n }\n }\n\n /**\n * Register the given node with this InertRoot and with InertManager.\n * @param {!Node} node\n */\n _manageNode(node) {\n const inertNode = this._inertManager.register(node, this);\n this._managedNodes.add(inertNode);\n }\n\n /**\n * Unregister the given node with this InertRoot and with InertManager.\n * @param {!Node} node\n */\n _unmanageNode(node) {\n const inertNode = this._inertManager.deregister(node, this);\n if (inertNode) {\n this._managedNodes.delete(inertNode);\n }\n }\n\n /**\n * Unregister the entire subtree starting at `startNode`.\n * @param {!Node} startNode\n */\n _unmanageSubtree(startNode) {\n composedTreeWalk(startNode, (node) => this._unmanageNode(node));\n }\n\n /**\n * If a descendant node is found with an `inert` attribute, adopt its managed nodes.\n * @param {!HTMLElement} node\n */\n _adoptInertRoot(node) {\n let inertSubroot = this._inertManager.getInertRoot(node);\n\n // During initialisation this inert root may not have been registered yet,\n // so register it now if need be.\n if (!inertSubroot) {\n this._inertManager.setInert(node, true);\n inertSubroot = this._inertManager.getInertRoot(node);\n }\n\n inertSubroot.managedNodes.forEach(function(savedInertNode) {\n this._manageNode(savedInertNode.node);\n }, this);\n }\n\n /**\n * Callback used when mutation observer detects subtree additions, removals, or attribute changes.\n * @param {!Array} records\n * @param {!MutationObserver} self\n */\n _onMutation(records, self) {\n records.forEach(function(record) {\n const target = /** @type {!HTMLElement} */ (record.target);\n if (record.type === 'childList') {\n // Manage added nodes\n slice.call(record.addedNodes).forEach(function(node) {\n this._makeSubtreeUnfocusable(node);\n }, this);\n\n // Un-manage removed nodes\n slice.call(record.removedNodes).forEach(function(node) {\n this._unmanageSubtree(node);\n }, this);\n } else if (record.type === 'attributes') {\n if (record.attributeName === 'tabindex') {\n // Re-initialise inert node if tabindex changes\n this._manageNode(target);\n } else if (target !== this._rootElement &&\n record.attributeName === 'inert' &&\n target.hasAttribute('inert')) {\n // If a new inert root is added, adopt its managed nodes and make sure it knows about the\n // already managed nodes from this inert subroot.\n this._adoptInertRoot(target);\n const inertSubroot = this._inertManager.getInertRoot(target);\n this._managedNodes.forEach(function(managedNode) {\n if (target.contains(managedNode.node)) {\n inertSubroot._manageNode(managedNode.node);\n }\n });\n }\n }\n }, this);\n }\n }\n\n /**\n * `InertNode` initialises and manages a single inert node.\n * A node is inert if it is a descendant of one or more inert root elements.\n *\n * On construction, `InertNode` saves the existing `tabindex` value for the node, if any, and\n * either removes the `tabindex` attribute or sets it to `-1`, depending on whether the element\n * is intrinsically focusable or not.\n *\n * `InertNode` maintains a set of `InertRoot`s which are descendants of this `InertNode`. When an\n * `InertRoot` is destroyed, and calls `InertManager.deregister()`, the `InertManager` notifies the\n * `InertNode` via `removeInertRoot()`, which in turn destroys the `InertNode` if no `InertRoot`s\n * remain in the set. On destruction, `InertNode` reinstates the stored `tabindex` if one exists,\n * or removes the `tabindex` attribute if the element is intrinsically focusable.\n */\n class InertNode {\n /**\n * @param {!Node} node A focusable element to be made inert.\n * @param {!InertRoot} inertRoot The inert root element associated with this inert node.\n */\n constructor(node, inertRoot) {\n /** @type {!Node} */\n this._node = node;\n\n /** @type {boolean} */\n this._overrodeFocusMethod = false;\n\n /**\n * @type {!Set} The set of descendant inert roots.\n * If and only if this set becomes empty, this node is no longer inert.\n */\n this._inertRoots = new Set([inertRoot]);\n\n /** @type {?number} */\n this._savedTabIndex = null;\n\n /** @type {boolean} */\n this._destroyed = false;\n\n // Save any prior tabindex info and make this node untabbable\n this.ensureUntabbable();\n }\n\n /**\n * Call this whenever this object is about to become obsolete.\n * This makes the managed node focusable again and deletes all of the previously stored state.\n */\n destructor() {\n this._throwIfDestroyed();\n\n if (this._node && this._node.nodeType === Node.ELEMENT_NODE) {\n const element = /** @type {!HTMLElement} */ (this._node);\n if (this._savedTabIndex !== null) {\n element.setAttribute('tabindex', this._savedTabIndex);\n } else {\n element.removeAttribute('tabindex');\n }\n\n // Use `delete` to restore native focus method.\n if (this._overrodeFocusMethod) {\n delete element.focus;\n }\n }\n\n // See note in InertRoot.destructor for why we cast these nulls to ANY.\n this._node = /** @type {?} */ (null);\n this._inertRoots = /** @type {?} */ (null);\n this._destroyed = true;\n }\n\n /**\n * @type {boolean} Whether this object is obsolete because the managed node is no longer inert.\n * If the object has been destroyed, any attempt to access it will cause an exception.\n */\n get destroyed() {\n return /** @type {!InertNode} */ (this)._destroyed;\n }\n\n /**\n * Throw if user tries to access destroyed InertNode.\n */\n _throwIfDestroyed() {\n if (this.destroyed) {\n throw new Error('Trying to access destroyed InertNode');\n }\n }\n\n /** @return {boolean} */\n get hasSavedTabIndex() {\n return this._savedTabIndex !== null;\n }\n\n /** @return {!Node} */\n get node() {\n this._throwIfDestroyed();\n return this._node;\n }\n\n /** @param {?number} tabIndex */\n set savedTabIndex(tabIndex) {\n this._throwIfDestroyed();\n this._savedTabIndex = tabIndex;\n }\n\n /** @return {?number} */\n get savedTabIndex() {\n this._throwIfDestroyed();\n return this._savedTabIndex;\n }\n\n /** Save the existing tabindex value and make the node untabbable and unfocusable */\n ensureUntabbable() {\n if (this.node.nodeType !== Node.ELEMENT_NODE) {\n return;\n }\n const element = /** @type {!HTMLElement} */ (this.node);\n if (matches.call(element, _focusableElementsString)) {\n if (/** @type {!HTMLElement} */ (element).tabIndex === -1 &&\n this.hasSavedTabIndex) {\n return;\n }\n\n if (element.hasAttribute('tabindex')) {\n this._savedTabIndex = /** @type {!HTMLElement} */ (element).tabIndex;\n }\n element.setAttribute('tabindex', '-1');\n if (element.nodeType === Node.ELEMENT_NODE) {\n element.focus = function() {};\n this._overrodeFocusMethod = true;\n }\n } else if (element.hasAttribute('tabindex')) {\n this._savedTabIndex = /** @type {!HTMLElement} */ (element).tabIndex;\n element.removeAttribute('tabindex');\n }\n }\n\n /**\n * Add another inert root to this inert node's set of managing inert roots.\n * @param {!InertRoot} inertRoot\n */\n addInertRoot(inertRoot) {\n this._throwIfDestroyed();\n this._inertRoots.add(inertRoot);\n }\n\n /**\n * Remove the given inert root from this inert node's set of managing inert roots.\n * If the set of managing inert roots becomes empty, this node is no longer inert,\n * so the object should be destroyed.\n * @param {!InertRoot} inertRoot\n */\n removeInertRoot(inertRoot) {\n this._throwIfDestroyed();\n this._inertRoots.delete(inertRoot);\n if (this._inertRoots.size === 0) {\n this.destructor();\n }\n }\n }\n\n /**\n * InertManager is a per-document singleton object which manages all inert roots and nodes.\n *\n * When an element becomes an inert root by having an `inert` attribute set and/or its `inert`\n * property set to `true`, the `setInert` method creates an `InertRoot` object for the element.\n * The `InertRoot` in turn registers itself as managing all of the element's focusable descendant\n * nodes via the `register()` method. The `InertManager` ensures that a single `InertNode` instance\n * is created for each such node, via the `_managedNodes` map.\n */\n class InertManager {\n /**\n * @param {!Document} document\n */\n constructor(document) {\n if (!document) {\n throw new Error('Missing required argument; InertManager needs to wrap a document.');\n }\n\n /** @type {!Document} */\n this._document = document;\n\n /**\n * All managed nodes known to this InertManager. In a map to allow looking up by Node.\n * @type {!Map}\n */\n this._managedNodes = new Map();\n\n /**\n * All inert roots known to this InertManager. In a map to allow looking up by Node.\n * @type {!Map}\n */\n this._inertRoots = new Map();\n\n /**\n * Observer for mutations on `document.body`.\n * @type {!MutationObserver}\n */\n this._observer = new MutationObserver(this._watchForInert.bind(this));\n\n // Add inert style.\n addInertStyle(document.head || document.body || document.documentElement);\n\n // Wait for document to be loaded.\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', this._onDocumentLoaded.bind(this));\n } else {\n this._onDocumentLoaded();\n }\n }\n\n /**\n * Set whether the given element should be an inert root or not.\n * @param {!HTMLElement} root\n * @param {boolean} inert\n */\n setInert(root, inert) {\n if (inert) {\n if (this._inertRoots.has(root)) { // element is already inert\n return;\n }\n\n const inertRoot = new InertRoot(root, this);\n root.setAttribute('inert', '');\n this._inertRoots.set(root, inertRoot);\n // If not contained in the document, it must be in a shadowRoot.\n // Ensure inert styles are added there.\n if (!this._document.body.contains(root)) {\n let parent = root.parentNode;\n while (parent) {\n if (parent.nodeType === 11) {\n addInertStyle(parent);\n }\n parent = parent.parentNode;\n }\n }\n } else {\n if (!this._inertRoots.has(root)) { // element is already non-inert\n return;\n }\n\n const inertRoot = this._inertRoots.get(root);\n inertRoot.destructor();\n this._inertRoots.delete(root);\n root.removeAttribute('inert');\n }\n }\n\n /**\n * Get the InertRoot object corresponding to the given inert root element, if any.\n * @param {!Node} element\n * @return {!InertRoot|undefined}\n */\n getInertRoot(element) {\n return this._inertRoots.get(element);\n }\n\n /**\n * Register the given InertRoot as managing the given node.\n * In the case where the node has a previously existing inert root, this inert root will\n * be added to its set of inert roots.\n * @param {!Node} node\n * @param {!InertRoot} inertRoot\n * @return {!InertNode} inertNode\n */\n register(node, inertRoot) {\n let inertNode = this._managedNodes.get(node);\n if (inertNode !== undefined) { // node was already in an inert subtree\n inertNode.addInertRoot(inertRoot);\n } else {\n inertNode = new InertNode(node, inertRoot);\n }\n\n this._managedNodes.set(node, inertNode);\n\n return inertNode;\n }\n\n /**\n * De-register the given InertRoot as managing the given inert node.\n * Removes the inert root from the InertNode's set of managing inert roots, and remove the inert\n * node from the InertManager's set of managed nodes if it is destroyed.\n * If the node is not currently managed, this is essentially a no-op.\n * @param {!Node} node\n * @param {!InertRoot} inertRoot\n * @return {?InertNode} The potentially destroyed InertNode associated with this node, if any.\n */\n deregister(node, inertRoot) {\n const inertNode = this._managedNodes.get(node);\n if (!inertNode) {\n return null;\n }\n\n inertNode.removeInertRoot(inertRoot);\n if (inertNode.destroyed) {\n this._managedNodes.delete(node);\n }\n\n return inertNode;\n }\n\n /**\n * Callback used when document has finished loading.\n */\n _onDocumentLoaded() {\n // Find all inert roots in document and make them actually inert.\n const inertElements = slice.call(this._document.querySelectorAll('[inert]'));\n inertElements.forEach(function(inertElement) {\n this.setInert(inertElement, true);\n }, this);\n\n // Comment this out to use programmatic API only.\n this._observer.observe(this._document.body || this._document.documentElement, {attributes: true, subtree: true, childList: true});\n }\n\n /**\n * Callback used when mutation observer detects attribute changes.\n * @param {!Array} records\n * @param {!MutationObserver} self\n */\n _watchForInert(records, self) {\n const _this = this;\n records.forEach(function(record) {\n switch (record.type) {\n case 'childList':\n slice.call(record.addedNodes).forEach(function(node) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return;\n }\n const inertElements = slice.call(node.querySelectorAll('[inert]'));\n if (matches.call(node, '[inert]')) {\n inertElements.unshift(node);\n }\n inertElements.forEach(function(inertElement) {\n this.setInert(inertElement, true);\n }, _this);\n }, _this);\n break;\n case 'attributes':\n if (record.attributeName !== 'inert') {\n return;\n }\n const target = /** @type {!HTMLElement} */ (record.target);\n const inert = target.hasAttribute('inert');\n _this.setInert(target, inert);\n break;\n }\n }, this);\n }\n }\n\n /**\n * Recursively walk the composed tree from |node|.\n * @param {!Node} node\n * @param {(function (!HTMLElement))=} callback Callback to be called for each element traversed,\n * before descending into child nodes.\n * @param {?ShadowRoot=} shadowRootAncestor The nearest ShadowRoot ancestor, if any.\n */\n function composedTreeWalk(node, callback, shadowRootAncestor) {\n if (node.nodeType == Node.ELEMENT_NODE) {\n const element = /** @type {!HTMLElement} */ (node);\n if (callback) {\n callback(element);\n }\n\n // Descend into node:\n // If it has a ShadowRoot, ignore all child elements - these will be picked\n // up by the or elements. Descend straight into the\n // ShadowRoot.\n const shadowRoot = /** @type {!HTMLElement} */ (element).shadowRoot;\n if (shadowRoot) {\n composedTreeWalk(shadowRoot, callback, shadowRoot);\n return;\n }\n\n // If it is a element, descend into distributed elements - these\n // are elements from outside the shadow root which are rendered inside the\n // shadow DOM.\n if (element.localName == 'content') {\n const content = /** @type {!HTMLContentElement} */ (element);\n // Verifies if ShadowDom v0 is supported.\n const distributedNodes = content.getDistributedNodes ?\n content.getDistributedNodes() : [];\n for (let i = 0; i < distributedNodes.length; i++) {\n composedTreeWalk(distributedNodes[i], callback, shadowRootAncestor);\n }\n return;\n }\n\n // If it is a element, descend into assigned nodes - these\n // are elements from outside the shadow root which are rendered inside the\n // shadow DOM.\n if (element.localName == 'slot') {\n const slot = /** @type {!HTMLSlotElement} */ (element);\n // Verify if ShadowDom v1 is supported.\n const distributedNodes = slot.assignedNodes ?\n slot.assignedNodes({flatten: true}) : [];\n for (let i = 0; i < distributedNodes.length; i++) {\n composedTreeWalk(distributedNodes[i], callback, shadowRootAncestor);\n }\n return;\n }\n }\n\n // If it is neither the parent of a ShadowRoot, a element, a \n // element, nor a element recurse normally.\n let child = node.firstChild;\n while (child != null) {\n composedTreeWalk(child, callback, shadowRootAncestor);\n child = child.nextSibling;\n }\n }\n\n /**\n * Adds a style element to the node containing the inert specific styles\n * @param {!Node} node\n */\n function addInertStyle(node) {\n if (node.querySelector('style#inert-style, link#inert-style')) {\n return;\n }\n const style = document.createElement('style');\n style.setAttribute('id', 'inert-style');\n style.textContent = '\\n'+\n '[inert] {\\n' +\n ' pointer-events: none;\\n' +\n ' cursor: default;\\n' +\n '}\\n' +\n '\\n' +\n '[inert], [inert] * {\\n' +\n ' -webkit-user-select: none;\\n' +\n ' -moz-user-select: none;\\n' +\n ' -ms-user-select: none;\\n' +\n ' user-select: none;\\n' +\n '}\\n';\n node.appendChild(style);\n }\n\n if (!HTMLElement.prototype.hasOwnProperty('inert')) {\n /** @type {!InertManager} */\n const inertManager = new InertManager(document);\n \n Object.defineProperty(HTMLElement.prototype, 'inert', {\n enumerable: true,\n /** @this {!HTMLElement} */\n get: function() {\n return this.hasAttribute('inert');\n },\n /** @this {!HTMLElement} */\n set: function(inert) {\n inertManager.setInert(this, inert);\n },\n });\n }\n})();\n"],"names":["slice","matches","_focusableElementsString","InertRoot","InertNode","inertManager","rootElement","_inertManager","_rootElement","_managedNodes","Set","this","hasAttribute","_savedAriaHidden","getAttribute","setAttribute","_makeSubtreeUnfocusable","_observer","MutationObserver","_onMutation","bind","observe","attributes","childList","subtree","node","inertRoot","_node","_overrodeFocusMethod","_inertRoots","_savedTabIndex","_destroyed","ensureUntabbable","document","Error","_document","Map","_watchForInert","head","body","documentElement","readyState","addEventListener","_onDocumentLoaded","composedTreeWalk","callback","shadowRootAncestor","nodeType","Node","ELEMENT_NODE","element","shadowRoot","localName","content","distributedNodes","getDistributedNodes","i","length","slot","assignedNodes","flatten","child","firstChild","nextSibling","addInertStyle","style","querySelector","createElement","textContent","appendChild","window","Array","prototype","Element","msMatchesSelector","join","disconnect","removeAttribute","forEach","inertNode","_unmanageNode","startNode","activeElement","_this2","_visitNode","contains","root","undefined","DOCUMENT_FRAGMENT_NODE","parentNode","blur","focus","_adoptInertRoot","call","_manageNode","register","add","deregister","_this3","inertSubroot","getInertRoot","setInert","managedNodes","savedInertNode","records","self","record","target","type","addedNodes","removedNodes","_unmanageSubtree","attributeName","managedNode","ariaHidden","_throwIfDestroyed","destroyed","tabIndex","hasSavedTabIndex","size","destructor","inert","has","set","parent","get","addInertRoot","removeInertRoot","querySelectorAll","inertElement","_this","inertElements","unshift","InertManager","HTMLElement","hasOwnProperty","defineProperty"],"mappings":"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"}