import { __commonJS } from "../../../_virtual/rolldown_runtime.mjs";
import { require_lib } from "../../@xmldom/xmldom/lib/index.mjs";
import { require_xpath } from "../node_modules/xpath/xpath.mjs";
import { require_dist } from "../../@xmldom/is-dom-node/dist/index.mjs";
import { require_utils } from "./utils.mjs";
import { require_c14n_canonicalization } from "./c14n-canonicalization.mjs";
import { require_exclusive_canonicalization } from "./exclusive-canonicalization.mjs";
import { require_util } from "../../util/util.mjs";
import { require_enveloped_signature } from "./enveloped-signature.mjs";
import { require_hash_algorithms } from "./hash-algorithms.mjs";
import { require_signature_algorithms } from "./signature-algorithms.mjs";

//#region ../../node_modules/xml-crypto/lib/signed-xml.js
var require_signed_xml = /* @__PURE__ */ __commonJS({ "../../node_modules/xml-crypto/lib/signed-xml.js": ((exports) => {
	Object.defineProperty(exports, "__esModule", { value: true });
	exports.SignedXml = void 0;
	const isDomNode = require_dist();
	const xmldom = require_lib();
	const util_1 = require_util();
	const xpath = require_xpath();
	const c14n = require_c14n_canonicalization();
	const envelopedSignatures = require_enveloped_signature();
	const execC14n = require_exclusive_canonicalization();
	const hashAlgorithms = require_hash_algorithms();
	const signatureAlgorithms = require_signature_algorithms();
	const utils = require_utils();
	var SignedXml = class SignedXml {
		/**
		* The SignedXml constructor provides an abstraction for sign and verify xml documents. The object is constructed using
		* @param options {@link SignedXmlOptions}
		*/
		constructor(options = {}) {
			/**
			* One of the supported signature algorithms.
			* @see {@link SignatureAlgorithmType}
			*/
			this.signatureAlgorithm = void 0;
			/**
			* Rules used to convert an XML document into its canonical form.
			*/
			this.canonicalizationAlgorithm = void 0;
			/**
			* It specifies a list of namespace prefixes that should be considered "inclusive" during the canonicalization process.
			*/
			this.inclusiveNamespacesPrefixList = [];
			this.namespaceResolver = { lookupNamespaceURI: function() {
				throw new Error("Not implemented");
			} };
			this.implicitTransforms = [];
			this.keyInfoAttributes = {};
			this.getKeyInfoContent = SignedXml.getKeyInfoContent;
			this.getCertFromKeyInfo = SignedXml.getCertFromKeyInfo;
			this.id = 0;
			this.signedXml = "";
			this.signatureXml = "";
			this.signatureNode = null;
			this.signatureValue = "";
			this.originalXmlWithIds = "";
			this.keyInfo = null;
			/**
			* Contains the references that were signed.
			* @see {@link Reference}
			*/
			this.references = [];
			/**
			* Contains the canonicalized XML of the references that were validly signed.
			*
			* This populates with the canonical XML of the reference only after
			* verifying the signature is cryptographically authentic.
			*/
			this.signedReferences = [];
			/**
			*  To add a new transformation algorithm create a new class that implements the {@link TransformationAlgorithm} interface, and register it here. More info: {@link https://github.com/node-saml/xml-crypto#customizing-algorithms|Customizing Algorithms}
			*/
			this.CanonicalizationAlgorithms = {
				"http://www.w3.org/TR/2001/REC-xml-c14n-20010315": c14n.C14nCanonicalization,
				"http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments": c14n.C14nCanonicalizationWithComments,
				"http://www.w3.org/2001/10/xml-exc-c14n#": execC14n.ExclusiveCanonicalization,
				"http://www.w3.org/2001/10/xml-exc-c14n#WithComments": execC14n.ExclusiveCanonicalizationWithComments,
				"http://www.w3.org/2000/09/xmldsig#enveloped-signature": envelopedSignatures.EnvelopedSignature
			};
			/**
			* To add a new hash algorithm create a new class that implements the {@link HashAlgorithm} interface, and register it here. More info: {@link https://github.com/node-saml/xml-crypto#customizing-algorithms|Customizing Algorithms}
			*/
			this.HashAlgorithms = {
				"http://www.w3.org/2000/09/xmldsig#sha1": hashAlgorithms.Sha1,
				"http://www.w3.org/2001/04/xmlenc#sha256": hashAlgorithms.Sha256,
				"http://www.w3.org/2001/04/xmlenc#sha512": hashAlgorithms.Sha512
			};
			/**
			* To add a new signature algorithm create a new class that implements the {@link SignatureAlgorithm} interface, and register it here. More info: {@link https://github.com/node-saml/xml-crypto#customizing-algorithms|Customizing Algorithms}
			*/
			this.SignatureAlgorithms = {
				"http://www.w3.org/2000/09/xmldsig#rsa-sha1": signatureAlgorithms.RsaSha1,
				"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256": signatureAlgorithms.RsaSha256,
				"http://www.w3.org/2001/04/xmldsig-more#rsa-sha512": signatureAlgorithms.RsaSha512
			};
			const { idMode, idAttribute, privateKey, publicCert, signatureAlgorithm, canonicalizationAlgorithm, inclusiveNamespacesPrefixList, implicitTransforms, keyInfoAttributes, getKeyInfoContent, getCertFromKeyInfo } = options;
			this.idMode = idMode;
			this.idAttributes = [
				"Id",
				"ID",
				"id"
			];
			if (idAttribute) this.idAttributes.unshift(idAttribute);
			this.privateKey = privateKey;
			this.publicCert = publicCert;
			this.signatureAlgorithm = signatureAlgorithm ?? this.signatureAlgorithm;
			this.canonicalizationAlgorithm = canonicalizationAlgorithm;
			if (typeof inclusiveNamespacesPrefixList === "string") this.inclusiveNamespacesPrefixList = inclusiveNamespacesPrefixList.split(" ");
			else if (utils.isArrayHasLength(inclusiveNamespacesPrefixList)) this.inclusiveNamespacesPrefixList = inclusiveNamespacesPrefixList;
			this.implicitTransforms = implicitTransforms ?? this.implicitTransforms;
			this.keyInfoAttributes = keyInfoAttributes ?? this.keyInfoAttributes;
			this.getKeyInfoContent = getKeyInfoContent ?? this.getKeyInfoContent;
			this.getCertFromKeyInfo = getCertFromKeyInfo ?? SignedXml.noop;
			this.CanonicalizationAlgorithms;
			this.HashAlgorithms;
			this.SignatureAlgorithms;
		}
		/**
		* Due to key-confusion issues, it's risky to have both hmac
		* and digital signature algorithms enabled at the same time.
		* This enables HMAC and disables other signing algorithms.
		*/
		enableHMAC() {
			this.SignatureAlgorithms = { "http://www.w3.org/2000/09/xmldsig#hmac-sha1": signatureAlgorithms.HmacSha1 };
			this.getKeyInfoContent = SignedXml.noop;
		}
		/**
		* Builds the contents of a KeyInfo element as an XML string.
		*
		* For example, if the value of the prefix argument is 'foo', then
		* the resultant XML string will be "<foo:X509Data></foo:X509Data>"
		*
		* @return an XML string representation of the contents of a KeyInfo element, or `null` if no `KeyInfo` element should be included
		*/
		static getKeyInfoContent({ publicCert, prefix }) {
			if (publicCert == null) return null;
			prefix = prefix ? `${prefix}:` : "";
			let x509Certs = "";
			if (Buffer.isBuffer(publicCert)) publicCert = publicCert.toString("latin1");
			let publicCertMatches = [];
			if (typeof publicCert === "string") publicCertMatches = publicCert.match(utils.EXTRACT_X509_CERTS) || [];
			if (publicCertMatches.length > 0) x509Certs = publicCertMatches.map((c) => `<${prefix}X509Certificate>${utils.pemToDer(c).toString("base64")}</${prefix}X509Certificate>`).join("");
			return `<${prefix}X509Data>${x509Certs}</${prefix}X509Data>`;
		}
		/**
		* Returns the value of the signing certificate based on the contents of the
		* specified KeyInfo.
		*
		* @param keyInfo KeyInfo element (@see https://www.w3.org/TR/2008/REC-xmldsig-core-20080610/#sec-X509Data)
		* @return the signing certificate as a string in PEM format
		*/
		static getCertFromKeyInfo(keyInfo) {
			if (keyInfo != null) {
				const cert = xpath.select1(".//*[local-name(.)='X509Certificate']", keyInfo);
				if (isDomNode.isNodeLike(cert)) return utils.derToPem(cert.textContent ?? "", "CERTIFICATE");
			}
			return null;
		}
		checkSignature(xml, callback) {
			if (callback != null && typeof callback !== "function") throw new Error("Last parameter must be a callback function");
			this.signedXml = xml;
			const doc = new xmldom.DOMParser().parseFromString(xml);
			this.references = [];
			const unverifiedSignedInfoCanon = this.getCanonSignedInfoXml(doc);
			if (!unverifiedSignedInfoCanon) {
				if (callback) {
					callback(/* @__PURE__ */ new Error("Canonical signed info cannot be empty"), false);
					return;
				}
				throw new Error("Canonical signed info cannot be empty");
			}
			const unverifiedSignedInfoDoc = new xmldom.DOMParser().parseFromString(unverifiedSignedInfoCanon, "text/xml").documentElement;
			if (!unverifiedSignedInfoDoc) {
				if (callback) {
					callback(/* @__PURE__ */ new Error("Could not parse unverifiedSignedInfoCanon into a document"), false);
					return;
				}
				throw new Error("Could not parse unverifiedSignedInfoCanon into a document");
			}
			const references = utils.findChildren(unverifiedSignedInfoDoc, "Reference");
			if (!utils.isArrayHasLength(references)) {
				if (callback) {
					callback(/* @__PURE__ */ new Error("could not find any Reference elements"), false);
					return;
				}
				throw new Error("could not find any Reference elements");
			}
			for (const reference of references) this.loadReference(reference);
			if (!this.getReferences().every((ref) => this.validateReference(ref, doc))) {
				this.signedReferences = [];
				this.references.forEach((ref) => {
					ref.signedReference = void 0;
				});
				if (callback) {
					callback(/* @__PURE__ */ new Error("Could not validate all references"), false);
					return;
				}
				return false;
			}
			const signer = this.findSignatureAlgorithm(this.signatureAlgorithm);
			const key = this.getCertFromKeyInfo(this.keyInfo) || this.publicCert || this.privateKey;
			if (key == null) throw new Error("KeyInfo or publicCert or privateKey is required to validate signature");
			if (signer.verifySignature(unverifiedSignedInfoCanon, key, this.signatureValue) === true) if (callback) callback(null, true);
			else return true;
			else {
				this.signedReferences = [];
				this.references.forEach((ref) => {
					ref.signedReference = void 0;
				});
				if (callback) {
					callback(/* @__PURE__ */ new Error(`invalid signature: the signature value ${this.signatureValue} is incorrect`));
					return;
				} else throw new Error(`invalid signature: the signature value ${this.signatureValue} is incorrect`);
			}
		}
		getCanonSignedInfoXml(doc) {
			if (this.signatureNode == null) throw new Error("No signature found.");
			if (typeof this.canonicalizationAlgorithm !== "string") throw new Error("Missing canonicalizationAlgorithm when trying to get signed info for XML");
			const signedInfo = utils.findChildren(this.signatureNode, "SignedInfo");
			if (signedInfo.length === 0) throw new Error("could not find SignedInfo element in the message");
			if (signedInfo.length > 1) throw new Error("could not get canonicalized signed info for a signature that contains multiple SignedInfo nodes");
			if (this.canonicalizationAlgorithm === "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" || this.canonicalizationAlgorithm === "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments") {
				if (!doc || typeof doc !== "object") throw new Error("When canonicalization method is non-exclusive, whole xml dom must be provided as an argument");
			}
			const c14nOptions = { ancestorNamespaces: utils.findAncestorNs(doc, "//*[local-name()='SignedInfo']") };
			return this.getCanonXml([this.canonicalizationAlgorithm], signedInfo[0], c14nOptions);
		}
		getCanonReferenceXml(doc, ref, node) {
			/**
			* Search for ancestor namespaces before canonicalization.
			*/
			if (Array.isArray(ref.transforms)) ref.ancestorNamespaces = utils.findAncestorNs(doc, ref.xpath, this.namespaceResolver);
			const c14nOptions = {
				inclusiveNamespacesPrefixList: ref.inclusiveNamespacesPrefixList,
				ancestorNamespaces: ref.ancestorNamespaces
			};
			return this.getCanonXml(ref.transforms, node, c14nOptions);
		}
		calculateSignatureValue(doc, callback) {
			const signedInfoCanon = this.getCanonSignedInfoXml(doc);
			const signer = this.findSignatureAlgorithm(this.signatureAlgorithm);
			if (this.privateKey == null) throw new Error("Private key is required to compute signature");
			if (typeof callback === "function") signer.getSignature(signedInfoCanon, this.privateKey, callback);
			else this.signatureValue = signer.getSignature(signedInfoCanon, this.privateKey);
		}
		findSignatureAlgorithm(name) {
			if (name == null) throw new Error("signatureAlgorithm is required");
			const algo = this.SignatureAlgorithms[name];
			if (algo) return new algo();
			else throw new Error(`signature algorithm '${name}' is not supported`);
		}
		findCanonicalizationAlgorithm(name) {
			if (name != null) {
				const algo = this.CanonicalizationAlgorithms[name];
				if (algo) return new algo();
			}
			throw new Error(`canonicalization algorithm '${name}' is not supported`);
		}
		findHashAlgorithm(name) {
			const algo = this.HashAlgorithms[name];
			if (algo) return new algo();
			else throw new Error(`hash algorithm '${name}' is not supported`);
		}
		validateElementAgainstReferences(elemOrXpath, doc) {
			let elem;
			if (typeof elemOrXpath === "string") {
				const firstElem = xpath.select1(elemOrXpath, doc);
				isDomNode.assertIsElementNode(firstElem);
				elem = firstElem;
			} else elem = elemOrXpath;
			for (const ref of this.getReferences()) {
				const uri = ref.uri?.[0] === "#" ? ref.uri.substring(1) : ref.uri;
				for (const attr of this.idAttributes) if (uri === elem.getAttribute(attr)) {
					ref.xpath = `//*[@*[local-name(.)='${attr}']='${uri}']`;
					break;
				}
				const canonXml = this.getCanonReferenceXml(doc, ref, elem);
				const digest = this.findHashAlgorithm(ref.digestAlgorithm).getHash(canonXml);
				if (utils.validateDigestValue(digest, ref.digestValue)) return ref;
			}
			throw new Error("No references passed validation");
		}
		validateReference(ref, doc) {
			const uri = ref.uri?.[0] === "#" ? ref.uri.substring(1) : ref.uri;
			let elem = null;
			if (uri === "") elem = xpath.select1("//*", doc);
			else if (uri?.indexOf("'") !== -1) throw new Error("Cannot validate a uri with quotes inside it");
			else {
				let num_elements_for_id = 0;
				for (const attr of this.idAttributes) {
					const tmp_elemXpath = `//*[@*[local-name(.)='${attr}']='${uri}']`;
					const tmp_elem = xpath.select(tmp_elemXpath, doc);
					if (utils.isArrayHasLength(tmp_elem)) {
						num_elements_for_id += tmp_elem.length;
						if (num_elements_for_id > 1) throw new Error("Cannot validate a document which contains multiple elements with the same value for the ID / Id / Id attributes, in order to prevent signature wrapping attack.");
						elem = tmp_elem[0];
						ref.xpath = tmp_elemXpath;
					}
				}
			}
			ref.getValidatedNode = (0, util_1.deprecate)((xpathSelector) => {
				xpathSelector = xpathSelector || ref.xpath;
				if (typeof xpathSelector !== "string" || ref.validationError != null) return null;
				const selectedValue = xpath.select1(xpathSelector, doc);
				return isDomNode.isNodeLike(selectedValue) ? selectedValue : null;
			}, "`ref.getValidatedNode()` is deprecated and insecure. Use `ref.signedReference` or `this.getSignedReferences()` instead.");
			if (!isDomNode.isNodeLike(elem)) {
				ref.validationError = /* @__PURE__ */ new Error(`invalid signature: the signature references an element with uri ${ref.uri} but could not find such element in the xml`);
				return false;
			}
			const canonXml = this.getCanonReferenceXml(doc, ref, elem);
			const digest = this.findHashAlgorithm(ref.digestAlgorithm).getHash(canonXml);
			if (!utils.validateDigestValue(digest, ref.digestValue)) {
				ref.validationError = /* @__PURE__ */ new Error(`invalid signature: for uri ${ref.uri} calculated digest is ${digest} but the xml to validate supplies digest ${ref.digestValue}`);
				return false;
			}
			this.signedReferences.push(canonXml);
			ref.signedReference = canonXml;
			return true;
		}
		findSignatures(doc) {
			const nodes = xpath.select("//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", doc);
			return isDomNode.isArrayOfNodes(nodes) ? nodes : [];
		}
		/**
		* Loads the signature information from the provided XML node or string.
		*
		* @param signatureNode The XML node or string representing the signature.
		*/
		loadSignature(signatureNode) {
			if (typeof signatureNode === "string") this.signatureNode = signatureNode = new xmldom.DOMParser().parseFromString(signatureNode);
			else this.signatureNode = signatureNode;
			this.signatureXml = signatureNode.toString();
			const node = xpath.select1(".//*[local-name(.)='CanonicalizationMethod']/@Algorithm", signatureNode);
			if (!isDomNode.isNodeLike(node)) throw new Error("could not find CanonicalizationMethod/@Algorithm element");
			if (isDomNode.isAttributeNode(node)) this.canonicalizationAlgorithm = node.value;
			const signatureAlgorithm = xpath.select1(".//*[local-name(.)='SignatureMethod']/@Algorithm", signatureNode);
			if (isDomNode.isAttributeNode(signatureAlgorithm)) this.signatureAlgorithm = signatureAlgorithm.value;
			const signedInfoNodes = utils.findChildren(this.signatureNode, "SignedInfo");
			if (!utils.isArrayHasLength(signedInfoNodes)) throw new Error("no signed info node found");
			if (signedInfoNodes.length > 1) throw new Error("could not load signature that contains multiple SignedInfo nodes");
			let canonicalizationAlgorithmForSignedInfo = this.canonicalizationAlgorithm;
			if (!canonicalizationAlgorithmForSignedInfo || canonicalizationAlgorithmForSignedInfo === "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" || canonicalizationAlgorithmForSignedInfo === "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments") canonicalizationAlgorithmForSignedInfo = "http://www.w3.org/2001/10/xml-exc-c14n#";
			const temporaryCanonSignedInfo = this.getCanonXml([canonicalizationAlgorithmForSignedInfo], signedInfoNodes[0]);
			const signedInfoDoc = new xmldom.DOMParser().parseFromString(temporaryCanonSignedInfo, "text/xml").documentElement;
			this.references = [];
			const references = utils.findChildren(signedInfoDoc, "Reference");
			if (!utils.isArrayHasLength(references)) throw new Error("could not find any Reference elements");
			for (const reference of references) this.loadReference(reference);
			const signatureValue = xpath.select1(".//*[local-name(.)='SignatureValue']/text()", signatureNode);
			if (isDomNode.isTextNode(signatureValue)) this.signatureValue = signatureValue.data.replace(/\r?\n/g, "");
			const keyInfo = xpath.select1(".//*[local-name(.)='KeyInfo']", signatureNode);
			if (isDomNode.isNodeLike(keyInfo)) this.keyInfo = keyInfo;
		}
		/**
		* Load the reference xml node to a model
		*
		*/
		loadReference(refNode) {
			let nodes = utils.findChildren(refNode, "DigestMethod");
			if (nodes.length === 0) throw new Error(`could not find DigestMethod in reference ${refNode.toString()}`);
			const digestAlgoNode = nodes[0];
			const attr = utils.findAttr(digestAlgoNode, "Algorithm");
			if (!attr) throw new Error(`could not find Algorithm attribute in node ${digestAlgoNode.toString()}`);
			const digestAlgo = attr.value;
			nodes = utils.findChildren(refNode, "DigestValue");
			if (nodes.length === 0) throw new Error(`could not find DigestValue node in reference ${refNode.toString()}`);
			if (nodes.length > 1) throw new Error(`could not load reference for a node that contains multiple DigestValue nodes: ${refNode.toString()}`);
			const digestValue = nodes[0].textContent;
			if (!digestValue) throw new Error(`could not find the value of DigestValue in ${refNode.toString()}`);
			const transforms = [];
			let inclusiveNamespacesPrefixList = [];
			nodes = utils.findChildren(refNode, "Transforms");
			if (nodes.length !== 0) {
				const transformsNode = nodes[0];
				const transformsAll = utils.findChildren(transformsNode, "Transform");
				for (const transform of transformsAll) {
					const transformAttr = utils.findAttr(transform, "Algorithm");
					if (transformAttr) transforms.push(transformAttr.value);
				}
				const inclusiveNamespaces = utils.findChildren(transformsAll[transformsAll.length - 1], "InclusiveNamespaces");
				if (utils.isArrayHasLength(inclusiveNamespaces)) inclusiveNamespacesPrefixList = inclusiveNamespaces.flatMap((namespace) => (namespace.getAttribute("PrefixList") ?? "").split(" ")).filter((value) => value.length > 0);
			}
			if (utils.isArrayHasLength(this.implicitTransforms)) this.implicitTransforms.forEach(function(t) {
				transforms.push(t);
			});
			/**
			* DigestMethods take an octet stream rather than a node set. If the output of the last transform is a node set, we
			* need to canonicalize the node set to an octet stream using non-exclusive canonicalization. If there are no
			* transforms, we need to canonicalize because URI dereferencing for a same-document reference will return a node-set.
			* @see:
			* https://www.w3.org/TR/xmldsig-core1/#sec-DigestMethod
			* https://www.w3.org/TR/xmldsig-core1/#sec-ReferenceProcessingModel
			* https://www.w3.org/TR/xmldsig-core1/#sec-Same-Document
			*/
			if (transforms.length === 0 || transforms[transforms.length - 1] === "http://www.w3.org/2000/09/xmldsig#enveloped-signature") transforms.push("http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
			const refUri = isDomNode.isElementNode(refNode) ? refNode.getAttribute("URI") || void 0 : void 0;
			this.addReference({
				transforms,
				digestAlgorithm: digestAlgo,
				uri: refUri,
				digestValue,
				inclusiveNamespacesPrefixList,
				isEmptyUri: false
			});
		}
		/**
		* Adds a reference to the signature.
		*
		* @param xpath The XPath expression to select the XML nodes to be referenced.
		* @param transforms An array of transform algorithms to be applied to the selected nodes.
		* @param digestAlgorithm The digest algorithm to use for computing the digest value.
		* @param uri The URI identifier for the reference. If empty, an empty URI will be used.
		* @param digestValue The expected digest value for the reference.
		* @param inclusiveNamespacesPrefixList The prefix list for inclusive namespace canonicalization.
		* @param isEmptyUri Indicates whether the URI is empty. Defaults to `false`.
		*/
		addReference({ xpath: xpath$1, transforms, digestAlgorithm, uri = "", digestValue, inclusiveNamespacesPrefixList = [], isEmptyUri = false }) {
			if (digestAlgorithm == null) throw new Error("digestAlgorithm is required");
			if (!utils.isArrayHasLength(transforms)) throw new Error("transforms must contain at least one transform algorithm");
			this.references.push({
				xpath: xpath$1,
				transforms,
				digestAlgorithm,
				uri,
				digestValue,
				inclusiveNamespacesPrefixList,
				isEmptyUri,
				getValidatedNode: () => {
					throw new Error("Reference has not been validated yet; Did you call `sig.checkSignature()`?");
				}
			});
		}
		/**
		* Returns the list of references.
		*/
		getReferences() {
			return this.references;
		}
		getSignedReferences() {
			return [...this.signedReferences];
		}
		computeSignature(xml, options, callbackParam) {
			let callback;
			if (typeof options === "function" && callbackParam == null) {
				callback = options;
				options = {};
			} else {
				callback = callbackParam;
				options = options ?? {};
			}
			const doc = new xmldom.DOMParser().parseFromString(xml);
			let xmlNsAttr = "xmlns";
			const signatureAttrs = [];
			let currentPrefix;
			const validActions = [
				"append",
				"prepend",
				"before",
				"after"
			];
			const prefix = options.prefix;
			const attrs = options.attrs || {};
			const location = options.location || {};
			const existingPrefixes = options.existingPrefixes || {};
			this.namespaceResolver = { lookupNamespaceURI: function(prefix$1) {
				return prefix$1 ? existingPrefixes[prefix$1] : null;
			} };
			location.reference = location.reference || "/*";
			location.action = location.action || "append";
			if (validActions.indexOf(location.action) === -1) {
				const err = /* @__PURE__ */ new Error(`location.action option has an invalid action: ${location.action}, must be any of the following values: ${validActions.join(", ")}`);
				if (!callback) throw err;
				else {
					callback(err);
					return;
				}
			}
			if (prefix) {
				xmlNsAttr += `:${prefix}`;
				currentPrefix = `${prefix}:`;
			} else currentPrefix = "";
			Object.keys(attrs).forEach(function(name) {
				if (name !== "xmlns" && name !== xmlNsAttr) signatureAttrs.push(`${name}="${attrs[name]}"`);
			});
			signatureAttrs.push(`${xmlNsAttr}="http://www.w3.org/2000/09/xmldsig#"`);
			let signatureXml = `<${currentPrefix}Signature ${signatureAttrs.join(" ")}>`;
			signatureXml += this.createSignedInfo(doc, prefix);
			signatureXml += this.getKeyInfo(prefix);
			signatureXml += `</${currentPrefix}Signature>`;
			this.originalXmlWithIds = doc.toString();
			let existingPrefixesString = "";
			Object.keys(existingPrefixes).forEach(function(key) {
				existingPrefixesString += `xmlns:${key}="${existingPrefixes[key]}" `;
			});
			const dummySignatureWrapper = `<Dummy ${existingPrefixesString}>${signatureXml}</Dummy>`;
			const signatureDoc = new xmldom.DOMParser().parseFromString(dummySignatureWrapper).documentElement.firstChild;
			const referenceNode = xpath.select1(location.reference, doc);
			if (!isDomNode.isNodeLike(referenceNode)) {
				const err2 = /* @__PURE__ */ new Error(`the following xpath cannot be used because it was not found: ${location.reference}`);
				if (!callback) throw err2;
				else {
					callback(err2);
					return;
				}
			}
			if (location.action === "append") referenceNode.appendChild(signatureDoc);
			else if (location.action === "prepend") referenceNode.insertBefore(signatureDoc, referenceNode.firstChild);
			else if (location.action === "before") {
				if (referenceNode.parentNode == null) throw new Error("`location.reference` refers to the root node (by default), so we can't insert `before`");
				referenceNode.parentNode.insertBefore(signatureDoc, referenceNode);
			} else if (location.action === "after") {
				if (referenceNode.parentNode == null) throw new Error("`location.reference` refers to the root node (by default), so we can't insert `after`");
				referenceNode.parentNode.insertBefore(signatureDoc, referenceNode.nextSibling);
			}
			this.signatureNode = signatureDoc;
			const signedInfoNodes = utils.findChildren(this.signatureNode, "SignedInfo");
			if (signedInfoNodes.length === 0) {
				const err3 = /* @__PURE__ */ new Error("could not find SignedInfo element in the message");
				if (!callback) throw err3;
				else {
					callback(err3);
					return;
				}
			}
			const signedInfoNode = signedInfoNodes[0];
			if (typeof callback === "function") this.calculateSignatureValue(doc, (err, signature) => {
				if (err) callback(err);
				else {
					this.signatureValue = signature || "";
					signatureDoc.insertBefore(this.createSignature(prefix), signedInfoNode.nextSibling);
					this.signatureXml = signatureDoc.toString();
					this.signedXml = doc.toString();
					callback(null, this);
				}
			});
			else {
				this.calculateSignatureValue(doc);
				signatureDoc.insertBefore(this.createSignature(prefix), signedInfoNode.nextSibling);
				this.signatureXml = signatureDoc.toString();
				this.signedXml = doc.toString();
			}
		}
		getKeyInfo(prefix) {
			const currentPrefix = prefix ? `${prefix}:` : "";
			let keyInfoAttrs = "";
			if (this.keyInfoAttributes) Object.keys(this.keyInfoAttributes).forEach((name) => {
				keyInfoAttrs += ` ${name}="${this.keyInfoAttributes[name]}"`;
			});
			const keyInfoContent = this.getKeyInfoContent({
				publicCert: this.publicCert,
				prefix
			});
			if (keyInfoAttrs || keyInfoContent) return `<${currentPrefix}KeyInfo${keyInfoAttrs}>${keyInfoContent}</${currentPrefix}KeyInfo>`;
			return "";
		}
		/**
		* Generate the Reference nodes (as part of the signature process)
		*
		*/
		createReferences(doc, prefix) {
			let res = "";
			prefix = prefix || "";
			prefix = prefix ? `${prefix}:` : prefix;
			for (const ref of this.getReferences()) {
				const nodes = xpath.selectWithResolver(ref.xpath ?? "", doc, this.namespaceResolver);
				if (!utils.isArrayHasLength(nodes)) throw new Error(`the following xpath cannot be signed because it was not found: ${ref.xpath}`);
				for (const node of nodes) {
					if (ref.isEmptyUri) res += `<${prefix}Reference URI="">`;
					else {
						const id = this.ensureHasId(node);
						ref.uri = id;
						res += `<${prefix}Reference URI="#${id}">`;
					}
					res += `<${prefix}Transforms>`;
					for (const trans of ref.transforms || []) {
						const transform = this.findCanonicalizationAlgorithm(trans);
						res += `<${prefix}Transform Algorithm="${transform.getAlgorithmName()}"`;
						if (utils.isArrayHasLength(ref.inclusiveNamespacesPrefixList)) {
							res += ">";
							res += `<InclusiveNamespaces PrefixList="${ref.inclusiveNamespacesPrefixList.join(" ")}" xmlns="${transform.getAlgorithmName()}"/>`;
							res += `</${prefix}Transform>`;
						} else res += " />";
					}
					const canonXml = this.getCanonReferenceXml(doc, ref, node);
					const digestAlgorithm = this.findHashAlgorithm(ref.digestAlgorithm);
					res += `</${prefix}Transforms><${prefix}DigestMethod Algorithm="${digestAlgorithm.getAlgorithmName()}" /><${prefix}DigestValue>${digestAlgorithm.getHash(canonXml)}</${prefix}DigestValue></${prefix}Reference>`;
				}
			}
			return res;
		}
		getCanonXml(transforms, node, options = {}) {
			options.defaultNsForPrefix = options.defaultNsForPrefix ?? SignedXml.defaultNsForPrefix;
			options.signatureNode = this.signatureNode;
			let transformedXml = node.cloneNode(true);
			transforms.forEach((transformName) => {
				if (isDomNode.isNodeLike(transformedXml)) transformedXml = this.findCanonicalizationAlgorithm(transformName).process(transformedXml, options);
			});
			return transformedXml.toString();
		}
		/**
		* Ensure an element has Id attribute. If not create it with unique value.
		* Work with both normal and wssecurity Id flavour
		*/
		ensureHasId(node) {
			let attr;
			if (this.idMode === "wssecurity") attr = utils.findAttr(node, "Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
			else this.idAttributes.some((idAttribute) => {
				attr = utils.findAttr(node, idAttribute);
				return !!attr;
			});
			if (attr) return attr.value;
			const id = `_${this.id++}`;
			if (this.idMode === "wssecurity") {
				node.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
				node.setAttributeNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "wsu:Id", id);
			} else node.setAttribute("Id", id);
			return id;
		}
		/**
		* Create the SignedInfo element
		*
		*/
		createSignedInfo(doc, prefix) {
			if (typeof this.canonicalizationAlgorithm !== "string") throw new Error("Missing canonicalizationAlgorithm when trying to create signed info for XML");
			const transform = this.findCanonicalizationAlgorithm(this.canonicalizationAlgorithm);
			const algo = this.findSignatureAlgorithm(this.signatureAlgorithm);
			let currentPrefix;
			currentPrefix = prefix || "";
			currentPrefix = currentPrefix ? `${currentPrefix}:` : currentPrefix;
			let res = `<${currentPrefix}SignedInfo>`;
			res += `<${currentPrefix}CanonicalizationMethod Algorithm="${transform.getAlgorithmName()}"`;
			if (utils.isArrayHasLength(this.inclusiveNamespacesPrefixList)) {
				res += ">";
				res += `<InclusiveNamespaces PrefixList="${this.inclusiveNamespacesPrefixList.join(" ")}" xmlns="${transform.getAlgorithmName()}"/>`;
				res += `</${currentPrefix}CanonicalizationMethod>`;
			} else res += " />";
			res += `<${currentPrefix}SignatureMethod Algorithm="${algo.getAlgorithmName()}" />`;
			res += this.createReferences(doc, prefix);
			res += `</${currentPrefix}SignedInfo>`;
			return res;
		}
		/**
		* Create the Signature element
		*
		*/
		createSignature(prefix) {
			let xmlNsAttr = "xmlns";
			if (prefix) {
				xmlNsAttr += `:${prefix}`;
				prefix += ":";
			} else prefix = "";
			const signatureValueXml = `<${prefix}SignatureValue>${this.signatureValue}</${prefix}SignatureValue>`;
			const dummySignatureWrapper = `<${prefix}Signature ${xmlNsAttr}="http://www.w3.org/2000/09/xmldsig#">${signatureValueXml}</${prefix}Signature>`;
			return new xmldom.DOMParser().parseFromString(dummySignatureWrapper).documentElement.firstChild;
		}
		/**
		* Returns just the signature part, must be called only after {@link computeSignature}
		*
		* @returns The signature XML.
		*/
		getSignatureXml() {
			return this.signatureXml;
		}
		/**
		* Returns the original xml with Id attributes added on relevant elements (required for validation), must be called only after {@link computeSignature}
		*
		* @returns The original XML with IDs.
		*/
		getOriginalXmlWithIds() {
			return this.originalXmlWithIds;
		}
		/**
		* Returns the original xml document with the signature in it, must be called only after {@link computeSignature}
		*
		* @returns The signed XML.
		*/
		getSignedXml() {
			return this.signedXml;
		}
	};
	exports.SignedXml = SignedXml;
	SignedXml.defaultNsForPrefix = { ds: "http://www.w3.org/2000/09/xmldsig#" };
	SignedXml.noop = () => null;
}) });

//#endregion
export default require_signed_xml();

export { require_signed_xml };
//# sourceMappingURL=signed-xml.mjs.map