UNPKG

tsdav

Version:

WebDAV, CALDAV, and CARDDAV client for Nodejs and the Browser

1,747 lines 152 kB
//#region \0rolldown/runtime.js var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports); var __exportAll = (all, no_symbols) => { let target = {}; for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" }); return target; }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details."); }); //#endregion //#region node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.js var require_ms = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Helpers. */ var s = 1e3; var m = s * 60; var h = m * 60; var d = h * 24; var w = d * 7; var y = d * 365.25; /** * Parse or format the given `val`. * * Options: * * - `long` verbose formatting [false] * * @param {String|Number} val * @param {Object} [options] * @throws {Error} throw an error if val is not a non-empty string or a number * @return {String|Number} * @api public */ module.exports = function(val, options) { options = options || {}; var type = typeof val; if (type === "string" && val.length > 0) return parse(val); else if (type === "number" && isFinite(val)) return options.long ? fmtLong(val) : fmtShort(val); throw new Error("val is not a non-empty string or a valid number. val=" + JSON.stringify(val)); }; /** * Parse the given `str` and return milliseconds. * * @param {String} str * @return {Number} * @api private */ function parse(str) { str = String(str); if (str.length > 100) return; var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str); if (!match) return; var n = parseFloat(match[1]); switch ((match[2] || "ms").toLowerCase()) { case "years": case "year": case "yrs": case "yr": case "y": return n * y; case "weeks": case "week": case "w": return n * w; case "days": case "day": case "d": return n * d; case "hours": case "hour": case "hrs": case "hr": case "h": return n * h; case "minutes": case "minute": case "mins": case "min": case "m": return n * m; case "seconds": case "second": case "secs": case "sec": case "s": return n * s; case "milliseconds": case "millisecond": case "msecs": case "msec": case "ms": return n; default: return; } } /** * Short format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtShort(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) return Math.round(ms / d) + "d"; if (msAbs >= h) return Math.round(ms / h) + "h"; if (msAbs >= m) return Math.round(ms / m) + "m"; if (msAbs >= s) return Math.round(ms / s) + "s"; return ms + "ms"; } /** * Long format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtLong(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) return plural(ms, msAbs, d, "day"); if (msAbs >= h) return plural(ms, msAbs, h, "hour"); if (msAbs >= m) return plural(ms, msAbs, m, "minute"); if (msAbs >= s) return plural(ms, msAbs, s, "second"); return ms + " ms"; } /** * Pluralization helper. */ function plural(ms, msAbs, n, name) { var isPlural = msAbs >= n * 1.5; return Math.round(ms / n) + " " + name + (isPlural ? "s" : ""); } })); //#endregion //#region node_modules/.pnpm/debug@4.4.3/node_modules/debug/src/common.js var require_common = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * This is the common logic for both the Node.js and web browser * implementations of `debug()`. */ function setup(env) { createDebug.debug = createDebug; createDebug.default = createDebug; createDebug.coerce = coerce; createDebug.disable = disable; createDebug.enable = enable; createDebug.enabled = enabled; createDebug.humanize = require_ms(); createDebug.destroy = destroy; Object.keys(env).forEach((key) => { createDebug[key] = env[key]; }); /** * The currently active debug mode names, and names to skip. */ createDebug.names = []; createDebug.skips = []; /** * Map of special "%n" handling functions, for the debug "format" argument. * * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". */ createDebug.formatters = {}; /** * Selects a color for a debug namespace * @param {String} namespace The namespace string for the debug instance to be colored * @return {Number|String} An ANSI color code for the given namespace * @api private */ function selectColor(namespace) { let hash = 0; for (let i = 0; i < namespace.length; i++) { hash = (hash << 5) - hash + namespace.charCodeAt(i); hash |= 0; } return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; } createDebug.selectColor = selectColor; /** * Create a debugger with the given `namespace`. * * @param {String} namespace * @return {Function} * @api public */ function createDebug(namespace) { let prevTime; let enableOverride = null; let namespacesCache; let enabledCache; function debug(...args) { if (!debug.enabled) return; const self = debug; const curr = Number(/* @__PURE__ */ new Date()); self.diff = curr - (prevTime || curr); self.prev = prevTime; self.curr = curr; prevTime = curr; args[0] = createDebug.coerce(args[0]); if (typeof args[0] !== "string") args.unshift("%O"); let index = 0; args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { if (match === "%%") return "%"; index++; const formatter = createDebug.formatters[format]; if (typeof formatter === "function") { const val = args[index]; match = formatter.call(self, val); args.splice(index, 1); index--; } return match; }); createDebug.formatArgs.call(self, args); (self.log || createDebug.log).apply(self, args); } debug.namespace = namespace; debug.useColors = createDebug.useColors(); debug.color = createDebug.selectColor(namespace); debug.extend = extend; debug.destroy = createDebug.destroy; Object.defineProperty(debug, "enabled", { enumerable: true, configurable: false, get: () => { if (enableOverride !== null) return enableOverride; if (namespacesCache !== createDebug.namespaces) { namespacesCache = createDebug.namespaces; enabledCache = createDebug.enabled(namespace); } return enabledCache; }, set: (v) => { enableOverride = v; } }); if (typeof createDebug.init === "function") createDebug.init(debug); return debug; } function extend(namespace, delimiter) { const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace); newDebug.log = this.log; return newDebug; } /** * Enables a debug mode by namespaces. This can include modes * separated by a colon and wildcards. * * @param {String} namespaces * @api public */ function enable(namespaces) { createDebug.save(namespaces); createDebug.namespaces = namespaces; createDebug.names = []; createDebug.skips = []; const split = (typeof namespaces === "string" ? namespaces : "").trim().replace(/\s+/g, ",").split(",").filter(Boolean); for (const ns of split) if (ns[0] === "-") createDebug.skips.push(ns.slice(1)); else createDebug.names.push(ns); } /** * Checks if the given string matches a namespace template, honoring * asterisks as wildcards. * * @param {String} search * @param {String} template * @return {Boolean} */ function matchesTemplate(search, template) { let searchIndex = 0; let templateIndex = 0; let starIndex = -1; let matchIndex = 0; while (searchIndex < search.length) if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*")) if (template[templateIndex] === "*") { starIndex = templateIndex; matchIndex = searchIndex; templateIndex++; } else { searchIndex++; templateIndex++; } else if (starIndex !== -1) { templateIndex = starIndex + 1; matchIndex++; searchIndex = matchIndex; } else return false; while (templateIndex < template.length && template[templateIndex] === "*") templateIndex++; return templateIndex === template.length; } /** * Disable debug output. * * @return {String} namespaces * @api public */ function disable() { const namespaces = [...createDebug.names, ...createDebug.skips.map((namespace) => "-" + namespace)].join(","); createDebug.enable(""); return namespaces; } /** * Returns true if the given mode name is enabled, false otherwise. * * @param {String} name * @return {Boolean} * @api public */ function enabled(name) { for (const skip of createDebug.skips) if (matchesTemplate(name, skip)) return false; for (const ns of createDebug.names) if (matchesTemplate(name, ns)) return true; return false; } /** * Coerce `val`. * * @param {Mixed} val * @return {Mixed} * @api private */ function coerce(val) { if (val instanceof Error) return val.stack || val.message; return val; } /** * XXX DO NOT USE. This is a temporary stub function. * XXX It WILL be removed in the next major release. */ function destroy() { console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); } createDebug.enable(createDebug.load()); return createDebug; } module.exports = setup; })); //#endregion //#region src/consts.ts var import_browser = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => { /** * This is the web browser implementation of `debug()`. */ exports.formatArgs = formatArgs; exports.save = save; exports.load = load; exports.useColors = useColors; exports.storage = localstorage(); exports.destroy = (() => { let warned = false; return () => { if (!warned) { warned = true; console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); } }; })(); /** * Colors. */ exports.colors = [ "#0000CC", "#0000FF", "#0033CC", "#0033FF", "#0066CC", "#0066FF", "#0099CC", "#0099FF", "#00CC00", "#00CC33", "#00CC66", "#00CC99", "#00CCCC", "#00CCFF", "#3300CC", "#3300FF", "#3333CC", "#3333FF", "#3366CC", "#3366FF", "#3399CC", "#3399FF", "#33CC00", "#33CC33", "#33CC66", "#33CC99", "#33CCCC", "#33CCFF", "#6600CC", "#6600FF", "#6633CC", "#6633FF", "#66CC00", "#66CC33", "#9900CC", "#9900FF", "#9933CC", "#9933FF", "#99CC00", "#99CC33", "#CC0000", "#CC0033", "#CC0066", "#CC0099", "#CC00CC", "#CC00FF", "#CC3300", "#CC3333", "#CC3366", "#CC3399", "#CC33CC", "#CC33FF", "#CC6600", "#CC6633", "#CC9900", "#CC9933", "#CCCC00", "#CCCC33", "#FF0000", "#FF0033", "#FF0066", "#FF0099", "#FF00CC", "#FF00FF", "#FF3300", "#FF3333", "#FF3366", "#FF3399", "#FF33CC", "#FF33FF", "#FF6600", "#FF6633", "#FF9900", "#FF9933", "#FFCC00", "#FFCC33" ]; /** * Currently only WebKit-based Web Inspectors, Firefox >= v31, * and the Firebug extension (any Firefox version) are known * to support "%c" CSS customizations. * * TODO: add a `localStorage` variable to explicitly enable/disable colors */ function useColors() { if (typeof window !== "undefined" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) return true; if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) return false; let m; return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || typeof navigator !== "undefined" && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31 || typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); } /** * Colorize log arguments if enabled. * * @api public */ function formatArgs(args) { args[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + args[0] + (this.useColors ? "%c " : " ") + "+" + module.exports.humanize(this.diff); if (!this.useColors) return; const c = "color: " + this.color; args.splice(1, 0, c, "color: inherit"); let index = 0; let lastC = 0; args[0].replace(/%[a-zA-Z%]/g, (match) => { if (match === "%%") return; index++; if (match === "%c") lastC = index; }); args.splice(lastC, 0, c); } /** * Invokes `console.debug()` when available. * No-op when `console.debug` is not a "function". * If `console.debug` is not available, falls back * to `console.log`. * * @api public */ exports.log = console.debug || console.log || (() => {}); /** * Save `namespaces`. * * @param {String} namespaces * @api private */ function save(namespaces) { try { if (namespaces) exports.storage.setItem("debug", namespaces); else exports.storage.removeItem("debug"); } catch (error) {} } /** * Load `namespaces`. * * @return {String} returns the previously persisted debug modes * @api private */ function load() { let r; try { r = exports.storage.getItem("debug") || exports.storage.getItem("DEBUG"); } catch (error) {} if (!r && typeof process !== "undefined" && "env" in process) r = process.env.DEBUG; return r; } /** * Localstorage attempts to return the localstorage. * * This is necessary because safari throws * when a user disables cookies/localstorage * and you attempt to access it. * * @return {LocalStorage} * @api private */ function localstorage() { try { return localStorage; } catch (error) {} } module.exports = require_common()(exports); const { formatters } = module.exports; /** * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. */ formatters.j = function(v) { try { return JSON.stringify(v); } catch (error) { return "[UnexpectedJSONParseError]: " + error.message; } }; })))()); let DAVNamespace = /* @__PURE__ */ function(DAVNamespace) { DAVNamespace["CALENDAR_SERVER"] = "http://calendarserver.org/ns/"; DAVNamespace["CALDAV_APPLE"] = "http://apple.com/ns/ical/"; DAVNamespace["CALDAV"] = "urn:ietf:params:xml:ns:caldav"; DAVNamespace["CARDDAV"] = "urn:ietf:params:xml:ns:carddav"; DAVNamespace["DAV"] = "DAV:"; return DAVNamespace; }({}); const DAVAttributeMap = { ["urn:ietf:params:xml:ns:caldav"]: "xmlns:c", ["urn:ietf:params:xml:ns:carddav"]: "xmlns:card", ["http://calendarserver.org/ns/"]: "xmlns:cs", ["http://apple.com/ns/ical/"]: "xmlns:ca", ["DAV:"]: "xmlns:d" }; let DAVNamespaceShort = /* @__PURE__ */ function(DAVNamespaceShort) { DAVNamespaceShort["CALDAV"] = "c"; DAVNamespaceShort["CARDDAV"] = "card"; DAVNamespaceShort["CALENDAR_SERVER"] = "cs"; DAVNamespaceShort["CALDAV_APPLE"] = "ca"; DAVNamespaceShort["DAV"] = "d"; return DAVNamespaceShort; }({}); let ICALObjects = /* @__PURE__ */ function(ICALObjects) { ICALObjects["VEVENT"] = "VEVENT"; ICALObjects["VTODO"] = "VTODO"; ICALObjects["VJOURNAL"] = "VJOURNAL"; ICALObjects["VFREEBUSY"] = "VFREEBUSY"; ICALObjects["VTIMEZONE"] = "VTIMEZONE"; ICALObjects["VALARM"] = "VALARM"; return ICALObjects; }({}); //#endregion //#region node_modules/.pnpm/sax@1.4.4/node_modules/sax/lib/sax.js var require_sax = /* @__PURE__ */ __commonJSMin(((exports) => { (function(sax) { sax.parser = function(strict, opt) { return new SAXParser(strict, opt); }; sax.SAXParser = SAXParser; sax.SAXStream = SAXStream; sax.createStream = createStream; sax.MAX_BUFFER_LENGTH = 64 * 1024; var buffers = [ "comment", "sgmlDecl", "textNode", "tagName", "doctype", "procInstName", "procInstBody", "entity", "attribName", "attribValue", "cdata", "script" ]; sax.EVENTS = [ "text", "processinginstruction", "sgmldeclaration", "doctype", "comment", "opentagstart", "attribute", "opentag", "closetag", "opencdata", "cdata", "closecdata", "error", "end", "ready", "script", "opennamespace", "closenamespace" ]; function SAXParser(strict, opt) { if (!(this instanceof SAXParser)) return new SAXParser(strict, opt); var parser = this; clearBuffers(parser); parser.q = parser.c = ""; parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH; parser.opt = opt || {}; parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags; parser.looseCase = parser.opt.lowercase ? "toLowerCase" : "toUpperCase"; parser.tags = []; parser.closed = parser.closedRoot = parser.sawRoot = false; parser.tag = parser.error = null; parser.strict = !!strict; parser.noscript = !!(strict || parser.opt.noscript); parser.state = S.BEGIN; parser.strictEntities = parser.opt.strictEntities; parser.ENTITIES = parser.strictEntities ? Object.create(sax.XML_ENTITIES) : Object.create(sax.ENTITIES); parser.attribList = []; if (parser.opt.xmlns) parser.ns = Object.create(rootNS); if (parser.opt.unquotedAttributeValues === void 0) parser.opt.unquotedAttributeValues = !strict; parser.trackPosition = parser.opt.position !== false; if (parser.trackPosition) parser.position = parser.line = parser.column = 0; emit(parser, "onready"); } if (!Object.create) Object.create = function(o) { function F() {} F.prototype = o; return new F(); }; if (!Object.keys) Object.keys = function(o) { var a = []; for (var i in o) if (o.hasOwnProperty(i)) a.push(i); return a; }; function checkBufferLength(parser) { var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10); var maxActual = 0; for (var i = 0, l = buffers.length; i < l; i++) { var len = parser[buffers[i]].length; if (len > maxAllowed) switch (buffers[i]) { case "textNode": closeText(parser); break; case "cdata": emitNode(parser, "oncdata", parser.cdata); parser.cdata = ""; break; case "script": emitNode(parser, "onscript", parser.script); parser.script = ""; break; default: error(parser, "Max buffer length exceeded: " + buffers[i]); } maxActual = Math.max(maxActual, len); } parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH - maxActual + parser.position; } function clearBuffers(parser) { for (var i = 0, l = buffers.length; i < l; i++) parser[buffers[i]] = ""; } function flushBuffers(parser) { closeText(parser); if (parser.cdata !== "") { emitNode(parser, "oncdata", parser.cdata); parser.cdata = ""; } if (parser.script !== "") { emitNode(parser, "onscript", parser.script); parser.script = ""; } } SAXParser.prototype = { end: function() { end(this); }, write, resume: function() { this.error = null; return this; }, close: function() { return this.write(null); }, flush: function() { flushBuffers(this); } }; var Stream; try { Stream = __require("stream").Stream; } catch (ex) { Stream = function() {}; } if (!Stream) Stream = function() {}; var streamWraps = sax.EVENTS.filter(function(ev) { return ev !== "error" && ev !== "end"; }); function createStream(strict, opt) { return new SAXStream(strict, opt); } function SAXStream(strict, opt) { if (!(this instanceof SAXStream)) return new SAXStream(strict, opt); Stream.apply(this); this._parser = new SAXParser(strict, opt); this.writable = true; this.readable = true; var me = this; this._parser.onend = function() { me.emit("end"); }; this._parser.onerror = function(er) { me.emit("error", er); me._parser.error = null; }; this._decoder = null; streamWraps.forEach(function(ev) { Object.defineProperty(me, "on" + ev, { get: function() { return me._parser["on" + ev]; }, set: function(h) { if (!h) { me.removeAllListeners(ev); me._parser["on" + ev] = h; return h; } me.on(ev, h); }, enumerable: true, configurable: false }); }); } SAXStream.prototype = Object.create(Stream.prototype, { constructor: { value: SAXStream } }); SAXStream.prototype.write = function(data) { if (typeof Buffer === "function" && typeof Buffer.isBuffer === "function" && Buffer.isBuffer(data)) { if (!this._decoder) this._decoder = new TextDecoder("utf8"); data = this._decoder.decode(data, { stream: true }); } this._parser.write(data.toString()); this.emit("data", data); return true; }; SAXStream.prototype.end = function(chunk) { if (chunk && chunk.length) this.write(chunk); if (this._decoder) { var remaining = this._decoder.decode(); if (remaining) { this._parser.write(remaining); this.emit("data", remaining); } } this._parser.end(); return true; }; SAXStream.prototype.on = function(ev, handler) { var me = this; if (!me._parser["on" + ev] && streamWraps.indexOf(ev) !== -1) me._parser["on" + ev] = function() { var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments); args.splice(0, 0, ev); me.emit.apply(me, args); }; return Stream.prototype.on.call(me, ev, handler); }; var CDATA = "[CDATA["; var DOCTYPE = "DOCTYPE"; var XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace"; var XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/"; var rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE }; var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/; var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/; var entityStart = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/; var entityBody = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/; function isWhitespace(c) { return c === " " || c === "\n" || c === "\r" || c === " "; } function isQuote(c) { return c === "\"" || c === "'"; } function isAttribEnd(c) { return c === ">" || isWhitespace(c); } function isMatch(regex, c) { return regex.test(c); } function notMatch(regex, c) { return !isMatch(regex, c); } var S = 0; sax.STATE = { BEGIN: S++, BEGIN_WHITESPACE: S++, TEXT: S++, TEXT_ENTITY: S++, OPEN_WAKA: S++, SGML_DECL: S++, SGML_DECL_QUOTED: S++, DOCTYPE: S++, DOCTYPE_QUOTED: S++, DOCTYPE_DTD: S++, DOCTYPE_DTD_QUOTED: S++, COMMENT_STARTING: S++, COMMENT: S++, COMMENT_ENDING: S++, COMMENT_ENDED: S++, CDATA: S++, CDATA_ENDING: S++, CDATA_ENDING_2: S++, PROC_INST: S++, PROC_INST_BODY: S++, PROC_INST_ENDING: S++, OPEN_TAG: S++, OPEN_TAG_SLASH: S++, ATTRIB: S++, ATTRIB_NAME: S++, ATTRIB_NAME_SAW_WHITE: S++, ATTRIB_VALUE: S++, ATTRIB_VALUE_QUOTED: S++, ATTRIB_VALUE_CLOSED: S++, ATTRIB_VALUE_UNQUOTED: S++, ATTRIB_VALUE_ENTITY_Q: S++, ATTRIB_VALUE_ENTITY_U: S++, CLOSE_TAG: S++, CLOSE_TAG_SAW_WHITE: S++, SCRIPT: S++, SCRIPT_ENDING: S++ }; sax.XML_ENTITIES = { amp: "&", gt: ">", lt: "<", quot: "\"", apos: "'" }; sax.ENTITIES = { amp: "&", gt: ">", lt: "<", quot: "\"", apos: "'", AElig: 198, Aacute: 193, Acirc: 194, Agrave: 192, Aring: 197, Atilde: 195, Auml: 196, Ccedil: 199, ETH: 208, Eacute: 201, Ecirc: 202, Egrave: 200, Euml: 203, Iacute: 205, Icirc: 206, Igrave: 204, Iuml: 207, Ntilde: 209, Oacute: 211, Ocirc: 212, Ograve: 210, Oslash: 216, Otilde: 213, Ouml: 214, THORN: 222, Uacute: 218, Ucirc: 219, Ugrave: 217, Uuml: 220, Yacute: 221, aacute: 225, acirc: 226, aelig: 230, agrave: 224, aring: 229, atilde: 227, auml: 228, ccedil: 231, eacute: 233, ecirc: 234, egrave: 232, eth: 240, euml: 235, iacute: 237, icirc: 238, igrave: 236, iuml: 239, ntilde: 241, oacute: 243, ocirc: 244, ograve: 242, oslash: 248, otilde: 245, ouml: 246, szlig: 223, thorn: 254, uacute: 250, ucirc: 251, ugrave: 249, uuml: 252, yacute: 253, yuml: 255, copy: 169, reg: 174, nbsp: 160, iexcl: 161, cent: 162, pound: 163, curren: 164, yen: 165, brvbar: 166, sect: 167, uml: 168, ordf: 170, laquo: 171, not: 172, shy: 173, macr: 175, deg: 176, plusmn: 177, sup1: 185, sup2: 178, sup3: 179, acute: 180, micro: 181, para: 182, middot: 183, cedil: 184, ordm: 186, raquo: 187, frac14: 188, frac12: 189, frac34: 190, iquest: 191, times: 215, divide: 247, OElig: 338, oelig: 339, Scaron: 352, scaron: 353, Yuml: 376, fnof: 402, circ: 710, tilde: 732, Alpha: 913, Beta: 914, Gamma: 915, Delta: 916, Epsilon: 917, Zeta: 918, Eta: 919, Theta: 920, Iota: 921, Kappa: 922, Lambda: 923, Mu: 924, Nu: 925, Xi: 926, Omicron: 927, Pi: 928, Rho: 929, Sigma: 931, Tau: 932, Upsilon: 933, Phi: 934, Chi: 935, Psi: 936, Omega: 937, alpha: 945, beta: 946, gamma: 947, delta: 948, epsilon: 949, zeta: 950, eta: 951, theta: 952, iota: 953, kappa: 954, lambda: 955, mu: 956, nu: 957, xi: 958, omicron: 959, pi: 960, rho: 961, sigmaf: 962, sigma: 963, tau: 964, upsilon: 965, phi: 966, chi: 967, psi: 968, omega: 969, thetasym: 977, upsih: 978, piv: 982, ensp: 8194, emsp: 8195, thinsp: 8201, zwnj: 8204, zwj: 8205, lrm: 8206, rlm: 8207, ndash: 8211, mdash: 8212, lsquo: 8216, rsquo: 8217, sbquo: 8218, ldquo: 8220, rdquo: 8221, bdquo: 8222, dagger: 8224, Dagger: 8225, bull: 8226, hellip: 8230, permil: 8240, prime: 8242, Prime: 8243, lsaquo: 8249, rsaquo: 8250, oline: 8254, frasl: 8260, euro: 8364, image: 8465, weierp: 8472, real: 8476, trade: 8482, alefsym: 8501, larr: 8592, uarr: 8593, rarr: 8594, darr: 8595, harr: 8596, crarr: 8629, lArr: 8656, uArr: 8657, rArr: 8658, dArr: 8659, hArr: 8660, forall: 8704, part: 8706, exist: 8707, empty: 8709, nabla: 8711, isin: 8712, notin: 8713, ni: 8715, prod: 8719, sum: 8721, minus: 8722, lowast: 8727, radic: 8730, prop: 8733, infin: 8734, ang: 8736, and: 8743, or: 8744, cap: 8745, cup: 8746, int: 8747, there4: 8756, sim: 8764, cong: 8773, asymp: 8776, ne: 8800, equiv: 8801, le: 8804, ge: 8805, sub: 8834, sup: 8835, nsub: 8836, sube: 8838, supe: 8839, oplus: 8853, otimes: 8855, perp: 8869, sdot: 8901, lceil: 8968, rceil: 8969, lfloor: 8970, rfloor: 8971, lang: 9001, rang: 9002, loz: 9674, spades: 9824, clubs: 9827, hearts: 9829, diams: 9830 }; Object.keys(sax.ENTITIES).forEach(function(key) { var e = sax.ENTITIES[key]; var s = typeof e === "number" ? String.fromCharCode(e) : e; sax.ENTITIES[key] = s; }); for (var s in sax.STATE) sax.STATE[sax.STATE[s]] = s; S = sax.STATE; function emit(parser, event, data) { parser[event] && parser[event](data); } function emitNode(parser, nodeType, data) { if (parser.textNode) closeText(parser); emit(parser, nodeType, data); } function closeText(parser) { parser.textNode = textopts(parser.opt, parser.textNode); if (parser.textNode) emit(parser, "ontext", parser.textNode); parser.textNode = ""; } function textopts(opt, text) { if (opt.trim) text = text.trim(); if (opt.normalize) text = text.replace(/\s+/g, " "); return text; } function error(parser, er) { closeText(parser); if (parser.trackPosition) er += "\nLine: " + parser.line + "\nColumn: " + parser.column + "\nChar: " + parser.c; er = new Error(er); parser.error = er; emit(parser, "onerror", er); return parser; } function end(parser) { if (parser.sawRoot && !parser.closedRoot) strictFail(parser, "Unclosed root tag"); if (parser.state !== S.BEGIN && parser.state !== S.BEGIN_WHITESPACE && parser.state !== S.TEXT) error(parser, "Unexpected end"); closeText(parser); parser.c = ""; parser.closed = true; emit(parser, "onend"); SAXParser.call(parser, parser.strict, parser.opt); return parser; } function strictFail(parser, message) { if (typeof parser !== "object" || !(parser instanceof SAXParser)) throw new Error("bad call to strictFail"); if (parser.strict) error(parser, message); } function newTag(parser) { if (!parser.strict) parser.tagName = parser.tagName[parser.looseCase](); var parent = parser.tags[parser.tags.length - 1] || parser; var tag = parser.tag = { name: parser.tagName, attributes: {} }; if (parser.opt.xmlns) tag.ns = parent.ns; parser.attribList.length = 0; emitNode(parser, "onopentagstart", tag); } function qname(name, attribute) { var qualName = name.indexOf(":") < 0 ? ["", name] : name.split(":"); var prefix = qualName[0]; var local = qualName[1]; if (attribute && name === "xmlns") { prefix = "xmlns"; local = ""; } return { prefix, local }; } function attrib(parser) { if (!parser.strict) parser.attribName = parser.attribName[parser.looseCase](); if (parser.attribList.indexOf(parser.attribName) !== -1 || parser.tag.attributes.hasOwnProperty(parser.attribName)) { parser.attribName = parser.attribValue = ""; return; } if (parser.opt.xmlns) { var qn = qname(parser.attribName, true); var prefix = qn.prefix; var local = qn.local; if (prefix === "xmlns") if (local === "xml" && parser.attribValue !== XML_NAMESPACE) strictFail(parser, "xml: prefix must be bound to " + XML_NAMESPACE + "\nActual: " + parser.attribValue); else if (local === "xmlns" && parser.attribValue !== XMLNS_NAMESPACE) strictFail(parser, "xmlns: prefix must be bound to " + XMLNS_NAMESPACE + "\nActual: " + parser.attribValue); else { var tag = parser.tag; var parent = parser.tags[parser.tags.length - 1] || parser; if (tag.ns === parent.ns) tag.ns = Object.create(parent.ns); tag.ns[local] = parser.attribValue; } parser.attribList.push([parser.attribName, parser.attribValue]); } else { parser.tag.attributes[parser.attribName] = parser.attribValue; emitNode(parser, "onattribute", { name: parser.attribName, value: parser.attribValue }); } parser.attribName = parser.attribValue = ""; } function openTag(parser, selfClosing) { if (parser.opt.xmlns) { var tag = parser.tag; var qn = qname(parser.tagName); tag.prefix = qn.prefix; tag.local = qn.local; tag.uri = tag.ns[qn.prefix] || ""; if (tag.prefix && !tag.uri) { strictFail(parser, "Unbound namespace prefix: " + JSON.stringify(parser.tagName)); tag.uri = qn.prefix; } var parent = parser.tags[parser.tags.length - 1] || parser; if (tag.ns && parent.ns !== tag.ns) Object.keys(tag.ns).forEach(function(p) { emitNode(parser, "onopennamespace", { prefix: p, uri: tag.ns[p] }); }); for (var i = 0, l = parser.attribList.length; i < l; i++) { var nv = parser.attribList[i]; var name = nv[0]; var value = nv[1]; var qualName = qname(name, true); var prefix = qualName.prefix; var local = qualName.local; var uri = prefix === "" ? "" : tag.ns[prefix] || ""; var a = { name, value, prefix, local, uri }; if (prefix && prefix !== "xmlns" && !uri) { strictFail(parser, "Unbound namespace prefix: " + JSON.stringify(prefix)); a.uri = prefix; } parser.tag.attributes[name] = a; emitNode(parser, "onattribute", a); } parser.attribList.length = 0; } parser.tag.isSelfClosing = !!selfClosing; parser.sawRoot = true; parser.tags.push(parser.tag); emitNode(parser, "onopentag", parser.tag); if (!selfClosing) { if (!parser.noscript && parser.tagName.toLowerCase() === "script") parser.state = S.SCRIPT; else parser.state = S.TEXT; parser.tag = null; parser.tagName = ""; } parser.attribName = parser.attribValue = ""; parser.attribList.length = 0; } function closeTag(parser) { if (!parser.tagName) { strictFail(parser, "Weird empty close tag."); parser.textNode += "</>"; parser.state = S.TEXT; return; } if (parser.script) { if (parser.tagName !== "script") { parser.script += "</" + parser.tagName + ">"; parser.tagName = ""; parser.state = S.SCRIPT; return; } emitNode(parser, "onscript", parser.script); parser.script = ""; } var t = parser.tags.length; var tagName = parser.tagName; if (!parser.strict) tagName = tagName[parser.looseCase](); var closeTo = tagName; while (t--) if (parser.tags[t].name !== closeTo) strictFail(parser, "Unexpected close tag"); else break; if (t < 0) { strictFail(parser, "Unmatched closing tag: " + parser.tagName); parser.textNode += "</" + parser.tagName + ">"; parser.state = S.TEXT; return; } parser.tagName = tagName; var s = parser.tags.length; while (s-- > t) { var tag = parser.tag = parser.tags.pop(); parser.tagName = parser.tag.name; emitNode(parser, "onclosetag", parser.tagName); var x = {}; for (var i in tag.ns) x[i] = tag.ns[i]; var parent = parser.tags[parser.tags.length - 1] || parser; if (parser.opt.xmlns && tag.ns !== parent.ns) Object.keys(tag.ns).forEach(function(p) { var n = tag.ns[p]; emitNode(parser, "onclosenamespace", { prefix: p, uri: n }); }); } if (t === 0) parser.closedRoot = true; parser.tagName = parser.attribValue = parser.attribName = ""; parser.attribList.length = 0; parser.state = S.TEXT; } function parseEntity(parser) { var entity = parser.entity; var entityLC = entity.toLowerCase(); var num; var numStr = ""; if (parser.ENTITIES[entity]) return parser.ENTITIES[entity]; if (parser.ENTITIES[entityLC]) return parser.ENTITIES[entityLC]; entity = entityLC; if (entity.charAt(0) === "#") if (entity.charAt(1) === "x") { entity = entity.slice(2); num = parseInt(entity, 16); numStr = num.toString(16); } else { entity = entity.slice(1); num = parseInt(entity, 10); numStr = num.toString(10); } entity = entity.replace(/^0+/, ""); if (isNaN(num) || numStr.toLowerCase() !== entity || num < 0 || num > 1114111) { strictFail(parser, "Invalid character entity"); return "&" + parser.entity + ";"; } return String.fromCodePoint(num); } function beginWhiteSpace(parser, c) { if (c === "<") { parser.state = S.OPEN_WAKA; parser.startTagPosition = parser.position; } else if (!isWhitespace(c)) { strictFail(parser, "Non-whitespace before first tag."); parser.textNode = c; parser.state = S.TEXT; } } function charAt(chunk, i) { var result = ""; if (i < chunk.length) result = chunk.charAt(i); return result; } function write(chunk) { var parser = this; if (this.error) throw this.error; if (parser.closed) return error(parser, "Cannot write after close. Assign an onready handler."); if (chunk === null) return end(parser); if (typeof chunk === "object") chunk = chunk.toString(); var i = 0; var c = ""; while (true) { c = charAt(chunk, i++); parser.c = c; if (!c) break; if (parser.trackPosition) { parser.position++; if (c === "\n") { parser.line++; parser.column = 0; } else parser.column++; } switch (parser.state) { case S.BEGIN: parser.state = S.BEGIN_WHITESPACE; if (c === "") continue; beginWhiteSpace(parser, c); continue; case S.BEGIN_WHITESPACE: beginWhiteSpace(parser, c); continue; case S.TEXT: if (parser.sawRoot && !parser.closedRoot) { var starti = i - 1; while (c && c !== "<" && c !== "&") { c = charAt(chunk, i++); if (c && parser.trackPosition) { parser.position++; if (c === "\n") { parser.line++; parser.column = 0; } else parser.column++; } } parser.textNode += chunk.substring(starti, i - 1); } if (c === "<" && !(parser.sawRoot && parser.closedRoot && !parser.strict)) { parser.state = S.OPEN_WAKA; parser.startTagPosition = parser.position; } else { if (!isWhitespace(c) && (!parser.sawRoot || parser.closedRoot)) strictFail(parser, "Text data outside of root node."); if (c === "&") parser.state = S.TEXT_ENTITY; else parser.textNode += c; } continue; case S.SCRIPT: if (c === "<") parser.state = S.SCRIPT_ENDING; else parser.script += c; continue; case S.SCRIPT_ENDING: if (c === "/") parser.state = S.CLOSE_TAG; else { parser.script += "<" + c; parser.state = S.SCRIPT; } continue; case S.OPEN_WAKA: if (c === "!") { parser.state = S.SGML_DECL; parser.sgmlDecl = ""; } else if (isWhitespace(c)) {} else if (isMatch(nameStart, c)) { parser.state = S.OPEN_TAG; parser.tagName = c; } else if (c === "/") { parser.state = S.CLOSE_TAG; parser.tagName = ""; } else if (c === "?") { parser.state = S.PROC_INST; parser.procInstName = parser.procInstBody = ""; } else { strictFail(parser, "Unencoded <"); if (parser.startTagPosition + 1 < parser.position) { var pad = parser.position - parser.startTagPosition; c = new Array(pad).join(" ") + c; } parser.textNode += "<" + c; parser.state = S.TEXT; } continue; case S.SGML_DECL: if (parser.sgmlDecl + c === "--") { parser.state = S.COMMENT; parser.comment = ""; parser.sgmlDecl = ""; continue; } if (parser.doctype && parser.doctype !== true && parser.sgmlDecl) { parser.state = S.DOCTYPE_DTD; parser.doctype += "<!" + parser.sgmlDecl + c; parser.sgmlDecl = ""; } else if ((parser.sgmlDecl + c).toUpperCase() === CDATA) { emitNode(parser, "onopencdata"); parser.state = S.CDATA; parser.sgmlDecl = ""; parser.cdata = ""; } else if ((parser.sgmlDecl + c).toUpperCase() === DOCTYPE) { parser.state = S.DOCTYPE; if (parser.doctype || parser.sawRoot) strictFail(parser, "Inappropriately located doctype declaration"); parser.doctype = ""; parser.sgmlDecl = ""; } else if (c === ">") { emitNode(parser, "onsgmldeclaration", parser.sgmlDecl); parser.sgmlDecl = ""; parser.state = S.TEXT; } else if (isQuote(c)) { parser.state = S.SGML_DECL_QUOTED; parser.sgmlDecl += c; } else parser.sgmlDecl += c; continue; case S.SGML_DECL_QUOTED: if (c === parser.q) { parser.state = S.SGML_DECL; parser.q = ""; } parser.sgmlDecl += c; continue; case S.DOCTYPE: if (c === ">") { parser.state = S.TEXT; emitNode(parser, "ondoctype", parser.doctype); parser.doctype = true; } else { parser.doctype += c; if (c === "[") parser.state = S.DOCTYPE_DTD; else if (isQuote(c)) { parser.state = S.DOCTYPE_QUOTED; parser.q = c; } } continue; case S.DOCTYPE_QUOTED: parser.doctype += c; if (c === parser.q) { parser.q = ""; parser.state = S.DOCTYPE; } continue; case S.DOCTYPE_DTD: if (c === "]") { parser.doctype += c; parser.state = S.DOCTYPE; } else if (c === "<") { parser.state = S.OPEN_WAKA; parser.startTagPosition = parser.position; } else if (isQuote(c)) { parser.doctype += c; parser.state = S.DOCTYPE_DTD_QUOTED; parser.q = c; } else parser.doctype += c; continue; case S.DOCTYPE_DTD_QUOTED: parser.doctype += c; if (c === parser.q) { parser.state = S.DOCTYPE_DTD; parser.q = ""; } continue; case S.COMMENT: if (c === "-") parser.state = S.COMMENT_ENDING; else parser.comment += c; continue; case S.COMMENT_ENDING: if (c === "-") { parser.state = S.COMMENT_ENDED; parser.comment = textopts(parser.opt, parser.comment); if (parser.comment) emitNode(parser, "oncomment", parser.comment); parser.comment = ""; } else { parser.comment += "-" + c; parser.state = S.COMMENT; } continue; case S.COMMENT_ENDED: if (c !== ">") { strictFail(parser, "Malformed comment"); parser.comment += "--" + c; parser.state = S.COMMENT; } else if (parser.doctype && parser.doctype !== true) parser.state = S.DOCTYPE_DTD; else parser.state = S.TEXT; continue; case S.CDATA: var starti = i - 1; while (c && c !== "]") { c = charAt(chunk, i++); if (c && parser.trackPosition) { parser.position++; if (c === "\n") { parser.line++; parser.column = 0; } else parser.column++; } } parser.cdata += chunk.substring(starti, i - 1); if (c === "]") parser.state = S.CDATA_ENDING; continue; case S.CDATA_ENDING: if (c === "]") parser.state = S.CDATA_ENDING_2; else { parser.cdata += "]" + c; parser.state = S.CDATA; } continue; case S.CDATA_ENDING_2: if (c === ">") { if (parser.cdata) emitNode(parser, "oncdata", parser.cdata); emitNode(parser, "onclosecdata"); parser.cdata = ""; parser.state = S.TEXT; } else if (c === "]") parser.cdata += "]"; else { parser.cdata += "]]" + c; parser.state = S.CDATA; } continue; case S.PROC_INST: if (c === "?") parser.state = S.PROC_INST_ENDING; else if (isWhitespace(c)) parser.state = S.PROC_INST_BODY; else parser.procInstName += c; continue; case S.PROC_INST_BODY: if (!parser.procInstBody && isWhitespace(c)) continue; else if (c === "?") parser.state = S.PROC_INST_ENDING; else parser.procInstBody += c; continue; case S.PROC_INST_ENDING: if (c === ">") { emitNode(parser, "onprocessinginstruction", { name: parser.procInstName, body: parser.procInstBody }); parser.procInstName = parser.procInstBody = ""; parser.state = S.TEXT; } else { parser.procInstBody += "?" + c; parser.state = S.PROC_INST_BODY; } continue; case S.OPEN_TAG: if (isMatch(nameBody, c)) parser.tagName += c; else { newTag(parser); if (c === ">") openTag(parser); else if (c === "/") parser.state = S.OPEN_TAG_SLASH; else { if (!isWhitespace(c)) strictFail(parser, "Invalid character in tag name"); parser.state = S.ATTRIB; } } continue; case S.OPEN_TAG_SLASH: if (c === ">") { openTag(parser, true); closeTag(parser); } else { strictFail(parser, "Forward-slash in opening tag not followed by >"); parser.state = S.ATTRIB; } continue; case S.ATTRIB: if (isWhitespace(c)) continue; else if (c === ">") openTag(parser); else if (c === "/") parser.state = S.OPEN_TAG_SLASH; else if (isMatch(nameStart, c)) { parser.attribName = c; parser.attribValue = ""; parser.state = S.ATTRIB_NAME; } else strictFail(parser, "Invalid attribute name"); continue; case S.ATTRIB_NAME: if (c === "=") parser.state = S.ATTRIB_VALUE; else if (c === ">") { strictFail(parser, "Attribute without value"); parser.attribValue = parser.attribName; attrib(parser); openTag(parser); } else if (isWhitespace(c)) parser.state = S.ATTRIB_NAME_SAW_WHITE; else if (isMatch(nameBody, c)) parser.attribName += c; else strictFail(parser, "Invalid attribute name"); continue; case S.ATTRIB_NAME_SAW_WHITE: if (c === "=") parser.state = S.ATTRIB_VALUE; else if (isWhitespace(c)) continue; else { strictFail(parser, "Attribute without value"); parser.tag.attributes[parser.attribName] = ""; parser.attribValue = ""; emitNode(parser, "onattribute", { name: parser.attribName, value: "" }); parser.attribName = ""; if (c === ">") openTag(parser); else if (isMatch(nameStart, c)) { parser.attribName = c; parser.state = S.ATTRIB_NAME; } else { strictFail(parser, "Invalid attribute name"); parser.state = S.ATTRIB; } } continue; case S.ATTRIB_VALUE: if (isWhitespace(c)) continue; else if (isQuote(c)) { parser.q = c; parser.state = S.ATTRIB_VALUE_QUOTED; } else { if (!parser.opt.unquotedAttributeValues) error(parser, "Unquoted attribute value"); parser.state = S.ATTRIB_VALUE_UNQUOTED; parser.attribValue = c; } continue; case S.ATTRIB_VALUE_QUOTED: if (c !== parser.q) { if (c === "&") parser.state = S.ATTRIB_VALUE_ENTITY_Q; else parser.attribValue += c; continue; } attrib(parser); parser.q = ""; parser.state = S.ATTRIB_VALUE_CLOSED; continue; case S.ATTRIB_VALUE_CLOSED: if (isWhitespace(c)) parser.state = S.ATTRIB; else if (c === ">") openTag(parser); else if (c === "/") parser.state = S.OPEN_TAG_SLASH; else if (isMatch(nameStart, c)) { strictFail(parser, "No whitespace between attributes"); parser.attribName = c; parser.attribValue = ""; parser.state = S.ATTRIB_NAME; } else strictFail(parser, "Invalid attribute name"); continue; case S.ATTRIB_VALUE_UNQUOTED: if (!isAttribEnd(c)) { if (c === "&") parser.state = S.ATTRIB_VALUE_ENTITY_U; else parser.attribValue += c; continue; } attrib(parser); if (c === ">") openTag(parser); else parser.state = S.ATTRIB; continue; case S.CLOSE_TAG: if (!parser.tagName) if (isWhitespace(c)) continue; else if (notMatch(nameStart, c)) if (parser.script) { parser.script += "</" + c; parser.state = S.SCRIPT; } else strictFail(parser, "Invalid tagname in closing tag."); else parser.tagName = c; else if (c === ">") closeTag(parser); else if (isMatch(nameBody, c)) parser.tagName += c; else if (parser.script) { parser.script += "</" + parser.tagName + c; parser.tagName = ""; parser.state = S.SCRIPT; } else { if (!isWhitespace(c)) strictFail(parser, "Invalid tagname in closing tag"); parser.state = S.CLOSE_TAG_SAW_WHITE; } continue; case S.CLOSE_TAG_SAW_WHITE: if (isWhitespace(c)) continue; if (c === ">") closeTag(parser); else strictFail(parser, "Invalid characters in closing tag"); continue; case S.TEXT_ENTITY: case S.ATTRIB_VALUE_ENTITY_Q: case S.ATTRIB_VALUE_ENTITY_U: var returnState; var buffer; switch (parser.state) { case S.TEXT_ENTITY: returnState = S.TEXT; buffer = "textNode"; break; case