UNPKG

@desertnet/html-parser

Version:

HTML parser and non-strict validator

266 lines (210 loc) 15.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NodeError = exports.NodeType = undefined; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _HTMLParseError = require("../HTMLParseError"); var _HTMLParseError2 = _interopRequireDefault(_HTMLParseError); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * HTML node types. * @enum {string} */ var NodeType = exports.NodeType = { ROOT: "ROOT", TAG: "TAG", ATTRIBUTE: "ATTRIBUTE", TEXT: "TEXT", ENTITY: "ENTITY", COMMENT: "COMMENT", CLOSETAG: "CLOSETAG" }; /** * HTML tree nodes base class. Should never be called outside of * subclass constructors! */ var HTMLNode = function () { function HTMLNode() { _classCallCheck(this, HTMLNode); /** * @private * @type {Array.<Foundation.HTML.Parser.HTMLNode>?} */ this._children = null; /** * @private * @type {Array.<Foundation.Scanner.Token>} */ this._sourceTokens = []; /** * @private * @type {Array.<HTMLParseError>?} */ this._errors = null; } /** * Subclasses must override this. * @return {boolean} */ _createClass(HTMLNode, [{ key: "toString", /** * Subclasses must override this. * @return {string} */ value: function toString() { throw new NodeError("toString not overriden in subclass", this); } /** * @return {NodeType} */ }, { key: "addToken", /** * @param {Foundation.Scanner.Token} token */ value: function addToken(token) { this._sourceTokens.push(token); // Create error objects when adding a token of type error. if (token.type === "error") { var error = new _HTMLParseError2.default(); error.message = "Invalid token: \"" + token.value + "\""; error.addToken(token); this.addError(error); } } /** * @return {Array.<Foundation.Scanner.Token>} */ }, { key: "appendChild", /** * @param {Foundation.HTML.Parser.HTMLNode} childNode * @return {Foundation.HTML.Parser.HTMLNode} */ value: function appendChild(childNode) { if (!this.canHaveChildren) { throw new NodeError("attempted to call appendChild on node that can't have children", this); } if (!this._children) { this._children = []; } this._children.push(childNode); return this; } /** * @public * @return {Array.<HTMLParseError>} */ }, { key: "addError", /** * @param {HTMLParseError} error */ value: function addError(error) { if (this._errors === null) { this._errors = []; } this._errors.push(error); } /** * @private * @return {Array.<HTMLParseError>} */ }, { key: "canHaveChildren", get: function get() { throw new NodeError("canHaveChildren not overriden in subclass", this); } }, { key: "type", get: function get() { throw new NodeError("type getter not overriden in subclass", this); } /** * @return {Array.<Foundation.HTML.Parser.HTMLNode>?} */ }, { key: "children", get: function get() { if (this._children === null || this._children.length === 0) { return null; } return this._children.slice(0); } /** * @return {Foundation.HTML.Parser.HTMLNode} */ }, { key: "lastChild", get: function get() { var children = this.children; if (children === null || children.length === 0) { return null; } return children[children.length - 1]; } }, { key: "tokens", get: function get() { return this._sourceTokens.slice(0); } /** * @return {Array.<number>?} */ }, { key: "indexRange", get: function get() { var tokens = this.tokens; if (tokens.length === 0) { return null; } var firstToken = tokens[0]; var lastToken = tokens[tokens.length - 1]; return [firstToken.index, lastToken.index + lastToken.value.length - 1]; } }, { key: "errors", get: function get() { if (this.canHaveChildren && this.children) { return this.children.reduce(function (accumulator, child) { return accumulator.concat(child.errors); }, this.ownErrors); } return this.ownErrors; } }, { key: "ownErrors", get: function get() { return this._errors === null ? [] : this._errors.slice(0); } }]); return HTMLNode; }(); /** * HTML node error class. This is a throwable Error object, not to be * confused with the HTMLParseError class which deals * with reporting errors found in the HTML source. */ exports.default = HTMLNode; var NodeError = exports.NodeError = function (_Error) { _inherits(NodeError, _Error); /** * @param {string} message * @param {Foundation.HTML.Parser.HTMLNode} node */ function NodeError(message, node) { _classCallCheck(this, NodeError); var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(NodeError).call(this, message)); _this.name = "HTMLParserNodeError"; _this.node = node; return _this; } return NodeError; }(Error); ; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9IVE1MTm9kZS9IVE1MTm9kZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTs7Ozs7Ozs7Ozs7O0FBRUE7Ozs7QUFJTyxJQUFNLDhCQUFXO0FBQ3RCLFFBQU0sTUFEZ0I7QUFFdEIsT0FBTSxLQUZnQjtBQUd0QixhQUFXLFdBSFc7QUFJdEIsUUFBTSxNQUpnQjtBQUt0QixVQUFTLFFBTGE7QUFNdEIsV0FBUyxTQU5hO0FBT3RCLFlBQVU7QUFQWSxDQUFqQjs7QUFVUDs7Ozs7SUFJcUIsUTtBQUNuQixzQkFBZTtBQUFBOztBQUNiOzs7O0FBSUEsU0FBSyxTQUFMLEdBQWlCLElBQWpCOztBQUVBOzs7O0FBSUEsU0FBSyxhQUFMLEdBQXFCLEVBQXJCOztBQUVBOzs7O0FBSUEsU0FBSyxPQUFMLEdBQWUsSUFBZjtBQUNEOztBQUVEOzs7Ozs7Ozs7O0FBUUE7Ozs7K0JBSVk7QUFDVixZQUFNLElBQUksU0FBSixDQUFjLG9DQUFkLEVBQW9ELElBQXBELENBQU47QUFDRDs7QUFFRDs7Ozs7Ozs7QUE2QkE7Ozs2QkFHVSxLLEVBQU87QUFDZixXQUFLLGFBQUwsQ0FBbUIsSUFBbkIsQ0FBd0IsS0FBeEI7O0FBRUE7QUFDQSxVQUFJLE1BQU0sSUFBTixLQUFlLE9BQW5CLEVBQTRCO0FBQzFCLFlBQUksUUFBUSw4QkFBWjtBQUNBLGNBQU0sT0FBTixHQUFnQixzQkFBc0IsTUFBTSxLQUE1QixHQUFvQyxJQUFwRDtBQUNBLGNBQU0sUUFBTixDQUFlLEtBQWY7QUFDQSxhQUFLLFFBQUwsQ0FBYyxLQUFkO0FBQ0Q7QUFDRjs7QUFFRDs7Ozs7Ozs7QUF3QkE7Ozs7Z0NBSWEsUyxFQUFXO0FBQ3RCLFVBQUksQ0FBRSxLQUFLLGVBQVgsRUFBNEI7QUFDMUIsY0FBTSxJQUFJLFNBQUosQ0FDSixnRUFESSxFQUM4RCxJQUQ5RCxDQUFOO0FBR0Q7O0FBRUQsVUFBSSxDQUFFLEtBQUssU0FBWCxFQUFzQjtBQUNwQixhQUFLLFNBQUwsR0FBaUIsRUFBakI7QUFDRDs7QUFFRCxXQUFLLFNBQUwsQ0FBZSxJQUFmLENBQW9CLFNBQXBCOztBQUVBLGFBQU8sSUFBUDtBQUNEOztBQUVEOzs7Ozs7Ozs7QUFjQTs7OzZCQUdVLEssRUFBTztBQUNmLFVBQUksS0FBSyxPQUFMLEtBQWlCLElBQXJCLEVBQTJCO0FBQ3pCLGFBQUssT0FBTCxHQUFlLEVBQWY7QUFDRDtBQUNELFdBQUssT0FBTCxDQUFhLElBQWIsQ0FBa0IsS0FBbEI7QUFDRDs7QUFFRDs7Ozs7Ozt3QkE1SHVCO0FBQ3JCLFlBQU0sSUFBSSxTQUFKLENBQWMsMkNBQWQsRUFBMkQsSUFBM0QsQ0FBTjtBQUNEOzs7d0JBYVc7QUFDVixZQUFNLElBQUksU0FBSixDQUFjLHVDQUFkLEVBQXVELElBQXZELENBQU47QUFDRDs7QUFFRDs7Ozs7O3dCQUdnQjtBQUNkLFVBQUksS0FBSyxTQUFMLEtBQW1CLElBQW5CLElBQTJCLEtBQUssU0FBTCxDQUFlLE1BQWYsS0FBMEIsQ0FBekQsRUFBNEQ7QUFDMUQsZUFBTyxJQUFQO0FBQ0Q7O0FBRUQsYUFBTyxLQUFLLFNBQUwsQ0FBZSxLQUFmLENBQXFCLENBQXJCLENBQVA7QUFDRDs7QUFFRDs7Ozs7O3dCQUdpQjtBQUNmLFVBQUksV0FBVyxLQUFLLFFBQXBCO0FBQ0EsVUFBSSxhQUFhLElBQWIsSUFBcUIsU0FBUyxNQUFULEtBQW9CLENBQTdDLEVBQWdEO0FBQzlDLGVBQU8sSUFBUDtBQUNEO0FBQ0QsYUFBTyxTQUFTLFNBQVMsTUFBVCxHQUFrQixDQUEzQixDQUFQO0FBQ0Q7Ozt3QkFvQmE7QUFDWixhQUFPLEtBQUssYUFBTCxDQUFtQixLQUFuQixDQUF5QixDQUF6QixDQUFQO0FBQ0Q7O0FBRUQ7Ozs7Ozt3QkFHa0I7QUFDaEIsVUFBSSxTQUFTLEtBQUssTUFBbEI7QUFDQSxVQUFJLE9BQU8sTUFBUCxLQUFrQixDQUF0QixFQUF5QjtBQUN2QixlQUFPLElBQVA7QUFDRDs7QUFFRCxVQUFJLGFBQWEsT0FBTyxDQUFQLENBQWpCO0FBQ0EsVUFBSSxZQUFZLE9BQU8sT0FBTyxNQUFQLEdBQWdCLENBQXZCLENBQWhCO0FBQ0EsYUFBTyxDQUNMLFdBQVcsS0FETixFQUVMLFVBQVUsS0FBVixHQUFrQixVQUFVLEtBQVYsQ0FBZ0IsTUFBbEMsR0FBMkMsQ0FGdEMsQ0FBUDtBQUlEOzs7d0JBMEJhO0FBQ1osVUFBSSxLQUFLLGVBQUwsSUFBd0IsS0FBSyxRQUFqQyxFQUEyQztBQUN6QyxlQUFPLEtBQUssUUFBTCxDQUFjLE1BQWQsQ0FBcUIsVUFBQyxXQUFELEVBQWMsS0FBZCxFQUF3QjtBQUNsRCxpQkFBTyxZQUFZLE1BQVosQ0FBbUIsTUFBTSxNQUF6QixDQUFQO0FBQ0QsU0FGTSxFQUVKLEtBQUssU0FGRCxDQUFQO0FBR0Q7O0FBRUQsYUFBTyxLQUFLLFNBQVo7QUFDRDs7O3dCQWdCZ0I7QUFDZixhQUFPLEtBQUssT0FBTCxLQUFpQixJQUFqQixHQUF3QixFQUF4QixHQUE2QixLQUFLLE9BQUwsQ0FBYSxLQUFiLENBQW1CLENBQW5CLENBQXBDO0FBQ0Q7Ozs7OztBQUdIOzs7Ozs7O2tCQTlKcUIsUTs7SUFtS1IsUyxXQUFBLFM7OztBQUNYOzs7O0FBSUEscUJBQWEsT0FBYixFQUFzQixJQUF0QixFQUE0QjtBQUFBOztBQUFBLDZGQUNwQixPQURvQjs7QUFFMUIsVUFBSyxJQUFMLEdBQVkscUJBQVo7QUFDQSxVQUFLLElBQUwsR0FBWSxJQUFaO0FBSDBCO0FBSTNCOzs7RUFUNEIsSzs7QUFVOUIiLCJmaWxlIjoiSFRNTE5vZGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgSFRNTFBhcnNlRXJyb3IgZnJvbSAnLi4vSFRNTFBhcnNlRXJyb3InXG5cbi8qKlxuICogSFRNTCBub2RlIHR5cGVzLlxuICogQGVudW0ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGNvbnN0IE5vZGVUeXBlID0ge1xuICBST09UOiBcIlJPT1RcIixcbiAgVEFHOiAgXCJUQUdcIixcbiAgQVRUUklCVVRFOiBcIkFUVFJJQlVURVwiLFxuICBURVhUOiBcIlRFWFRcIixcbiAgRU5USVRZOiAgXCJFTlRJVFlcIixcbiAgQ09NTUVOVDogXCJDT01NRU5UXCIsXG4gIENMT1NFVEFHOiBcIkNMT1NFVEFHXCJcbn07XG5cbi8qKlxuICogSFRNTCB0cmVlIG5vZGVzIGJhc2UgY2xhc3MuIFNob3VsZCBuZXZlciBiZSBjYWxsZWQgb3V0c2lkZSBvZlxuICogc3ViY2xhc3MgY29uc3RydWN0b3JzIVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBIVE1MTm9kZSB7XG4gIGNvbnN0cnVjdG9yICgpIHtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheS48Rm91bmRhdGlvbi5IVE1MLlBhcnNlci5IVE1MTm9kZT4/fVxuICAgICAqL1xuICAgIHRoaXMuX2NoaWxkcmVuID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5LjxGb3VuZGF0aW9uLlNjYW5uZXIuVG9rZW4+fVxuICAgICAqL1xuICAgIHRoaXMuX3NvdXJjZVRva2VucyA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXkuPEhUTUxQYXJzZUVycm9yPj99XG4gICAgICovXG4gICAgdGhpcy5fZXJyb3JzID0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJjbGFzc2VzIG11c3Qgb3ZlcnJpZGUgdGhpcy5cbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIGdldCBjYW5IYXZlQ2hpbGRyZW4gKCkge1xuICAgIHRocm93IG5ldyBOb2RlRXJyb3IoXCJjYW5IYXZlQ2hpbGRyZW4gbm90IG92ZXJyaWRlbiBpbiBzdWJjbGFzc1wiLCB0aGlzKVxuICB9XG5cbiAgLyoqXG4gICAqIFN1YmNsYXNzZXMgbXVzdCBvdmVycmlkZSB0aGlzLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICB0b1N0cmluZyAoKSB7XG4gICAgdGhyb3cgbmV3IE5vZGVFcnJvcihcInRvU3RyaW5nIG5vdCBvdmVycmlkZW4gaW4gc3ViY2xhc3NcIiwgdGhpcylcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtOb2RlVHlwZX1cbiAgICovXG4gIGdldCB0eXBlICgpIHtcbiAgICB0aHJvdyBuZXcgTm9kZUVycm9yKFwidHlwZSBnZXR0ZXIgbm90IG92ZXJyaWRlbiBpbiBzdWJjbGFzc1wiLCB0aGlzKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5LjxGb3VuZGF0aW9uLkhUTUwuUGFyc2VyLkhUTUxOb2RlPj99XG4gICAqL1xuICBnZXQgY2hpbGRyZW4gKCkge1xuICAgIGlmICh0aGlzLl9jaGlsZHJlbiA9PT0gbnVsbCB8fCB0aGlzLl9jaGlsZHJlbi5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9jaGlsZHJlbi5zbGljZSgwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtGb3VuZGF0aW9uLkhUTUwuUGFyc2VyLkhUTUxOb2RlfVxuICAgKi9cbiAgZ2V0IGxhc3RDaGlsZCAoKSB7XG4gICAgdmFyIGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlbjtcbiAgICBpZiAoY2hpbGRyZW4gPT09IG51bGwgfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGNoaWxkcmVuW2NoaWxkcmVuLmxlbmd0aCAtIDFdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7Rm91bmRhdGlvbi5TY2FubmVyLlRva2VufSB0b2tlblxuICAgKi9cbiAgYWRkVG9rZW4gKHRva2VuKSB7XG4gICAgdGhpcy5fc291cmNlVG9rZW5zLnB1c2godG9rZW4pO1xuXG4gICAgLy8gQ3JlYXRlIGVycm9yIG9iamVjdHMgd2hlbiBhZGRpbmcgYSB0b2tlbiBvZiB0eXBlIGVycm9yLlxuICAgIGlmICh0b2tlbi50eXBlID09PSBcImVycm9yXCIpIHtcbiAgICAgIHZhciBlcnJvciA9IG5ldyBIVE1MUGFyc2VFcnJvcigpO1xuICAgICAgZXJyb3IubWVzc2FnZSA9IFwiSW52YWxpZCB0b2tlbjogXFxcIlwiICsgdG9rZW4udmFsdWUgKyBcIlxcXCJcIjtcbiAgICAgIGVycm9yLmFkZFRva2VuKHRva2VuKTtcbiAgICAgIHRoaXMuYWRkRXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheS48Rm91bmRhdGlvbi5TY2FubmVyLlRva2VuPn1cbiAgICovXG4gIGdldCB0b2tlbnMgKCkge1xuICAgIHJldHVybiB0aGlzLl9zb3VyY2VUb2tlbnMuc2xpY2UoMCk7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7QXJyYXkuPG51bWJlcj4/fVxuICAgKi9cbiAgZ2V0IGluZGV4UmFuZ2UgKCkge1xuICAgIHZhciB0b2tlbnMgPSB0aGlzLnRva2VucztcbiAgICBpZiAodG9rZW5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIGZpcnN0VG9rZW4gPSB0b2tlbnNbMF07XG4gICAgdmFyIGxhc3RUb2tlbiA9IHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gMV07XG4gICAgcmV0dXJuIFtcbiAgICAgIGZpcnN0VG9rZW4uaW5kZXgsXG4gICAgICBsYXN0VG9rZW4uaW5kZXggKyBsYXN0VG9rZW4udmFsdWUubGVuZ3RoIC0gMVxuICAgIF07XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtGb3VuZGF0aW9uLkhUTUwuUGFyc2VyLkhUTUxOb2RlfSBjaGlsZE5vZGVcbiAgICogQHJldHVybiB7Rm91bmRhdGlvbi5IVE1MLlBhcnNlci5IVE1MTm9kZX1cbiAgICovXG4gIGFwcGVuZENoaWxkIChjaGlsZE5vZGUpIHtcbiAgICBpZiAoISB0aGlzLmNhbkhhdmVDaGlsZHJlbikge1xuICAgICAgdGhyb3cgbmV3IE5vZGVFcnJvcihcbiAgICAgICAgXCJhdHRlbXB0ZWQgdG8gY2FsbCBhcHBlbmRDaGlsZCBvbiBub2RlIHRoYXQgY2FuJ3QgaGF2ZSBjaGlsZHJlblwiLCB0aGlzXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghIHRoaXMuX2NoaWxkcmVuKSB7XG4gICAgICB0aGlzLl9jaGlsZHJlbiA9IFtdO1xuICAgIH1cblxuICAgIHRoaXMuX2NoaWxkcmVuLnB1c2goY2hpbGROb2RlKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwdWJsaWNcbiAgICogQHJldHVybiB7QXJyYXkuPEhUTUxQYXJzZUVycm9yPn1cbiAgICovXG4gIGdldCBlcnJvcnMgKCkge1xuICAgIGlmICh0aGlzLmNhbkhhdmVDaGlsZHJlbiAmJiB0aGlzLmNoaWxkcmVuKSB7XG4gICAgICByZXR1cm4gdGhpcy5jaGlsZHJlbi5yZWR1Y2UoKGFjY3VtdWxhdG9yLCBjaGlsZCkgPT4ge1xuICAgICAgICByZXR1cm4gYWNjdW11bGF0b3IuY29uY2F0KGNoaWxkLmVycm9ycylcbiAgICAgIH0sIHRoaXMub3duRXJyb3JzKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm93bkVycm9yc1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTFBhcnNlRXJyb3J9IGVycm9yXG4gICAqL1xuICBhZGRFcnJvciAoZXJyb3IpIHtcbiAgICBpZiAodGhpcy5fZXJyb3JzID09PSBudWxsKSB7XG4gICAgICB0aGlzLl9lcnJvcnMgPSBbXTtcbiAgICB9XG4gICAgdGhpcy5fZXJyb3JzLnB1c2goZXJyb3IpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEByZXR1cm4ge0FycmF5LjxIVE1MUGFyc2VFcnJvcj59XG4gICAqL1xuICBnZXQgb3duRXJyb3JzICgpIHtcbiAgICByZXR1cm4gdGhpcy5fZXJyb3JzID09PSBudWxsID8gW10gOiB0aGlzLl9lcnJvcnMuc2xpY2UoMCk7XG4gIH1cbn1cblxuLyoqXG4gKiBIVE1MIG5vZGUgZXJyb3IgY2xhc3MuIFRoaXMgaXMgYSB0aHJvd2FibGUgRXJyb3Igb2JqZWN0LCBub3QgdG8gYmVcbiAqIGNvbmZ1c2VkIHdpdGggdGhlIEhUTUxQYXJzZUVycm9yIGNsYXNzIHdoaWNoIGRlYWxzXG4gKiB3aXRoIHJlcG9ydGluZyBlcnJvcnMgZm91bmQgaW4gdGhlIEhUTUwgc291cmNlLlxuICovXG5leHBvcnQgY2xhc3MgTm9kZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAgICogQHBhcmFtIHtGb3VuZGF0aW9uLkhUTUwuUGFyc2VyLkhUTUxOb2RlfSBub2RlXG4gICAqL1xuICBjb25zdHJ1Y3RvciAobWVzc2FnZSwgbm9kZSkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiSFRNTFBhcnNlck5vZGVFcnJvclwiO1xuICAgIHRoaXMubm9kZSA9IG5vZGU7XG4gIH1cbn07XG4iXX0=