tsdav
Version:
WebDAV, CALDAV, and CARDDAV client for Nodejs and the Browser
1,747 lines • 152 kB
JavaScript
//#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