From 2b4757367470d8e36bc00901dac567e375796ed4 Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Tue, 13 Nov 2018 00:24:09 -0500 Subject: update viz 2 to use the newest version, which has some performance improvements and is easier to read the code for. also update the description --- assets/viz/2/goog/dom/asserts.js | 311 ++++++++++++++++ assets/viz/2/goog/dom/dom.js | 459 ++++++++++++++++++------ assets/viz/2/goog/dom/htmlelement.js | 29 ++ assets/viz/2/goog/dom/safe.js | 110 +++++- assets/viz/2/goog/dom/tagname.js | 666 ++++++++++++++++++++++++++++------- 5 files changed, 1322 insertions(+), 253 deletions(-) create mode 100644 assets/viz/2/goog/dom/asserts.js create mode 100644 assets/viz/2/goog/dom/htmlelement.js (limited to 'assets/viz/2/goog/dom') diff --git a/assets/viz/2/goog/dom/asserts.js b/assets/viz/2/goog/dom/asserts.js new file mode 100644 index 0000000..a8f93ba --- /dev/null +++ b/assets/viz/2/goog/dom/asserts.js @@ -0,0 +1,311 @@ +// Copyright 2017 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +goog.provide('goog.dom.asserts'); + +goog.require('goog.asserts'); + +/** + * @fileoverview Custom assertions to ensure that an element has the appropriate + * type. + * + * Using a goog.dom.safe wrapper on an object on the incorrect type (via an + * incorrect static type cast) can result in security bugs: For instance, + * g.d.s.setAnchorHref ensures that the URL assigned to the .href attribute + * satisfies the SafeUrl contract, i.e., is safe to dereference as a hyperlink. + * However, the value assigned to a HTMLLinkElement's .href property requires + * the stronger TrustedResourceUrl contract, since it can refer to a stylesheet. + * Thus, using g.d.s.setAnchorHref on an (incorrectly statically typed) object + * of type HTMLLinkElement can result in a security vulnerability. + * Assertions of the correct run-time type help prevent such incorrect use. + * + * In some cases, code using the DOM API is tested using mock objects (e.g., a + * plain object such as {'href': url} instead of an actual Location object). + * To allow such mocking, the assertions permit objects of types that are not + * relevant DOM API objects at all (for instance, not Element or Location). + * + * Note that instanceof checks don't work straightforwardly in older versions of + * IE, or across frames (see, + * http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object, + * http://stackoverflow.com/questions/26248599/instanceof-htmlelement-in-iframe-is-not-element-or-object). + * + * Hence, these assertions may pass vacuously in such scenarios. The resulting + * risk of security bugs is limited by the following factors: + * - A bug can only arise in scenarios involving incorrect static typing (the + * wrapper methods are statically typed to demand objects of the appropriate, + * precise type). + * - Typically, code is tested and exercised in multiple browsers. + */ + +/** + * Asserts that a given object is a Location. + * + * To permit this assertion to pass in the context of tests where DOM APIs might + * be mocked, also accepts any other type except for subtypes of {!Element}. + * This is to ensure that, for instance, HTMLLinkElement is not being used in + * place of a Location, since this could result in security bugs due to stronger + * contracts required for assignments to the href property of the latter. + * + * @param {?Object} o The object whose type to assert. + * @return {!Location} + */ +goog.dom.asserts.assertIsLocation = function(o) { + if (goog.asserts.ENABLE_ASSERTS) { + var win = goog.dom.asserts.getWindow_(o); + if (typeof win.Location != 'undefined' && + typeof win.Element != 'undefined') { + goog.asserts.assert( + o && (o instanceof win.Location || !(o instanceof win.Element)), + 'Argument is not a Location (or a non-Element mock); got: %s', + goog.dom.asserts.debugStringForType_(o)); + } + } + return /** @type {!Location} */ (o); +}; + +/** + * Asserts that a given object is a HTMLAnchorElement. + * + * To permit this assertion to pass in the context of tests where elements might + * be mocked, also accepts objects that are not of type Location nor a subtype + * of Element. + * + * @param {?Object} o The object whose type to assert. + * @return {!HTMLAnchorElement} + */ +goog.dom.asserts.assertIsHTMLAnchorElement = function(o) { + if (goog.asserts.ENABLE_ASSERTS) { + var win = goog.dom.asserts.getWindow_(o); + if (typeof win.HTMLAnchorElement != 'undefined' && + typeof win.Location != 'undefined' && + typeof win.Element != 'undefined') { + goog.asserts.assert( + o && + (o instanceof win.HTMLAnchorElement || + !((o instanceof win.Location) || (o instanceof win.Element))), + 'Argument is not a HTMLAnchorElement (or a non-Element mock); ' + + 'got: %s', + goog.dom.asserts.debugStringForType_(o)); + } + } + return /** @type {!HTMLAnchorElement} */ (o); +}; + +/** + * Asserts that a given object is a HTMLLinkElement. + * + * To permit this assertion to pass in the context of tests where elements might + * be mocked, also accepts objects that are not a subtype of Element. + * + * @param {?Object} o The object whose type to assert. + * @return {!HTMLLinkElement} + */ +goog.dom.asserts.assertIsHTMLLinkElement = function(o) { + if (goog.asserts.ENABLE_ASSERTS) { + var win = goog.dom.asserts.getWindow_(o); + if (typeof win.HTMLLinkElement != 'undefined' && + typeof win.Location != 'undefined' && + typeof win.Element != 'undefined') { + goog.asserts.assert( + o && + (o instanceof win.HTMLLinkElement || + !((o instanceof win.Location) || (o instanceof win.Element))), + 'Argument is not a HTMLLinkElement (or a non-Element mock); got: %s', + goog.dom.asserts.debugStringForType_(o)); + } + } + return /** @type {!HTMLLinkElement} */ (o); +}; + +/** + * Asserts that a given object is a HTMLImageElement. + * + * To permit this assertion to pass in the context of tests where elements might + * be mocked, also accepts objects that are not a subtype of Element. + * + * @param {?Object} o The object whose type to assert. + * @return {!HTMLImageElement} + */ +goog.dom.asserts.assertIsHTMLImageElement = function(o) { + if (goog.asserts.ENABLE_ASSERTS) { + var win = goog.dom.asserts.getWindow_(o); + if (typeof win.HTMLImageElement != 'undefined' && + typeof win.Element != 'undefined') { + goog.asserts.assert( + o && + (o instanceof win.HTMLImageElement || + !(o instanceof win.Element)), + 'Argument is not a HTMLImageElement (or a non-Element mock); got: %s', + goog.dom.asserts.debugStringForType_(o)); + } + } + return /** @type {!HTMLImageElement} */ (o); +}; + +/** + * Asserts that a given object is a HTMLEmbedElement. + * + * To permit this assertion to pass in the context of tests where elements might + * be mocked, also accepts objects that are not a subtype of Element. + * + * @param {?Object} o The object whose type to assert. + * @return {!HTMLEmbedElement} + */ +goog.dom.asserts.assertIsHTMLEmbedElement = function(o) { + if (goog.asserts.ENABLE_ASSERTS) { + var win = goog.dom.asserts.getWindow_(o); + if (typeof win.HTMLEmbedElement != 'undefined' && + typeof win.Element != 'undefined') { + goog.asserts.assert( + o && + (o instanceof win.HTMLEmbedElement || + !(o instanceof win.Element)), + 'Argument is not a HTMLEmbedElement (or a non-Element mock); got: %s', + goog.dom.asserts.debugStringForType_(o)); + } + } + return /** @type {!HTMLEmbedElement} */ (o); +}; + +/** + * Asserts that a given object is a HTMLFrameElement. + * + * To permit this assertion to pass in the context of tests where elements might + * be mocked, also accepts objects that are not a subtype of Element. + * + * @param {?Object} o The object whose type to assert. + * @return {!HTMLFrameElement} + */ +goog.dom.asserts.assertIsHTMLFrameElement = function(o) { + if (goog.asserts.ENABLE_ASSERTS) { + var win = goog.dom.asserts.getWindow_(o); + if (typeof win.HTMLFrameElement != 'undefined' && + typeof win.Element != 'undefined') { + goog.asserts.assert( + o && + (o instanceof win.HTMLFrameElement || + !(o instanceof win.Element)), + 'Argument is not a HTMLFrameElement (or a non-Element mock); got: %s', + goog.dom.asserts.debugStringForType_(o)); + } + } + return /** @type {!HTMLFrameElement} */ (o); +}; + +/** + * Asserts that a given object is a HTMLIFrameElement. + * + * To permit this assertion to pass in the context of tests where elements might + * be mocked, also accepts objects that are not a subtype of Element. + * + * @param {?Object} o The object whose type to assert. + * @return {!HTMLIFrameElement} + */ +goog.dom.asserts.assertIsHTMLIFrameElement = function(o) { + if (goog.asserts.ENABLE_ASSERTS) { + var win = goog.dom.asserts.getWindow_(o); + if (typeof win.HTMLIFrameElement != 'undefined' && + typeof win.Element != 'undefined') { + goog.asserts.assert( + o && + (o instanceof win.HTMLIFrameElement || + !(o instanceof win.Element)), + 'Argument is not a HTMLIFrameElement (or a non-Element mock); ' + + 'got: %s', + goog.dom.asserts.debugStringForType_(o)); + } + } + return /** @type {!HTMLIFrameElement} */ (o); +}; + +/** + * Asserts that a given object is a HTMLObjectElement. + * + * To permit this assertion to pass in the context of tests where elements might + * be mocked, also accepts objects that are not a subtype of Element. + * + * @param {?Object} o The object whose type to assert. + * @return {!HTMLObjectElement} + */ +goog.dom.asserts.assertIsHTMLObjectElement = function(o) { + if (goog.asserts.ENABLE_ASSERTS) { + var win = goog.dom.asserts.getWindow_(o); + if (typeof win.HTMLObjectElement != 'undefined' && + typeof win.Element != 'undefined') { + goog.asserts.assert( + o && + (o instanceof win.HTMLObjectElement || + !(o instanceof win.Element)), + 'Argument is not a HTMLObjectElement (or a non-Element mock); ' + + 'got: %s', + goog.dom.asserts.debugStringForType_(o)); + } + } + return /** @type {!HTMLObjectElement} */ (o); +}; + +/** + * Asserts that a given object is a HTMLScriptElement. + * + * To permit this assertion to pass in the context of tests where elements might + * be mocked, also accepts objects that are not a subtype of Element. + * + * @param {?Object} o The object whose type to assert. + * @return {!HTMLScriptElement} + */ +goog.dom.asserts.assertIsHTMLScriptElement = function(o) { + if (goog.asserts.ENABLE_ASSERTS) { + var win = goog.dom.asserts.getWindow_(o); + if (typeof win.HTMLScriptElement != 'undefined' && + typeof win.Element != 'undefined') { + goog.asserts.assert( + o && + (o instanceof win.HTMLScriptElement || + !(o instanceof win.Element)), + 'Argument is not a HTMLScriptElement (or a non-Element mock); ' + + 'got: %s', + goog.dom.asserts.debugStringForType_(o)); + } + } + return /** @type {!HTMLScriptElement} */ (o); +}; + +/** + * Returns a string representation of a value's type. + * + * @param {*} value An object, or primitive. + * @return {string} The best display name for the value. + * @private + */ +goog.dom.asserts.debugStringForType_ = function(value) { + if (goog.isObject(value)) { + return value.constructor.displayName || value.constructor.name || + Object.prototype.toString.call(value); + } else { + return value === undefined ? 'undefined' : + value === null ? 'null' : typeof value; + } +}; + +/** + * Gets window of element. + * @param {?Object} o + * @return {!Window} + * @private + */ +goog.dom.asserts.getWindow_ = function(o) { + var doc = o && o.ownerDocument; + var win = doc && /** @type {?Window} */ (doc.defaultView || doc.parentWindow); + return win || /** @type {!Window} */ (goog.global); +}; diff --git a/assets/viz/2/goog/dom/dom.js b/assets/viz/2/goog/dom/dom.js index 4d3cdf9..919a0b6 100644 --- a/assets/viz/2/goog/dom/dom.js +++ b/assets/viz/2/goog/dom/dom.js @@ -170,6 +170,24 @@ goog.dom.getRequiredElementHelper_ = function(doc, id) { goog.dom.$ = goog.dom.getElement; +/** + * Gets elements by tag name. + * @param {!goog.dom.TagName} tagName + * @param {(!Document|!Element)=} opt_parent Parent element or document where to + * look for elements. Defaults to document. + * @return {!NodeList} List of elements. The members of the list are + * {!Element} if tagName is not a member of goog.dom.TagName or more + * specific types if it is (e.g. {!HTMLAnchorElement} for + * goog.dom.TagName.A). + * @template T + * @template R := cond(isUnknown(T), 'Element', T) =: + */ +goog.dom.getElementsByTagName = function(tagName, opt_parent) { + var parent = opt_parent || document; + return parent.getElementsByTagName(String(tagName)); +}; + + /** * Looks up elements by both tag and class name, using browser native functions * ({@code querySelectorAll}, {@code getElementsByTagName} or @@ -189,11 +207,16 @@ goog.dom.$ = goog.dom.getElement; * * @see {goog.dom.query} * - * @param {?string=} opt_tag Element tag name. + * @param {(string|?goog.dom.TagName)=} opt_tag Element tag name. * @param {?string=} opt_class Optional class name. * @param {(Document|Element)=} opt_el Optional element to look in. - * @return {!IArrayLike} Array-like list of elements (only a length - * property and numerical indices are guaranteed to exist). + * @return {!IArrayLike} Array-like list of elements (only a length property + * and numerical indices are guaranteed to exist). The members of the array + * are {!Element} if opt_tag is not a member of goog.dom.TagName or more + * specific types if it is (e.g. {!HTMLAnchorElement} for + * goog.dom.TagName.A). + * @template T + * @template R := cond(isUnknown(T), 'Element', T) =: */ goog.dom.getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) { return goog.dom.getElementsByTagNameAndClass_( @@ -201,6 +224,24 @@ goog.dom.getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) { }; +/** + * Gets the first element matching the tag and the class. + * + * @param {(string|?goog.dom.TagName)=} opt_tag Element tag name. + * @param {?string=} opt_class Optional class name. + * @param {(Document|Element)=} opt_el Optional element to look in. + * @return {?R} Reference to a DOM node. The return type is {?Element} if + * tagName is a string or a more specific type if it is a member of + * goog.dom.TagName (e.g. {?HTMLAnchorElement} for goog.dom.TagName.A). + * @template T + * @template R := cond(isUnknown(T), 'Element', T) =: + */ +goog.dom.getElementByTagNameAndClass = function(opt_tag, opt_class, opt_el) { + return goog.dom.getElementByTagNameAndClass_( + document, opt_tag, opt_class, opt_el); +}; + + /** * Returns a static, array-like list of the elements with the provided * className. @@ -231,11 +272,9 @@ goog.dom.getElementByClass = function(className, opt_el) { var retVal = null; if (parent.getElementsByClassName) { retVal = parent.getElementsByClassName(className)[0]; - } else if (goog.dom.canUseQuerySelector_(parent)) { - retVal = parent.querySelector('.' + className); } else { - retVal = goog.dom.getElementsByTagNameAndClass_( - document, '*', className, opt_el)[0]; + retVal = + goog.dom.getElementByTagNameAndClass_(document, '*', className, opt_el); } return retVal || null; }; @@ -273,17 +312,23 @@ goog.dom.canUseQuerySelector_ = function(parent) { /** * Helper for {@code getElementsByTagNameAndClass}. * @param {!Document} doc The document to get the elements in. - * @param {?string=} opt_tag Element tag name. + * @param {(string|?goog.dom.TagName)=} opt_tag Element tag name. * @param {?string=} opt_class Optional class name. * @param {(Document|Element)=} opt_el Optional element to look in. - * @return {!IArrayLike} Array-like list of elements (only a length - * property and numerical indices are guaranteed to exist). + * @return {!IArrayLike} Array-like list of elements (only a length property + * and numerical indices are guaranteed to exist). The members of the array + * are {!Element} if opt_tag is not a member of goog.dom.TagName or more + * specific types if it is (e.g. {!HTMLAnchorElement} for + * goog.dom.TagName.A). + * @template T + * @template R := cond(isUnknown(T), 'Element', T) =: * @private */ goog.dom.getElementsByTagNameAndClass_ = function( doc, opt_tag, opt_class, opt_el) { var parent = opt_el || doc; - var tagName = (opt_tag && opt_tag != '*') ? opt_tag.toUpperCase() : ''; + var tagName = + (opt_tag && opt_tag != '*') ? String(opt_tag).toUpperCase() : ''; if (goog.dom.canUseQuerySelector_(parent) && (tagName || opt_class)) { var query = tagName + (opt_class ? '.' + opt_class : ''); @@ -335,25 +380,81 @@ goog.dom.getElementsByTagNameAndClass_ = function( }; +/** + * Helper for goog.dom.getElementByTagNameAndClass. + * + * @param {!Document} doc The document to get the elements in. + * @param {(string|?goog.dom.TagName)=} opt_tag Element tag name. + * @param {?string=} opt_class Optional class name. + * @param {(Document|Element)=} opt_el Optional element to look in. + * @return {?R} Reference to a DOM node. The return type is {?Element} if + * tagName is a string or a more specific type if it is a member of + * goog.dom.TagName (e.g. {?HTMLAnchorElement} for goog.dom.TagName.A). + * @template T + * @template R := cond(isUnknown(T), 'Element', T) =: + * @private + */ +goog.dom.getElementByTagNameAndClass_ = function( + doc, opt_tag, opt_class, opt_el) { + var parent = opt_el || doc; + var tag = (opt_tag && opt_tag != '*') ? String(opt_tag).toUpperCase() : ''; + if (goog.dom.canUseQuerySelector_(parent) && (tag || opt_class)) { + return parent.querySelector(tag + (opt_class ? '.' + opt_class : '')); + } + var elements = + goog.dom.getElementsByTagNameAndClass_(doc, opt_tag, opt_class, opt_el); + return elements[0] || null; +}; + + + /** * Alias for {@code getElementsByTagNameAndClass}. - * @param {?string=} opt_tag Element tag name. + * @param {(string|?goog.dom.TagName)=} opt_tag Element tag name. * @param {?string=} opt_class Optional class name. * @param {Element=} opt_el Optional element to look in. - * @return {!IArrayLike} Array-like list of elements (only a length - * property and numerical indices are guaranteed to exist). + * @return {!IArrayLike} Array-like list of elements (only a length property + * and numerical indices are guaranteed to exist). The members of the array + * are {!Element} if opt_tag is not a member of goog.dom.TagName or more + * specific types if it is (e.g. {!HTMLAnchorElement} for + * goog.dom.TagName.A). + * @template T + * @template R := cond(isUnknown(T), 'Element', T) =: * @deprecated Use {@link goog.dom.getElementsByTagNameAndClass} instead. */ goog.dom.$$ = goog.dom.getElementsByTagNameAndClass; /** - * Sets multiple properties on a node. + * Sets multiple properties, and sometimes attributes, on an element. Note that + * properties are simply object properties on the element instance, while + * attributes are visible in the DOM. Many properties map to attributes with the + * same names, some with different names, and there are also unmappable cases. + * + * This method sets properties by default (which means that custom attributes + * are not supported). These are the exeptions (some of which is legacy): + * - "style": Even though this is an attribute name, it is translated to a + * property, "style.cssText". Note that this property sanitizes and formats + * its value, unlike the attribute. + * - "class": This is an attribute name, it is translated to the "className" + * property. + * - "for": This is an attribute name, it is translated to the "htmlFor" + * property. + * - Entries in {@see goog.dom.DIRECT_ATTRIBUTE_MAP_} are set as attributes, + * this is probably due to browser quirks. + * - "aria-*", "data-*": Always set as attributes, they have no property + * counterparts. + * * @param {Element} element DOM node to set properties on. * @param {Object} properties Hash of property:value pairs. + * Property values can be strings or goog.string.TypedString values (such as + * goog.html.SafeUrl). */ goog.dom.setProperties = function(element, properties) { goog.object.forEach(properties, function(val, key) { + if (val && val.implementsGoogStringTypedString) { + val = val.getTypedStringValue(); + } if (key == 'style') { element.style.cssText = val; } else if (key == 'class') { @@ -674,7 +775,7 @@ goog.dom.getWindow = function(opt_doc) { * @private */ goog.dom.getWindow_ = function(doc) { - return doc.parentWindow || doc.defaultView; + return /** @type {!Window} */ (doc.parentWindow || doc.defaultView); }; @@ -684,18 +785,26 @@ goog.dom.getWindow_ = function(doc) { * first node as childNodes. * * So: - * createDom('div', null, createDom('p'), createDom('p')); - * would return a div with two child paragraphs + * createDom(goog.dom.TagName.DIV, null, createDom(goog.dom.TagName.P), + * createDom(goog.dom.TagName.P)); would return a div with two child + * paragraphs * - * @param {string} tagName Tag to create. - * @param {(Object|Array|string)=} opt_attributes If object, then a map + * For passing properties, please see {@link goog.dom.setProperties} for more + * information. + * + * @param {string|!goog.dom.TagName} tagName Tag to create. + * @param {?Object|?Array|string=} opt_attributes If object, then a map * of name-value pairs for attributes. If a string, then this is the * className of the new element. If an array, the elements will be joined * together as the className of the new element. * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or * strings for text nodes. If one of the var_args is an array or NodeList, * its elements will be added as childNodes instead. - * @return {!Element} Reference to a DOM node. + * @return {R} Reference to a DOM node. The return type is {!Element} if tagName + * is a string or a more specific type if it is a member of + * goog.dom.TagName (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A). + * @template T + * @template R := cond(isUnknown(T), 'Element', T) =: */ goog.dom.createDom = function(tagName, opt_attributes, var_args) { return goog.dom.createDom_(document, arguments); @@ -711,7 +820,7 @@ goog.dom.createDom = function(tagName, opt_attributes, var_args) { * @private */ goog.dom.createDom_ = function(doc, args) { - var tagName = args[0]; + var tagName = String(args[0]); var attributes = args[1]; // Internet Explorer is dumb: @@ -797,14 +906,19 @@ goog.dom.append_ = function(doc, parent, args, startIndex) { /** * Alias for {@code createDom}. - * @param {string} tagName Tag to create. - * @param {(string|Object)=} opt_attributes If object, then a map of name-value - * pairs for attributes. If a string, then this is the className of the new - * element. + * @param {string|!goog.dom.TagName} tagName Tag to create. + * @param {?Object|?Array|string=} opt_attributes If object, then a map + * of name-value pairs for attributes. If a string, then this is the + * className of the new element. If an array, the elements will be joined + * together as the className of the new element. * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or * strings for text nodes. If one of the var_args is an array, its * children will be added as childNodes instead. - * @return {!Element} Reference to a DOM node. + * @return {R} Reference to a DOM node. The return type is {!Element} if tagName + * is a string or a more specific type if it is a member of + * goog.dom.TagName (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A). + * @template T + * @template R := cond(isUnknown(T), 'Element', T) =: * @deprecated Use {@link goog.dom.createDom} instead. */ goog.dom.$dom = goog.dom.createDom; @@ -812,11 +926,31 @@ goog.dom.$dom = goog.dom.createDom; /** * Creates a new element. - * @param {string} name Tag name. - * @return {!Element} The new element. + * @param {string|!goog.dom.TagName} name Tag to create. + * @return {R} The new element. The return type is {!Element} if name is + * a string or a more specific type if it is a member of goog.dom.TagName + * (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A). + * @template T + * @template R := cond(isUnknown(T), 'Element', T) =: */ goog.dom.createElement = function(name) { - return document.createElement(name); + return goog.dom.createElement_(document, name); +}; + + +/** + * Creates a new element. + * @param {!Document} doc The document to create the element in. + * @param {string|!goog.dom.TagName} name Tag to create. + * @return {R} The new element. The return type is {!Element} if name is + * a string or a more specific type if it is a member of goog.dom.TagName + * (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A). + * @template T + * @template R := cond(isUnknown(T), 'Element', T) =: + * @private + */ +goog.dom.createElement_ = function(doc, name) { + return doc.createElement(String(name)); }; @@ -839,7 +973,7 @@ goog.dom.createTextNode = function(content) { * @return {!Element} The created table. */ goog.dom.createTable = function(rows, columns, opt_fillWithNbsp) { - // TODO(user): Return HTMLTableElement, also in prototype function. + // TODO(mlourenco): Return HTMLTableElement, also in prototype function. // Callers need to be updated to e.g. not assign numbers to table.cellSpacing. return goog.dom.createTable_(document, rows, columns, !!opt_fillWithNbsp); }; @@ -856,13 +990,13 @@ goog.dom.createTable = function(rows, columns, opt_fillWithNbsp) { * @private */ goog.dom.createTable_ = function(doc, rows, columns, fillWithNbsp) { - var table = /** @type {!HTMLTableElement} */ - (doc.createElement(goog.dom.TagName.TABLE)); - var tbody = table.appendChild(doc.createElement(goog.dom.TagName.TBODY)); + var table = goog.dom.createElement_(doc, goog.dom.TagName.TABLE); + var tbody = + table.appendChild(goog.dom.createElement_(doc, goog.dom.TagName.TBODY)); for (var i = 0; i < rows; i++) { - var tr = doc.createElement(goog.dom.TagName.TR); + var tr = goog.dom.createElement_(doc, goog.dom.TagName.TR); for (var j = 0; j < columns; j++) { - var td = doc.createElement(goog.dom.TagName.TD); + var td = goog.dom.createElement_(doc, goog.dom.TagName.TD); // IE <= 9 will create a text node if we set text content to the empty // string, so we avoid doing it unless necessary. This ensures that the // same DOM tree is returned on all browsers. @@ -916,7 +1050,7 @@ goog.dom.safeHtmlToNode = function(html) { * @private */ goog.dom.safeHtmlToNode_ = function(doc, html) { - var tempDiv = doc.createElement(goog.dom.TagName.DIV); + var tempDiv = goog.dom.createElement_(doc, goog.dom.TagName.DIV); if (goog.dom.BrowserFeature.INNER_HTML_NEEDS_SCOPED_ELEMENT) { goog.dom.safe.setInnerHtml( tempDiv, goog.html.SafeHtml.concat(goog.html.SafeHtml.BR, html)); @@ -986,7 +1120,7 @@ goog.dom.isCss1CompatMode_ = function(doc) { * the behavior is inconsistent: * *
- *   var a = document.createElement(goog.dom.TagName.BR);
+ *   var a = goog.dom.createElement(goog.dom.TagName.BR);
  *   a.appendChild(document.createTextNode('foo'));
  *   a.appendChild(document.createTextNode('bar'));
  *   console.log(a.childNodes.length);  // 2
@@ -1006,31 +1140,31 @@ goog.dom.canHaveChildren = function(node) {
     return false;
   }
   switch (/** @type {!Element} */ (node).tagName) {
-    case goog.dom.TagName.APPLET:
-    case goog.dom.TagName.AREA:
-    case goog.dom.TagName.BASE:
-    case goog.dom.TagName.BR:
-    case goog.dom.TagName.COL:
-    case goog.dom.TagName.COMMAND:
-    case goog.dom.TagName.EMBED:
-    case goog.dom.TagName.FRAME:
-    case goog.dom.TagName.HR:
-    case goog.dom.TagName.IMG:
-    case goog.dom.TagName.INPUT:
-    case goog.dom.TagName.IFRAME:
-    case goog.dom.TagName.ISINDEX:
-    case goog.dom.TagName.KEYGEN:
-    case goog.dom.TagName.LINK:
-    case goog.dom.TagName.NOFRAMES:
-    case goog.dom.TagName.NOSCRIPT:
-    case goog.dom.TagName.META:
-    case goog.dom.TagName.OBJECT:
-    case goog.dom.TagName.PARAM:
-    case goog.dom.TagName.SCRIPT:
-    case goog.dom.TagName.SOURCE:
-    case goog.dom.TagName.STYLE:
-    case goog.dom.TagName.TRACK:
-    case goog.dom.TagName.WBR:
+    case String(goog.dom.TagName.APPLET):
+    case String(goog.dom.TagName.AREA):
+    case String(goog.dom.TagName.BASE):
+    case String(goog.dom.TagName.BR):
+    case String(goog.dom.TagName.COL):
+    case String(goog.dom.TagName.COMMAND):
+    case String(goog.dom.TagName.EMBED):
+    case String(goog.dom.TagName.FRAME):
+    case String(goog.dom.TagName.HR):
+    case String(goog.dom.TagName.IMG):
+    case String(goog.dom.TagName.INPUT):
+    case String(goog.dom.TagName.IFRAME):
+    case String(goog.dom.TagName.ISINDEX):
+    case String(goog.dom.TagName.KEYGEN):
+    case String(goog.dom.TagName.LINK):
+    case String(goog.dom.TagName.NOFRAMES):
+    case String(goog.dom.TagName.NOSCRIPT):
+    case String(goog.dom.TagName.META):
+    case String(goog.dom.TagName.OBJECT):
+    case String(goog.dom.TagName.PARAM):
+    case String(goog.dom.TagName.SCRIPT):
+    case String(goog.dom.TagName.SOURCE):
+    case String(goog.dom.TagName.STYLE):
+    case String(goog.dom.TagName.TRACK):
+    case String(goog.dom.TagName.WBR):
       return false;
   }
   return true;
@@ -1363,8 +1497,8 @@ goog.dom.getParentElement = function(element) {
 
 /**
  * Whether a node contains another node.
- * @param {?Node} parent The node that should contain the other node.
- * @param {?Node} descendant The node to test presence of.
+ * @param {?Node|undefined} parent The node that should contain the other node.
+ * @param {?Node|undefined} descendant The node to test presence of.
  * @return {boolean} Whether the parent node contains the descendent node.
  */
 goog.dom.contains = function(parent, descendant) {
@@ -1623,7 +1757,7 @@ goog.dom.setTextContent = function(node, text) {
   if ('textContent' in node) {
     node.textContent = text;
   } else if (node.nodeType == goog.dom.NodeType.TEXT) {
-    node.data = text;
+    /** @type {!Text} */ (node).data = String(text);
   } else if (
       node.firstChild && node.firstChild.nodeType == goog.dom.NodeType.TEXT) {
     // If the first child is a text node we just change its data and remove the
@@ -1631,7 +1765,7 @@ goog.dom.setTextContent = function(node, text) {
     while (node.lastChild != node.firstChild) {
       node.removeChild(node.lastChild);
     }
-    node.firstChild.data = text;
+    /** @type {!Text} */ (node.firstChild).data = String(text);
   } else {
     goog.dom.removeChildren(node);
     var doc = goog.dom.getOwnerDocument(node);
@@ -1655,7 +1789,7 @@ goog.dom.getOuterHtml = function(element) {
     return element.outerHTML;
   } else {
     var doc = goog.dom.getOwnerDocument(element);
-    var div = doc.createElement(goog.dom.TagName.DIV);
+    var div = goog.dom.createElement_(doc, goog.dom.TagName.DIV);
     div.appendChild(element.cloneNode(true));
     return div.innerHTML;
   }
@@ -1828,11 +1962,14 @@ goog.dom.isFocusable = function(element) {
  * @private
  */
 goog.dom.hasSpecifiedTabIndex_ = function(element) {
-  // IE returns 0 for an unset tabIndex, so we must use getAttributeNode(),
-  // which returns an object with a 'specified' property if tabIndex is
-  // specified.  This works on other browsers, too.
-  var attrNode = element.getAttributeNode('tabindex');  // Must be lowercase!
-  return goog.isDefAndNotNull(attrNode) && attrNode.specified;
+  // IE8 and below don't support hasAttribute(), instead check whether the
+  // 'tabindex' attributeNode is specified. Otherwise check hasAttribute().
+  if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9')) {
+    var attrNode = element.getAttributeNode('tabindex');  // Must be lowercase!
+    return goog.isDefAndNotNull(attrNode) && attrNode.specified;
+  } else {
+    return element.hasAttribute('tabindex');
+  }
 };
 
 
@@ -2085,21 +2222,25 @@ goog.dom.isNodeList = function(val) {
  * tag name and/or class name. If the passed element matches the specified
  * criteria, the element itself is returned.
  * @param {Node} element The DOM node to start with.
- * @param {?(goog.dom.TagName|string)=} opt_tag The tag name to match (or
+ * @param {?(goog.dom.TagName|string)=} opt_tag The tag name to match (or
  *     null/undefined to match only based on class name).
  * @param {?string=} opt_class The class name to match (or null/undefined to
  *     match only based on tag name).
  * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the
  *     dom.
- * @return {Element} The first ancestor that matches the passed criteria, or
- *     null if no match is found.
+ * @return {?R} The first ancestor that matches the passed criteria, or
+ *     null if no match is found. The return type is {?Element} if opt_tag is
+ *     not a member of goog.dom.TagName or a more specific type if it is (e.g.
+ *     {?HTMLAnchorElement} for goog.dom.TagName.A).
+ * @template T
+ * @template R := cond(isUnknown(T), 'Element', T) =:
  */
 goog.dom.getAncestorByTagNameAndClass = function(
     element, opt_tag, opt_class, opt_maxSearchSteps) {
   if (!opt_tag && !opt_class) {
     return null;
   }
-  var tagName = opt_tag ? opt_tag.toUpperCase() : null;
+  var tagName = opt_tag ? String(opt_tag).toUpperCase() : null;
   return /** @type {Element} */ (goog.dom.getAncestor(element, function(node) {
     return (!tagName || node.nodeName == tagName) &&
         (!opt_class ||
@@ -2142,7 +2283,7 @@ goog.dom.getAncestorByClass = function(element, className, opt_maxSearchSteps) {
  */
 goog.dom.getAncestor = function(
     element, matcher, opt_includeNode, opt_maxSearchSteps) {
-  if (!opt_includeNode) {
+  if (element && !opt_includeNode) {
     element = element.parentNode;
   }
   var steps = 0;
@@ -2201,9 +2342,11 @@ goog.dom.getPixelRatio = function() {
   if (goog.isDef(win.devicePixelRatio)) {
     return win.devicePixelRatio;
   } else if (win.matchMedia) {
-    return goog.dom.matchesPixelRatio_(.75) ||
-        goog.dom.matchesPixelRatio_(1.5) || goog.dom.matchesPixelRatio_(2) ||
-        goog.dom.matchesPixelRatio_(3) || 1;
+    // Should be for IE10 and FF6-17 (this basically clamps to lower)
+    // Note that the order of these statements is important
+    return goog.dom.matchesPixelRatio_(3) || goog.dom.matchesPixelRatio_(2) ||
+           goog.dom.matchesPixelRatio_(1.5) || goog.dom.matchesPixelRatio_(1) ||
+           .75;
   }
   return 1;
 };
@@ -2218,14 +2361,35 @@ goog.dom.getPixelRatio = function() {
  */
 goog.dom.matchesPixelRatio_ = function(pixelRatio) {
   var win = goog.dom.getWindow();
+  /**
+   * Due to the 1:96 fixed ratio of CSS in to CSS px, 1dppx is equivalent to
+   * 96dpi.
+   * @const {number}
+   */
+  var dpiPerDppx = 96;
   var query =
-      ('(-webkit-min-device-pixel-ratio: ' + pixelRatio + '),' +
-       '(min--moz-device-pixel-ratio: ' + pixelRatio + '),' +
-       '(min-resolution: ' + pixelRatio + 'dppx)');
+      // FF16-17
+      '(min-resolution: ' + pixelRatio + 'dppx),' +
+      // FF6-15
+      '(min--moz-device-pixel-ratio: ' + pixelRatio + '),' +
+      // IE10 (this works for the two browsers above too but I don't want to
+      // trust the 1:96 fixed ratio magic)
+      '(min-resolution: ' + (pixelRatio * dpiPerDppx) + 'dpi)';
   return win.matchMedia(query).matches ? pixelRatio : 0;
 };
 
 
+/**
+ * Gets '2d' context of a canvas. Shortcut for canvas.getContext('2d') with a
+ * type information.
+ * @param {!HTMLCanvasElement} canvas
+ * @return {!CanvasRenderingContext2D}
+ */
+goog.dom.getCanvasContext2D = function(canvas) {
+  return /** @type {!CanvasRenderingContext2D} */ (canvas.getContext('2d'));
+};
+
+
 
 /**
  * Create an instance of a DOM helper with a new document object.
@@ -2303,6 +2467,25 @@ goog.dom.DomHelper.prototype.getRequiredElement = function(id) {
 goog.dom.DomHelper.prototype.$ = goog.dom.DomHelper.prototype.getElement;
 
 
+/**
+ * Gets elements by tag name.
+ * @param {!goog.dom.TagName} tagName
+ * @param {(!Document|!Element)=} opt_parent Parent element or document where to
+ *     look for elements. Defaults to document of this DomHelper.
+ * @return {!NodeList} List of elements. The members of the list are
+ *     {!Element} if tagName is not a member of goog.dom.TagName or more
+ *     specific types if it is (e.g. {!HTMLAnchorElement} for
+ *     goog.dom.TagName.A).
+ * @template T
+ * @template R := cond(isUnknown(T), 'Element', T) =:
+ */
+goog.dom.DomHelper.prototype.getElementsByTagName =
+    function(tagName, opt_parent) {
+  var parent = opt_parent || this.document_;
+  return parent.getElementsByTagName(String(tagName));
+};
+
+
 /**
  * Looks up elements by both tag and class name, using browser native functions
  * ({@code querySelectorAll}, {@code getElementsByTagName} or
@@ -2311,11 +2494,17 @@ goog.dom.DomHelper.prototype.$ = goog.dom.DomHelper.prototype.getElement;
  *
  * @see goog.dom.query
  *
- * @param {?string=} opt_tag Element tag name or * for all tags.
+ * @param {(string|?goog.dom.TagName)=} opt_tag Element tag name or * for all
+ *     tags.
  * @param {?string=} opt_class Optional class name.
  * @param {(Document|Element)=} opt_el Optional element to look in.
- * @return {!IArrayLike} Array-like list of elements (only a length
- *     property and numerical indices are guaranteed to exist).
+ * @return {!IArrayLike} Array-like list of elements (only a length property
+ *     and numerical indices are guaranteed to exist). The members of the array
+ *     are {!Element} if opt_tag is not a member of goog.dom.TagName or more
+ *     specific types if it is (e.g. {!HTMLAnchorElement} for
+ *     goog.dom.TagName.A).
+ * @template T
+ * @template R := cond(isUnknown(T), 'Element', T) =:
  */
 goog.dom.DomHelper.prototype.getElementsByTagNameAndClass = function(
     opt_tag, opt_class, opt_el) {
@@ -2324,6 +2513,25 @@ goog.dom.DomHelper.prototype.getElementsByTagNameAndClass = function(
 };
 
 
+/**
+ * Gets the first element matching the tag and the class.
+ *
+ * @param {(string|?goog.dom.TagName)=} opt_tag Element tag name.
+ * @param {?string=} opt_class Optional class name.
+ * @param {(Document|Element)=} opt_el Optional element to look in.
+ * @return {?R} Reference to a DOM node. The return type is {?Element} if
+ *     tagName is a string or a more specific type if it is a member of
+ *     goog.dom.TagName (e.g. {?HTMLAnchorElement} for goog.dom.TagName.A).
+ * @template T
+ * @template R := cond(isUnknown(T), 'Element', T) =:
+ */
+goog.dom.DomHelper.prototype.getElementByTagNameAndClass = function(
+    opt_tag, opt_class, opt_el) {
+  return goog.dom.getElementByTagNameAndClass_(
+      this.document_, opt_tag, opt_class, opt_el);
+};
+
+
 /**
  * Returns an array of all the elements with the provided className.
  * @see {goog.dom.query}
@@ -2372,11 +2580,16 @@ goog.dom.DomHelper.prototype.getRequiredElementByClass = function(
  * @deprecated Use DomHelper getElementsByTagNameAndClass.
  * @see goog.dom.query
  *
- * @param {?string=} opt_tag Element tag name.
+ * @param {(string|?goog.dom.TagName)=} opt_tag Element tag name.
  * @param {?string=} opt_class Optional class name.
  * @param {Element=} opt_el Optional element to look in.
- * @return {!IArrayLike} Array-like list of elements (only a length
- *     property and numerical indices are guaranteed to exist).
+ * @return {!IArrayLike} Array-like list of elements (only a length property
+ *     and numerical indices are guaranteed to exist). The members of the array
+ *     are {!Element} if opt_tag is a string or more specific types if it is
+ *     a member of goog.dom.TagName (e.g. {!HTMLAnchorElement} for
+ *     goog.dom.TagName.A).
+ * @template T
+ * @template R := cond(isUnknown(T), 'Element', T) =:
  */
 goog.dom.DomHelper.prototype.$$ =
     goog.dom.DomHelper.prototype.getElementsByTagNameAndClass;
@@ -2426,23 +2639,29 @@ goog.dom.Appendable;
  * first node as childNodes.
  *
  * So:
- * createDom('div', null, createDom('p'), createDom('p'));
- * would return a div with two child paragraphs
+ * createDom(goog.dom.TagName.DIV, null, createDom(goog.dom.TagName.P),
+ * createDom(goog.dom.TagName.P)); would return a div with two child
+ * paragraphs
  *
  * An easy way to move all child nodes of an existing element to a new parent
  * element is:
- * createDom('div', null, oldElement.childNodes);
+ * createDom(goog.dom.TagName.DIV, null, oldElement.childNodes);
  * which will remove all child nodes from the old element and add them as
  * child nodes of the new DIV.
  *
- * @param {string} tagName Tag to create.
- * @param {Object|string=} opt_attributes If object, then a map of name-value
- *     pairs for attributes. If a string, then this is the className of the new
- *     element.
+ * @param {string|!goog.dom.TagName} tagName Tag to create.
+ * @param {?Object|?Array|string=} opt_attributes If object, then a map
+ *     of name-value pairs for attributes. If a string, then this is the
+ *     className of the new element. If an array, the elements will be joined
+ *     together as the className of the new element.
  * @param {...goog.dom.Appendable} var_args Further DOM nodes or
  *     strings for text nodes. If one of the var_args is an array or
  *     NodeList, its elements will be added as childNodes instead.
- * @return {!Element} Reference to a DOM node.
+ * @return {R} Reference to a DOM node. The return type is {!Element} if tagName
+ *     is a string or a more specific type if it is a member of
+ *     goog.dom.TagName (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).
+ * @template T
+ * @template R := cond(isUnknown(T), 'Element', T) =:
  */
 goog.dom.DomHelper.prototype.createDom = function(
     tagName, opt_attributes, var_args) {
@@ -2452,14 +2671,19 @@ goog.dom.DomHelper.prototype.createDom = function(
 
 /**
  * Alias for {@code createDom}.
- * @param {string} tagName Tag to create.
- * @param {(Object|string)=} opt_attributes If object, then a map of name-value
- *     pairs for attributes. If a string, then this is the className of the new
- *     element.
+ * @param {string|!goog.dom.TagName} tagName Tag to create.
+ * @param {?Object|?Array|string=} opt_attributes If object, then a map
+ *     of name-value pairs for attributes. If a string, then this is the
+ *     className of the new element. If an array, the elements will be joined
+ *     together as the className of the new element.
  * @param {...goog.dom.Appendable} var_args Further DOM nodes or strings for
  *     text nodes.  If one of the var_args is an array, its children will be
  *     added as childNodes instead.
- * @return {!Element} Reference to a DOM node.
+ * @return {R} Reference to a DOM node. The return type is {!Element} if tagName
+ *     is a string or a more specific type if it is a member of
+ *     goog.dom.TagName (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).
+ * @template T
+ * @template R := cond(isUnknown(T), 'Element', T) =:
  * @deprecated Use {@link goog.dom.DomHelper.prototype.createDom} instead.
  */
 goog.dom.DomHelper.prototype.$dom = goog.dom.DomHelper.prototype.createDom;
@@ -2467,11 +2691,15 @@ goog.dom.DomHelper.prototype.$dom = goog.dom.DomHelper.prototype.createDom;
 
 /**
  * Creates a new element.
- * @param {string} name Tag name.
- * @return {!Element} The new element.
+ * @param {string|!goog.dom.TagName} name Tag to create.
+ * @return {R} The new element. The return type is {!Element} if name is
+ *     a string or a more specific type if it is a member of goog.dom.TagName
+ *     (e.g. {!HTMLAnchorElement} for goog.dom.TagName.A).
+ * @template T
+ * @template R := cond(isUnknown(T), 'Element', T) =:
  */
 goog.dom.DomHelper.prototype.createElement = function(name) {
-  return this.document_.createElement(name);
+  return goog.dom.createElement_(this.document_, name);
 };
 
 
@@ -2948,14 +3176,18 @@ goog.dom.DomHelper.prototype.isNodeList = goog.dom.isNodeList;
  * tag name and/or class name. If the passed element matches the specified
  * criteria, the element itself is returned.
  * @param {Node} element The DOM node to start with.
- * @param {?(goog.dom.TagName|string)=} opt_tag The tag name to match (or
+ * @param {?(goog.dom.TagName|string)=} opt_tag The tag name to match (or
  *     null/undefined to match only based on class name).
  * @param {?string=} opt_class The class name to match (or null/undefined to
  *     match only based on tag name).
  * @param {number=} opt_maxSearchSteps Maximum number of levels to search up the
  *     dom.
- * @return {Element} The first ancestor that matches the passed criteria, or
- *     null if no match is found.
+ * @return {?R} The first ancestor that matches the passed criteria, or
+ *     null if no match is found. The return type is {?Element} if opt_tag is
+ *     not a member of goog.dom.TagName or a more specific type if it is (e.g.
+ *     {?HTMLAnchorElement} for goog.dom.TagName.A).
+ * @template T
+ * @template R := cond(isUnknown(T), 'Element', T) =:
  */
 goog.dom.DomHelper.prototype.getAncestorByTagNameAndClass =
     goog.dom.getAncestorByTagNameAndClass;
@@ -2990,3 +3222,12 @@ goog.dom.DomHelper.prototype.getAncestorByClass = goog.dom.getAncestorByClass;
  *     no match.
  */
 goog.dom.DomHelper.prototype.getAncestor = goog.dom.getAncestor;
+
+
+/**
+ * Gets '2d' context of a canvas. Shortcut for canvas.getContext('2d') with a
+ * type information.
+ * @param {!HTMLCanvasElement} canvas
+ * @return {!CanvasRenderingContext2D}
+ */
+goog.dom.DomHelper.prototype.getCanvasContext2D = goog.dom.getCanvasContext2D;
diff --git a/assets/viz/2/goog/dom/htmlelement.js b/assets/viz/2/goog/dom/htmlelement.js
new file mode 100644
index 0000000..c48f753
--- /dev/null
+++ b/assets/viz/2/goog/dom/htmlelement.js
@@ -0,0 +1,29 @@
+// Copyright 2017 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+goog.provide('goog.dom.HtmlElement');
+
+
+
+/**
+ * This subclass of HTMLElement is used when only a HTMLElement is possible and
+ * not any of its subclasses. Normally, a type can refer to an instance of
+ * itself or an instance of any subtype. More concretely, if HTMLElement is used
+ * then the compiler must assume that it might still be e.g. HTMLScriptElement.
+ * With this, the type check knows that it couldn't be any special element.
+ *
+ * @constructor
+ * @extends {HTMLElement}
+ */
+goog.dom.HtmlElement = function() {};
diff --git a/assets/viz/2/goog/dom/safe.js b/assets/viz/2/goog/dom/safe.js
index 012ad22..b9390a0 100644
--- a/assets/viz/2/goog/dom/safe.js
+++ b/assets/viz/2/goog/dom/safe.js
@@ -29,19 +29,22 @@
  *
  * For example, assigning to an element's .innerHTML property a string that is
  * derived (even partially) from untrusted input typically results in an XSS
- * vulnerability. The type-safe wrapper goog.html.setInnerHtml consumes a value
- * of type goog.html.SafeHtml, whose contract states that using its values in a
- * HTML context will not result in XSS. Hence a program that is free of direct
- * assignments to any element's innerHTML property (with the exception of the
- * assignment to .innerHTML in this file) is guaranteed to be free of XSS due to
- * assignment of untrusted strings to the innerHTML property.
+ * vulnerability. The type-safe wrapper goog.dom.safe.setInnerHtml consumes a
+ * value of type goog.html.SafeHtml, whose contract states that using its values
+ * in a HTML context will not result in XSS. Hence a program that is free of
+ * direct assignments to any element's innerHTML property (with the exception of
+ * the assignment to .innerHTML in this file) is guaranteed to be free of XSS
+ * due to assignment of untrusted strings to the innerHTML property.
  */
 
 goog.provide('goog.dom.safe');
 goog.provide('goog.dom.safe.InsertAdjacentHtmlPosition');
 
 goog.require('goog.asserts');
+goog.require('goog.dom.asserts');
 goog.require('goog.html.SafeHtml');
+goog.require('goog.html.SafeScript');
+goog.require('goog.html.SafeStyle');
 goog.require('goog.html.SafeUrl');
 goog.require('goog.html.TrustedResourceUrl');
 goog.require('goog.string');
@@ -69,12 +72,35 @@ goog.dom.safe.insertAdjacentHtml = function(node, position, html) {
 };
 
 
+/**
+ * Tags not allowed in goog.dom.safe.setInnerHtml.
+ * @private @const {!Object}
+ */
+goog.dom.safe.SET_INNER_HTML_DISALLOWED_TAGS_ = {
+  'MATH': true,
+  'SCRIPT': true,
+  'STYLE': true,
+  'SVG': true,
+  'TEMPLATE': true
+};
+
+
 /**
  * Assigns known-safe HTML to an element's innerHTML property.
  * @param {!Element} elem The element whose innerHTML is to be assigned to.
  * @param {!goog.html.SafeHtml} html The known-safe HTML to assign.
+ * @throws {Error} If called with one of these tags: math, script, style, svg,
+ *     template.
  */
 goog.dom.safe.setInnerHtml = function(elem, html) {
+  if (goog.asserts.ENABLE_ASSERTS) {
+    var tagName = elem.tagName.toUpperCase();
+    if (goog.dom.safe.SET_INNER_HTML_DISALLOWED_TAGS_[tagName]) {
+      throw Error(
+          'goog.dom.safe.setInnerHtml cannot be used to set content of ' +
+          elem.tagName + '.');
+    }
+  }
   elem.innerHTML = goog.html.SafeHtml.unwrap(html);
 };
 
@@ -89,6 +115,17 @@ goog.dom.safe.setOuterHtml = function(elem, html) {
 };
 
 
+/**
+ * Sets the given element's style property to the contents of the provided
+ * SafeStyle object.
+ * @param {!Element} elem
+ * @param {!goog.html.SafeStyle} style
+ */
+goog.dom.safe.setStyle = function(elem, style) {
+  elem.style.cssText = goog.html.SafeStyle.unwrap(style);
+};
+
+
 /**
  * Writes known-safe HTML to a document.
  * @param {!Document} doc The document to be written to.
@@ -119,12 +156,13 @@ goog.dom.safe.documentWrite = function(doc, html) {
  * @see goog.html.SafeUrl#sanitize
  */
 goog.dom.safe.setAnchorHref = function(anchor, url) {
+  goog.dom.asserts.assertIsHTMLAnchorElement(anchor);
   /** @type {!goog.html.SafeUrl} */
   var safeUrl;
   if (url instanceof goog.html.SafeUrl) {
     safeUrl = url;
   } else {
-    safeUrl = goog.html.SafeUrl.sanitize(url);
+    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);
   }
   anchor.href = goog.html.SafeUrl.unwrap(safeUrl);
 };
@@ -143,12 +181,13 @@ goog.dom.safe.setAnchorHref = function(anchor, url) {
  * @see goog.html.SafeUrl#sanitize
  */
 goog.dom.safe.setImageSrc = function(imageElement, url) {
+  goog.dom.asserts.assertIsHTMLImageElement(imageElement);
   /** @type {!goog.html.SafeUrl} */
   var safeUrl;
   if (url instanceof goog.html.SafeUrl) {
     safeUrl = url;
   } else {
-    safeUrl = goog.html.SafeUrl.sanitize(url);
+    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);
   }
   imageElement.src = goog.html.SafeUrl.unwrap(safeUrl);
 };
@@ -169,6 +208,7 @@ goog.dom.safe.setImageSrc = function(imageElement, url) {
  * @param {!goog.html.TrustedResourceUrl} url The URL to assign.
  */
 goog.dom.safe.setEmbedSrc = function(embed, url) {
+  goog.dom.asserts.assertIsHTMLEmbedElement(embed);
   embed.src = goog.html.TrustedResourceUrl.unwrap(url);
 };
 
@@ -188,6 +228,7 @@ goog.dom.safe.setEmbedSrc = function(embed, url) {
  * @param {!goog.html.TrustedResourceUrl} url The URL to assign.
  */
 goog.dom.safe.setFrameSrc = function(frame, url) {
+  goog.dom.asserts.assertIsHTMLFrameElement(frame);
   frame.src = goog.html.TrustedResourceUrl.unwrap(url);
 };
 
@@ -207,10 +248,30 @@ goog.dom.safe.setFrameSrc = function(frame, url) {
  * @param {!goog.html.TrustedResourceUrl} url The URL to assign.
  */
 goog.dom.safe.setIframeSrc = function(iframe, url) {
+  goog.dom.asserts.assertIsHTMLIFrameElement(iframe);
   iframe.src = goog.html.TrustedResourceUrl.unwrap(url);
 };
 
 
+/**
+ * Safely assigns HTML to an iframe element's srcdoc property.
+ *
+ * Example usage:
+ *   goog.dom.safe.setIframeSrcdoc(iframeEl, safeHtml);
+ * which is a safe alternative to
+ *   iframeEl.srcdoc = html;
+ * The latter can result in loading untrusted code.
+ *
+ * @param {!HTMLIFrameElement} iframe The iframe element whose srcdoc property
+ *     is to be assigned to.
+ * @param {!goog.html.SafeHtml} html The HTML to assign.
+ */
+goog.dom.safe.setIframeSrcdoc = function(iframe, html) {
+  goog.dom.asserts.assertIsHTMLIFrameElement(iframe);
+  iframe.srcdoc = goog.html.SafeHtml.unwrap(html);
+};
+
+
 /**
  * Safely sets a link element's href and rel properties. Whether or not
  * the URL assigned to href has to be a goog.html.TrustedResourceUrl
@@ -237,6 +298,7 @@ goog.dom.safe.setIframeSrc = function(iframe, url) {
  * @see goog.html.SafeUrl#sanitize
  */
 goog.dom.safe.setLinkHrefAndRel = function(link, url, rel) {
+  goog.dom.asserts.assertIsHTMLLinkElement(link);
   link.rel = rel;
   if (goog.string.caseInsensitiveContains(rel, 'stylesheet')) {
     goog.asserts.assert(
@@ -249,7 +311,8 @@ goog.dom.safe.setLinkHrefAndRel = function(link, url, rel) {
     link.href = goog.html.SafeUrl.unwrap(url);
   } else {  // string
     // SafeUrl.sanitize must return legitimate SafeUrl when passed a string.
-    link.href = goog.html.SafeUrl.sanitize(url).getTypedStringValue();
+    link.href =
+        goog.html.SafeUrl.sanitizeAssertUnchanged(url).getTypedStringValue();
   }
 };
 
@@ -269,12 +332,13 @@ goog.dom.safe.setLinkHrefAndRel = function(link, url, rel) {
  * @param {!goog.html.TrustedResourceUrl} url The URL to assign.
  */
 goog.dom.safe.setObjectData = function(object, url) {
+  goog.dom.asserts.assertIsHTMLObjectElement(object);
   object.data = goog.html.TrustedResourceUrl.unwrap(url);
 };
 
 
 /**
- * Safely assigns a URL to an iframe element's src property.
+ * Safely assigns a URL to a script element's src property.
  *
  * Example usage:
  *   goog.dom.safe.setScriptSrc(scriptEl, url);
@@ -288,10 +352,31 @@ goog.dom.safe.setObjectData = function(object, url) {
  * @param {!goog.html.TrustedResourceUrl} url The URL to assign.
  */
 goog.dom.safe.setScriptSrc = function(script, url) {
+  goog.dom.asserts.assertIsHTMLScriptElement(script);
   script.src = goog.html.TrustedResourceUrl.unwrap(url);
 };
 
 
+/**
+ * Safely assigns a value to a script element's content.
+ *
+ * Example usage:
+ *   goog.dom.safe.setScriptContent(scriptEl, content);
+ * which is a safe alternative to
+ *   scriptEl.text = content;
+ * The latter can result in executing untrusted code unless it is ensured that
+ * the code is loaded from a trustworthy resource.
+ *
+ * @param {!HTMLScriptElement} script The script element whose content is being
+ *     set.
+ * @param {!goog.html.SafeScript} content The content to assign.
+ */
+goog.dom.safe.setScriptContent = function(script, content) {
+  goog.dom.asserts.assertIsHTMLScriptElement(script);
+  script.text = goog.html.SafeScript.unwrap(content);
+};
+
+
 /**
  * Safely assigns a URL to a Location object's href property.
  *
@@ -312,12 +397,13 @@ goog.dom.safe.setScriptSrc = function(script, url) {
  * @see goog.html.SafeUrl#sanitize
  */
 goog.dom.safe.setLocationHref = function(loc, url) {
+  goog.dom.asserts.assertIsLocation(loc);
   /** @type {!goog.html.SafeUrl} */
   var safeUrl;
   if (url instanceof goog.html.SafeUrl) {
     safeUrl = url;
   } else {
-    safeUrl = goog.html.SafeUrl.sanitize(url);
+    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);
   }
   loc.href = goog.html.SafeUrl.unwrap(safeUrl);
 };
@@ -358,7 +444,7 @@ goog.dom.safe.openInWindow = function(
   if (url instanceof goog.html.SafeUrl) {
     safeUrl = url;
   } else {
-    safeUrl = goog.html.SafeUrl.sanitize(url);
+    safeUrl = goog.html.SafeUrl.sanitizeAssertUnchanged(url);
   }
   var win = opt_openerWin || window;
   return win.open(
diff --git a/assets/viz/2/goog/dom/tagname.js b/assets/viz/2/goog/dom/tagname.js
index ad44d85..b3808ad 100644
--- a/assets/viz/2/goog/dom/tagname.js
+++ b/assets/viz/2/goog/dom/tagname.js
@@ -13,148 +13,550 @@
 // limitations under the License.
 
 /**
- * @fileoverview Defines the goog.dom.TagName enum.  This enumerates
+ * @fileoverview Defines the goog.dom.TagName class. Its constants enumerate
  * all HTML tag names specified in either the the W3C HTML 4.01 index of
  * elements or the HTML5 draft specification.
  *
  * References:
  * http://www.w3.org/TR/html401/index/elements.html
  * http://dev.w3.org/html5/spec/section-index.html
- *
  */
 goog.provide('goog.dom.TagName');
 
+goog.require('goog.dom.HtmlElement');
+
 
 /**
- * Enum of all html tag names specified by the W3C HTML4.01 and HTML5
- * specifications.
- * @enum {string}
+ * A tag name with the type of the element stored in the generic.
+ * @param {string} tagName
+ * @constructor
+ * @template T
  */
-goog.dom.TagName = {
-  A: 'A',
-  ABBR: 'ABBR',
-  ACRONYM: 'ACRONYM',
-  ADDRESS: 'ADDRESS',
-  APPLET: 'APPLET',
-  AREA: 'AREA',
-  ARTICLE: 'ARTICLE',
-  ASIDE: 'ASIDE',
-  AUDIO: 'AUDIO',
-  B: 'B',
-  BASE: 'BASE',
-  BASEFONT: 'BASEFONT',
-  BDI: 'BDI',
-  BDO: 'BDO',
-  BIG: 'BIG',
-  BLOCKQUOTE: 'BLOCKQUOTE',
-  BODY: 'BODY',
-  BR: 'BR',
-  BUTTON: 'BUTTON',
-  CANVAS: 'CANVAS',
-  CAPTION: 'CAPTION',
-  CENTER: 'CENTER',
-  CITE: 'CITE',
-  CODE: 'CODE',
-  COL: 'COL',
-  COLGROUP: 'COLGROUP',
-  COMMAND: 'COMMAND',
-  DATA: 'DATA',
-  DATALIST: 'DATALIST',
-  DD: 'DD',
-  DEL: 'DEL',
-  DETAILS: 'DETAILS',
-  DFN: 'DFN',
-  DIALOG: 'DIALOG',
-  DIR: 'DIR',
-  DIV: 'DIV',
-  DL: 'DL',
-  DT: 'DT',
-  EM: 'EM',
-  EMBED: 'EMBED',
-  FIELDSET: 'FIELDSET',
-  FIGCAPTION: 'FIGCAPTION',
-  FIGURE: 'FIGURE',
-  FONT: 'FONT',
-  FOOTER: 'FOOTER',
-  FORM: 'FORM',
-  FRAME: 'FRAME',
-  FRAMESET: 'FRAMESET',
-  H1: 'H1',
-  H2: 'H2',
-  H3: 'H3',
-  H4: 'H4',
-  H5: 'H5',
-  H6: 'H6',
-  HEAD: 'HEAD',
-  HEADER: 'HEADER',
-  HGROUP: 'HGROUP',
-  HR: 'HR',
-  HTML: 'HTML',
-  I: 'I',
-  IFRAME: 'IFRAME',
-  IMG: 'IMG',
-  INPUT: 'INPUT',
-  INS: 'INS',
-  ISINDEX: 'ISINDEX',
-  KBD: 'KBD',
-  KEYGEN: 'KEYGEN',
-  LABEL: 'LABEL',
-  LEGEND: 'LEGEND',
-  LI: 'LI',
-  LINK: 'LINK',
-  MAP: 'MAP',
-  MARK: 'MARK',
-  MATH: 'MATH',
-  MENU: 'MENU',
-  META: 'META',
-  METER: 'METER',
-  NAV: 'NAV',
-  NOFRAMES: 'NOFRAMES',
-  NOSCRIPT: 'NOSCRIPT',
-  OBJECT: 'OBJECT',
-  OL: 'OL',
-  OPTGROUP: 'OPTGROUP',
-  OPTION: 'OPTION',
-  OUTPUT: 'OUTPUT',
-  P: 'P',
-  PARAM: 'PARAM',
-  PRE: 'PRE',
-  PROGRESS: 'PROGRESS',
-  Q: 'Q',
-  RP: 'RP',
-  RT: 'RT',
-  RUBY: 'RUBY',
-  S: 'S',
-  SAMP: 'SAMP',
-  SCRIPT: 'SCRIPT',
-  SECTION: 'SECTION',
-  SELECT: 'SELECT',
-  SMALL: 'SMALL',
-  SOURCE: 'SOURCE',
-  SPAN: 'SPAN',
-  STRIKE: 'STRIKE',
-  STRONG: 'STRONG',
-  STYLE: 'STYLE',
-  SUB: 'SUB',
-  SUMMARY: 'SUMMARY',
-  SUP: 'SUP',
-  SVG: 'SVG',
-  TABLE: 'TABLE',
-  TBODY: 'TBODY',
-  TD: 'TD',
-  TEMPLATE: 'TEMPLATE',
-  TEXTAREA: 'TEXTAREA',
-  TFOOT: 'TFOOT',
-  TH: 'TH',
-  THEAD: 'THEAD',
-  TIME: 'TIME',
-  TITLE: 'TITLE',
-  TR: 'TR',
-  TRACK: 'TRACK',
-  TT: 'TT',
-  U: 'U',
-  UL: 'UL',
-  VAR: 'VAR',
-  VIDEO: 'VIDEO',
-  WBR: 'WBR'
+goog.dom.TagName = function(tagName) {
+  /** @private {string} */
+  this.tagName_ = tagName;
 };
+
+
+/**
+ * Returns the tag name.
+ * @return {string}
+ * @override
+ */
+goog.dom.TagName.prototype.toString = function() {
+  return this.tagName_;
+};
+
+
+// Closure Compiler unconditionally converts the following constants to their
+// string value (goog.dom.TagName.A -> 'A'). These are the consequences:
+// 1. Don't add any members or static members to goog.dom.TagName as they
+//    couldn't be accessed after this optimization.
+// 2. Keep the constant name and its string value the same:
+//    goog.dom.TagName.X = new goog.dom.TagName('Y');
+//    is converted to 'X', not 'Y'.
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.A = new goog.dom.TagName('A');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.ABBR = new goog.dom.TagName('ABBR');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.ACRONYM = new goog.dom.TagName('ACRONYM');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.ADDRESS = new goog.dom.TagName('ADDRESS');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.APPLET = new goog.dom.TagName('APPLET');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.AREA = new goog.dom.TagName('AREA');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.ARTICLE = new goog.dom.TagName('ARTICLE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.ASIDE = new goog.dom.TagName('ASIDE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.AUDIO = new goog.dom.TagName('AUDIO');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.B = new goog.dom.TagName('B');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.BASE = new goog.dom.TagName('BASE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.BASEFONT = new goog.dom.TagName('BASEFONT');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.BDI = new goog.dom.TagName('BDI');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.BDO = new goog.dom.TagName('BDO');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.BIG = new goog.dom.TagName('BIG');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.BLOCKQUOTE = new goog.dom.TagName('BLOCKQUOTE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.BODY = new goog.dom.TagName('BODY');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.BR = new goog.dom.TagName('BR');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.BUTTON = new goog.dom.TagName('BUTTON');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.CANVAS = new goog.dom.TagName('CANVAS');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.CAPTION = new goog.dom.TagName('CAPTION');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.CENTER = new goog.dom.TagName('CENTER');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.CITE = new goog.dom.TagName('CITE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.CODE = new goog.dom.TagName('CODE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.COL = new goog.dom.TagName('COL');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.COLGROUP = new goog.dom.TagName('COLGROUP');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.COMMAND = new goog.dom.TagName('COMMAND');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.DATA = new goog.dom.TagName('DATA');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.DATALIST = new goog.dom.TagName('DATALIST');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.DD = new goog.dom.TagName('DD');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.DEL = new goog.dom.TagName('DEL');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.DETAILS = new goog.dom.TagName('DETAILS');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.DFN = new goog.dom.TagName('DFN');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.DIALOG = new goog.dom.TagName('DIALOG');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.DIR = new goog.dom.TagName('DIR');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.DIV = new goog.dom.TagName('DIV');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.DL = new goog.dom.TagName('DL');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.DT = new goog.dom.TagName('DT');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.EM = new goog.dom.TagName('EM');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.EMBED = new goog.dom.TagName('EMBED');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.FIELDSET = new goog.dom.TagName('FIELDSET');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.FIGCAPTION = new goog.dom.TagName('FIGCAPTION');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.FIGURE = new goog.dom.TagName('FIGURE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.FONT = new goog.dom.TagName('FONT');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.FOOTER = new goog.dom.TagName('FOOTER');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.FORM = new goog.dom.TagName('FORM');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.FRAME = new goog.dom.TagName('FRAME');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.FRAMESET = new goog.dom.TagName('FRAMESET');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.H1 = new goog.dom.TagName('H1');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.H2 = new goog.dom.TagName('H2');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.H3 = new goog.dom.TagName('H3');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.H4 = new goog.dom.TagName('H4');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.H5 = new goog.dom.TagName('H5');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.H6 = new goog.dom.TagName('H6');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.HEAD = new goog.dom.TagName('HEAD');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.HEADER = new goog.dom.TagName('HEADER');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.HGROUP = new goog.dom.TagName('HGROUP');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.HR = new goog.dom.TagName('HR');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.HTML = new goog.dom.TagName('HTML');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.I = new goog.dom.TagName('I');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.IFRAME = new goog.dom.TagName('IFRAME');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.IMG = new goog.dom.TagName('IMG');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.INPUT = new goog.dom.TagName('INPUT');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.INS = new goog.dom.TagName('INS');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.ISINDEX = new goog.dom.TagName('ISINDEX');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.KBD = new goog.dom.TagName('KBD');
+
+
+// HTMLKeygenElement is deprecated.
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.KEYGEN = new goog.dom.TagName('KEYGEN');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.LABEL = new goog.dom.TagName('LABEL');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.LEGEND = new goog.dom.TagName('LEGEND');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.LI = new goog.dom.TagName('LI');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.LINK = new goog.dom.TagName('LINK');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.MAP = new goog.dom.TagName('MAP');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.MARK = new goog.dom.TagName('MARK');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.MATH = new goog.dom.TagName('MATH');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.MENU = new goog.dom.TagName('MENU');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.META = new goog.dom.TagName('META');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.METER = new goog.dom.TagName('METER');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.NAV = new goog.dom.TagName('NAV');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.NOFRAMES = new goog.dom.TagName('NOFRAMES');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.NOSCRIPT = new goog.dom.TagName('NOSCRIPT');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.OBJECT = new goog.dom.TagName('OBJECT');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.OL = new goog.dom.TagName('OL');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.OPTGROUP = new goog.dom.TagName('OPTGROUP');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.OPTION = new goog.dom.TagName('OPTION');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.OUTPUT = new goog.dom.TagName('OUTPUT');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.P = new goog.dom.TagName('P');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.PARAM = new goog.dom.TagName('PARAM');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.PRE = new goog.dom.TagName('PRE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.PROGRESS = new goog.dom.TagName('PROGRESS');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.Q = new goog.dom.TagName('Q');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.RP = new goog.dom.TagName('RP');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.RT = new goog.dom.TagName('RT');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.RUBY = new goog.dom.TagName('RUBY');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.S = new goog.dom.TagName('S');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.SAMP = new goog.dom.TagName('SAMP');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.SCRIPT = new goog.dom.TagName('SCRIPT');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.SECTION = new goog.dom.TagName('SECTION');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.SELECT = new goog.dom.TagName('SELECT');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.SMALL = new goog.dom.TagName('SMALL');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.SOURCE = new goog.dom.TagName('SOURCE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.SPAN = new goog.dom.TagName('SPAN');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.STRIKE = new goog.dom.TagName('STRIKE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.STRONG = new goog.dom.TagName('STRONG');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.STYLE = new goog.dom.TagName('STYLE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.SUB = new goog.dom.TagName('SUB');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.SUMMARY = new goog.dom.TagName('SUMMARY');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.SUP = new goog.dom.TagName('SUP');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.SVG = new goog.dom.TagName('SVG');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.TABLE = new goog.dom.TagName('TABLE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.TBODY = new goog.dom.TagName('TBODY');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.TD = new goog.dom.TagName('TD');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.TEMPLATE = new goog.dom.TagName('TEMPLATE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.TEXTAREA = new goog.dom.TagName('TEXTAREA');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.TFOOT = new goog.dom.TagName('TFOOT');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.TH = new goog.dom.TagName('TH');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.THEAD = new goog.dom.TagName('THEAD');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.TIME = new goog.dom.TagName('TIME');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.TITLE = new goog.dom.TagName('TITLE');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.TR = new goog.dom.TagName('TR');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.TRACK = new goog.dom.TagName('TRACK');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.TT = new goog.dom.TagName('TT');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.U = new goog.dom.TagName('U');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.UL = new goog.dom.TagName('UL');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.VAR = new goog.dom.TagName('VAR');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.VIDEO = new goog.dom.TagName('VIDEO');
+
+
+/** @type {!goog.dom.TagName} */
+goog.dom.TagName.WBR = new goog.dom.TagName('WBR');
-- 
cgit v1.2.3