{"version":3,"sources":["jsdelivr-header.js","/npm/@inrupt/solid-client@4.0.0/src/interfaces.ts","/npm/@inrupt/solid-client@4.0.0/src/interfaces.internal.ts","/npm/@inrupt/solid-client@4.0.0/src/resource/resource.internal.ts","/npm/@inrupt/solid-client@4.0.0/src/constants.ts","/npm/@inrupt/solid-client@4.0.0/src/resource/resource.ts","/npm/@inrupt/solid-client@4.0.0/src/formats/jsonLd.ts","/npm/@inrupt/solid-client@4.0.0/src/rdf.internal.ts","/npm/@inrupt/solid-client@4.0.0/src/datatypes.ts","/npm/@inrupt/solid-client@4.0.0/src/rdfjs.internal.ts","/npm/@inrupt/solid-client@4.0.0/src/formats/turtle.ts","/npm/@inrupt/solid-client@4.0.0/src/formats/prefixes.ts","/npm/@inrupt/solid-client@4.0.0/src/rdfjs.ts","/npm/@inrupt/solid-client@4.0.0/src/formats/solidDatasetAsTurtle.ts","/npm/@inrupt/solid-client@4.0.0/src/resource/file.ts","/npm/@inrupt/solid-client@4.0.0/src/thing/thing.internal.ts","/npm/@inrupt/solid-client@4.0.0/src/thing/get.ts","/npm/@inrupt/solid-client@4.0.0/src/thing/thing.ts","/npm/@inrupt/solid-client@4.0.0/src/resource/iri.internal.ts","/npm/@inrupt/solid-client@4.0.0/src/resource/solidDataset.ts","/npm/@inrupt/solid-client@4.0.0/src/resource/mock.ts","/npm/@inrupt/solid-client@4.0.0/src/thing/add.ts","/npm/@inrupt/solid-client@4.0.0/src/thing/remove.ts","/npm/@inrupt/solid-client@4.0.0/src/thing/set.ts","/npm/@inrupt/solid-client@4.0.0/src/thing/build.ts","/npm/@inrupt/solid-client@4.0.0/src/thing/mock.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/acp.internal.ts","/npm/@inrupt/solid-client@4.0.0/src/acl/acl.internal.ts","/npm/@inrupt/solid-client@4.0.0/src/acl/acl.ts","/npm/@inrupt/solid-client@4.0.0/src/acl/agent.ts","/npm/@inrupt/solid-client@4.0.0/src/acl/group.ts","/npm/@inrupt/solid-client@4.0.0/src/acl/class.ts","/npm/@inrupt/solid-client@4.0.0/src/acl/mock.internal.ts","/npm/@inrupt/solid-client@4.0.0/src/acl/mock.ts","/npm/@inrupt/solid-client@4.0.0/src/profile/jwks.ts","/npm/@inrupt/solid-client@4.0.0/src/profile/webid.ts","/npm/@inrupt/solid-client@4.0.0/src/universal/getAclServerResourceInfo.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/constants.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/control.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/internal/getDefaultAccessControlUrl.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/internal/getDefaultAccessControlThing.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/internal/getModes.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/internal/setAcr.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/internal/setModes.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/util/setVcAccess.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/util/getVcAccess.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/acp.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/control.internal.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/internal/getAccessControlResourceThing.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/accessControl/getAccessControlUrlAll.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/internal/getPolicyUrls.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/getPolicyUrlAll.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/getAcrPolicyUrlAll.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/getAllowModes.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/getDenyModes.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/util/getAgentAccess.ts","/npm/@inrupt/solid-client@4.0.0/src/access/wac.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/util/getAcrUrl.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/util/getResourceAcr.ts","/npm/@inrupt/solid-client@4.0.0/src/universal/getAgentAccess.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/util/getAgentUrlAll.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/util/getAgentAccessAll.ts","/npm/@inrupt/solid-client@4.0.0/src/universal/getAgentAccessAll.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/util/getPublicAccess.ts","/npm/@inrupt/solid-client@4.0.0/src/universal/getPublicAccess.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/internal/setAccessControlResourceThing.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/internal/getDefaultAgentMatcherPolicyUrl.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/internal/setDefaultAccessControlThingIfNotExist.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/addAcrPolicyUrl.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/addPolicyUrl.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/internal/setDefaultAgentMatcherPolicyThingIfNotExist.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/internal/getDefaultAgentMatcherPolicyMatcherUrl.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/internal/setDefaultAgentMatcherPolicyMatcherThingIfNotExist.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/matcher.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/util/setAgentAccess.ts","/npm/@inrupt/solid-client@4.0.0/src/universal/setAgentAccess.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/util/setPublicAccess.ts","/npm/@inrupt/solid-client@4.0.0/src/universal/setPublicAccess.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/addMemberAcrPolicyUrl.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/addMemberPolicyUrl.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/accessControl/getMemberAccessControlUrlAll.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/getMemberAcrPolicyUrlAll.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/getMemberPolicyUrlAll.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/removeAcrPolicyUrl.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/removeMemberAcrPolicyUrl.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/removeMemberPolicyUrl.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/removePolicyUrl.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy/setResourcePolicy.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/policy.ts","/npm/@inrupt/solid-client@4.0.0/src/acp/mock.ts","/npm/@inrupt/solid-client@4.0.0/src/index.ts"],"names":[],"mappings":"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","file":"/npm/@inrupt/solid-client@4.0.0/dist/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.48.0.\n * Original file: /npm/@inrupt/solid-client@4.0.0/dist/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Quad, NamedNode } from \"@rdfjs/types\";\nimport type { Access } from \"./acl/acl\";\nimport type { ImmutableDataset, LocalNodeIri, Subject } from \"./rdf.internal\";\n\n/**\n * Alias to indicate where we expect to be given a URL represented as an RDF/JS NamedNode.\n */\nexport type Url = NamedNode;\n/** @hidden Alias of Url for those who prefer to use IRI terminology. */\nexport type Iri = Url;\n/**\n * Alias to indicate where we expect to be given a URL.\n */\nexport type UrlString = string;\n/** @hidden Alias of UrlString for those who prefer to use IRI terminology. */\nexport type IriString = UrlString;\n/**\n * Alias to indicate where we expect to be given a WebId.\n */\nexport type WebId = UrlString;\n\n/**\n * A SolidDataset represents all Quads from a single Resource.\n */\nexport type SolidDataset = ImmutableDataset;\n\n/**\n * A File is anything stored on a Pod in a format that solid-client does not have special affordances for, e.g. an image, or a plain JSON file.\n */\nexport type File = Blob;\n\n/**\n * A JSON data structure that represents a set of public keys as a JSON object.\n * See https://datatracker.ietf.org/doc/html/rfc7517 for details.\n */\nexport type Jwk = Record<string, string>;\n\n/**\n * A JSON data structure holding a list of JWK.\n */\nexport type Jwks = {\n  keys: Jwk[];\n};\n\n/**\n * A Resource is something that can be fetched from a Pod - either structured data in a [[SolidDataset]], or any other [[File]].\n */\nexport type Resource = SolidDataset | File;\n\n/**\n * A Thing represents all Quads with a given Subject URL and a given Named\n * Graph, from a single Resource.\n */\nexport type Thing = Subject;\n\n/**\n * A [[Thing]] for which we know what the full Subject URL is.\n */\nexport type ThingPersisted = Thing & { url: UrlString };\n/**\n * A [[Thing]] whose full Subject URL will be determined when it is persisted.\n */\nexport type ThingLocal = Thing & { url: LocalNodeIri };\n\n/**\n * Represents the BlankNode that will be initialised to a NamedNode when persisted.\n *\n * This is a Blank Node with a `name` property attached, which will be used to construct this\n * Node's full URL once it is persisted, where it will transform into a Named Node.\n *\n * @hidden Utility type; library users should not need to interact with LocalNodes directly.\n */\nexport type LocalNode = NamedNode<LocalNodeIri>;\n\n/**\n * Data that was sent to a Pod includes this metadata describing its relation to the Pod Resource it was sent to.\n *\n * **Do not read these properties directly**; their internal representation may change at any time.\n * Instead, use functions such as [[getSourceUrl]], [[isRawData]] and [[getContentType]].\n */\nexport type WithResourceInfo = {\n  /** @hidden */\n  internal_resourceInfo: {\n    sourceIri: UrlString;\n    isRawData: boolean;\n    contentType?: string;\n  };\n};\n\ntype internal_WacAllow = {\n  user: Access;\n  public: Access;\n};\n\n/**\n * What access the current user has to a particular Resource, and what access everybody has.\n *\n * Note that access for everybody is at the time of writing not returned by\n * servers implementing Access Control Policies, so the `public` property is\n * only available on servers that implement Web Access Control.\n *\n * @since 1.7.0\n */\nexport type EffectiveAccess = {\n  user: {\n    read: boolean;\n    append: boolean;\n    write: boolean;\n  };\n  public?: {\n    read: boolean;\n    append: boolean;\n    write: boolean;\n  };\n};\n\n/**\n * URLs of Resources linked to a given Resource, indexed by relation.\n *\n * @since 1.7.0\n */\nexport type LinkedResourceUrlAll = Record<UrlString | string, UrlString[]>;\n\n/**\n * Data that was fetched from a Pod includes this metadata describing its relation to the Pod Resource it was fetched from.\n *\n * **Do not read these properties directly**; their internal representation may change at any time.\n * Instead, use functions such as [[getSourceUrl]], [[isRawData]] and [[getContentType]].\n */\nexport type WithServerResourceInfo = WithResourceInfo & {\n  /** @hidden */\n  internal_resourceInfo: {\n    /**\n     * The URL reported by the server as possibly containing an ACL file. Note that this file might\n     * not necessarily exist, in which case the ACL of the nearest Container with an ACL applies.\n     *\n     * `linkedResources`, which this property is redundant with, was added later.\n     * Thus, this one will be removed at some point.\n     *\n     * @ignore We anticipate the Solid spec to change how the ACL gets accessed, which would result\n     *         in this API changing as well.\n     */\n    aclUrl?: UrlString;\n    /**\n     * Content-Location is the relative or absolute direct URL to use to access the resource when content negotiation happened.\n     */\n    contentLocation?: UrlString;\n    /**\n     * An object of the links in the `Link` header, keyed by their `rel`.\n     * @hidden\n     */\n    linkedResources: LinkedResourceUrlAll;\n    /**\n     * Location is the relative or absolute URL target of a redirection or the URL of a newly created resource.\n     */\n    location?: UrlString;\n    /**\n     * Access permissions for the current user and the general public for this resource.\n     *\n     * @ignore There is no consensus yet about how this functionality will be incorporated in the\n     *         final spec, so the final implementation might influence this API in the future.\n     * @see https://github.com/solid/solid-spec/blob/cb1373a369398d561b909009bd0e5a8c3fec953b/api-rest.md#wac-allow-headers\n     * @see https://github.com/solid/specification/issues/171\n     */\n    permissions?: internal_WacAllow;\n  };\n};\n\n/**\n * @hidden Data structure to keep track of operations done by us; should not be read or manipulated by the developer.\n */\nexport type WithChangeLog = SolidDataset & {\n  internal_changeLog: {\n    additions: Quad[];\n    deletions: Quad[];\n  };\n};\n\n/**\n * Verify whether a given SolidDataset includes metadata about where it was sent to.\n *\n * @param dataset A [[SolidDataset]] that may have metadata attached about the Resource it was retrieved from.\n * @returns True if `dataset` includes metadata about the Resource it was sent to, false if not.\n * @since 0.2.0\n */\nexport function hasResourceInfo<T>(\n  resource: T,\n): resource is T & WithResourceInfo {\n  const potentialResourceInfo = resource as T & WithResourceInfo;\n  return (\n    typeof potentialResourceInfo === \"object\" &&\n    typeof potentialResourceInfo.internal_resourceInfo === \"object\"\n  );\n}\n\n/**\n * Verify whether a given SolidDataset includes metadata about where it was retrieved from.\n *\n * @param dataset A [[SolidDataset]] that may have metadata attached about the Resource it was retrieved from.\n * @returns True if `dataset` includes metadata about the Resource it was retrieved from, false if not.\n * @since 0.6.0\n */\nexport function hasServerResourceInfo<T>(\n  resource: T,\n): resource is T & WithServerResourceInfo {\n  const potentialResourceInfo = resource as T & WithServerResourceInfo;\n  return (\n    typeof potentialResourceInfo === \"object\" &&\n    typeof potentialResourceInfo.internal_resourceInfo === \"object\" &&\n    typeof potentialResourceInfo.internal_resourceInfo.linkedResources ===\n      \"object\"\n  );\n}\n\n/** @internal */\nexport function hasChangelog<T extends SolidDataset>(\n  dataset: T,\n): dataset is T & WithChangeLog {\n  const potentialChangeLog = dataset as T & WithChangeLog;\n  return (\n    typeof potentialChangeLog.internal_changeLog === \"object\" &&\n    Array.isArray(potentialChangeLog.internal_changeLog.additions) &&\n    Array.isArray(potentialChangeLog.internal_changeLog.deletions)\n  );\n}\n\n/**\n * A RequestInit restriction where the method is set by the library\n *\n * Please note that this function is still experimental and can change in a non-major release.\n */\nexport type UploadRequestInit = Omit<RequestInit, \"method\">;\n\n/**\n * Errors thrown by solid-client extend this class, and can thereby be distinguished from errors\n * thrown in lower-level libraries.\n * @since 1.2.0\n */\nexport class SolidClientError extends Error {}\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n */\nexport type AccessModes = {\n  read: boolean;\n  append: boolean;\n  write: boolean;\n  controlRead: boolean;\n  controlWrite: boolean;\n};\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Iri, IriString } from \"./interfaces\";\n\n/** @internal */\nexport function internal_toIriString(iri: Iri | IriString): IriString {\n  return typeof iri === \"string\" ? iri : iri.value;\n}\n\n/**\n * @hidden\n * @param inputUrl The URL to normalize\n * @param options If trailingSlash is set, a trailing slash will be respectively added/removed.\n * The input URL trailing slash is left unchanged if trailingSlash is undefined.\n * @returns the normalized URL, without relative components, slash sequences, and proper trailing slash.\n */\nexport function normalizeUrl(\n  inputUrl: IriString,\n  options: { trailingSlash?: boolean } = {},\n): IriString {\n  // Normalize relative components.\n  const normalizedUrl = new URL(inputUrl);\n\n  // Collapse slash sequences.\n  normalizedUrl.pathname = normalizedUrl.pathname.replace(/\\/\\/+/g, \"/\");\n\n  // Enforce a trailing slash is present/absent.\n  if (\n    options.trailingSlash === false &&\n    normalizedUrl.pathname.slice(-1) === \"/\"\n  ) {\n    normalizedUrl.pathname = normalizedUrl.pathname.slice(\n      0,\n      normalizedUrl.pathname.length - 1,\n    );\n  }\n  if (\n    options.trailingSlash === true &&\n    normalizedUrl.pathname.slice(-1) !== \"/\"\n  ) {\n    normalizedUrl.pathname = `${normalizedUrl.pathname}/`;\n  }\n\n  return normalizedUrl.href;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport LinkHeader from \"http-link-header\";\nimport type { Access } from \"../acl/acl\";\nimport type { WithServerResourceInfo } from \"../interfaces\";\n\n/**\n * @internal\n */\nexport function internal_parseResourceInfo(\n  response: Response,\n): WithServerResourceInfo[\"internal_resourceInfo\"] {\n  const contentTypeParts =\n    response.headers.get(\"Content-Type\")?.split(\";\") ?? [];\n  // If the server offers a Turtle or JSON-LD serialisation on its own accord,\n  // that tells us whether it is RDF data that the server can understand\n  // (and hence can be updated with a PATCH request with SPARQL INSERT and DELETE statements),\n  // in which case our SolidDataset-related functions should handle it.\n  // For more context, see https://github.com/inrupt/solid-client-js/pull/214.\n  const isSolidDataset =\n    contentTypeParts.length > 0 &&\n    [\"text/turtle\", \"application/ld+json\"].includes(contentTypeParts[0]);\n\n  const resourceInfo: WithServerResourceInfo[\"internal_resourceInfo\"] = {\n    sourceIri: response.url,\n    isRawData: !isSolidDataset,\n    contentLocation: response.headers.get(\"Content-Location\") ?? undefined,\n    contentType: response.headers.get(\"Content-Type\") ?? undefined,\n    linkedResources: {},\n    location: response.headers.get(\"Location\") ?? undefined,\n  };\n\n  const linkHeader = response.headers.get(\"Link\");\n  if (linkHeader) {\n    const parsedLinks = LinkHeader.parse(linkHeader);\n    // Set ACL link\n    const aclLinks = parsedLinks.get(\"rel\", \"acl\");\n    if (aclLinks.length === 1) {\n      resourceInfo.aclUrl = new URL(\n        aclLinks[0].uri,\n        resourceInfo.sourceIri,\n      ).href;\n    }\n    // Parse all link headers and expose them in a standard way\n    // (this can replace the parsing of the ACL link above):\n    resourceInfo.linkedResources = parsedLinks.refs.reduce((rels, ref) => {\n      rels[ref.rel] ??= [];\n      rels[ref.rel].push(new URL(ref.uri, resourceInfo.sourceIri).href);\n      return rels;\n    }, resourceInfo.linkedResources);\n  }\n\n  const wacAllowHeader = response.headers.get(\"WAC-Allow\");\n  if (wacAllowHeader) {\n    resourceInfo.permissions = parseWacAllowHeader(wacAllowHeader);\n  }\n\n  return resourceInfo;\n}\n\n/**\n * Parse a WAC-Allow header into user and public access booleans.\n *\n * @param wacAllowHeader A WAC-Allow header in the format `user=\"read append write control\",public=\"read\"`\n * @see https://github.com/solid/solid-spec/blob/cb1373a369398d561b909009bd0e5a8c3fec953b/api-rest.md#wac-allow-headers\n */\nfunction parseWacAllowHeader(wacAllowHeader: string) {\n  function parsePermissionStatement(permissionStatement: string): Access {\n    const permissions = permissionStatement.split(\" \");\n    const writePermission = permissions.includes(\"write\");\n    return writePermission\n      ? {\n          read: permissions.includes(\"read\"),\n          append: true,\n          write: true,\n          control: permissions.includes(\"control\"),\n        }\n      : {\n          read: permissions.includes(\"read\"),\n          append: permissions.includes(\"append\"),\n          write: false,\n          control: permissions.includes(\"control\"),\n        };\n  }\n  function getStatementFor(header: string, scope: \"user\" | \"public\") {\n    const relevantEntries = header\n      .split(\",\")\n      .map((rawEntry) => rawEntry.split(\"=\"))\n      .filter((parts) => parts.length === 2 && parts[0].trim() === scope);\n\n    // There should only be one statement with the given scope:\n    if (relevantEntries.length !== 1) {\n      return \"\";\n    }\n    const relevantStatement = relevantEntries[0][1].trim();\n\n    // The given statement should be wrapped in double quotes to be valid:\n    if (\n      relevantStatement.charAt(0) !== '\"' ||\n      relevantStatement.charAt(relevantStatement.length - 1) !== '\"'\n    ) {\n      return \"\";\n    }\n    // Return the statment without the wrapping quotes, e.g.: read append write control\n    return relevantStatement.substring(1, relevantStatement.length - 1);\n  }\n\n  return {\n    user: parsePermissionStatement(getStatementFor(wacAllowHeader, \"user\")),\n    public: parsePermissionStatement(getStatementFor(wacAllowHeader, \"public\")),\n  };\n}\n\n/** @hidden Used to instantiate a separate instance from input parameters */\nexport function internal_cloneResource<ResourceExt extends object>(\n  resource: ResourceExt,\n): ResourceExt {\n  let clonedResource;\n  if (typeof (resource as File).slice === \"function\") {\n    // If given Resource is a File:\n    clonedResource = Object.assign((resource as File).slice(), { ...resource });\n  } else {\n    // If it is just a plain object containing metadata:\n    clonedResource = { ...resource };\n  }\n\n  return clonedResource;\n}\n\n/** @internal */\nexport function internal_isUnsuccessfulResponse(\n  response: Response,\n): response is Response & { ok: false } {\n  return !response.ok;\n}\n\nexport function internal_isAuthenticationFailureResponse(\n  response: Response,\n): response is Response & { status: 401 | 403 } {\n  return response.status === 401 || response.status === 403;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\n// TODO: These should be replaced by auto-generated constants,\n//       if we can ensure that unused constants will be excluded from bundles.\n\n/** @hidden */\nexport const acl = {\n  Authorization: \"http://www.w3.org/ns/auth/acl#Authorization\",\n  AuthenticatedAgent: \"http://www.w3.org/ns/auth/acl#AuthenticatedAgent\",\n  accessTo: \"http://www.w3.org/ns/auth/acl#accessTo\",\n  agent: \"http://www.w3.org/ns/auth/acl#agent\",\n  agentGroup: \"http://www.w3.org/ns/auth/acl#agentGroup\",\n  agentClass: \"http://www.w3.org/ns/auth/acl#agentClass\",\n  default: \"http://www.w3.org/ns/auth/acl#default\",\n  defaultForNew: \"http://www.w3.org/ns/auth/acl#defaultForNew\",\n  mode: \"http://www.w3.org/ns/auth/acl#mode\",\n  origin: \"http://www.w3.org/ns/auth/acl#origin\",\n} as const;\n\n/** @hidden */\nexport const rdf = {\n  type: \"http://www.w3.org/1999/02/22-rdf-syntax-ns#type\",\n} as const;\n\n/** @hidden */\nexport const rdfs = {\n  seeAlso: \"http://www.w3.org/2000/01/rdf-schema#seeAlso\",\n} as const;\n\n/** @hidden */\nexport const ldp = {\n  BasicContainer: \"http://www.w3.org/ns/ldp#BasicContainer\",\n  Container: \"http://www.w3.org/ns/ldp#Container\",\n  Resource: \"http://www.w3.org/ns/ldp#Resource\",\n  contains: \"http://www.w3.org/ns/ldp#contains\",\n} as const;\n\n/** @hidden */\nexport const foaf = {\n  Agent: \"http://xmlns.com/foaf/0.1/Agent\",\n  primaryTopic: \"http://xmlns.com/foaf/0.1/primaryTopic\",\n  isPrimaryTopicOf: \"http://xmlns.com/foaf/0.1/isPrimaryTopicOf\",\n} as const;\n\n/** @hidden */\nexport const acp = {\n  AccessControlResource: \"http://www.w3.org/ns/solid/acp#AccessControlResource\",\n  Policy: \"http://www.w3.org/ns/solid/acp#Policy\",\n  AccessControl: \"http://www.w3.org/ns/solid/acp#AccessControl\",\n  Read: \"http://www.w3.org/ns/solid/acp#Read\",\n  Append: \"http://www.w3.org/ns/solid/acp#Append\",\n  Write: \"http://www.w3.org/ns/solid/acp#Write\",\n  /** @deprecated Removed from the ACP proposal, to be replaced by Matchers. */\n  Rule: \"http://www.w3.org/ns/solid/acp#Rule\",\n  Matcher: \"http://www.w3.org/ns/solid/acp#Matcher\",\n  accessControl: \"http://www.w3.org/ns/solid/acp#accessControl\",\n  memberAccessControl: \"http://www.w3.org/ns/solid/acp#memberAccessControl\",\n  apply: \"http://www.w3.org/ns/solid/acp#apply\",\n  /** @deprecated Removed from the ACP proposal, to be replaced by memberAccessControls. */\n  applyMembers: \"http://www.w3.org/ns/solid/acp#applyMembers\",\n  allow: \"http://www.w3.org/ns/solid/acp#allow\",\n  deny: \"http://www.w3.org/ns/solid/acp#deny\",\n  allOf: \"http://www.w3.org/ns/solid/acp#allOf\",\n  anyOf: \"http://www.w3.org/ns/solid/acp#anyOf\",\n  noneOf: \"http://www.w3.org/ns/solid/acp#noneOf\",\n  access: \"http://www.w3.org/ns/solid/acp#access\",\n  /** @deprecated Removed from the ACP proposal, to be replaced by memberAccessControls. */\n  accessMembers: \"http://www.w3.org/ns/solid/acp#accessMembers\",\n  agent: \"http://www.w3.org/ns/solid/acp#agent\",\n  group: \"http://www.w3.org/ns/solid/acp#group\",\n  client: \"http://www.w3.org/ns/solid/acp#client\",\n  PublicAgent: \"http://www.w3.org/ns/solid/acp#PublicAgent\",\n  AuthenticatedAgent: \"http://www.w3.org/ns/solid/acp#AuthenticatedAgent\",\n  CreatorAgent: \"http://www.w3.org/ns/solid/acp#CreatorAgent\",\n} as const;\n\n/** @hidden */\nexport const solid = {\n  PublicOidcClient: \"http://www.w3.org/ns/solid/terms#PublicOidcClient\",\n} as const;\n\n/** @hidden */\nexport const security = {\n  publicKey: \"https://w3id.org/security#publicKey\",\n} as const;\n\n/** @hidden */\nexport const pim = {\n  storage: \"http://www.w3.org/ns/pim/space#storage\",\n} as const;\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\n// This linter exception is introduced for legacy reasons.\n\nimport { ClientHttpError } from \"@inrupt/solid-client-errors\";\nimport type {\n  WithProblemDetails,\n  ProblemDetails,\n} from \"@inrupt/solid-client-errors\";\nimport type {\n  UrlString,\n  Url,\n  WebId,\n  Resource,\n  WithServerResourceInfo,\n  WithResourceInfo,\n  LinkedResourceUrlAll,\n  EffectiveAccess,\n} from \"../interfaces\";\nimport {\n  hasResourceInfo,\n  hasServerResourceInfo,\n  SolidClientError,\n} from \"../interfaces\";\nimport { internal_toIriString, normalizeUrl } from \"../interfaces.internal\";\nimport {\n  internal_isAuthenticationFailureResponse,\n  internal_isUnsuccessfulResponse,\n  internal_parseResourceInfo,\n} from \"./resource.internal\";\nimport { acp } from \"../constants\";\n\n/**\n * Retrieve the information about a resource (e.g. access permissions) without\n * fetching the resource itself.\n *\n * @param url URL to fetch Resource metadata from.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters).\n * @returns Promise resolving to the metadata describing the given Resource, or rejecting if fetching it failed.\n * @since 0.4.0\n */\nexport async function getResourceInfo(\n  url: UrlString,\n  options?: {\n    fetch?: typeof fetch;\n    ignoreAuthenticationErrors?: boolean;\n  },\n): Promise<WithServerResourceInfo> {\n  const response = await (options?.fetch ?? fetch)(normalizeUrl(url), {\n    method: \"HEAD\",\n  });\n  return responseToResourceInfo(response, {\n    ignoreAuthenticationErrors: options?.ignoreAuthenticationErrors ?? false,\n  });\n}\n\n/**\n * Parse Solid metadata from a Response obtained by fetching a Resource from a Solid Pod,\n *\n * @param response A Fetch API Response. See {@link https://developer.mozilla.org/en-US/docs/Web/API/Response MDN}.\n * @returns Resource metadata readable by functions such as [[getSourceUrl]].\n * @hidden This interface is not exposed yet until we've tried it out in practice.\n */\nexport function responseToResourceInfo(\n  response: Response,\n  options: {\n    ignoreAuthenticationErrors: boolean;\n  } = { ignoreAuthenticationErrors: false },\n): WithServerResourceInfo {\n  if (\n    internal_isUnsuccessfulResponse(response) &&\n    (!internal_isAuthenticationFailureResponse(response) ||\n      !options.ignoreAuthenticationErrors)\n  ) {\n    throw new FetchError(\n      `Fetching the metadata of the Resource at [${response.url}] failed: [${response.status}] [${response.statusText}].`,\n      response,\n    );\n  }\n\n  const resourceInfo = internal_parseResourceInfo(response);\n\n  return { internal_resourceInfo: resourceInfo };\n}\n\n/**\n * @param resource Resource for which to check whether it is a Container.\n * @returns Whether `resource` is a Container.\n */\nexport function isContainer(\n  resource: Url | UrlString | WithResourceInfo,\n): boolean {\n  const containerUrl = hasResourceInfo(resource)\n    ? getSourceUrl(resource)\n    : internal_toIriString(resource);\n  return containerUrl.endsWith(\"/\");\n}\n\n/**\n * This function will tell you whether a given Resource contains raw data, or a SolidDataset.\n *\n * @param resource Resource for which to check whether it contains raw data.\n * @return Whether `resource` contains raw data.\n */\nexport function isRawData(resource: WithResourceInfo): boolean {\n  return resource.internal_resourceInfo.isRawData;\n}\n\n/**\n * @param resource Resource for which to determine the Content Type.\n * @returns The Content Type, if known, or null if not known.\n */\nexport function getContentType(resource: WithResourceInfo): string | null {\n  return resource.internal_resourceInfo.contentType ?? null;\n}\n\n/**\n * @param resource\n * @returns The URL from which the Resource has been fetched, or null if it is not known.\n */\nexport function getSourceUrl(resource: WithResourceInfo): string;\nexport function getSourceUrl(resource: Resource): string | null;\nexport function getSourceUrl(\n  resource: Resource | WithResourceInfo,\n): string | null {\n  if (hasResourceInfo(resource)) {\n    return resource.internal_resourceInfo.sourceIri;\n  }\n  return null;\n}\n/** @hidden Alias of getSourceUrl for those who prefer to use IRI terminology. */\nexport const getSourceIri = getSourceUrl;\n\n/**\n * Given a Resource that exposes information about the owner of the Pod it is in, returns the WebID of that owner.\n *\n * Data about the owner of the Pod is exposed when the following conditions hold:\n * - The Pod server supports exposing the Pod owner\n * - The current user is allowed to see who the Pod owner is.\n *\n * If one or more of those conditions are false, this function will return `null`.\n *\n * @param resource A Resource that contains information about the owner of the Pod it is in.\n * @returns The WebID of the owner of the Pod the Resource is in, if provided, or `null` if not.\n * @since 0.6.0\n */\nexport function getPodOwner(resource: WithServerResourceInfo): WebId | null {\n  if (!hasServerResourceInfo(resource)) {\n    return null;\n  }\n\n  const podOwners =\n    getLinkedResourceUrlAll(resource)[\n      \"http://www.w3.org/ns/solid/terms#podOwner\"\n    ] ?? [];\n\n  return podOwners.length === 1 ? podOwners[0] : null;\n}\n\n/**\n * Given a WebID and a Resource that exposes information about the owner of the Pod it is in, returns whether the given WebID is the owner of the Pod.\n *\n * Data about the owner of the Pod is exposed when the following conditions hold:\n * - The Pod server supports exposing the Pod owner\n * - The current user is allowed to see who the Pod owner is.\n *\n * If one or more of those conditions are false, this function will return `null`.\n *\n * @param webId The WebID of which to check whether it is the Pod Owner's.\n * @param resource A Resource that contains information about the owner of the Pod it is in.\n * @returns Whether the given WebID is the Pod Owner's, if the Pod Owner is exposed, or `null` if it is not exposed.\n * @since 0.6.0\n */\nexport function isPodOwner(\n  webId: WebId,\n  resource: WithServerResourceInfo,\n): boolean | null {\n  const podOwner = getPodOwner(resource);\n\n  if (typeof podOwner !== \"string\") {\n    return null;\n  }\n\n  return podOwner === webId;\n}\n\n/**\n * Get the URLs of Resources linked to the given Resource.\n *\n * Solid servers can link Resources to each other. For example, in servers\n * implementing Web Access Control, Resources can have an Access Control List\n * Resource linked to it via the `acl` relation.\n *\n * @param resource A Resource fetched from a Solid Pod.\n * @returns The URLs of Resources linked to the given Resource, indexed by the key that links them.\n * @since 1.7.0\n */\nexport function getLinkedResourceUrlAll(\n  resource: WithServerResourceInfo,\n): LinkedResourceUrlAll {\n  return resource.internal_resourceInfo.linkedResources;\n}\n\n/**\n * Get what access the current user has to the given Resource.\n *\n * This function can tell you what access the current user has for the given\n * Resource, allowing you to e.g. determine that changes to it will be rejected\n * before attempting to do so.\n * Additionally, for servers adhering to the Web Access Control specification,\n * it will tell you what access unauthenticated users have to the given Resource.\n *\n * @param resource A Resource fetched from a Solid Pod.\n * @returns What access the current user and, if supported by the server, unauthenticated users have to the given Resource.\n * @since 1.7.0\n */\nexport function getEffectiveAccess(\n  resource: WithServerResourceInfo,\n): EffectiveAccess {\n  if (typeof resource.internal_resourceInfo.permissions === \"object\") {\n    return {\n      user: {\n        read: resource.internal_resourceInfo.permissions.user.read,\n        append: resource.internal_resourceInfo.permissions.user.append,\n        write: resource.internal_resourceInfo.permissions.user.write,\n      },\n      public: {\n        read: resource.internal_resourceInfo.permissions.public.read,\n        append: resource.internal_resourceInfo.permissions.public.append,\n        write: resource.internal_resourceInfo.permissions.public.write,\n      },\n    };\n  }\n\n  const linkedResourceUrls = getLinkedResourceUrlAll(resource);\n  return {\n    user: {\n      read: linkedResourceUrls[acp.allow]?.includes(acp.Read) ?? false,\n      append:\n        (linkedResourceUrls[acp.allow]?.includes(acp.Append) ||\n          linkedResourceUrls[acp.allow]?.includes(acp.Write)) ??\n        false,\n      write: linkedResourceUrls[acp.allow]?.includes(acp.Write) ?? false,\n    },\n  };\n}\n\n/**\n * Extends the regular JavaScript error object with access to the status code and status message.\n * @since 1.2.0\n */\nexport class FetchError extends SolidClientError implements WithProblemDetails {\n  /** @since 1.3.0 */\n  public readonly response: Response & { ok: false };\n\n  private httpError: ClientHttpError;\n\n  constructor(\n    message: string,\n    errorResponse: Response & { ok: false },\n    responseBody?: string,\n  ) {\n    super(message);\n    this.response = errorResponse;\n    if (typeof responseBody === \"string\") {\n      this.httpError = new ClientHttpError(\n        errorResponse,\n        responseBody,\n        message,\n      );\n    } else {\n      // If no response body is provided, defaults are applied.\n      this.httpError = new ClientHttpError(errorResponse, \"\", message);\n    }\n  }\n\n  get statusCode(): number {\n    return this.response.status;\n  }\n\n  get statusText(): string | undefined {\n    return this.response.statusText;\n  }\n\n  get problemDetails(): ProblemDetails {\n    return this.httpError.problemDetails;\n  }\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport { JsonLdParser } from \"jsonld-streaming-parser\";\nimport { FetchDocumentLoader } from \"jsonld-context-parser\";\nimport { getSourceUrl } from \"../resource/resource\";\nimport type { Parser } from \"../resource/solidDataset\";\n\n/**\n * ```{note} This function is still experimental and subject to change, even\n * in a non-major release.\n * ```\n * This returns a parser that transforms a JSON-LD string into a set of RDFJS quads.\n *\n * @returns A Parser object.\n * @since 1.15.0\n */\nexport const getJsonLdParser = (): Parser => {\n  const onQuadCallbacks: Array<Parameters<Parser[\"onQuad\"]>[0]> = [];\n  const onCompleteCallbacks: Array<Parameters<Parser[\"onComplete\"]>[0]> = [];\n  const onErrorCallbacks: Array<Parameters<Parser[\"onError\"]>[0]> = [];\n\n  return {\n    onQuad: (callback) => {\n      onQuadCallbacks.push(callback);\n    },\n    onError: (callback) => {\n      onErrorCallbacks.push(callback);\n    },\n    onComplete: (callback) => {\n      onCompleteCallbacks.push(callback);\n    },\n    // The following returns a Promise that can be awaited, which is undocumented\n    // behavior that doesn't match the type signature. It prevents a potentially\n    // breaking change, and will be updated on the next major release.\n    parse: (source, resourceInfo) =>\n      new Promise<void>((res) => {\n        const parser = new JsonLdParser({\n          baseIRI: getSourceUrl(resourceInfo),\n          documentLoader: new FetchDocumentLoader((...args) => fetch(...args)),\n        });\n\n        let endCalled = false;\n        function end() {\n          if (!endCalled) {\n            endCalled = true;\n            onCompleteCallbacks.forEach((callback) => callback());\n            res();\n          }\n        }\n\n        parser.on(\"end\", end);\n        parser.on(\"error\", (err) => {\n          onErrorCallbacks.forEach((callback) => callback(err));\n          end();\n        });\n        onQuadCallbacks.forEach((callback) => parser.on(\"data\", callback));\n\n        parser.write(source);\n        parser.end();\n      }),\n  };\n};\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\n// @rdfjs/dataset is a CommonJS module, so named imports break in Node.\n// Thus, import the default export, then obtain the `dataset` property from there.\nimport type * as RdfJs from \"@rdfjs/types\";\nimport { Store } from \"n3\";\nimport type { IriString } from \"./interfaces\";\nimport type { XmlSchemaTypeIri } from \"./datatypes\";\n\nexport const rdfJsDataset: RdfJs.DatasetCoreFactory<RdfJs.Quad>[\"dataset\"] = (\n  quads: RdfJs.Quad[],\n) => new Store(quads);\n\nexport const localNodeSkolemPrefix =\n  \"https://inrupt.com/.well-known/sdk-local-node/\" as const;\nexport type LocalNodeIri = `${typeof localNodeSkolemPrefix}${string}`;\nexport type LocalNodeName = string;\ntype DataTypeIriString = XmlSchemaTypeIri | IriString;\ntype LocaleString = string;\nexport type BlankNodeId = `_:${string}`;\n\nexport type Objects = Readonly<\n  Partial<{\n    literals: Readonly<Record<DataTypeIriString, readonly string[]>>;\n    langStrings: Readonly<Record<LocaleString, readonly string[]>>;\n    namedNodes: ReadonlyArray<LocalNodeIri | IriString>;\n    blankNodes: ReadonlyArray<Predicates | BlankNodeId>;\n  }>\n>;\n\nexport type Predicates = Readonly<Record<IriString, Objects>>;\n\nexport type Subject = Readonly<{\n  type: \"Subject\";\n  url: BlankNodeId | LocalNodeIri | IriString;\n  predicates: Predicates;\n}>;\n\nexport type Graph = Readonly<\n  Record<BlankNodeId | LocalNodeIri | IriString, Subject>\n>;\n\nexport type ImmutableDataset = Readonly<{\n  type: \"Dataset\";\n  graphs: Readonly<Record<IriString, Graph> & { default: Graph }>;\n}>;\n\n/**\n * Runtime freezing might be too much overhead;\n * if so, this function allows us to replace it by a function\n * that merely marks its input as Readonly<> for static analysis.\n */\nexport const { freeze } = Object;\n\nexport function isLocalNodeIri(\n  iri: LocalNodeIri | IriString,\n): iri is LocalNodeIri {\n  return (\n    iri.substring(0, localNodeSkolemPrefix.length) === localNodeSkolemPrefix\n  );\n}\nexport function getLocalNodeName(localNodeIri: LocalNodeIri): string {\n  return localNodeIri.substring(localNodeSkolemPrefix.length);\n}\nexport function getLocalNodeIri(localNodeName: string): LocalNodeIri {\n  return `${localNodeSkolemPrefix}${localNodeName}` as LocalNodeIri;\n}\n\nexport function isBlankNodeId<T>(value: T | BlankNodeId): value is BlankNodeId {\n  return typeof value === \"string\" && value.substring(0, 2) === \"_:\";\n}\n\nexport function getBlankNodeValue(blankNodeId: BlankNodeId): string {\n  return blankNodeId.substring(2);\n}\n\nexport function getBlankNodeId(blankNode: RdfJs.BlankNode): BlankNodeId {\n  return `_:${blankNode.value}` as const;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { NamedNode, Literal, Term, Quad_Subject } from \"@rdfjs/types\";\nimport { DataFactory } from \"./rdfjs.internal\";\nimport type { IriString, Iri, LocalNode } from \"./interfaces\";\nimport { SolidClientError } from \"./interfaces\";\nimport { internal_toIriString } from \"./interfaces.internal\";\nimport { getLocalNodeName, isLocalNodeIri } from \"./rdf.internal\";\n\n/**\n * IRIs of the XML Schema data types we support\n */\nexport const xmlSchemaTypes = {\n  boolean: \"http://www.w3.org/2001/XMLSchema#boolean\",\n  dateTime: \"http://www.w3.org/2001/XMLSchema#dateTime\",\n  date: \"http://www.w3.org/2001/XMLSchema#date\",\n  time: \"http://www.w3.org/2001/XMLSchema#time\",\n  decimal: \"http://www.w3.org/2001/XMLSchema#decimal\",\n  integer: \"http://www.w3.org/2001/XMLSchema#integer\",\n  string: \"http://www.w3.org/2001/XMLSchema#string\",\n  langString: \"http://www.w3.org/1999/02/22-rdf-syntax-ns#langString\",\n} as const;\n\nexport type XmlSchemaTypeIri =\n  (typeof xmlSchemaTypes)[keyof typeof xmlSchemaTypes];\n\n/**\n * @internal\n * @param value Value to serialise.\n * @returns String representation of `value`.\n * @see https://www.w3.org/TR/xmlschema-2/#boolean-lexical-representation\n */\nexport function serializeBoolean(value: boolean): string {\n  return value ? \"true\" : \"false\";\n}\n/**\n * @internal\n * @param value Value to deserialise.\n * @returns Deserialized boolean, or null if the given value is not a valid serialised boolean.\n * @see https://www.w3.org/TR/xmlschema-2/#boolean-lexical-representation\n */\nexport function deserializeBoolean(value: string): boolean | null {\n  if (value === \"true\" || value === \"1\") {\n    return true;\n  }\n  if (value === \"false\" || value === \"0\") {\n    return false;\n  }\n  return null;\n}\n\n/**\n * Time type for time data type attributes\n *\n * @since 1.10.0\n */\nexport type Time = {\n  hour: number;\n  minute: number;\n  second: number;\n  millisecond?: number;\n  timezoneHourOffset?: number;\n  timezoneMinuteOffset?: number;\n};\n\n/**\n * @internal\n * @param value Value to serialise.\n * @returns String representation of `value` in UTC.\n * @see https://www.w3.org/TR/xmlschema-2/#time-lexical-repr\n */\nexport function serializeTime(value: Time): string {\n  let millisecondString;\n  let timezoneString;\n\n  if (value.millisecond) {\n    if (value.millisecond < 10) {\n      millisecondString = `00${value.millisecond}`;\n    } else if (value.millisecond < 100) {\n      millisecondString = `0${value.millisecond}`;\n    } else {\n      millisecondString = value.millisecond;\n    }\n  }\n\n  if (typeof value.timezoneHourOffset === \"number\") {\n    const timezoneFormatted =\n      Math.abs(value.timezoneHourOffset) < 10\n        ? `0${Math.abs(value.timezoneHourOffset)}`\n        : Math.abs(value.timezoneHourOffset);\n\n    timezoneString =\n      value.timezoneHourOffset >= 0\n        ? `+${timezoneFormatted}`\n        : `-${timezoneFormatted}`;\n\n    if (value.timezoneMinuteOffset) {\n      timezoneString = `${timezoneString}:${\n        value.timezoneMinuteOffset < 10\n          ? `0${value.timezoneMinuteOffset}`\n          : value.timezoneMinuteOffset\n      }`;\n    } else {\n      timezoneString += \":00\";\n    }\n  }\n\n  return `${value.hour < 10 ? `0${value.hour}` : value.hour}:${\n    value.minute < 10 ? `0${value.minute}` : value.minute\n  }:${value.second < 10 ? `0${value.second}` : value.second}${\n    value.millisecond ? `.${millisecondString}` : \"\"\n  }${timezoneString || \"\"}`;\n}\n\n/**\n * @internal\n * @param literalString Value to deserialise.\n * @returns Deserialized time, or null if the given value is not a valid serialised datetime.\n * @see https://www.w3.org/TR/xmlschema-2/#time-lexical-repr\n */\nexport function deserializeTime(literalString: string): Time | null {\n  // Time in the format described at\n  // https://www.w3.org/TR/xmlschema-2/#time-lexical-repr\n  // \\d\\d:\\d\\d:\\d\\d - Two digits for the hour, minute and second, respectively, separated by a `:`.\n  //                  Example: \"13:37:42\".\n  // (\\.\\d+)? - Optionally a `.` followed by one or more digits representing milliseconds.\n  //            Example: \".1337\".\n  // (Z|(\\+|-)\\d\\d:\\d\\d) - The letter Z indicating UTC, or a `+` or `-` followed by two digits for\n  //                       the hour offset and two for the minute offset, separated by a `:`.\n  //                       Example: \"+13:37\".\n  const timeRegEx = /\\d\\d:\\d\\d:\\d\\d(\\.\\d+)?(Z|(\\+|-)\\d\\d:\\d\\d)?/;\n  if (!timeRegEx.test(literalString)) {\n    return null;\n  }\n  const [timeString, timezoneString] = splitTimeFromTimezone(literalString);\n  const [hourString, minuteString, timeRest] = timeString.split(\":\");\n  let utcHours = Number.parseInt(hourString, 10);\n  let utcMinutes = Number.parseInt(minuteString, 10);\n  const [secondString, optionalMillisecondString] = timeRest.split(\".\");\n  const utcSeconds = Number.parseInt(secondString, 10);\n  const utcMilliseconds = optionalMillisecondString\n    ? Number.parseInt(optionalMillisecondString, 10)\n    : undefined;\n\n  if (utcMinutes >= 60) {\n    utcHours += 1;\n    utcMinutes -= 60;\n  }\n\n  const deserializedTime: Time = {\n    hour: utcHours,\n    minute: utcMinutes,\n    second: utcSeconds,\n  };\n  if (typeof utcMilliseconds === \"number\") {\n    deserializedTime.millisecond = utcMilliseconds;\n  }\n  if (typeof timezoneString === \"string\") {\n    const [hourOffset, minuteOffset] = getTimezoneOffsets(timezoneString);\n    if (\n      typeof hourOffset !== \"number\" ||\n      hourOffset > 24 ||\n      typeof minuteOffset !== \"number\" ||\n      minuteOffset > 59\n    ) {\n      return null;\n    }\n    deserializedTime.timezoneHourOffset = hourOffset;\n    deserializedTime.timezoneMinuteOffset = minuteOffset;\n  }\n  return deserializedTime;\n}\n\n/**\n * @internal\n * @param value Value to serialise.\n * @returns String representation of `value`.\n * @see https://www.w3.org/TR/xmlschema-2/#dateTime-lexical-representation\n */\nexport function serializeDatetime(value: Date): string {\n  // Although the XML Schema DateTime is not _exactly_ an ISO 8601 string\n  // (see https://www.w3.org/TR/xmlschema-2/#deviantformats),\n  // the deviations only affect the parsing, not the serialisation.\n  // Therefore, we can just use .toISOString():\n  return value.toISOString();\n}\n\n/**\n * @internal\n * @param value Value to deserialise.\n * @returns Deserialized datetime, or null if the given value is not a valid serialised datetime.\n * @see https://www.w3.org/TR/xmlschema-2/#dateTime-lexical-representation\n */\nexport function deserializeDatetime(literalString: string): Date | null {\n  // DateTime in the format described at\n  // https://www.w3.org/TR/xmlschema-2/#dateTime-lexical-representation\n  // (without constraints on the value).\n  // -? - An optional leading `-`.\n  // \\d{4,}- - Four or more digits followed by a `-` representing the year. Example: \"3000-\".\n  // \\d\\d-\\d\\d - Two digits representing the month and two representing the day of the month,\n  //             separated by a `-`. Example: \"11-03\".\n  // T - The letter T, separating the date from the time.\n  // \\d\\d:\\d\\d:\\d\\d - Two digits for the hour, minute and second, respectively, separated by a `:`.\n  //                  Example: \"13:37:42\".\n  // (\\.\\d+)? - Optionally a `.` followed by one or more digits representing milliseconds.\n  //            Example: \".1337\".\n  // (Z|(\\+|-)\\d\\d:\\d\\d) - The letter Z indicating UTC, or a `+` or `-` followed by two digits for\n  //                       the hour offset and two for the minute offset, separated by a `:`.\n  //                       Example: \"+13:37\".\n  const datetimeRegEx =\n    /-?\\d{4,}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d(\\.\\d+)?(Z|(\\+|-)\\d\\d:\\d\\d)?/;\n  if (!datetimeRegEx.test(literalString)) {\n    return null;\n  }\n\n  const [signedDateString, rest] = literalString.split(\"T\");\n  // The date string can optionally be prefixed with `-`,\n  // in which case the year is negative:\n  const [yearMultiplier, dateString] =\n    signedDateString.charAt(0) === \"-\"\n      ? [-1, signedDateString.substring(1)]\n      : [1, signedDateString];\n  const [yearString, monthString, dayString] = dateString.split(\"-\");\n  const utcFullYear = Number.parseInt(yearString, 10) * yearMultiplier;\n  const utcMonth = Number.parseInt(monthString, 10) - 1;\n  const utcDate = Number.parseInt(dayString, 10);\n  const [timeString, timezoneString] = splitTimeFromTimezone(rest);\n  const [hourOffset, minuteOffset] =\n    typeof timezoneString === \"string\"\n      ? getTimezoneOffsets(timezoneString)\n      : [0, 0];\n  const [hourString, minuteString, timeRest] = timeString.split(\":\");\n  const utcHours = Number.parseInt(hourString, 10) + hourOffset;\n  const utcMinutes = Number.parseInt(minuteString, 10) + minuteOffset;\n  const [secondString, optionalMillisecondString] = timeRest.split(\".\");\n  const utcSeconds = Number.parseInt(secondString, 10);\n  const utcMilliseconds = optionalMillisecondString\n    ? Number.parseInt(optionalMillisecondString, 10)\n    : 0;\n  const date = new Date(\n    Date.UTC(\n      utcFullYear,\n      utcMonth,\n      utcDate,\n      utcHours,\n      utcMinutes,\n      utcSeconds,\n      utcMilliseconds,\n    ),\n  );\n\n  // For the year, values from 0 to 99 map to the years 1900 to 1999. Since the serialisation\n  // always writes out the years fully, we should correct this to actually map to the years 0 to 99.\n  // See\n  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date#Individual_date_and_time_component_values\n  if (utcFullYear >= 0 && utcFullYear < 100) {\n    // Note that we base it on the calculated year, rather than the year that was actually read.\n    // This is because the year might actually differ from the value listed in the serialisation,\n    // i.e. when moving the timezone offset to UTC pushes it into a different year:\n    date.setUTCFullYear(date.getUTCFullYear() - 1900);\n  }\n  return date;\n}\n\n/**\n * @internal\n * @param value Value to serialise.\n * @returns String representation of `value`.\n * @see https://www.w3.org/TR/xmlschema-2/#date-lexical-representation\n */\nexport function serializeDate(value: Date): string {\n  const year = value.getFullYear();\n  const month = value.getMonth() + 1;\n  const day = value.getDate();\n  const [, timezone] = splitTimeFromTimezone(value.toISOString());\n\n  return `${year}-${String(month).padStart(2, \"0\")}-${String(day).padStart(\n    2,\n    \"0\",\n  )}${timezone}`;\n}\n\n/**\n * @internal\n * @param value Value to deserialise.\n * @returns Deserialized datetime, or null if the given value is not a valid serialised datetime.\n * @see https://www.w3.org/TR/xmlschema-2/#date-lexical-representation\n */\nexport function deserializeDate(literalString: string): Date | null {\n  // Date in the format described at\n  // https://www.w3.org/TR/xmlschema-2/#date-lexical-representation\n  // (without constraints on the value).\n  // -? - An optional leading `-`.\n  // \\d{4,}- - Four or more digits followed by a `-` representing the year. Example: \"3000-\".\n  // \\d\\d-\\d\\d - Two digits representing the month and two representing the day of the month,\n  //             separated by a `-`. Example: \"11-03\".\n  // (Z|(\\+|-)\\d\\d:\\d\\d) - Optionally, the letter Z indicating UTC, or a `+` or `-` followed by two digits for\n  //                       the hour offset and two for the minute offset, separated by a `:`.\n  //                       Example: \"+13:37\".\n\n  const dateRegEx = /-?\\d{4,}-\\d\\d-\\d\\d(Z|(\\+|-)\\d\\d:\\d\\d)?/;\n  if (!dateRegEx.test(literalString)) {\n    return null;\n  }\n\n  const signedDateString = literalString;\n  // The date string can optionally be prefixed with `-`,\n  // in which case the year is negative:\n  const [yearMultiplier, dateString] =\n    signedDateString.charAt(0) === \"-\"\n      ? [-1, signedDateString.substring(1)]\n      : [1, signedDateString];\n  const [yearString, monthString, dayAndTimezoneString] = dateString.split(\"-\");\n\n  const dayString =\n    dayAndTimezoneString.length > 2\n      ? dayAndTimezoneString.substring(0, 2)\n      : dayAndTimezoneString;\n\n  const utcFullYear = Number.parseInt(yearString, 10) * yearMultiplier;\n  const utcMonth = Number.parseInt(monthString, 10) - 1;\n  const utcDate = Number.parseInt(dayString, 10);\n  const hour = 12;\n\n  // setting at 12:00 avoids all timezones\n  const date = new Date(Date.UTC(utcFullYear, utcMonth, utcDate, hour));\n\n  // For the year, values from 0 to 99 map to the years 1900 to 1999. Since the serialisation\n  // always writes out the years fully, we should correct this to actually map to the years 0 to 99.\n  // See\n  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date#Individual_date_and_time_component_values\n  if (utcFullYear >= 0 && utcFullYear < 100) {\n    date.setUTCFullYear(date.getUTCFullYear() - 1900);\n  }\n  return date;\n}\n\n/**\n * @param timeString An XML Schema time string.\n * @returns A tuple [timeString, timezoneString].\n * @see https://www.w3.org/TR/xmlschema-2/#time-lexical-repr\n */\nfunction splitTimeFromTimezone(timeString: string): [string, string?] {\n  if (timeString.endsWith(\"Z\")) {\n    return [timeString.substring(0, timeString.length - 1), \"Z\"];\n  }\n  const splitOnPlus = timeString.split(\"+\");\n  const splitOnMinus = timeString.split(\"-\");\n\n  if (splitOnPlus.length === 1 && splitOnMinus.length === 1) {\n    return [splitOnPlus[0], undefined];\n  }\n\n  return splitOnPlus.length > splitOnMinus.length\n    ? [splitOnPlus[0], `+${splitOnPlus[1]}`]\n    : [splitOnMinus[0], `-${splitOnMinus[1]}`];\n}\n\n/**\n * @param timezoneString Lexical representation of a time zone in XML Schema.\n * @returns A tuple of the hour and minute offset of the time zone.\n * @see https://www.w3.org/TR/xmlschema-2/#dateTime-timezones\n */\nfunction getTimezoneOffsets(timezoneString: string): [number, number] {\n  if (timezoneString === \"Z\") {\n    return [0, 0];\n  }\n  const multiplier = timezoneString.charAt(0) === \"+\" ? 1 : -1;\n  const [hourString, minuteString] = timezoneString.substring(1).split(\":\");\n  const hours = Number.parseInt(hourString, 10);\n  const minutes = Number.parseInt(minuteString, 10);\n  return [hours * multiplier, minutes * multiplier];\n}\n\n/**\n * @internal\n * @param value Value to serialise.\n * @returns String representation of `value`.\n * @see https://www.w3.org/TR/xmlschema-2/#decimal-lexical-representation\n */\nexport function serializeDecimal(value: number): string {\n  return value.toString();\n}\n/**\n * @internal\n * @param value Value to deserialise.\n * @returns Deserialized decimal, or null if the given value is not a valid serialised decimal.\n * @see https://www.w3.org/TR/xmlschema-2/#decimal-lexical-representation\n */\nexport function deserializeDecimal(literalString: string): number | null {\n  const deserialized = Number.parseFloat(literalString);\n  if (Number.isNaN(deserialized)) {\n    return null;\n  }\n  return deserialized;\n}\n\n/**\n * @internal\n * @param value Value to serialise.\n * @returns String representation of `value`.\n */\nexport function serializeInteger(value: number): string {\n  return value.toString();\n}\n/**\n * @internal\n * @param value Value to deserialise.\n * @returns Deserialized integer, or null if the given value is not a valid serialised integer.\n */\nexport function deserializeInteger(literalString: string): number | null {\n  const deserialized = Number.parseInt(literalString, 10);\n  if (Number.isNaN(deserialized)) {\n    return null;\n  }\n  return deserialized;\n}\n\n/**\n * @internal\n * @param locale Locale to transform into a consistent format.\n */\nexport function normalizeLocale(locale: string): string {\n  return locale.toLowerCase();\n}\n\n/**\n * @internal Library users shouldn't need to be exposed to raw NamedNodes.\n * @param value The value that might or might not be a Named Node.\n * @returns Whether `value` is a Named Node.\n */\nexport function isNamedNode<T>(value: T | NamedNode): value is NamedNode {\n  return isTerm(value) && value.termType === \"NamedNode\";\n}\n\n/**\n * @internal Library users shouldn't need to be exposed to raw Literals.\n * @param value The value that might or might not be a Literal.\n * @returns Whether `value` is a Literal.\n */\nexport function isLiteral<T>(value: T | Literal): value is Literal {\n  return isTerm(value) && value.termType === \"Literal\";\n}\n\n/**\n * @internal Library users shouldn't need to be exposed to raw Terms.\n * @param value The value that might or might not be a Term.\n * @returns Whether `value` is a Term.\n */\nexport function isTerm<T>(value: T | Term): value is Term {\n  return (\n    value !== null &&\n    typeof value === \"object\" &&\n    typeof (value as Term).termType === \"string\" &&\n    typeof (value as Term).value === \"string\" &&\n    typeof (value as Term).equals === \"function\"\n  );\n}\n\n/**\n * @internal Library users shouldn't need to be exposed to LocalNodes.\n * @param value The value that might or might not be a Node with no known IRI yet.\n * @returns Whether `value` is a Node with no known IRI yet.\n */\nexport function isLocalNode<T>(\n  value: T | Quad_Subject | LocalNode,\n): value is LocalNode {\n  return isNamedNode(value) && isLocalNodeIri(value.value);\n}\n\n/**\n * Ensure that a given value is a valid URL.\n *\n * @internal Library users shouldn't need to be exposed to raw URLs.\n * @param iri The value of which to verify that it is a valid URL.\n */\nexport function internal_isValidUrl(iri: Iri | IriString): iri is Iri {\n  const iriString = internal_toIriString(iri);\n  // If the runtime environment supports URL, instantiate one.\n  // If the given IRI is not a valid URL, it will throw an error.\n  // See: https://developer.mozilla.org/en-US/docs/Web/API/URL\n  /* istanbul ignore if [URL is available in our testing environment, so we cannot test the alternative] */\n  if (typeof URL !== \"function\") {\n    // If we can't validate the URL, do not throw an error:\n    return true;\n  }\n  try {\n    new URL(iriString);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Ensure that a given value is a Named Node.\n *\n * If the given parameter is a Named Node already, it will be returned as-is. If it is a string, it\n * will check whether it is a valid IRI. If not, it will throw an error; otherwise a Named Node\n * representing the given IRI will be returned.\n *\n * @internal Library users shouldn't need to be exposed to raw NamedNodes.\n * @param iri The IRI that should be converted into a Named Node, if it isn't one yet.\n */\nexport function asNamedNode(iri: Iri | IriString): NamedNode {\n  if (!internal_isValidUrl(iri)) {\n    throw new ValidUrlExpectedError(iri);\n  }\n  if (isNamedNode(iri)) {\n    return iri;\n  }\n  return DataFactory.namedNode(iri);\n}\n\n/**\n * @internal Utility method; library users should not need to interact with LocalNodes directly.\n * @param localNode The LocalNode to resolve to a NamedNode.\n * @param resourceIri The Resource in which the Node will be saved.\n */\nexport function resolveIriForLocalNode(\n  localNode: LocalNode,\n  resourceIri: IriString,\n): NamedNode {\n  return DataFactory.namedNode(\n    resolveLocalIri(getLocalNodeName(localNode.value), resourceIri),\n  );\n}\n\n/**\n * @internal API for internal use only.\n * @param name The name identifying a Thing.\n * @param resourceIri The Resource in which the Thing can be found.\n */\nexport function resolveLocalIri(\n  name: string,\n  resourceIri: IriString,\n): IriString {\n  /* istanbul ignore if [The URL interface is available in the testing environment, so we cannot test this] */\n  if (typeof URL !== \"function\") {\n    throw new Error(\n      \"The URL interface is not available, so an IRI cannot be determined.\",\n    );\n  }\n  const thingIri = new URL(resourceIri);\n  thingIri.hash = name;\n  return thingIri.href;\n}\n\n/**\n * This error is thrown when a given value is not a proper URL.\n */\nexport class ValidUrlExpectedError extends SolidClientError {\n  public readonly receivedValue: unknown;\n\n  constructor(receivedValue: unknown) {\n    const value = isNamedNode(receivedValue)\n      ? receivedValue.value\n      : receivedValue;\n    const message = `Expected a valid URL, but received: [${value}].`;\n    super(message);\n    this.receivedValue = value;\n  }\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport { DataFactory } from \"n3\";\nimport type * as RdfJs from \"@rdfjs/types\";\nimport type {\n  Graph,\n  ImmutableDataset,\n  Objects,\n  Predicates,\n  Subject,\n} from \"./rdf.internal\";\nimport {\n  freeze,\n  getBlankNodeId,\n  getBlankNodeValue,\n  isBlankNodeId,\n} from \"./rdf.internal\";\nimport type { ToRdfJsOptions } from \"./rdfjs\";\nimport type { IriString } from \"./interfaces\";\nimport { xmlSchemaTypes } from \"./datatypes\";\n\nexport { DataFactory };\n\nexport function addRdfJsQuadToDataset(\n  dataset: ImmutableDataset,\n  quad: RdfJs.Quad,\n): ImmutableDataset {\n  const supportedGraphTypes: Array<typeof quad.graph.termType> = [\n    \"NamedNode\",\n    \"DefaultGraph\",\n  ];\n  if (!supportedGraphTypes.includes(quad.graph.termType)) {\n    throw new Error(\n      `Cannot parse Quads with nodes of type [${quad.graph.termType}] as their Graph node.`,\n    );\n  }\n  const graphId =\n    quad.graph.termType === \"DefaultGraph\" ? \"default\" : quad.graph.value;\n\n  const graph: Graph = dataset.graphs[graphId] ?? {};\n  return freeze({\n    ...dataset,\n    graphs: freeze({\n      ...dataset.graphs,\n      [graphId]: addRdfJsQuadToGraph(graph, quad),\n    }),\n  });\n}\n\nfunction addRdfJsQuadToGraph(graph: Graph, quad: RdfJs.Quad): Graph {\n  const supportedSubjectTypes: Array<typeof quad.subject.termType> = [\n    \"NamedNode\",\n    \"BlankNode\",\n  ];\n  if (!supportedSubjectTypes.includes(quad.subject.termType)) {\n    throw new Error(\n      `Cannot parse Quads with nodes of type [${quad.subject.termType}] as their Subject node.`,\n    );\n  }\n\n  const subjectIri =\n    quad.subject.termType === \"BlankNode\"\n      ? `_:${quad.subject.value}`\n      : quad.subject.value;\n\n  const subject: Subject = graph[subjectIri] ?? {\n    type: \"Subject\",\n    url: subjectIri,\n    predicates: {},\n  };\n  return freeze({\n    ...graph,\n    [subjectIri]: addRdfJsQuadToSubject(subject, quad),\n  });\n}\n\nfunction addRdfJsQuadToSubject(subject: Subject, quad: RdfJs.Quad): Subject {\n  return freeze({\n    ...subject,\n    predicates: addRdfJsQuadToPredicates(subject.predicates, quad),\n  });\n}\n\nfunction addRdfJsQuadToPredicates(\n  predicates: Predicates,\n  quad: RdfJs.Quad,\n): Predicates {\n  const supportedPredicateTypes: Array<typeof quad.predicate.termType> = [\n    \"NamedNode\",\n  ];\n  if (!supportedPredicateTypes.includes(quad.predicate.termType)) {\n    throw new Error(\n      `Cannot parse Quads with nodes of type [${quad.predicate.termType}] as their Predicate node.`,\n    );\n  }\n  const predicateIri = quad.predicate.value;\n  const objects = predicates[predicateIri] ?? {};\n  return freeze({\n    ...predicates,\n    [predicateIri]: addRdfJsQuadToObjects(objects, quad),\n  });\n}\n\nfunction addRdfJsQuadToObjects(objects: Objects, quad: RdfJs.Quad): Objects {\n  if (quad.object.termType === \"NamedNode\") {\n    const namedNodes = freeze([\n      ...(objects.namedNodes ?? []),\n      quad.object.value,\n    ]);\n    return freeze({\n      ...objects,\n      namedNodes,\n    });\n  }\n\n  if (quad.object.termType === \"Literal\") {\n    if (quad.object.datatype.value === xmlSchemaTypes.langString) {\n      const locale = quad.object.language.toLowerCase();\n      const thisLocaleStrings = freeze([\n        ...(objects.langStrings?.[locale] ?? []),\n        quad.object.value,\n      ]);\n      const langStrings = freeze({\n        ...(objects.langStrings ?? {}),\n        [locale]: thisLocaleStrings,\n      });\n      return freeze({\n        ...objects,\n        langStrings,\n      });\n    }\n\n    // If the Object is a non-langString Literal\n    const thisTypeValues = freeze([\n      ...(objects.literals?.[quad.object.datatype.value] ?? []),\n      quad.object.value,\n    ]);\n    const literals = freeze({\n      ...(objects.literals ?? {}),\n      [quad.object.datatype.value]: thisTypeValues,\n    });\n    return freeze({\n      ...objects,\n      literals,\n    });\n  }\n\n  if (quad.object.termType === \"BlankNode\") {\n    const blankNodes = freeze([\n      ...(objects.blankNodes ?? []),\n      getBlankNodeId(quad.object),\n    ]);\n    return freeze({\n      ...objects,\n      blankNodes,\n    });\n  }\n\n  throw new Error(\n    `Objects of type [${quad.object.termType}] are not supported.`,\n  );\n}\n\nexport function toRdfJsQuads(\n  dataset: ImmutableDataset,\n  options: ToRdfJsOptions = {},\n): RdfJs.Quad[] {\n  const quads: RdfJs.Quad[] = [];\n  const dataFactory = options.dataFactory ?? DataFactory;\n\n  Object.keys(dataset.graphs).forEach((graphIri: IriString) => {\n    const graph = dataset.graphs[graphIri];\n    const graphNode =\n      graphIri === \"default\"\n        ? dataFactory.defaultGraph()\n        : dataFactory.namedNode(graphIri);\n\n    Object.keys(graph).forEach((subjectIri) => {\n      const { predicates } = graph[subjectIri];\n      const subjectNode = isBlankNodeId(subjectIri)\n        ? dataFactory.blankNode(getBlankNodeValue(subjectIri))\n        : dataFactory.namedNode(subjectIri);\n      quads.push(\n        ...subjectToRdfJsQuads(predicates, subjectNode, graphNode, options),\n      );\n    });\n  });\n\n  return quads;\n}\n\nexport function subjectToRdfJsQuads(\n  predicates: Predicates,\n  subjectNode: RdfJs.NamedNode | RdfJs.BlankNode,\n  graphNode: RdfJs.NamedNode | RdfJs.DefaultGraph,\n  options: ToRdfJsOptions = {},\n): RdfJs.Quad[] {\n  const quads: RdfJs.Quad[] = [];\n  const dataFactory = options.dataFactory ?? DataFactory;\n\n  Object.keys(predicates).forEach((predicateIri) => {\n    const predicateNode = dataFactory.namedNode(predicateIri);\n    const langStrings = predicates[predicateIri].langStrings ?? {};\n    const namedNodes = predicates[predicateIri].namedNodes ?? [];\n    const literals = predicates[predicateIri].literals ?? {};\n    const blankNodes = predicates[predicateIri].blankNodes ?? [];\n\n    const literalTypes = Object.keys(literals);\n    literalTypes.forEach((typeIri) => {\n      const typeNode = dataFactory.namedNode(typeIri);\n      const literalValues = literals[typeIri];\n      literalValues.forEach((value) => {\n        const literalNode = dataFactory.literal(value, typeNode);\n        quads.push(\n          dataFactory.quad(\n            subjectNode,\n            predicateNode,\n            literalNode,\n            graphNode,\n          ) as RdfJs.Quad,\n        );\n      });\n    });\n\n    const locales = Object.keys(langStrings);\n    locales.forEach((locale) => {\n      const localeValues = langStrings[locale];\n      localeValues.forEach((value) => {\n        const langStringNode = dataFactory.literal(value, locale);\n        quads.push(\n          dataFactory.quad(\n            subjectNode,\n            predicateNode,\n            langStringNode,\n            graphNode,\n          ) as RdfJs.Quad,\n        );\n      });\n    });\n\n    namedNodes.forEach((namedNodeIri) => {\n      const node = dataFactory.namedNode(namedNodeIri);\n      quads.push(\n        dataFactory.quad(\n          subjectNode,\n          predicateNode,\n          node,\n          graphNode,\n        ) as RdfJs.Quad,\n      );\n    });\n\n    blankNodes.forEach((blankNodeIdOrPredicates) => {\n      if (isBlankNodeId(blankNodeIdOrPredicates)) {\n        const blankNode = dataFactory.blankNode(\n          getBlankNodeValue(blankNodeIdOrPredicates),\n        );\n        quads.push(\n          dataFactory.quad(\n            subjectNode,\n            predicateNode,\n            blankNode,\n            graphNode,\n          ) as RdfJs.Quad,\n        );\n      } else {\n        const node = dataFactory.blankNode();\n        const blankNodeObjectQuad = dataFactory.quad(\n          subjectNode,\n          predicateNode,\n          node,\n          graphNode,\n        ) as RdfJs.Quad;\n        const blankNodeSubjectQuads = subjectToRdfJsQuads(\n          blankNodeIdOrPredicates,\n          node,\n          graphNode,\n        );\n        quads.push(blankNodeObjectQuad);\n        quads.push(...blankNodeSubjectQuads);\n      }\n    });\n  });\n\n  return quads;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Quad } from \"@rdfjs/types\";\nimport { Parser as N3Parser, Writer as N3Writer } from \"n3\";\nimport type { IriString } from \"../interfaces\";\nimport { DataFactory } from \"../rdfjs.internal\";\nimport { getSourceUrl } from \"../resource/resource\";\nimport type { Parser } from \"../resource/solidDataset\";\n\n/**\n * ```{note} This function is still experimental and subject to change, even\n * in a non-major release.\n * ```\n * This returns a parser that transforms a JSON-LD string into a set of RDFJS quads.\n *\n * @returns A Parser object.\n * @since 1.15.0\n */\nexport const getTurtleParser = (): Parser => {\n  const onQuadCallbacks: Array<Parameters<Parser[\"onQuad\"]>[0]> = [];\n  const onCompleteCallbacks: Array<Parameters<Parser[\"onComplete\"]>[0]> = [];\n  const onErrorCallbacks: Array<Parameters<Parser[\"onError\"]>[0]> = [];\n\n  return {\n    onQuad: (callback) => {\n      onQuadCallbacks.push(callback);\n    },\n    onError: (callback) => {\n      onErrorCallbacks.push(callback);\n    },\n    onComplete: (callback) => {\n      onCompleteCallbacks.push(callback);\n    },\n    parse: (source, resourceInfo) => {\n      getParser(getSourceUrl(resourceInfo)).parse(source, (error, quad) => {\n        if (error) {\n          onErrorCallbacks.forEach((callback) => callback(error));\n        } else if (quad) {\n          onQuadCallbacks.forEach((callback) => callback(quad));\n        } else {\n          onCompleteCallbacks.forEach((callback) => callback());\n        }\n      });\n    },\n  };\n};\n\nfunction getParser(baseIri: IriString) {\n  return new N3Parser({ format: \"text/turtle\", baseIRI: baseIri });\n}\n\n/**\n * @param quads Triples that should be serialised to Turtle\n * @internal Utility method for internal use; not part of the public API.\n */\nexport async function triplesToTurtle(\n  quads: Quad[],\n  options?: Partial<{ prefixes: Record<string, string> }>,\n): Promise<string> {\n  const format = \"text/turtle\";\n  const writer = new N3Writer({ format, prefixes: options?.prefixes });\n  // Remove any potentially lingering references to Named Graphs in Quads;\n  // they'll be determined by the URL the Turtle will be sent to:\n  const triples = quads.map((quad) =>\n    DataFactory.quad(quad.subject, quad.predicate, quad.object, undefined),\n  );\n  writer.addQuads(triples);\n  const writePromise = new Promise<string>((resolve, reject) => {\n    writer.end((error, result) => {\n      /* istanbul ignore if [n3.js doesn't actually pass an error nor a result, apparently: https://github.com/rdfjs/N3.js/blob/62682e48c02d8965b4d728cb5f2cbec6b5d1b1b8/src/N3Writer.js#L290] */\n      if (error) {\n        reject(error);\n      } else {\n        resolve(result);\n      }\n    });\n  });\n\n  const rawTurtle = await writePromise;\n  return rawTurtle;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nexport const prefixes = {\n  acl: \"http://www.w3.org/ns/auth/acl#\",\n  acp: \"http://www.w3.org/ns/solid/acp#\",\n  cc: \"http://creativecommons.org/ns#\",\n  cert: \"http://www.w3.org/ns/auth/cert#\",\n  csvw: \"http://www.w3.org/ns/csvw#\",\n  current: \"#\",\n  dc: \"http://purl.org/dc/terms/\",\n  dcam: \"http://purl.org/dc/dcam/\",\n  dcat: \"http://www.w3.org/ns/dcat#\",\n  dctype: \"http://purl.org/dc/dcmitype/\",\n  foaf: \"http://xmlns.com/foaf/0.1/\",\n  ldp: \"http://www.w3.org/ns/ldp#\",\n  owl: \"http://www.w3.org/2002/07/owl#\",\n  posixstat: \"http://www.w3.org/ns/posix/stat#\",\n  rdf: \"http://www.w3.org/1999/02/22-rdf-syntax-ns#\",\n  rdfs: \"http://www.w3.org/2000/01/rdf-schema#\",\n  schema: \"https://schema.org/\",\n  shacl: \"http://www.w3.org/ns/shacl#\",\n  skos: \"http://www.w3.org/2004/02/skos/core#\",\n  skosxl: \"http://www.w3.org/2008/05/skos-xl#\",\n  solid: \"http://www.w3.org/ns/solid/terms#\",\n  swapdoc: \"http://www.w3.org/2000/10/swap/pim/doc#\",\n  ui: \"http://www.w3.org/ns/ui#\",\n  vann: \"http://purl.org/vocab/vann/\",\n  vcard: \"http://www.w3.org/2006/vcard/ns#\",\n  ws: \"http://www.w3.org/ns/pim/space#\",\n  xsd: \"http://www.w3.org/2001/XMLSchema#\",\n};\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\n// Note: Different RDF/JS implementations can, of course, behave differently.\n// Some important differences identified so far:\n//   1. RDF String Literals:\n//      The DataFactory signature for creating an RDF literal is:\n//         literal(value: string | number, languageOrDatatype?: string | RDF.NamedNode): Literal\n//\n//       The @rdfjs/data-model implementation checks if the 2nd param is a\n//      string, and if so it looks for a ':' character in that string. If\n//      present it considers the value a Datatype IRI, and so wraps the string\n//      in a call to DataFactory.namedNode().\n//\n//       The N3 implementation checks if the 2nd param is a string, and if so\n//      considers the value a language tag. If and only if the 2nd param is\n//      explicitly passed in as a NamedNode will it be treated as a Datatype\n//      IRI.\nimport type {\n  DataFactory,\n  DatasetCore,\n  DatasetCoreFactory,\n} from \"@rdfjs/types\";\nimport { rdfJsDataset, type ImmutableDataset } from \"./rdf.internal\";\nimport { addRdfJsQuadToDataset, toRdfJsQuads } from \"./rdfjs.internal\";\n\n/**\n * Convert an RDF/JS Dataset into a [[SolidDataset]]\n *\n * Parse an RDF/JS\n * {@link https://rdf.js.org/dataset-spec/#datasetcore-interface DatasetCore},\n * into a [[SolidDataset]]. Note that, when saving the returned SolidDataset to\n * a Solid Pod, only Quads in the Default Graph will be stored.\n *\n * @param rdfJsDataset The source RDF/JS Dataset.\n * @returns A [[SolidDataset]] containing the same data as the given RDF/JS Dataset.\n * @since 1.9.0\n */\nexport function fromRdfJsDataset(dataset: DatasetCore): ImmutableDataset {\n  const solidDataset: ImmutableDataset = {\n    graphs: { default: {} },\n    type: \"Dataset\",\n  };\n  return Array.from(dataset).reduce(\n    (datasetAcc, quad) => addRdfJsQuadToDataset(datasetAcc, quad),\n    solidDataset,\n  );\n}\n\nexport type ToRdfJsOptions = Partial<{\n  dataFactory: DataFactory;\n  datasetFactory: DatasetCoreFactory;\n}>;\n/**\n * Convert a [[SolidDataset]] into an RDF/JS Dataset\n *\n * Export a [[SolidDataset]] into an RDF/JS\n * {@link https://rdf.js.org/dataset-spec/#datasetcore-interface DatasetCore}.\n *\n * @param set A [[SolidDataset]] to export into an RDF/JS Dataset.\n * @param options Optional parameter that allows you to pass in your own RDF/JS DataFactory or DatasetCoreFactory.\n * @returns An RDF/JS Dataset containing the data from the given SolidDataset.\n * @since 1.9.0\n */\nexport function toRdfJsDataset(\n  set: ImmutableDataset,\n  options: ToRdfJsOptions = {},\n): DatasetCore {\n  const datasetFactory = options.datasetFactory?.dataset ?? rdfJsDataset;\n  return datasetFactory(toRdfJsQuads(set, options));\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport { NamedNode, Writer } from \"n3\";\nimport type { SolidDataset } from \"../interfaces\";\nimport { prefixes as defaultPrefixes } from \"./prefixes\";\nimport { toRdfJsDataset } from \"../rdfjs\";\n\n/**\n * A function to serialise a Solid Dataset as Turtle\n *\n * @param dataset The Dataset to serialize as Turtle\n * @param options.prefixes The Prefixes to use for Turtle serialisation (defaulting to a set of well known prefixes)\n * @param options.thing Restricts serialisation to the part of a dataset related to the thing\n * @returns RDF serialised as Turtle\n * @since 1.20.0\n */\nexport async function solidDatasetAsTurtle(\n  dataset: SolidDataset,\n  options?: {\n    prefixes?: Record<string, string>;\n    thing?: string;\n  },\n): Promise<string> {\n  const { prefixes = defaultPrefixes, thing } = { ...options };\n  const writer = new Writer({ format: \"application/turtle\", prefixes });\n  const subject = thing ? new NamedNode(thing) : undefined;\n\n  // If the subject is undefined, all the triples match.\n  for (const quad of toRdfJsDataset(dataset).match(subject)) {\n    writer.addQuad(quad);\n  }\n\n  return new Promise<string>((resolve, reject) => {\n    writer.end((error, result) => {\n      /* istanbul ignore next */\n      if (error) {\n        reject(error);\n      } else {\n        resolve(result);\n      }\n    });\n  });\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { File as NodeFile } from \"buffer\";\nimport type {\n  File as BlobFile,\n  UploadRequestInit,\n  WithResourceInfo,\n  Url,\n  UrlString,\n  WithServerResourceInfo,\n} from \"../interfaces\";\nimport { hasResourceInfo } from \"../interfaces\";\nimport { internal_toIriString, normalizeUrl } from \"../interfaces.internal\";\nimport { getSourceIri, FetchError } from \"./resource\";\nimport {\n  internal_cloneResource,\n  internal_isUnsuccessfulResponse,\n  internal_parseResourceInfo,\n} from \"./resource.internal\";\n\n/**\n * Options when fetching a file from a Pod.\n *\n * Available options:\n * - `fetch`: A custom `fetch` function with the same signature as\n *   [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch).\n *   This will be used to execute the actual requests. This option can be used to, for example,\n *   attach credentials to requests that need authentication.\n */\nexport type GetFileOptions = {\n  fetch: typeof fetch;\n  /** @internal */\n  init: UploadRequestInit;\n};\n\nconst RESERVED_HEADERS = [\"Slug\", \"If-None-Match\", \"Content-Type\"];\n\n/**\n * Some of the headers must be set by the library, rather than directly.\n */\nfunction containsReserved(header: Record<string, string>): boolean {\n  return RESERVED_HEADERS.some((reserved) => header[reserved] !== undefined);\n}\n\n/**\n * Retrieves a file from a URL and returns the file as a blob.\n *\n * For example:\n *\n * ```\n * const fileBlob = await getFile(\"https://pod.example.com/some/file\", { fetch: fetch });\n * ```\n *\n * For additional examples, see\n * [Read/Write Files](https://docs.inrupt.com/sdk/javascript-sdktutorial/read-write-files/#retrieve-a-file).\n *\n * @param fileUrl The URL of the file to return\n * @param options Fetching options: a custom fetcher and/or headers.\n * @returns The file as a blob.\n */\nexport async function getFile(\n  fileUrl: Url | UrlString,\n  options?: Partial<GetFileOptions>,\n): Promise<BlobFile & WithServerResourceInfo> {\n  const normalizedUrl = normalizeUrl(internal_toIriString(fileUrl), {\n    trailingSlash: false,\n  });\n  const response = await (options?.fetch ?? fetch)(\n    normalizedUrl,\n    options?.init,\n  );\n  if (internal_isUnsuccessfulResponse(response)) {\n    const errorBody = await response.clone().text();\n    throw new FetchError(\n      `Fetching the File failed: [${response.status}] [${\n        response.statusText\n      }] ${errorBody}.`,\n      response,\n      errorBody,\n    );\n  }\n  const resourceInfo = internal_parseResourceInfo(response);\n  const data = await response.blob();\n  const fileWithResourceInfo: BlobFile & WithServerResourceInfo = Object.assign(\n    data,\n    {\n      internal_resourceInfo: resourceInfo,\n    },\n  );\n\n  return fileWithResourceInfo;\n}\n\n/**\n * Deletes a file at a given URL.\n *\n * For example:\n *\n * ```\n * await deleteFile( \"https://pod.example.com/some/file\", { fetch: fetch });\n * ```\n *\n * For additional examples, see\n * [Read/Write Files](https://docs.inrupt.com/sdk/javascript-sdktutorial/read-write-files/#delete-a-file).\n *\n * @param file The URL of the file to delete or the file itself (if it has ResourceInfo).\n */\nexport async function deleteFile(\n  file: Url | UrlString | WithResourceInfo,\n  options?: Partial<GetFileOptions>,\n): Promise<void> {\n  const url = hasResourceInfo(file)\n    ? internal_toIriString(getSourceIri(file))\n    : normalizeUrl(internal_toIriString(file), { trailingSlash: false });\n  const response = await (options?.fetch ?? fetch)(url, {\n    ...options?.init,\n    method: \"DELETE\",\n  });\n\n  if (internal_isUnsuccessfulResponse(response)) {\n    const errorBody = await response.clone().text();\n    throw new FetchError(\n      `Deleting the file at [${url}] failed: [${response.status}] [${\n        response.statusText\n      }] ${errorBody}.`,\n      response,\n      errorBody,\n    );\n  }\n}\n\n/**\n * Options available when saving a file (extends the options available when\n * writing a file: [[WriteFileOptions]]).\n *\n */\ntype SaveFileOptions = WriteFileOptions & {\n  /**\n   * This option can be used as a hint to the server in how to name a new file.\n   * Note: the server is still free to choose a completely different, unrelated\n   * name if it chooses.\n   * @deprecated Provide a `File` input with a `name` property as input to `saveFileInContainer` instead.\n   */\n  slug?: string;\n};\n\n/**\n * Saves a file in an existing folder/Container associated with the given URL.\n *\n * For example:\n *\n * ```\n * const savedFile = await saveFileInContainer(\n *   \"https://pod.example.com/some/existing/container/\",\n *   new File([\"This is a plain piece of text\"], \"suggestedFileName.txt\", { type: \"text/plain\" }),\n *   { fetch: fetch }\n * );\n * ```\n *\n * For additional example, see\n * [Read/Write Files](https://docs.inrupt.com/sdk/javascript-sdktutorial/read-write-files/#save-a-file-into-an-existing-container).\n *\n * In the `options` parameter,\n *\n * - You can suggest a file name in the `slug` field.  However, the Solid\n *   Server may or may not use the suggested `slug` as the file name.\n *\n * - *Recommended:* You can specify the [media type](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type)\n *   of the file in the `contentType`.  If unspecified, the function uses the default type of\n *   `application/octet-stream`, indicating a binary data file.\n *\n * The function saves a file into an *existing* Container. If the\n * Container does not exist, either:\n * - Create the Container first using [[createContainerAt]], and then\n *   use the function, or\n * - Use [[overwriteFile]] to save the file. [[overwriteFile]] creates\n *   the Containers in the saved file path as needed.\n *\n * Users who only have `Append` but not `Write` access to a Container\n * can use [[saveFileInContainer]] to save new files to the Container.\n * That is, [[saveFileInContainer]] is useful in situations where users\n * can add new files to a Container but not change existing files in\n * the Container, such as users given access to send notifications to\n * another's Pod but not to view or delete existing notifications in that Pod.\n *\n * Users with `Write` access to the given folder/Container may prefer to\n * use [[overwriteFile]].\n *\n * @param folderUrl The URL of an existing folder where the new file is saved.\n * @param file The file to be written.\n * @param options Additional parameters for file creation (e.g. a slug).\n * @returns A Promise that resolves to the saved file, if available, or `null` if the current user does not have Read access to the newly-saved file. It rejects if saving fails.\n */\nexport async function saveFileInContainer<\n  FileExt extends File | BlobFile | NodeFile,\n>(\n  folderUrl: Url | UrlString,\n  file: FileExt,\n  options?: Partial<SaveFileOptions>,\n): Promise<FileExt & WithResourceInfo> {\n  const folderUrlString = normalizeUrl(internal_toIriString(folderUrl), {\n    trailingSlash: true,\n  });\n  const response = await writeFile(folderUrlString, file, \"POST\", options);\n\n  if (internal_isUnsuccessfulResponse(response)) {\n    const errorBody = await response.clone().text();\n    throw new FetchError(\n      `Saving the file in [${folderUrl}] failed: [${response.status}] [${\n        response.statusText\n      }] ${errorBody}.`,\n      response,\n      errorBody,\n    );\n  }\n\n  const locationHeader = response.headers.get(\"Location\");\n  if (locationHeader === null) {\n    throw new Error(\n      \"Could not determine the location of the newly saved file.\",\n    );\n  }\n\n  const fileIri = new URL(locationHeader, new URL(folderUrlString).origin).href;\n\n  const blobClone = internal_cloneResource(file);\n\n  const resourceInfo: WithResourceInfo = {\n    internal_resourceInfo: {\n      isRawData: true,\n      sourceIri: fileIri,\n      contentType: getContentType(file, options?.contentType),\n    },\n  };\n\n  return Object.assign(blobClone, resourceInfo);\n}\n\n/**\n * Options available when writing a file.\n */\nexport type WriteFileOptions = GetFileOptions & {\n  /**\n   * Allows a file's content type to be provided explicitly, if known. Value is\n   * expected to be a valid\n   * [media type](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type).\n   * For example, if you know your file is a JPEG image, then you should provide\n   * the media type `image/jpeg`. If you don't know, or don't provide a media\n   * type, a default type of `application/octet-stream` will be applied (which\n   * indicates that the file should be regarded as pure binary data).\n   */\n  contentType: string;\n};\n\n/**\n * Saves a file at a given URL. If a file already exists at the URL,\n * the function overwrites the existing file.\n *\n * For example:\n *\n * ```\n * const savedFile = await overwriteFile(\n *   \"https://pod.example.com/some/container/myFile.txt\",\n *   new File([\"This is a plain piece of text\"], \"myFile\", { type: \"text/plain\" }),\n *   { fetch: fetch }\n * );\n * ```\n *\n * For additional example, see\n * [Read/Write Files](https://docs.inrupt.com/sdk/javascript-sdktutorial/read-write-files/#write-a-file-to-a-specific-url).\n *\n * *Recommended:* In the `options` parameter, you can specify the\n * [media type](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type)\n * of the file in the `contentType`.  If unspecified, the function uses the default type of\n * `application/octet-stream`, indicating a binary data file.\n *\n * When saving a file with [[overwriteFile]], the Solid server creates any\n * intermediary Containers as needed; i.e., the Containers do not\n * need to be created in advance. For example, when saving a file to the target URL of\n * https://example.pod/container/resource, if https://example.pod/container/ does not exist,\n * the container is created as part of the save.\n *\n * @param fileUrl The URL where the file is saved.\n * @param file The file to be written.\n * @param options Additional parameters for file creation (e.g., media type).\n */\nexport async function overwriteFile<FileExt extends File | BlobFile | NodeFile>(\n  fileUrl: Url | UrlString,\n  file: FileExt,\n  options?: Partial<WriteFileOptions>,\n): Promise<FileExt & WithResourceInfo> {\n  const fileUrlString = internal_toIriString(fileUrl);\n  const response = await writeFile(fileUrlString, file, \"PUT\", options);\n\n  if (internal_isUnsuccessfulResponse(response)) {\n    const errorBody = await response.clone().text();\n    throw new FetchError(\n      `Overwriting the file at [${fileUrlString}] failed: [${\n        response.status\n      }] [${response.statusText}] ${errorBody}.`,\n      response,\n      errorBody,\n    );\n  }\n\n  const blobClone = internal_cloneResource(file);\n  const resourceInfo = internal_parseResourceInfo(response);\n  resourceInfo.sourceIri = fileUrlString;\n  resourceInfo.isRawData = true;\n\n  return Object.assign(blobClone, { internal_resourceInfo: resourceInfo });\n}\n\nfunction isHeadersArray(\n  headers: Headers | Record<string, string> | string[][],\n): headers is string[][] {\n  return Array.isArray(headers);\n}\n\n/**\n * The return type of this function is misleading: it should ONLY be used to check\n * whether an object has a forEach method that returns <key, value> pairs.\n *\n * @param headers A headers object that might have a forEach\n */\nfunction hasHeadersObjectForEach(\n  headers: Headers | Record<string, string> | string[][],\n): headers is Headers {\n  return typeof (headers as Headers).forEach === \"function\";\n}\n\n/**\n * @hidden\n * This function feels unnecessarily complicated, but is required in order to\n * have Headers according to type definitions in both Node and browser environments.\n * This might require a fix upstream to be cleaned up.\n *\n * @param headersToFlatten A structure containing headers potentially in several formats\n */\nexport function flattenHeaders(\n  headersToFlatten: Headers | Record<string, string> | string[][] | undefined,\n): Record<string, string> {\n  if (typeof headersToFlatten === \"undefined\") {\n    return {};\n  }\n\n  let flatHeaders: Record<string, string> = {};\n\n  if (isHeadersArray(headersToFlatten)) {\n    headersToFlatten.forEach(([key, value]) => {\n      flatHeaders[key] = value;\n    });\n    // Note that the following line must be a elsif, because string[][] has a forEach,\n    // but it returns string[] instead of <key, value>\n  } else if (hasHeadersObjectForEach(headersToFlatten)) {\n    headersToFlatten.forEach((value: string, key: string) => {\n      flatHeaders[key] = value;\n    });\n  } else {\n    // If the headers are already a Record<string, string>,\n    // they can directly be returned.\n    flatHeaders = headersToFlatten;\n  }\n\n  return flatHeaders;\n}\n\n/**\n * Internal function that performs the actual write HTTP query, either POST\n * or PUT depending on the use case.\n *\n * @param fileUrl The URL where the file is saved\n * @param file The file to be written\n * @param method The HTTP method\n * @param options Additional parameters for file creation (e.g. a slug, or media type)\n */\nasync function writeFile<T extends File | BlobFile | NodeFile>(\n  targetUrl: UrlString,\n  file: T,\n  method: \"PUT\" | \"POST\",\n  options: Partial<SaveFileOptions> = {},\n): Promise<Response> {\n  const headers = flattenHeaders(options.init?.headers ?? {});\n  if (containsReserved(headers)) {\n    throw new Error(\n      `No reserved header (${RESERVED_HEADERS.join(\n        \", \",\n      )}) should be set in the optional RequestInit.`,\n    );\n  }\n\n  // If a slug is in the parameters, set the request headers accordingly\n  if (options.slug !== undefined) {\n    headers.Slug = options.slug;\n  } else if (\"name\" in file && file.name !== undefined) {\n    headers.Slug = file.name;\n  }\n  headers[\"Content-Type\"] = getContentType(file, options.contentType);\n\n  return (options.fetch ?? fetch)(targetUrl, {\n    ...options.init,\n    headers,\n    method,\n    body: file as BlobFile,\n  });\n}\n\nfunction getContentType(\n  file: File | BlobFile | NodeFile,\n  contentTypeOverride?: string,\n): string {\n  if (typeof contentTypeOverride === \"string\") {\n    return contentTypeOverride;\n  }\n  const fileType =\n    typeof file === \"object\" &&\n    file !== null &&\n    \"type\" in file &&\n    typeof file.type === \"string\" &&\n    file.type.length > 0\n      ? file.type\n      : undefined;\n\n  return fileType ?? \"application/octet-stream\";\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Quad, Quad_Object } from \"@rdfjs/types\";\nimport {\n  isNamedNode,\n  isLiteral,\n  xmlSchemaTypes,\n  deserializeBoolean,\n  deserializeDatetime,\n  deserializeDecimal,\n  deserializeInteger,\n} from \"../datatypes\";\nimport type { Thing, SolidDataset, WithChangeLog } from \"../interfaces\";\nimport { hasChangelog } from \"../interfaces\";\nimport { ThingExpectedError, isThing } from \"./thing\";\nimport { freeze } from \"../rdf.internal\";\n\n/** @hidden For internal use only. */\nexport function internal_getReadableValue(value: Quad_Object): string {\n  if (isNamedNode(value)) {\n    return `<${value.value}> (URL)`;\n  }\n  if (isLiteral(value)) {\n    /* istanbul ignore if: thingAsMarkdown always instantiates a NamedNode, so we can't hit this code path in tests. */\n    if (!isNamedNode(value.datatype)) {\n      return `[${value.value}] (RDF/JS Literal of unknown type)`;\n    }\n    let val;\n    switch (value.datatype.value) {\n      case xmlSchemaTypes.boolean:\n        val =\n          deserializeBoolean(value.value)?.valueOf() ??\n          `Invalid data: \\`${value.value}\\``;\n        return `${val} (boolean)`;\n      case xmlSchemaTypes.dateTime:\n        val =\n          deserializeDatetime(value.value)?.toUTCString() ??\n          `Invalid data: \\`${value.value}\\``;\n        return `${val} (datetime)`;\n      case xmlSchemaTypes.decimal:\n        val =\n          deserializeDecimal(value.value)?.toString() ??\n          `Invalid data: \\`${value.value}\\``;\n        return `${val} (decimal)`;\n      case xmlSchemaTypes.integer:\n        val =\n          deserializeInteger(value.value)?.toString() ??\n          `Invalid data: \\`${value.value}\\``;\n        return `${val} (integer)`;\n      case xmlSchemaTypes.langString:\n        return `\"${value.value}\" (${value.language} string)`;\n      case xmlSchemaTypes.string:\n        return `\"${value.value}\" (string)`;\n      default:\n        return `[${value.value}] (RDF/JS Literal of type: \\`${value.datatype.value}\\`)`;\n    }\n  }\n  /* istanbul ignore else: thingAsMarkdown doesn't generate other Nodes, so we can't hit this path in tests. */\n  if (value.termType === \"BlankNode\") {\n    return `[${value.value}] (RDF/JS BlankNode)`;\n  }\n  /* istanbul ignore next: thingAsMarkdown doesn't generate Quad Nodes, so we can't hit this path in tests. */\n  if (value.termType === \"Quad\") {\n    return `??? (nested RDF* Quad)`;\n  }\n  /* istanbul ignore else: The if statements are exhaustive; if not, TypeScript will complain. */\n  /* istanbul ignore next: thingAsMarkdown doesn't generate Variable Nodes, so we can't hit this path in tests. */\n  if (value.termType === \"Variable\") {\n    return `?${value.value} (RDF/JS Variable)`;\n  }\n  /* istanbul ignore next: The if statements are exhaustive; if not, TypeScript will complain. */\n  return value;\n}\n\n/**\n * @hidden\n */\nexport function internal_throwIfNotThing(thing: Thing): void {\n  if (!isThing(thing)) {\n    throw new ThingExpectedError(thing);\n  }\n}\n\n/**\n * @hidden\n * @param solidDataset\n */\nexport function internal_addAdditionsToChangeLog<Dataset extends SolidDataset>(\n  solidDataset: Dataset,\n  additions: Quad[],\n): Dataset & WithChangeLog {\n  const changeLog = hasChangelog(solidDataset)\n    ? solidDataset.internal_changeLog\n    : /* istanbul ignore next: This function always gets called after addDeletionsToChangeLog, so the ChangeLog always already exists in tests: */\n      { additions: [], deletions: [] };\n\n  const [newAdditions, newDeletions] = additions\n    .filter((addition) => !containsBlankNode(addition))\n    .reduce(\n      ([additionsAcc, deletionsAcc], addition) => {\n        const existingDeletion = deletionsAcc.find((deletion) =>\n          deletion.equals(addition),\n        );\n        if (typeof existingDeletion !== \"undefined\") {\n          return [\n            additionsAcc,\n            deletionsAcc.filter((deletion) => !deletion.equals(addition)),\n          ];\n        }\n        return [additionsAcc.concat(addition), deletionsAcc];\n      },\n      [changeLog.additions, changeLog.deletions],\n    );\n\n  return freeze({\n    ...solidDataset,\n    internal_changeLog: {\n      additions: newAdditions,\n      deletions: newDeletions,\n    },\n  });\n}\n\n/**\n * @hidden\n * @param solidDataset\n */\nexport function internal_addDeletionsToChangeLog<Dataset extends SolidDataset>(\n  solidDataset: Dataset,\n  deletions: Quad[],\n): Dataset & WithChangeLog {\n  const changeLog = hasChangelog(solidDataset)\n    ? solidDataset.internal_changeLog\n    : { additions: [], deletions: [] };\n\n  const [newAdditions, newDeletions] = deletions\n    .filter((deletion) => !containsBlankNode(deletion))\n    .reduce(\n      ([additionsAcc, deletionsAcc], deletion) => {\n        const existingAddition = additionsAcc.find((addition) =>\n          addition.equals(deletion),\n        );\n        if (typeof existingAddition !== \"undefined\") {\n          return [\n            additionsAcc.filter((addition) => !addition.equals(deletion)),\n            deletionsAcc,\n          ];\n        }\n        return [additionsAcc, deletionsAcc.concat(deletion)];\n      },\n      [changeLog.additions, changeLog.deletions],\n    );\n\n  return freeze({\n    ...solidDataset,\n    internal_changeLog: {\n      additions: newAdditions,\n      deletions: newDeletions,\n    },\n  });\n}\n\n/**\n * Enforces the presence of a Changelog for a given dataset. If a changelog is\n * already present, it is unchanged. Otherwise, an empty changelog is created.\n * @hidden\n * @param solidDataset\n */\nexport function internal_withChangeLog<Dataset extends SolidDataset>(\n  solidDataset: Dataset,\n): Dataset & WithChangeLog {\n  const newSolidDataset: Dataset & WithChangeLog = hasChangelog(solidDataset)\n    ? solidDataset\n    : freeze({\n        ...solidDataset,\n        internal_changeLog: { additions: [], deletions: [] },\n      });\n  return newSolidDataset;\n}\n\n/**\n * We don't currently support reading and writing Blank Nodes, so this function can be used to skip those Quads.\n *\n * This is needed because we cannot reconcile Blank Nodes in additions and\n * deletions. Down the road, we should do a diff before saving a SolidDataset\n * against a saved copy of the originally-fetched one, based on our own data\n * structures, which should make it easier to reconcile.\n */\nfunction containsBlankNode(quad: Quad): boolean {\n  return (\n    quad.subject.termType === \"BlankNode\" ||\n    quad.object.termType === \"BlankNode\"\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Quad_Object, NamedNode, Literal } from \"@rdfjs/types\";\nimport type { Thing, Url, UrlString } from \"../interfaces\";\nimport type { XmlSchemaTypeIri, Time } from \"../datatypes\";\nimport {\n  deserializeBoolean,\n  deserializeDatetime,\n  deserializeDate,\n  deserializeTime,\n  deserializeDecimal,\n  deserializeInteger,\n  xmlSchemaTypes,\n  internal_isValidUrl,\n} from \"../datatypes\";\nimport { internal_throwIfNotThing } from \"./thing.internal\";\nimport { ValidPropertyUrlExpectedError } from \"./thing\";\nimport { internal_toIriString } from \"../interfaces.internal\";\nimport {\n  getBlankNodeValue,\n  getLocalNodeName,\n  isBlankNodeId,\n  isLocalNodeIri,\n} from \"../rdf.internal\";\nimport { DataFactory } from \"../rdfjs.internal\";\n\n/**\n * Returns the URLs of all Properties that the given [[Thing ]]has values for.b\n *\n * @param thing The [[Thing]] of which to get that Property URLs that have a value.\n * @returns The URLs of the Properties for which values are defined for the given Thing.\n * @hidden This is an advanced API that should not be needed for most Solid use cases. If you do find yourself needing this, please file a feature request sharing your use case.\n */\nexport function getPropertyAll(thing: Thing): UrlString[] {\n  return Object.keys(thing.predicates).filter(\n    (predicate) => getTerm(thing, predicate) !== null,\n  );\n}\n\n/**\n * Returns the URL value of the specified Property from a [[Thing]].\n * If the Property is not present or its value is not of type URL, returns null.\n * If the Property has multiple URL values, returns one of its URL values.\n *\n * @param thing The [[Thing]] to read a URL value from.\n * @param property The Property whose URL value to return.\n * @returns A URL value for the given Property if present, or null if the Property is not present or the value is not of type URL.\n */\nexport function getUrl(\n  thing: Thing,\n  property: Url | UrlString,\n): UrlString | null {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const predicateUrl = internal_toIriString(property);\n  const firstUrl = thing.predicates[predicateUrl]?.namedNodes?.[0] ?? null;\n  if (firstUrl === null) {\n    return null;\n  }\n  return isLocalNodeIri(firstUrl) ? `#${getLocalNodeName(firstUrl)}` : firstUrl;\n}\n/** @hidden Alias of [[getUrl]] for those who prefer IRI terminology. */\nexport const getIri = getUrl;\n\n/**\n * Returns the URL values of the specified Property from a [[Thing]].\n * If the Property is not present, returns an empty array.\n * If the Property's value is not of type URL, omits that value in the array.\n *\n * @param thing The [[Thing]] to read the URL values from.\n * @param property The Property whose URL values to return.\n * @returns An array of URL values for the given Property.\n */\nexport function getUrlAll(\n  thing: Thing,\n  property: Url | UrlString,\n): UrlString[] {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const predicateUrl = internal_toIriString(property);\n  return (\n    thing.predicates[predicateUrl]?.namedNodes?.map((iri) =>\n      isLocalNodeIri(iri) ? `#${getLocalNodeName(iri)}` : iri,\n    ) ?? []\n  );\n}\n/** @hidden Alias of [[getUrlAll]] for those who prefer IRI terminology. */\nexport const getIriAll = getUrlAll;\n\n/**\n * Returns the boolean value of the specified Property from a [[Thing]].\n * If the Property is not present or its value is not of type boolean, returns null.\n * If the Property has multiple boolean values, returns one of its values.\n *\n * @param thing The [[Thing]] to read a boolean value from.\n * @param property The Property whose boolean value to return.\n * @returns A boolean value for the given Property if present, or null if the Property is not present or the value is not of type boolean.\n */\nexport function getBoolean(\n  thing: Thing,\n  property: Url | UrlString,\n): boolean | null {\n  internal_throwIfNotThing(thing);\n  const literalString = getLiteralOfType(\n    thing,\n    property,\n    xmlSchemaTypes.boolean,\n  );\n\n  if (literalString === null) {\n    return null;\n  }\n\n  return deserializeBoolean(literalString);\n}\n\n/**\n * Returns the boolean values of the specified Property from a [[Thing]].\n * If the Property is not present, returns an empty array.\n * If the Property's value is not of type boolean, omits that value in the array.\n *\n * @param thing The [[Thing]] to read the boolean values from.\n * @param property The Property whose boolean values to return.\n * @returns An array of boolean values for the given Property.\n */\nexport function getBooleanAll(\n  thing: Thing,\n  property: Url | UrlString,\n): boolean[] {\n  internal_throwIfNotThing(thing);\n  const literalStrings = getLiteralAllOfType(\n    thing,\n    property,\n    xmlSchemaTypes.boolean,\n  );\n\n  return literalStrings\n    .map(deserializeBoolean)\n    .filter((possibleBoolean) => possibleBoolean !== null) as boolean[];\n}\n\n/**\n * Returns the datetime value of the specified Property from a [[Thing]].\n * If the Property is not present or its value is not of type datetime, returns null.\n * If the Property has multiple datetime values, returns one of its values.\n *\n * @param thing The [[Thing]] to read a datetime value from.\n * @param property The Property whose datetime value to return.\n * @returns A datetime value for the given Property if present, or null if the Property is not present or the value is not of type datetime.\n */\nexport function getDatetime(\n  thing: Thing,\n  property: Url | UrlString,\n): Date | null {\n  internal_throwIfNotThing(thing);\n  const literalString = getLiteralOfType(\n    thing,\n    property,\n    xmlSchemaTypes.dateTime,\n  );\n\n  if (literalString === null) {\n    return null;\n  }\n\n  return deserializeDatetime(literalString);\n}\n\n/**\n * Returns the datetime values of the specified Property from a [[Thing]].\n * If the Property is not present, returns an empty array.\n * If the Property's value is not of type datetime, omits that value in the array.\n *\n * @param thing The [[Thing]] to read the datetime values from.\n * @param property The Property whose datetime values to return.\n * @returns An array of datetime values for the given Property.\n */\nexport function getDatetimeAll(\n  thing: Thing,\n  property: Url | UrlString,\n): Date[] {\n  internal_throwIfNotThing(thing);\n  const literalStrings = getLiteralAllOfType(\n    thing,\n    property,\n    xmlSchemaTypes.dateTime,\n  );\n\n  return literalStrings\n    .map(deserializeDatetime)\n    .filter((potentialDatetime) => potentialDatetime !== null) as Date[];\n}\n\n/**\n * Returns the date value of the specified Property from a [[Thing]].\n * If the Property is not present or its value is not of type date, returns null.\n * If the Property has multiple date values, returns one of its values.\n *\n * @param thing The [[Thing]] to read a date value from.\n * @param property The Property whose date value to return.\n * @returns A date value for the given Property if present, or null if the Property is not present or the value is not of type date.\n * @since 1.10.0\n */\nexport function getDate(thing: Thing, property: Url | UrlString): Date | null {\n  internal_throwIfNotThing(thing);\n\n  const literalString = getLiteralOfType(thing, property, xmlSchemaTypes.date);\n\n  if (literalString === null) {\n    return null;\n  }\n\n  return deserializeDate(literalString);\n}\n\n/**\n * Returns the date values of the specified Property from a [[Thing]].\n * If the Property is not present, returns an empty array.\n * If the Property's value is not of type date, omits that value in the array.\n *\n * @param thing The [[Thing]] to read the date values from.\n * @param property The Property whose date values to return.\n * @returns An array of date values for the given Property.\n * @since 1.10.0\n */\nexport function getDateAll(thing: Thing, property: Url | UrlString): Date[] {\n  internal_throwIfNotThing(thing);\n  const literalStrings = getLiteralAllOfType(\n    thing,\n    property,\n    xmlSchemaTypes.date,\n  );\n\n  return literalStrings\n    .map(deserializeDate)\n    .filter((potentialDate) => potentialDate !== null) as Date[];\n}\n\n/**\n * Returns the time value of the specified Property from a [[Thing]].\n * If the Property is not present or its value is not of type time, returns null.\n * If the Property has multiple time values, returns one of its values.\n *\n * @param thing The [[Thing]] to read a time value from.\n * @param property The Property whose time value to return.\n * @returns A time value for the given Property if present, or null if the Property is not present or the value is not of type time.\n * @since 1.10.0\n */\nexport function getTime(thing: Thing, property: Url | UrlString): Time | null {\n  internal_throwIfNotThing(thing);\n  const literalString = getLiteralOfType(thing, property, xmlSchemaTypes.time);\n\n  if (literalString === null) {\n    return null;\n  }\n\n  return deserializeTime(literalString);\n}\n\n/**\n * Returns the time values of the specified Property from a [[Thing]].\n * If the Property is not present, returns an empty array.\n * If the Property's value is not of type time, omits that value in the array.\n *\n * @param thing The [[Thing]] to read the time values from.\n * @param property The Property whose time values to return.\n * @returns An array of time values for the given Property.\n * @since 1.10.0\n */\nexport function getTimeAll(thing: Thing, property: Url | UrlString): Time[] {\n  internal_throwIfNotThing(thing);\n  const literalStrings = getLiteralAllOfType(\n    thing,\n    property,\n    xmlSchemaTypes.time,\n  );\n\n  return literalStrings\n    .map(deserializeTime)\n    .filter((potentialTime) => potentialTime !== null) as Time[];\n}\n\n/**\n * Returns the decimal value of the specified Property from a [[Thing]].\n * If the Property is not present or its value is not of type decimal, returns null.\n * If the Property has multiple decimal values, returns one of its values.\n *\n * @param thing The [[Thing]] to read a decimal value from.\n * @param property The Property whose decimal value to return.\n * @returns A decimal value for the given Property if present, or null if the Property is not present or the value is not of type decimal.\n */\nexport function getDecimal(\n  thing: Thing,\n  property: Url | UrlString,\n): number | null {\n  internal_throwIfNotThing(thing);\n  const literalString = getLiteralOfType(\n    thing,\n    property,\n    xmlSchemaTypes.decimal,\n  );\n\n  if (literalString === null) {\n    return null;\n  }\n\n  return deserializeDecimal(literalString);\n}\n\n/**\n * Returns the decimal values of the specified Property from a [[Thing]].\n * If the Property is not present, returns an empty array.\n * If the Property's value is not of type decimal, omits that value in the array.\n *\n * @param thing The [[Thing]] to read the decimal values from.\n * @param property The Property whose decimal values to return.\n * @returns An array of decimal values for the given Property.\n */\nexport function getDecimalAll(\n  thing: Thing,\n  property: Url | UrlString,\n): number[] {\n  internal_throwIfNotThing(thing);\n  const literalStrings = getLiteralAllOfType(\n    thing,\n    property,\n    xmlSchemaTypes.decimal,\n  );\n\n  return literalStrings\n    .map((literalString) => deserializeDecimal(literalString))\n    .filter((potentialDecimal) => potentialDecimal !== null) as number[];\n}\n\n/**\n * Returns the integer value of the specified Property from a [[Thing]].\n * If the Property is not present or its value is not of type integer, returns null.\n * If the Property has multiple integer values, returns one of its values.\n *\n * @param thing The [[Thing]] to read an integer value from.\n * @param property The Property whose integer value to return.\n * @returns A integer value for the given Property if present, or null if the Property is not present or the value is not of type datetime.\n */\nexport function getInteger(\n  thing: Thing,\n  property: Url | UrlString,\n): number | null {\n  internal_throwIfNotThing(thing);\n  const literalString = getLiteralOfType(\n    thing,\n    property,\n    xmlSchemaTypes.integer,\n  );\n\n  if (literalString === null) {\n    return null;\n  }\n\n  return deserializeInteger(literalString);\n}\n\n/**\n * Returns the integer values of the specified Property from a [[Thing]].\n * If the Property is not present, returns an empty array.\n * If the Property's value is not of type integer, omits that value in the array.\n *\n * @param thing The [[Thing]] to read the integer values from.\n * @param property The Property whose integer values to return.\n * @returns An array of integer values for the given Property.\n */\nexport function getIntegerAll(\n  thing: Thing,\n  property: Url | UrlString,\n): number[] {\n  internal_throwIfNotThing(thing);\n  const literalStrings = getLiteralAllOfType(\n    thing,\n    property,\n    xmlSchemaTypes.integer,\n  );\n\n  return literalStrings\n    .map((literalString) => deserializeInteger(literalString))\n    .filter((potentialInteger) => potentialInteger !== null) as number[];\n}\n\n/**\n * Returns the English (language tag \"en\") string value of the specified Property from a [[Thing]].\n * If the Property is not present as a string in English, returns null.\n * If the Property has multiple English string values, returns one of its values.\n *\n * @param thing The [[Thing]] to read a localised string value from.\n * @param property The Property whose localised string value to return.\n * @returns An English string value for the given Property if present, or null otherwise.\n * @since 1.13.0\n */\nexport function getStringEnglish(\n  thing: Thing,\n  property: Url | UrlString,\n): string | null {\n  return getStringWithLocale(thing, property, \"en\");\n}\n\n/**\n * Returns the localized string value of the specified Property from a [[Thing]].\n * If the Property is not present as a string in the specified locale, returns null.\n * If the Property has multiple string values for the specified locale, returns one of its values.\n *\n * @param thing The [[Thing]] to read a localised string value from.\n * @param property The Property whose localised string value to return.\n * @param locale The desired locale for the string value.\n * @returns A localised string value for the given Property if present in the specified `locale`, or null otherwise.\n */\nexport function getStringWithLocale(\n  thing: Thing,\n  property: Url | UrlString,\n  locale: string,\n): string | null {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const predicateIri = internal_toIriString(property);\n  const langStrings = thing.predicates[predicateIri]?.langStrings ?? {};\n  const existingLocales = Object.keys(langStrings);\n  const matchingLocale = existingLocales.find(\n    (existingLocale) =>\n      existingLocale.toLowerCase() === locale.toLowerCase() &&\n      Array.isArray(langStrings[existingLocale]) &&\n      langStrings[existingLocale].length > 0,\n  );\n  return typeof matchingLocale === \"string\"\n    ? langStrings[matchingLocale][0]\n    : null;\n}\n\n/**\n * Returns the English (language tag \"en\") string values of the specified Property from a [[Thing]].\n * If the Property is not present, returns an empty array.\n * If the Property's value is not an English string, omits that value in the array.\n *\n * @param thing The [[Thing]] to read a localised string value from.\n * @param property The Property whose localised string value to return.\n * @returns An array of English string values for the given Property.\n */\nexport function getStringEnglishAll(\n  thing: Thing,\n  property: Url | UrlString,\n): string[] {\n  return getStringWithLocaleAll(thing, property, \"en\");\n}\n\n/**\n * Returns the localized string values of the specified Property from a [[Thing]].\n * If the Property is not present, returns an empty array.\n * If the Property's value is not a string of the specified locale, omits that value in the array.\n *\n * @param thing The [[Thing]] to read the localised string values from.\n * @param property The Property whose localised string values to return.\n * @param locale The desired locale for the string values.\n * @returns An array of localised string values for the given Property.\n */\nexport function getStringWithLocaleAll(\n  thing: Thing,\n  property: Url | UrlString,\n  locale: string,\n): string[] {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const predicateIri = internal_toIriString(property);\n  const langStrings = thing.predicates[predicateIri]?.langStrings ?? {};\n  const existingLocales = Object.keys(langStrings);\n  const matchingLocale = existingLocales.find(\n    (existingLocale) =>\n      existingLocale.toLowerCase() === locale.toLowerCase() &&\n      Array.isArray(langStrings[existingLocale]) &&\n      langStrings[existingLocale].length > 0,\n  );\n  return typeof matchingLocale === \"string\"\n    ? [...langStrings[matchingLocale]]\n    : [];\n}\n\n/**\n * Returns all localized string values mapped by the locales for the specified property from the\n * specified [[Thing]] (explicitly filters out non-language string literals).\n *\n * @param thing The [[Thing]] to read the localised string values from.\n * @param property The Property whose localised string values to return.\n * @returns A Map of objects, keyed on locale with the value an array of string values (for that locale).\n */\nexport function getStringByLocaleAll(\n  thing: Thing,\n  property: Url | UrlString,\n): Map<string, string[]> {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const predicateIri = internal_toIriString(property);\n  const stringsByLocale = thing.predicates[predicateIri]?.langStrings ?? {};\n  return new Map(\n    Object.entries(stringsByLocale).map(([locale, values]) => [\n      locale,\n      [...values],\n    ]),\n  );\n}\n\n/**\n * Returns the string value of the specified Property from a [[Thing]].\n * If the Property is not present or its value is not of type string, returns null.\n * If the Property has multiple string values, returns one of its values.\n *\n * @param thing The [[Thing]] to read a string value from.\n * @param property The Property whose string value to return.\n * @returns A string value for the given Property if present, or null if the Property is not present or the value is not of type string.\n */\nexport function getStringNoLocale(\n  thing: Thing,\n  property: Url | UrlString,\n): string | null {\n  internal_throwIfNotThing(thing);\n  const literalString = getLiteralOfType(\n    thing,\n    property,\n    xmlSchemaTypes.string,\n  );\n\n  return literalString;\n}\n\n/**\n * Returns the string values of the specified Property from a [[Thing]].\n * If the Property is not present, returns an empty array.\n * If the Property's value is not of type string, omits that value in the array.\n *\n * @param thing The [[Thing]] to read the string values from.\n * @param property The Property whose string values to return.\n * @returns An array of string values for the given Property.\n */\nexport function getStringNoLocaleAll(\n  thing: Thing,\n  property: Url | UrlString,\n): string[] {\n  internal_throwIfNotThing(thing);\n  const literalStrings = getLiteralAllOfType(\n    thing,\n    property,\n    xmlSchemaTypes.string,\n  );\n\n  return literalStrings;\n}\n\n/**\n * @param thing The [[Thing]] to read a NamedNode value from.\n * @param property The given Property for which you want the NamedNode value.\n * @returns A NamedNode value for the given Property, if present, or null otherwise.\n * @ignore This should not be needed due to the other get*() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @see https://rdf.js.org/data-model-spec/#namednode-interface\n */\nexport function getNamedNode(\n  thing: Thing,\n  property: Url | UrlString,\n): NamedNode | null {\n  const iriString = getIri(thing, property);\n\n  if (iriString === null) {\n    return null;\n  }\n\n  return DataFactory.namedNode(iriString);\n}\n\n/**\n * @param thing The [[Thing]] to read the NamedNode values from.\n * @param property The given Property for which you want the NamedNode values.\n * @returns The NamedNode values for the given Property.\n * @ignore This should not be needed due to the other get*() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @see https://rdf.js.org/data-model-spec/#namednode-interface\n */\nexport function getNamedNodeAll(\n  thing: Thing,\n  property: Url | UrlString,\n): NamedNode[] {\n  const iriStrings = getIriAll(thing, property);\n\n  return iriStrings.map((iriString) => DataFactory.namedNode(iriString));\n}\n\n/**\n * @param thing The [[Thing]] to read a Literal value from.\n * @param property The given Property for which you want the Literal value.\n * @returns A Literal value for the given Property, if present, or null otherwise.\n * @ignore This should not be needed due to the other get*() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @see https://rdf.js.org/data-model-spec/#literal-interface\n */\nexport function getLiteral(\n  thing: Thing,\n  property: Url | UrlString,\n): Literal | null {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const predicateIri = internal_toIriString(property);\n  const langStrings = thing.predicates[predicateIri]?.langStrings ?? {};\n  const locales = Object.keys(langStrings);\n  if (locales.length > 0) {\n    const nonEmptyLocale = locales.find(\n      (locale) =>\n        Array.isArray(langStrings[locale]) && langStrings[locale].length > 0,\n    );\n    if (typeof nonEmptyLocale === \"string\") {\n      return DataFactory.literal(\n        langStrings[nonEmptyLocale][0],\n        nonEmptyLocale,\n      );\n    }\n  }\n\n  const otherLiterals = thing.predicates[predicateIri]?.literals ?? {};\n  const dataTypes = Object.keys(otherLiterals);\n\n  if (dataTypes.length > 0) {\n    const nonEmptyDataType = dataTypes.find(\n      (dataType) =>\n        Array.isArray(otherLiterals[dataType]) &&\n        otherLiterals[dataType].length > 0,\n    );\n    if (typeof nonEmptyDataType === \"string\") {\n      return DataFactory.literal(\n        otherLiterals[nonEmptyDataType][0],\n        DataFactory.namedNode(nonEmptyDataType),\n      );\n    }\n  }\n\n  return null;\n}\n\n/**\n * @param thing The [[Thing]] to read the Literal values from.\n * @param property The given Property for which you want the Literal values.\n * @returns The Literal values for the given Property.\n * @ignore This should not be needed due to the other get*All() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @see https://rdf.js.org/data-model-spec/#literal-interface\n */\nexport function getLiteralAll(\n  thing: Thing,\n  property: Url | UrlString,\n): Literal[] {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const predicateIri = internal_toIriString(property);\n  let literals: Literal[] = [];\n\n  const langStrings = thing.predicates[predicateIri]?.langStrings ?? {};\n  const locales = Object.keys(langStrings);\n  for (const locale of locales) {\n    const stringsInLocale = langStrings[locale];\n    const localeLiterals = stringsInLocale.map((langString) =>\n      DataFactory.literal(langString, locale),\n    );\n    literals = literals.concat(localeLiterals);\n  }\n\n  const otherLiterals = thing.predicates[predicateIri]?.literals ?? {};\n  const dataTypes = Object.keys(otherLiterals);\n\n  for (const dataType of dataTypes) {\n    const values = otherLiterals[dataType];\n    const typeNode = DataFactory.namedNode(dataType);\n    const dataTypeLiterals = values.map((value) =>\n      DataFactory.literal(value, typeNode),\n    );\n    literals = literals.concat(dataTypeLiterals);\n  }\n\n  return literals;\n}\n\n/**\n * @param thing The [[Thing]] to read a raw RDF/JS value from.\n * @param property The given Property for which you want the raw value.\n * @returns A Term for the given Property, if present, or null otherwise.\n * @ignore This should not be needed due to the other get*() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @see https://rdf.js.org/data-model-spec/\n * @since 0.3.0\n */\nexport function getTerm(\n  thing: Thing,\n  property: Url | UrlString,\n): Quad_Object | null {\n  internal_throwIfNotThing(thing);\n  const namedNode = getNamedNode(thing, property);\n  if (namedNode !== null) {\n    return namedNode;\n  }\n\n  const literal = getLiteral(thing, property);\n  if (literal !== null) {\n    return literal;\n  }\n\n  const predicateIri = internal_toIriString(property);\n  const blankNodes = thing.predicates[predicateIri]?.blankNodes ?? [];\n  if (blankNodes.length > 0) {\n    const blankNodeValue = isBlankNodeId(blankNodes[0])\n      ? getBlankNodeValue(blankNodes[0])\n      : undefined;\n    return DataFactory.blankNode(blankNodeValue);\n  }\n\n  return null;\n}\n\n/**\n * @param thing The [[Thing]] to read the raw RDF/JS values from.\n * @param property The given Property for which you want the raw values.\n * @returns The Terms for the given Property.\n * @ignore This should not be needed due to the other get*() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @see https://rdf.js.org/data-model-spec/\n * @since 0.3.0\n */\nexport function getTermAll(\n  thing: Thing,\n  property: Url | UrlString,\n): Quad_Object[] {\n  internal_throwIfNotThing(thing);\n  const namedNodes = getNamedNodeAll(thing, property);\n\n  const literals = getLiteralAll(thing, property);\n\n  const predicateIri = internal_toIriString(property);\n  const blankNodeValues = thing.predicates[predicateIri]?.blankNodes ?? [];\n  const blankNodes = blankNodeValues.map((rawBlankNode) => {\n    const blankNodeName = isBlankNodeId(rawBlankNode)\n      ? getBlankNodeValue(rawBlankNode)\n      : undefined;\n    return DataFactory.blankNode(blankNodeName);\n  });\n\n  const terms: Quad_Object[] = (namedNodes as Quad_Object[])\n    .concat(literals)\n    .concat(blankNodes);\n  return terms;\n}\n\n/**\n * @param thing The [Thing]] to read a Literal of the given type from.\n * @param property The given Property for which you want the Literal value.\n * @param literalType Set type of the Literal data.\n * @returns The stringified value for the given Property and type, if present, or null otherwise.\n */\nfunction getLiteralOfType<Datatype extends XmlSchemaTypeIri>(\n  thing: Thing,\n  property: Url | UrlString,\n  literalType: Datatype,\n): string | null {\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const predicateIri = internal_toIriString(property);\n  return thing.predicates[predicateIri]?.literals?.[literalType]?.[0] ?? null;\n}\n\n/**\n * @param thing The [Thing]] to read the Literals of the given type from.\n * @param property The given Property for which you want the Literal values.\n * @param literalType Set type of the Literal data.\n * @returns The stringified values for the given Property and type.\n */\nfunction getLiteralAllOfType<Datatype extends XmlSchemaTypeIri>(\n  thing: Thing,\n  property: Url | UrlString,\n  literalType: Datatype,\n): string[] {\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const predicateIri = internal_toIriString(property);\n  const literalsOfType =\n    thing.predicates[predicateIri]?.literals?.[literalType] ?? [];\n  return [...literalsOfType];\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\n// The following module is present but ESM-only, which seems to confuse ESLint.\n// eslint-disable-next-line import/no-unresolved\nimport { v4 as uuidv4 } from \"uuid\";\nimport {\n  isNamedNode,\n  resolveLocalIri,\n  internal_isValidUrl,\n} from \"../datatypes\";\nimport type {\n  UrlString,\n  Url,\n  Thing,\n  ThingLocal,\n  ThingPersisted,\n  SolidDataset,\n  WithChangeLog,\n  IriString,\n} from \"../interfaces\";\nimport { SolidClientError, hasServerResourceInfo } from \"../interfaces\";\nimport { DataFactory, subjectToRdfJsQuads } from \"../rdfjs.internal\";\nimport { getSourceUrl } from \"../resource/resource\";\nimport {\n  internal_addAdditionsToChangeLog,\n  internal_addDeletionsToChangeLog,\n  internal_getReadableValue,\n} from \"./thing.internal\";\nimport type { BlankNodeId, LocalNodeIri } from \"../rdf.internal\";\nimport {\n  freeze,\n  getLocalNodeIri,\n  getLocalNodeName,\n  isBlankNodeId,\n  isLocalNodeIri,\n} from \"../rdf.internal\";\nimport { internal_toIriString } from \"../interfaces.internal\";\nimport { getTermAll } from \"./get\";\n\n/**\n * @hidden Scopes are not yet consistently used in Solid and hence not properly implemented in this library yet (the add*() and set*() functions do not respect it yet), so we're not exposing these to developers at this point in time.\n */\nexport interface GetThingOptions {\n  /**\n   * Which Named Graph to extract the Thing from.\n   *\n   * If not specified, the Thing will include Quads from all Named Graphs in the given\n   * [[SolidDataset]].\n   * */\n  scope?: Url | UrlString;\n}\nexport function getThing(\n  solidDataset: SolidDataset,\n  thingUrl: UrlString | Url,\n  options?: GetThingOptions,\n): ThingPersisted | null;\nexport function getThing(\n  solidDataset: SolidDataset,\n  thingUrl: LocalNodeIri,\n  options?: GetThingOptions,\n): ThingLocal | null;\nexport function getThing(\n  solidDataset: SolidDataset,\n  thingUrl: UrlString | Url | LocalNodeIri | BlankNodeId,\n  options?: GetThingOptions,\n): Thing | null;\n/**\n * Extract Quads with a given Subject from a [[SolidDataset]] into a [[Thing]].\n *\n * @param solidDataset The [[SolidDataset]] to extract the [[Thing]] from.\n * @param thingUrl The identifier of the desired [[Thing]] (URL or Blank Node identifier).\n * @param options Not yet implemented.\n */\nexport function getThing(\n  solidDataset: SolidDataset,\n  thingUrl: UrlString | Url | LocalNodeIri | BlankNodeId,\n  options: GetThingOptions = {},\n): Thing | null {\n  if (!internal_isValidUrl(thingUrl) && !thingUrl.match(/^_:/)) {\n    throw new ValidThingUrlExpectedError(thingUrl);\n  }\n\n  const graph =\n    typeof options.scope !== \"undefined\"\n      ? internal_toIriString(options.scope)\n      : \"default\";\n  const thingsByIri = solidDataset.graphs[graph] ?? {};\n  const thingIri = internal_toIriString(thingUrl);\n  const resolvedThingIri =\n    isLocalNodeIri(thingIri) && hasServerResourceInfo(solidDataset)\n      ? resolveLocalIri(getLocalNodeName(thingIri), getSourceUrl(solidDataset))\n      : thingIri;\n  const thing = thingsByIri[resolvedThingIri];\n  if (typeof thing === \"undefined\") {\n    return null;\n  }\n  return thing;\n}\n\n/**\n * Get all [[Thing]]s in a [[SolidDataset]].\n *\n * @param solidDataset The [[SolidDataset]] to extract the [[Thing]]s from.\n * @param options Not yet implemented.\n */\nexport function getThingAll(\n  solidDataset: SolidDataset,\n  options: GetThingOptions & {\n    /**\n     * Can Things local to the current dataset, and having no IRI, be returned ?\n     */\n    acceptBlankNodes?: boolean;\n  } = { acceptBlankNodes: false },\n): Thing[] {\n  const graph =\n    typeof options.scope !== \"undefined\"\n      ? internal_toIriString(options.scope)\n      : \"default\";\n  const thingsByIri = solidDataset.graphs[graph] ?? {};\n  return Object.values(thingsByIri).filter(\n    (thing) => !isBlankNodeId(thing.url) || options.acceptBlankNodes,\n  );\n}\n\n/**\n * Insert a [[Thing]] into a [[SolidDataset]], replacing previous instances of that Thing.\n *\n * @param solidDataset The SolidDataset to insert a Thing into.\n * @param thing The Thing to insert into the given SolidDataset.\n * @returns A new SolidDataset equal to the given SolidDataset, but with the given Thing.\n */\nexport function setThing<Dataset extends SolidDataset>(\n  solidDataset: Dataset,\n  thing: Thing,\n): Dataset & WithChangeLog {\n  const thingIri =\n    isThingLocal(thing) && hasServerResourceInfo(solidDataset)\n      ? resolveLocalIri(getLocalNodeName(thing.url), getSourceUrl(solidDataset))\n      : thing.url;\n  const defaultGraph = solidDataset.graphs.default;\n  const updatedDefaultGraph = freeze({\n    ...defaultGraph,\n    [thingIri]: freeze({ ...thing, url: thingIri }),\n  });\n  const updatedGraphs = freeze({\n    ...solidDataset.graphs,\n    default: updatedDefaultGraph,\n  });\n\n  const subjectNode = DataFactory.namedNode(thingIri);\n\n  const deletedThingPredicates =\n    solidDataset.graphs.default[thingIri]?.predicates;\n  const deletions =\n    typeof deletedThingPredicates !== \"undefined\"\n      ? subjectToRdfJsQuads(\n          deletedThingPredicates,\n          subjectNode,\n          DataFactory.defaultGraph(),\n        )\n      : [];\n\n  const additions = subjectToRdfJsQuads(\n    thing.predicates,\n    subjectNode,\n    DataFactory.defaultGraph(),\n  );\n  return internal_addAdditionsToChangeLog(\n    internal_addDeletionsToChangeLog(\n      freeze({\n        ...solidDataset,\n        graphs: updatedGraphs,\n      }),\n      deletions,\n    ),\n    additions,\n  );\n}\n\n/**\n * Remove a Thing from a SolidDataset.\n *\n * @param solidDataset The SolidDataset to remove a Thing from.\n * @param thing The Thing to remove from `solidDataset`.\n * @returns A new [[SolidDataset]] equal to the input SolidDataset, excluding the given Thing.\n */\nexport function removeThing<Dataset extends SolidDataset>(\n  solidDataset: Dataset,\n  thing: UrlString | Url | Thing,\n): Dataset & WithChangeLog {\n  let thingIri: IriString;\n  if (isNamedNode(thing)) {\n    thingIri = thing.value;\n  } else if (typeof thing === \"string\") {\n    thingIri =\n      isLocalNodeIri(thing) && hasServerResourceInfo(solidDataset)\n        ? resolveLocalIri(getLocalNodeName(thing), getSourceUrl(solidDataset))\n        : thing;\n  } else if (isThingLocal(thing)) {\n    thingIri = thing.url;\n  } else {\n    thingIri = asIri(thing);\n  }\n\n  const defaultGraph = solidDataset.graphs.default;\n  const updatedDefaultGraph = { ...defaultGraph };\n  delete updatedDefaultGraph[thingIri];\n  const updatedGraphs = freeze({\n    ...solidDataset.graphs,\n    default: freeze(updatedDefaultGraph),\n  });\n\n  const subjectNode = DataFactory.namedNode(thingIri);\n  const deletedThingPredicates =\n    solidDataset.graphs.default[thingIri]?.predicates;\n  const deletions =\n    typeof deletedThingPredicates !== \"undefined\"\n      ? subjectToRdfJsQuads(\n          deletedThingPredicates,\n          subjectNode,\n          DataFactory.defaultGraph(),\n        )\n      : [];\n\n  return internal_addDeletionsToChangeLog(\n    freeze({\n      ...solidDataset,\n      graphs: updatedGraphs,\n    }),\n    deletions,\n  );\n}\n\n/** Pass these options to [[createThing]] to initialise a new [[Thing]] whose URL will be determined when it is saved. */\nexport type CreateThingLocalOptions = {\n  /**\n   * The name that should be used for this [[Thing]] when constructing its URL.\n   *\n   * If not provided, a random one will be generated.\n   */\n  name?: string;\n};\n/** Pass these options to [[createThing]] to initialise a new [[Thing]] whose URL is already known. */\nexport type CreateThingPersistedOptions = {\n  /**\n   * The URL of the newly created [[Thing]].\n   */\n  url: UrlString;\n};\n/** The options you pass to [[createThing]].\n * - To specify the URL for the initialised Thing, pass [[CreateThingPersistedOptions]].\n * - To have the URL determined during the save, pass [[CreateThingLocalOptions]].\n */\nexport type CreateThingOptions =\n  CreateThingLocalOptions | CreateThingPersistedOptions;\n/**\n * Initialise a new [[Thing]] in memory with a given URL.\n *\n * @param options See [[CreateThingPersistedOptions]] for how to specify the new [[Thing]]'s URL.\n */\nexport function createThing(\n  options: CreateThingPersistedOptions,\n): ThingPersisted;\n/**\n * Initialise a new [[Thing]] in memory.\n *\n * @param options Optional parameters that affect the final URL of this [[Thing]] when saved.\n */\nexport function createThing(options?: CreateThingLocalOptions): ThingLocal;\nexport function createThing(options?: CreateThingOptions): Thing;\nexport function createThing(options: CreateThingOptions = {}): Thing {\n  if (typeof (options as CreateThingPersistedOptions).url !== \"undefined\") {\n    const { url } = options as CreateThingPersistedOptions;\n    if (!internal_isValidUrl(url)) {\n      throw new ValidThingUrlExpectedError(url);\n    }\n    const thing: ThingPersisted = freeze({\n      type: \"Subject\",\n      predicates: freeze({}),\n      url,\n    });\n    return thing;\n  }\n  const name = (options as CreateThingLocalOptions).name ?? generateName();\n  const localNodeIri = getLocalNodeIri(name);\n  const thing: ThingLocal = freeze({\n    type: \"Subject\",\n    predicates: freeze({}),\n    url: localNodeIri,\n  });\n  return thing;\n}\n\n/**\n * @param input An value that might be a [[Thing]].\n * @returns Whether `input` is a Thing.\n * @since 0.2.0\n */\nexport function isThing<X>(input: X | Thing): input is Thing {\n  return (\n    typeof input === \"object\" &&\n    input !== null &&\n    typeof (input as Thing).type === \"string\" &&\n    (input as Thing).type === \"Subject\"\n  );\n}\n\ntype IsNotThingLocal<T extends Thing> = T extends ThingLocal ? never : T;\n/**\n * Get the URL to a given [[Thing]].\n *\n * @param thing The [[Thing]] you want to obtain the URL from.\n * @param baseUrl If `thing` is not persisted yet, the base URL that should be used to construct this [[Thing]]'s URL.\n */\nexport function asUrl(thing: ThingLocal, baseUrl: UrlString): UrlString;\nexport function asUrl<T extends ThingPersisted>(\n  thing: T & IsNotThingLocal<T>,\n): UrlString;\nexport function asUrl(thing: Thing, baseUrl: UrlString): UrlString;\nexport function asUrl(thing: Thing, baseUrl?: UrlString): UrlString {\n  if (isThingLocal(thing)) {\n    if (typeof baseUrl === \"undefined\") {\n      throw new Error(\n        \"The URL of a Thing that has not been persisted cannot be determined without a base URL.\",\n      );\n    }\n    return resolveLocalIri(getLocalNodeName(thing.url), baseUrl);\n  }\n\n  return thing.url;\n}\n/** @hidden Alias of [[asUrl]] for those who prefer IRI terminology. */\nexport const asIri = asUrl;\n\n/**\n * Gets a human-readable representation of the given Thing to aid debugging.\n *\n * Note that changes to the exact format of the return value are not considered a breaking change;\n * it is intended to aid in debugging, not as a serialisation method that can be reliably parsed.\n *\n * @param thing The Thing to get a human-readable representation of.\n * @since 0.3.0\n */\nexport function thingAsMarkdown(thing: Thing): string {\n  let thingAsMarkdown = \"\";\n\n  if (isThingLocal(thing)) {\n    thingAsMarkdown += `## Thing (no URL yet — identifier: \\`#${getLocalNodeName(\n      thing.url,\n    )}\\`)\\n`;\n  } else {\n    thingAsMarkdown += `## Thing: ${thing.url}\\n`;\n  }\n\n  const predicateIris = Object.keys(thing.predicates);\n  if (predicateIris.length === 0) {\n    thingAsMarkdown += \"\\n<empty>\\n\";\n  } else {\n    for (const predicate of predicateIris) {\n      thingAsMarkdown += `\\nProperty: ${predicate}\\n`;\n\n      const values = getTermAll(thing, predicate);\n      thingAsMarkdown += values.reduce((acc, value) => {\n        return `${acc}- ${internal_getReadableValue(value)}\\n`;\n      }, \"\");\n    }\n  }\n\n  return thingAsMarkdown;\n}\n\n/**\n * @param thing The [[Thing]] of which a URL might or might not be known.\n * @return `true` if `thing` has no known URL yet.\n * @since 1.7.0\n */\nexport function isThingLocal(\n  thing: ThingPersisted | ThingLocal,\n): thing is ThingLocal {\n  return isLocalNodeIri(thing.url);\n}\n\n/**\n * This error is thrown when a function expected to receive a [[Thing]] but received something else.\n * @since 1.2.0\n */\nexport class ThingExpectedError extends SolidClientError {\n  public readonly receivedValue: unknown;\n\n  constructor(receivedValue: unknown) {\n    const message = `Expected a Thing, but received: [${receivedValue}].`;\n    super(message);\n    this.receivedValue = receivedValue;\n  }\n}\n\n/**\n * This error is thrown when a function expected to receive a valid URL to identify a property but received something else.\n */\nexport class ValidPropertyUrlExpectedError extends SolidClientError {\n  public readonly receivedProperty: unknown;\n\n  constructor(receivedValue: unknown) {\n    const value = isNamedNode(receivedValue)\n      ? receivedValue.value\n      : receivedValue;\n    const message = `Expected a valid URL to identify a property, but received: [${value}].`;\n    super(message);\n    this.receivedProperty = value;\n  }\n}\n\n/**\n * This error is thrown when a function expected to receive a valid URL value but received something else.\n */\nexport class ValidValueUrlExpectedError extends SolidClientError {\n  public readonly receivedValue: unknown;\n\n  constructor(receivedValue: unknown) {\n    const value = isNamedNode(receivedValue)\n      ? receivedValue.value\n      : receivedValue;\n    const message = `Expected a valid URL value, but received: [${value}].`;\n    super(message);\n    this.receivedValue = value;\n  }\n}\n\n/**\n * This error is thrown when a function expected to receive a valid URL to identify a [[Thing]] but received something else.\n */\nexport class ValidThingUrlExpectedError extends SolidClientError {\n  public readonly receivedValue: unknown;\n\n  constructor(receivedValue: unknown) {\n    const value = isNamedNode(receivedValue)\n      ? receivedValue.value\n      : receivedValue;\n    const message = `Expected a valid URL to identify a Thing, but received: [${value}].`;\n    super(message);\n    this.receivedValue = value;\n  }\n}\n\n/**\n * Generate a string that can be used as the unique identifier for a Thing\n *\n * This function works by starting with a date string (so that Things can be\n * sorted chronologically), followed by a random number generated by taking a\n * random number between 0 and 1, and cutting off the `0.`.\n *\n * @internal\n * @returns An string that's likely to be unique\n */\nconst generateName = () => {\n  return uuidv4();\n};\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { IriString } from \"../interfaces\";\n\n/**\n * This function normalizes IRIs as managed by the server to ease accurate comparison.\n * @param iri\n * @hidden\n */\nexport function normalizeServerSideIri(iri: IriString): IriString {\n  const iriObj = new URL(iri);\n  iriObj.hash = \"\";\n  return iriObj.href;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Quad, NamedNode, Quad_Object, DatasetCore } from \"@rdfjs/types\";\nimport { Store as N3Store } from \"n3\";\nimport { DataFactory, toRdfJsQuads } from \"../rdfjs.internal\";\nimport { ldp } from \"../constants\";\nimport { triplesToTurtle, getTurtleParser } from \"../formats/turtle\";\nimport { isLocalNode, isNamedNode, resolveIriForLocalNode } from \"../datatypes\";\nimport type {\n  UrlString,\n  WithResourceInfo,\n  Url,\n  IriString,\n  Thing,\n  ThingPersisted,\n  WithServerResourceInfo,\n  SolidDataset,\n  WithChangeLog,\n  LocalNode,\n} from \"../interfaces\";\nimport { hasResourceInfo, hasChangelog } from \"../interfaces\";\nimport { internal_toIriString, normalizeUrl } from \"../interfaces.internal\";\nimport {\n  getSourceUrl,\n  isContainer,\n  FetchError,\n  responseToResourceInfo,\n  getContentType,\n} from \"./resource\";\nimport {\n  internal_isUnsuccessfulResponse,\n  internal_parseResourceInfo,\n} from \"./resource.internal\";\nimport { thingAsMarkdown, getThing, getThingAll } from \"../thing/thing\";\nimport {\n  internal_getReadableValue,\n  internal_withChangeLog,\n} from \"../thing/thing.internal\";\nimport { getIriAll } from \"../thing/get\";\nimport { normalizeServerSideIri } from \"./iri.internal\";\nimport { freeze, getLocalNodeName, isLocalNodeIri } from \"../rdf.internal\";\nimport { fromRdfJsDataset } from \"../rdfjs\";\n\n/**\n * Initialise a new [[SolidDataset]] in memory.\n *\n * @returns An empty [[SolidDataset]].\n */\nexport function createSolidDataset(): SolidDataset {\n  return freeze({\n    type: \"Dataset\",\n    graphs: {\n      default: {},\n    },\n  });\n}\n\n/**\n * A Parser takes a string and generates {@link https://rdf.js.org/data-model-spec/|RDF/JS Quads}.\n *\n * By providing an object conforming to the `Parser` interface, you can handle\n * RDF serialisations other than `text/turtle`, which `@inrupt/solid-client`\n * supports by default. This can be useful to retrieve RDF data from sources\n * other than a Solid Pod.\n *\n * A Parser has the following properties:\n * - `onQuad`: Registers the callback with which parsed\n * {@link https://rdf.js.org/data-model-spec/|RDF/JS Quads} can be provided to\n * `@inrupt/solid-client`.\n * - `onError`: Registers the callback with which `@inrupt/solid-client` can be\n * notified of errors parsing the input.\n * - `onComplete`: Registers the callback with which `@inrupt/solid-client` can\n * be notified that parsing is complete.\n * - `parse`: Accepts the serialised input string and an object containing the\n * input Resource's metadata.\n * The input metadata can be read using functions like [[getSourceUrl]] and\n * [[getContentType]].\n *\n * For example, the following defines a parser that reads an RDFa serialisation\n * using the\n * [rdfa-streaming-parser](https://www.npmjs.com/package/rdfa-streaming-parser)\n * library:\n *\n * ```javascript\n * import { RdfaParser } from \"rdfa-streaming-parser\";\n *\n * // ...\n *\n * const getRdfaParser = () => {\n *   const onQuadCallbacks = [];\n *   const onCompleteCallbacks = [];\n *   const onErrorCallbacks = [];\n *\n *   return {\n *     onQuad: (callback) => onQuadCallbacks.push(callback),\n *     onError: (callback) => onErrorCallbacks.push(callback),\n *     onComplete: (callback) => onCompleteCallbacks.push(callback),\n *     parse: async (source, resourceInfo) => {\n *       const parser = new RdfaParser({\n *         baseIRI: getSourceUrl(resourceInfo),\n *         contentType: getContentType(resourceInfo) ?? \"text/html\",\n *       });\n *       parser.on(\"data\", (quad) => {\n *         onQuadCallbacks.forEach((callback) => callback(quad));\n *       });\n *       parser.on(\"error\", (error) => {\n *         onErrorCallbacks.forEach((callback) => callback(error));\n *       });\n *       parser.write(source);\n *       parser.end();\n *       onCompleteCallbacks.forEach((callback) => callback());\n *     },\n *   };\n * };\n * ```\n */\nexport type Parser = {\n  onQuad: (onQuadCallback: (quad: Quad) => void) => void;\n  onError: (onErrorCallback: (error: unknown) => void) => void;\n  onComplete: (onCompleteCallback: () => void) => void;\n  parse: (source: string, resourceInfo: WithServerResourceInfo) => void;\n};\ntype ContentType = string;\n/**\n * Custom parsers to load [[SolidDataset]]s serialised in different RDF formats.\n *\n * Provide your own parsers by providing an object on the `parsers` property\n * with the supported content type as the key, and the parser as a value.\n * For documentation on how to provide a parser, see [[Parser]].\n */\nexport type ParseOptions = {\n  parsers: Record<ContentType, Parser>;\n};\n\n/**\n * @hidden This interface is not exposed yet until we've tried it out in practice.\n */\nexport async function responseToSolidDataset(\n  response: Response,\n  parseOptions: Partial<ParseOptions> = {},\n): Promise<SolidDataset & WithServerResourceInfo> {\n  if (internal_isUnsuccessfulResponse(response)) {\n    const errorBody = await response.clone().text();\n    throw new FetchError(\n      `Fetching the SolidDataset at [${response.url}] failed: [${\n        response.status\n      }] [${response.statusText}] ${errorBody}.`,\n      response,\n      errorBody,\n    );\n  }\n\n  const resourceInfo = responseToResourceInfo(response);\n\n  const parsers: Record<ContentType, Parser> = {\n    \"text/turtle\": getTurtleParser(),\n    ...parseOptions.parsers,\n  };\n  const contentType = getContentType(resourceInfo);\n  if (contentType === null) {\n    throw new Error(\n      `Could not determine the content type of the Resource at [${getSourceUrl(\n        resourceInfo,\n      )}].`,\n    );\n  }\n\n  const mimeType = contentType.split(\";\")[0];\n  const parser = parsers[mimeType];\n  if (typeof parser === \"undefined\") {\n    throw new Error(\n      `The Resource at [${getSourceUrl(\n        resourceInfo,\n      )}] has a MIME type of [${mimeType}], but the only parsers available are for the following MIME types: [${Object.keys(\n        parsers,\n      ).join(\", \")}].`,\n    );\n  }\n\n  const data = await response.text();\n  const rdfjsDataset = await new Promise<DatasetCore>((resolve, reject) => {\n    const store = new N3Store();\n    parser.onError((error) => {\n      reject(\n        new Error(\n          `Encountered an error parsing the Resource at [${getSourceUrl(\n            resourceInfo,\n          )}] with content type [${contentType}]: ${error}`,\n        ),\n      );\n    });\n    parser.onQuad((quad) => {\n      store.add(quad);\n    });\n    parser.onComplete(() => {\n      resolve(store);\n    });\n\n    parser.parse(data, resourceInfo);\n  });\n  const solidDataset: SolidDataset = freeze(fromRdfJsDataset(rdfjsDataset));\n  return freeze({\n    ...solidDataset,\n    ...resourceInfo,\n  });\n}\n\n/**\n * Fetch a SolidDataset from the given URL. Currently requires the SolidDataset to be available as [Turtle](https://www.w3.org/TR/turtle/).\n *\n * Note that the URL of a container ends with a [trailing slash \"/\"](https://solidproject.org/TR/protocol#uri).\n * If it is missing, some libraries will add it automatically, which may result in additional round-trips, possibly including\n * authentication errors ([more information](https://github.com/inrupt/solid-client-js/issues/1216#issuecomment-904703695)).\n *\n * @param url URL to fetch a [[SolidDataset]] from.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns Promise resolving to a [[SolidDataset]] containing the data at the given Resource, or rejecting if fetching it failed.\n */\nexport async function getSolidDataset(\n  url: UrlString | Url,\n  options?: Partial<{ fetch: typeof fetch } & ParseOptions>,\n): Promise<SolidDataset & WithServerResourceInfo> {\n  const normalizedUrl = normalizeUrl(internal_toIriString(url));\n  const parserContentTypes = Object.keys(options?.parsers ?? {});\n  const acceptedContentTypes =\n    parserContentTypes.length > 0\n      ? parserContentTypes.join(\", \")\n      : \"text/turtle\";\n  const response = await (options?.fetch ?? fetch)(normalizedUrl, {\n    headers: {\n      Accept: acceptedContentTypes,\n    },\n  });\n  if (internal_isUnsuccessfulResponse(response)) {\n    const errorBody = await response.clone().text();\n    throw new FetchError(\n      `Fetching the Resource at [${normalizedUrl}] failed: [${\n        response.status\n      }] [${response.statusText}] ${errorBody}.`,\n      response,\n      errorBody,\n    );\n  }\n  const solidDataset = await responseToSolidDataset(response, options);\n\n  return solidDataset;\n}\n\ntype UpdateableDataset = SolidDataset &\n  WithChangeLog &\n  WithServerResourceInfo & { internal_resourceInfo: { sourceIri: IriString } };\n\n/**\n * Create a SPARQL UPDATE Patch request from a [[SolidDataset]] with a changelog.\n * @param solidDataset the [[SolidDataset]] that has been locally updated, and that should be persisted.\n * @returns an HTTP PATCH request configuration object, aligned with the [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters), containing a SPARQL UPDATE.\n * @hidden\n */\nasync function prepareSolidDatasetUpdate(\n  solidDataset: UpdateableDataset,\n): Promise<RequestInit> {\n  const deleteStatement =\n    solidDataset.internal_changeLog.deletions.length > 0\n      ? `DELETE DATA {${(\n          await triplesToTurtle(\n            solidDataset.internal_changeLog.deletions.map(\n              getNamedNodesForLocalNodes,\n            ),\n          )\n        ).trim()}};`\n      : \"\";\n  const insertStatement =\n    solidDataset.internal_changeLog.additions.length > 0\n      ? `INSERT DATA {${(\n          await triplesToTurtle(\n            solidDataset.internal_changeLog.additions.map(\n              getNamedNodesForLocalNodes,\n            ),\n          )\n        ).trim()}};`\n      : \"\";\n\n  return {\n    method: \"PATCH\",\n    body: `${deleteStatement} ${insertStatement}`,\n    headers: {\n      \"Content-Type\": \"application/sparql-update\",\n    },\n  };\n}\n\n/**\n * Create a Put request to write a locally created [[SolidDataset]] to a Pod.\n * @param solidDataset the [[SolidDataset]] that has been locally updated, and that should be persisted.\n * @returns an HTTP PUT request configuration object, aligned with the [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters), containing a serialization of the [[SolidDataset]].\n * @hidden\n */\nasync function prepareSolidDatasetCreation(\n  solidDataset: SolidDataset,\n  options?: Partial<{ prefixes: Record<string, string> }>,\n): Promise<RequestInit> {\n  return {\n    method: \"PUT\",\n    body: await triplesToTurtle(\n      toRdfJsQuads(solidDataset).map(getNamedNodesForLocalNodes),\n      options,\n    ),\n    headers: {\n      \"Content-Type\": \"text/turtle\",\n      \"If-None-Match\": \"*\",\n      Link: `<${ldp.Resource}>; rel=\"type\"`,\n    },\n  };\n}\n\n/**\n * Given a SolidDataset, store it in a Solid Pod (overwriting the existing data at the given URL).\n *\n * A SolidDataset keeps track of the data changes compared to the data in the Pod; i.e.,\n * the changelog tracks both the old value and new values of the property being modified. This\n * function applies the changes to the current SolidDataset. If the old value specified in the\n * changelog does not correspond to the value currently in the Pod, this function will throw an\n * error (common issues are listed in [the documentation](https://docs.inrupt.com/sdk/javascript-sdkreference/error-codes/)).\n *\n * The SolidDataset returned by this function will contain the data sent to the Pod, and a ChangeLog\n * up-to-date with the saved data. Note that if the data on the server was modified in between the\n * first fetch and saving it, the updated data will not be reflected in the returned SolidDataset.\n * To make sure you have the latest data, call [[getSolidDataset]] again after saving the data.\n *\n * The Solid server will create any intermediary Containers that do not exist yet, so they do not\n * need to be created in advance. For example, if the target URL is\n * https://example.pod/container/resource and https://example.pod/container/ does not exist yet,\n * it will exist after this function resolves successfully.\n *\n * @param url URL to save `solidDataset` to.\n * @param solidDataset The [[SolidDataset]] to save.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n *  `options.prefixes`: A prefix map to customize the serialization. Only applied on resource creation if the serialization allows it.\n * @returns A Promise resolving to a [[SolidDataset]] containing the stored data, or rejecting if saving it failed.\n */\nexport async function saveSolidDatasetAt<Dataset extends SolidDataset>(\n  url: UrlString | Url,\n  solidDataset: Dataset,\n  options?: Partial<\n    { fetch?: typeof fetch } & { prefixes: Record<string, string> }\n  >,\n): Promise<Dataset & WithServerResourceInfo & WithChangeLog> {\n  const targetUrl = normalizeUrl(internal_toIriString(url));\n  const datasetWithChangelog = internal_withChangeLog(solidDataset);\n\n  const requestInit = isUpdate(datasetWithChangelog, targetUrl)\n    ? await prepareSolidDatasetUpdate(datasetWithChangelog)\n    : await prepareSolidDatasetCreation(datasetWithChangelog, options);\n\n  const response = await (options?.fetch ?? fetch)(targetUrl, requestInit);\n\n  if (internal_isUnsuccessfulResponse(response)) {\n    const diagnostics = isUpdate(datasetWithChangelog, targetUrl)\n      ? `The changes that were sent to the Pod are listed below.\\n\\n${changeLogAsMarkdown(\n          datasetWithChangelog,\n        )}`\n      : `The SolidDataset that was sent to the Pod is listed below.\\n\\n${solidDatasetAsMarkdown(\n          datasetWithChangelog,\n        )}`;\n    const errorBody = await response.clone().text();\n    throw new FetchError(\n      `Storing the Resource at [${targetUrl}] failed: [${response.status}] [${\n        response.statusText\n      }] ${errorBody}.\\n\\n${diagnostics}`,\n      response,\n      errorBody,\n    );\n  }\n\n  const resourceInfo: WithServerResourceInfo[\"internal_resourceInfo\"] = {\n    ...internal_parseResourceInfo(response),\n    isRawData: false,\n  };\n  const storedDataset: Dataset & WithChangeLog & WithServerResourceInfo =\n    freeze({\n      ...solidDataset,\n      internal_changeLog: { additions: [], deletions: [] },\n      internal_resourceInfo: resourceInfo,\n    });\n\n  const storedDatasetWithResolvedIris =\n    resolveLocalIrisInSolidDataset(storedDataset);\n\n  return storedDatasetWithResolvedIris;\n}\n\n/**\n * Deletes the SolidDataset at a given URL.\n *\n * If operating on a container, the container must be empty otherwise a 409 CONFLICT will be raised.\n *\n * @param solidDataset The URL of the SolidDataset to delete or the SolidDataset itself (if it has ResourceInfo).\n * @since 0.6.0\n */\nexport async function deleteSolidDataset(\n  solidDataset: Url | UrlString | WithResourceInfo,\n  options?: { fetch?: typeof fetch },\n): Promise<void> {\n  const url = hasResourceInfo(solidDataset)\n    ? internal_toIriString(getSourceUrl(solidDataset))\n    : normalizeUrl(internal_toIriString(solidDataset));\n  const response = await (options?.fetch ?? fetch)(url, { method: \"DELETE\" });\n\n  if (internal_isUnsuccessfulResponse(response)) {\n    const errorBody = await response.clone().text();\n    throw new FetchError(\n      `Deleting the SolidDataset at [${url}] failed: [${response.status}] [${\n        response.statusText\n      }] ${errorBody}.`,\n      response,\n      errorBody,\n    );\n  }\n}\n\n/**\n * Create a Container at the given URL. Some content may optionally be specified,\n * e.g. to add metadata describing the container.\n *\n * Throws an error if creating the Container failed, e.g. because the current user does not have\n * permissions to, or because the Container already exists.\n *\n * Note that a Solid server will automatically create the necessary Containers when storing a\n * Resource; i.e. there is no need to call this function if it is immediately followed by\n * [[saveSolidDatasetAt]] or [[overwriteFile]].\n *\n * @param url URL of the empty Container that is to be created.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @param solidDataset Optional parameter - if provided we use this dataset as the body of the HTT request, meaning it's data is included in the Container resource.\n * @since 0.2.0\n */\nexport async function createContainerAt(\n  url: UrlString | Url,\n  options: {\n    fetch?: typeof fetch;\n    initialContent?: SolidDataset;\n  } = {},\n): Promise<SolidDataset & WithServerResourceInfo> {\n  const normalizedUrl = normalizeUrl(internal_toIriString(url), {\n    trailingSlash: true,\n  });\n  const response = await (options.fetch ?? fetch)(normalizedUrl, {\n    method: \"PUT\",\n    body: options.initialContent\n      ? await triplesToTurtle(\n          toRdfJsQuads(options.initialContent).map(getNamedNodesForLocalNodes),\n        )\n      : undefined,\n    headers: {\n      Accept: \"text/turtle\",\n      \"Content-Type\": \"text/turtle\",\n      \"If-None-Match\": \"*\",\n      // This header should not be required to create a Container,\n      // but ESS currently expects it:\n      Link: `<${ldp.BasicContainer}>; rel=\"type\"`,\n    },\n  });\n\n  if (internal_isUnsuccessfulResponse(response)) {\n    const containerType =\n      options.initialContent === undefined ? \"empty\" : \"non-empty\";\n    const errorBody = await response.clone().text();\n    throw new FetchError(\n      `Creating the ${containerType} Container at [${url}] failed: [${\n        response.status\n      }] [${response.statusText}] ${errorBody}.`,\n      response,\n      errorBody,\n    );\n  }\n\n  const resourceInfo = internal_parseResourceInfo(response);\n  const containerDataset: SolidDataset &\n    WithChangeLog &\n    WithServerResourceInfo = freeze({\n    ...(options.initialContent ?? createSolidDataset()),\n    internal_changeLog: { additions: [], deletions: [] },\n    internal_resourceInfo: resourceInfo,\n  });\n\n  return containerDataset;\n}\n\nfunction isSourceIriEqualTo(\n  dataset: SolidDataset & WithResourceInfo,\n  iri: IriString,\n): boolean {\n  return (\n    normalizeServerSideIri(dataset.internal_resourceInfo.sourceIri) ===\n    normalizeServerSideIri(iri)\n  );\n}\n\nfunction isUpdate(\n  solidDataset: SolidDataset,\n  url: UrlString,\n): solidDataset is UpdateableDataset {\n  return (\n    hasChangelog(solidDataset) &&\n    hasResourceInfo(solidDataset) &&\n    typeof solidDataset.internal_resourceInfo.sourceIri === \"string\" &&\n    isSourceIriEqualTo(solidDataset, url)\n  );\n}\n\ntype SaveInContainerOptions = {\n  fetch?: typeof fetch;\n  slugSuggestion?: string;\n};\n\n/**\n * Given a SolidDataset, store it in a Solid Pod in a new Resource inside a Container.\n *\n * The Container at the given URL should already exist; if it does not, you can initialise it first\n * using [[createContainerAt]], or directly save the SolidDataset at the desired location using\n * [[saveSolidDatasetAt]].\n *\n * This function is primarily useful if the current user does not have access to change existing files in\n * a Container, but is allowed to add new files; in other words, they have Append, but not Write\n * access to a Container. This is useful in situations where someone wants to allow others to,\n * for example, send notifications to their Pod, but not to view or delete existing notifications.\n * You can pass a suggestion for the new Resource's name, but the server may decide to give it\n * another name — for example, if a Resource with that name already exists inside the given\n * Container.\n * If the user does have access to write directly to a given location, [[saveSolidDatasetAt]]\n * will do the job just fine, and does not require the parent Container to exist in advance.\n *\n * @param containerUrl URL of the Container in which to create a new Resource.\n * @param solidDataset The [[SolidDataset]] to save to a new Resource in the given Container.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns A Promise resolving to a [[SolidDataset]] containing the saved data. The Promise rejects if the save failed.\n */\nexport async function saveSolidDatasetInContainer(\n  containerUrl: UrlString | Url,\n  solidDataset: SolidDataset,\n  options?: SaveInContainerOptions,\n): Promise<SolidDataset & WithResourceInfo> {\n  const normalizedUrl = normalizeUrl(internal_toIriString(containerUrl), {\n    trailingSlash: true,\n  });\n\n  const rawTurtle = await triplesToTurtle(\n    toRdfJsQuads(solidDataset).map(getNamedNodesForLocalNodes),\n  );\n  const headers: RequestInit[\"headers\"] = {\n    \"Content-Type\": \"text/turtle\",\n    Link: `<${ldp.Resource}>; rel=\"type\"`,\n  };\n  if (options?.slugSuggestion) {\n    headers.slug = options.slugSuggestion;\n  }\n  const response = await (options?.fetch ?? fetch)(normalizedUrl, {\n    method: \"POST\",\n    body: rawTurtle,\n    headers,\n  });\n\n  if (internal_isUnsuccessfulResponse(response)) {\n    const errorBody = await response.clone().text();\n    throw new FetchError(\n      `Storing the Resource in the Container at [${normalizedUrl}] failed: [${\n        response.status\n      }] [${response.statusText}] ${errorBody}.\\n\\n` +\n        `The SolidDataset that was sent to the Pod is listed below.\\n\\n${solidDatasetAsMarkdown(\n          solidDataset,\n        )}`,\n      response,\n      errorBody,\n    );\n  }\n\n  const internalResourceInfo = internal_parseResourceInfo(response);\n\n  if (!internalResourceInfo.location) {\n    throw new Error(\n      \"Could not determine the location of the newly saved SolidDataset.\",\n    );\n  }\n\n  let resourceIri;\n\n  try {\n    // Try to parse the location header as a URL (safe if it's an absolute URL)``\n    // This should help determine the container URL if normalisation happened on the server side.\n    resourceIri = new URL(internalResourceInfo.location).href;\n  } catch {\n    // If it's a relative URL then, rely on the response.url to construct the sourceIri\n    resourceIri = new URL(internalResourceInfo.location, response.url).href;\n  }\n\n  const resourceInfo: WithResourceInfo = {\n    internal_resourceInfo: {\n      isRawData: false,\n      sourceIri: resourceIri,\n    },\n  };\n\n  const resourceWithResourceInfo: SolidDataset & WithResourceInfo = freeze({\n    ...solidDataset,\n    ...resourceInfo,\n  });\n\n  const resourceWithResolvedIris = resolveLocalIrisInSolidDataset(\n    resourceWithResourceInfo,\n  );\n\n  return resourceWithResolvedIris;\n}\n\n/**\n * Create an empty Container inside the Container at the given URL.\n *\n * Throws an error if creating the Container failed, e.g. because the current user does not have\n * permissions to.\n *\n * The Container in which to create the new Container should itself already exist.\n *\n * This function is primarily useful if the current user does not have access to change existing files in\n * a Container, but is allowed to add new files; in other words, they have Append, but not Write\n * access to a Container. This is useful in situations where someone wants to allow others to,\n * for example, send notifications to their Pod, but not to view or delete existing notifications.\n * You can pass a suggestion for the new Resource's name, but the server may decide to give it\n * another name — for example, if a Resource with that name already exists inside the given\n * Container.\n * If the user does have access to write directly to a given location, [[createContainerAt]]\n * will do the job just fine, and does not require the parent Container to exist in advance.\n *\n * @param containerUrl URL of the Container in which the empty Container is to\n * be created.\n * @param options Optional parameter `options.fetch`: An alternative `fetch`\n * function to make the HTTP request, compatible with the browser-native [fetch\n * API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).`options.slugSuggestion`\n * accepts a string for your new Container's name.\n * @returns A promise that resolves to a SolidDataset with ResourceInfo if\n * successful, and that rejects otherwise.\n * @since 0.2.0\n */\nexport async function createContainerInContainer(\n  containerUrl: UrlString | Url,\n  options?: SaveInContainerOptions,\n): Promise<SolidDataset & WithResourceInfo> {\n  const normalizedUrl = normalizeUrl(internal_toIriString(containerUrl), {\n    trailingSlash: true,\n  });\n  const headers: RequestInit[\"headers\"] = {\n    \"Content-Type\": \"text/turtle\",\n    Link: `<${ldp.BasicContainer}>; rel=\"type\"`,\n  };\n  if (options?.slugSuggestion) {\n    headers.slug = options.slugSuggestion;\n  }\n  const response = await (options?.fetch ?? fetch)(normalizedUrl, {\n    method: \"POST\",\n    headers,\n  });\n\n  if (internal_isUnsuccessfulResponse(response)) {\n    const errorBody = await response.clone().text();\n    throw new FetchError(\n      `Creating an empty Container in the Container at [${normalizedUrl}] failed: [${\n        response.status\n      }] [${response.statusText}] ${errorBody}.`,\n      response,\n      errorBody,\n    );\n  }\n\n  const internalResourceInfo = internal_parseResourceInfo(response);\n\n  if (!internalResourceInfo.location) {\n    throw new Error(\n      \"Could not determine the location of the newly created Container.\",\n    );\n  }\n  try {\n    // Try to parse the location header as a URL (safe if it's an absolute URL)``\n    // This should help determine the container URL if normalisation happened on the server side.\n    const sourceIri = new URL(internalResourceInfo.location).toString();\n    return freeze({\n      ...createSolidDataset(),\n      internal_resourceInfo: {\n        ...internalResourceInfo,\n        sourceIri,\n      },\n    });\n  } catch {\n    // If it's a relative URL then, rely on the response.url to construct the sourceIri\n  }\n\n  return freeze({\n    ...createSolidDataset(),\n    internal_resourceInfo: {\n      ...internalResourceInfo,\n      sourceIri: new URL(internalResourceInfo.location, response.url).href,\n    },\n  });\n}\n\n/**\n * Deletes the Container at a given URL.\n *\n * @param container The URL of the Container to delete or the Container Dataset itself (if it has ResourceInfo).\n * @since 0.6.0\n */\nexport async function deleteContainer(\n  container: Url | UrlString | WithResourceInfo,\n  options?: { fetch?: typeof fetch },\n): Promise<void> {\n  const normalizedUrl = hasResourceInfo(container)\n    ? internal_toIriString(getSourceUrl(container))\n    : normalizeUrl(internal_toIriString(container));\n\n  if (!isContainer(container)) {\n    throw new Error(\n      `You're trying to delete the Container at [${normalizedUrl}], but Container URLs should end in a \\`/\\`. Are you sure this is a Container?`,\n    );\n  }\n\n  const response = await (options?.fetch ?? fetch)(normalizedUrl, {\n    method: \"DELETE\",\n  });\n\n  if (internal_isUnsuccessfulResponse(response)) {\n    const errorBody = await response.clone().text();\n    throw new FetchError(\n      `Deleting the Container at [${normalizedUrl}] failed: [${\n        response.status\n      }] [${response.statusText}] ${errorBody}.`,\n      response,\n      errorBody,\n    );\n  }\n}\n\nfunction isChildResource(a: string, b: string): boolean {\n  const parent = new URL(b);\n  const child = new URL(a);\n  // Explicitly test on the whole URL to enforce similar origins.\n  const isAncestor = child.href.startsWith(parent.href);\n  const relativePath = child.pathname\n    .substring(parent.pathname.length, child.pathname.length)\n    .replace(/(^\\/)|(\\/$)/g, \"\");\n  // The child path component that isn't present in the parent should only\n  // potentially include slashes at the end (if it is a container).\n  return isAncestor && relativePath.length >= 1 && !relativePath.includes(\"/\");\n}\n\n/**\n * Given a [[SolidDataset]] representing a Container (see [[isContainer]]), fetch the URLs of all\n * contained resources that respect [slash semantics](https://solidproject.org/TR/protocol#uri-slash-semantics)\n * (see {@link validateContainedResourceAll}).\n * If the solidDataset given is not a container, or is missing resourceInfo, throw an error.\n *\n * @param solidDataset The container from which to fetch all contained Resource URLs.\n * @returns A list of URLs, each of which points to a contained Resource of the given SolidDataset.\n * @since 1.3.0\n */\n\nexport function getContainedResourceUrlAll(\n  solidDataset: SolidDataset & WithResourceInfo,\n): UrlString[] {\n  const containerUrl = getSourceUrl(solidDataset);\n  const container = getThing(solidDataset, containerUrl);\n  if (container === null) {\n    return [];\n  }\n  // See https://www.w3.org/TR/2015/REC-ldp-20150226/#h-ldpc-http_post:\n  // > a containment triple MUST be added to the state of the LDPC whose subject is the LDPC URI,\n  // > whose predicate is ldp:contains and whose object is the URI for the newly created document\n  return (\n    getIriAll(container, ldp.contains)\n      // See https://solidproject.org/TR/protocol#resource-containment\n      .filter((childUrl) => isChildResource(childUrl, containerUrl))\n  );\n}\n\n/**\n * Given a {@link SolidDataset} representing a [Container](https://solidproject.org/TR/protocol#resource-containment)\n * (see {@link isContainer}), verify that all its containment claims are valid. Containment of a resource is valid if\n * it respects [slash semantics](https://solidproject.org/TR/protocol#uri-slash-semantics).\n *\n * For the example, given a container at https://example.org/container/:\n *  - The following resources are valid:\n *    - https://example.org/container/resource\n *    - https://example.org/container/subcontainer/\n *  - The following resources are invalid:\n *    - https://example.org/container/resource/invalid (not a direct child resource)\n *    - https://example.org/container2 (not a child resource)\n *    - https://domain2.example.org/container/resource (not a direct child resource)\n *\n * If a component claim is invalid, {@link validateContainedResourceAll} returns the invalid component's URL\n * as part of its return object.\n *\n * Note: It is recommended that this function always be used before calling\n * {@link getContainedResourceUrlAll} since {@link getContainedResourceUrlAll} does not\n * return Resources for which containment is invalid. Using the function in conjunction\n * with {@link getContainedResourceUrlAll} allows for the detection of unexpected behaviour from servers,\n * including malicious containment triples that could appear. Because ESS conforms to the Solid Protocol,\n * i.e., respects slash semantics for its containment triples, validateContainedResourceAll returns true for\n * containers fetched from ESS.\n *\n * @param solidDataset The container from which containment claims are validated.\n * @returns A validation report, including the offending contained resources URL if any.\n * @since 1.30.1\n */\nexport function validateContainedResourceAll(\n  solidDataset: SolidDataset & WithResourceInfo,\n): { isValid: boolean; invalidContainedResources: string[] } {\n  const containerUrl = getSourceUrl(solidDataset);\n  const container = getThing(solidDataset, containerUrl);\n  if (container === null) {\n    return { isValid: true, invalidContainedResources: [] };\n  }\n\n  // See https://www.w3.org/TR/2015/REC-ldp-20150226/#h-ldpc-http_post:\n  // > a containment triple MUST be added to the state of the LDPC whose subject is the LDPC URI,\n  // > whose predicate is ldp:contains and whose object is the URI for the newly created document\n  const invalidChildren = getIriAll(container, ldp.contains)\n    // See https://solidproject.org/TR/protocol#resource-containment\n    .filter((childUrl) => !isChildResource(childUrl, containerUrl));\n\n  if (invalidChildren.length > 0) {\n    return { isValid: false, invalidContainedResources: invalidChildren };\n  }\n  return { isValid: true, invalidContainedResources: [] };\n}\n\n/**\n * Gets a human-readable representation of the given SolidDataset to aid debugging.\n *\n * Note that changes to the exact format of the return value are not considered a breaking change;\n * it is intended to aid in debugging, not as a serialisation method that can be reliably parsed.\n *\n * @param solidDataset The [[SolidDataset]] to get a human-readable representation of.\n * @since 0.3.0\n */\nexport function solidDatasetAsMarkdown(solidDataset: SolidDataset): string {\n  let readableSolidDataset = \"\";\n\n  if (hasResourceInfo(solidDataset)) {\n    readableSolidDataset += `# SolidDataset: ${getSourceUrl(solidDataset)}\\n`;\n  } else {\n    readableSolidDataset += `# SolidDataset (no URL yet)\\n`;\n  }\n\n  const things = getThingAll(solidDataset);\n  if (things.length === 0) {\n    readableSolidDataset += \"\\n<empty>\\n\";\n  } else {\n    things.forEach((thing) => {\n      readableSolidDataset += `\\n${thingAsMarkdown(thing)}`;\n      if (hasChangelog(solidDataset)) {\n        readableSolidDataset += `\\n${getReadableChangeLogSummary(\n          solidDataset,\n          thing,\n        )}\\n`;\n      }\n    });\n  }\n\n  return readableSolidDataset;\n}\n\n/**\n * Gets a human-readable representation of the local changes to a Resource to aid debugging.\n *\n * Note that changes to the exact format of the return value are not considered a breaking change;\n * it is intended to aid in debugging, not as a serialisation method that can be reliably parsed.\n *\n * @param solidDataset The Resource of which to get a human-readable representation of the changes applied to it locally.\n * @since 0.3.0\n */\nexport function changeLogAsMarkdown(\n  solidDataset: SolidDataset & WithChangeLog,\n): string {\n  if (!hasResourceInfo(solidDataset)) {\n    return \"This is a newly initialized SolidDataset, so there is no source to compare it to.\";\n  }\n  if (\n    !hasChangelog(solidDataset) ||\n    (solidDataset.internal_changeLog.additions.length === 0 &&\n      solidDataset.internal_changeLog.deletions.length === 0)\n  ) {\n    return (\n      `## Changes compared to ${getSourceUrl(solidDataset)}\\n\\n` +\n      `This SolidDataset has not been modified since it was fetched from ${getSourceUrl(\n        solidDataset,\n      )}.\\n`\n    );\n  }\n\n  let readableChangeLog = `## Changes compared to ${getSourceUrl(\n    solidDataset,\n  )}\\n`;\n\n  const changeLogsByThingAndProperty =\n    sortChangeLogByThingAndProperty(solidDataset);\n  Object.keys(changeLogsByThingAndProperty).forEach((thingUrl) => {\n    readableChangeLog += `\\n### Thing: ${thingUrl}\\n`;\n    const changeLogByProperty = changeLogsByThingAndProperty[thingUrl];\n    Object.keys(changeLogByProperty).forEach((propertyUrl) => {\n      readableChangeLog += `\\nProperty: ${propertyUrl}\\n`;\n      const { deleted } = changeLogByProperty[propertyUrl];\n      const { added } = changeLogByProperty[propertyUrl];\n      if (deleted.length > 0) {\n        readableChangeLog += \"- Removed:\\n\";\n        readableChangeLog += deleted.reduce((acc, deletedValue) => {\n          return `${acc}  - ${internal_getReadableValue(deletedValue)}\\n`;\n        }, \"\");\n      }\n      if (added.length > 0) {\n        readableChangeLog += \"- Added:\\n\";\n        readableChangeLog += added.reduce((acc, addedValue) => {\n          return `${acc}  - ${internal_getReadableValue(addedValue)}\\n`;\n        }, \"\");\n      }\n    });\n  });\n\n  return readableChangeLog;\n}\n\nfunction sortChangeLogByThingAndProperty(\n  solidDataset: WithChangeLog & WithResourceInfo,\n) {\n  const changeLogsByThingAndProperty: Record<\n    UrlString,\n    Record<UrlString, { added: Quad_Object[]; deleted: Quad_Object[] }>\n  > = Object.create(null);\n  solidDataset.internal_changeLog.deletions.forEach((deletion) => {\n    const subjectNode = isLocalNode(deletion.subject)\n      ? /* istanbul ignore next: Unsaved deletions should be removed from the additions list instead, so this code path shouldn't be hit: */\n        resolveIriForLocalNode(deletion.subject, getSourceUrl(solidDataset))\n      : deletion.subject;\n    if (!isNamedNode(subjectNode) || !isNamedNode(deletion.predicate)) {\n      return;\n    }\n    const thingUrl = internal_toIriString(subjectNode);\n    const propertyUrl = internal_toIriString(deletion.predicate);\n    changeLogsByThingAndProperty[thingUrl] ??= Object.create(null);\n    changeLogsByThingAndProperty[thingUrl][propertyUrl] ??= {\n      added: [],\n      deleted: [],\n    };\n    changeLogsByThingAndProperty[thingUrl][propertyUrl].deleted.push(\n      deletion.object,\n    );\n  });\n  solidDataset.internal_changeLog.additions.forEach((addition) => {\n    const subjectNode = isLocalNode(addition.subject)\n      ? /* istanbul ignore next: setThing already resolves local Subjects when adding them, so this code path should never be hit. */\n        resolveIriForLocalNode(addition.subject, getSourceUrl(solidDataset))\n      : addition.subject;\n    if (!isNamedNode(subjectNode) || !isNamedNode(addition.predicate)) {\n      return;\n    }\n    const thingUrl = internal_toIriString(subjectNode);\n    const propertyUrl = internal_toIriString(addition.predicate);\n    changeLogsByThingAndProperty[thingUrl] ??= Object.create(null);\n    changeLogsByThingAndProperty[thingUrl][propertyUrl] ??= {\n      added: [],\n      deleted: [],\n    };\n    changeLogsByThingAndProperty[thingUrl][propertyUrl].added.push(\n      addition.object,\n    );\n  });\n\n  return changeLogsByThingAndProperty;\n}\n\nfunction getReadableChangeLogSummary(\n  solidDataset: WithChangeLog,\n  thing: Thing,\n): string {\n  const subject = DataFactory.namedNode(thing.url);\n  const nrOfAdditions = solidDataset.internal_changeLog.additions.reduce(\n    (count, addition) => (addition.subject.equals(subject) ? count + 1 : count),\n    0,\n  );\n  const nrOfDeletions = solidDataset.internal_changeLog.deletions.reduce(\n    (count, deletion) => (deletion.subject.equals(subject) ? count + 1 : count),\n    0,\n  );\n  const additionString =\n    nrOfAdditions === 1\n      ? \"1 new value added\"\n      : `${nrOfAdditions} new values added`;\n  const deletionString =\n    nrOfDeletions === 1 ? \"1 value removed\" : `${nrOfDeletions} values removed`;\n  return `(${additionString} / ${deletionString})`;\n}\n\nfunction getNamedNodesForLocalNodes(quad: Quad): Quad {\n  const subject = isNamedNode(quad.subject)\n    ? getNamedNodeFromLocalNode(quad.subject)\n    : /* istanbul ignore next: We don't allow non-NamedNodes as the Subject, so this code path should never be hit: */\n      quad.subject;\n  const object = isNamedNode(quad.object)\n    ? getNamedNodeFromLocalNode(quad.object)\n    : quad.object;\n  return DataFactory.quad(subject, quad.predicate, object, quad.graph);\n}\n\nfunction getNamedNodeFromLocalNode(node: LocalNode | NamedNode): NamedNode {\n  if (isLocalNodeIri(node.value)) {\n    return DataFactory.namedNode(`#${getLocalNodeName(node.value)}`);\n  }\n  return node;\n}\n\nfunction resolveLocalIrisInSolidDataset<\n  Dataset extends SolidDataset & WithResourceInfo,\n>(solidDataset: Dataset): Dataset {\n  const resourceIri = getSourceUrl(solidDataset);\n  const defaultGraph = solidDataset.graphs.default;\n  const thingIris = Object.keys(defaultGraph);\n\n  const updatedDefaultGraph = thingIris.reduce((graphAcc, thingIri) => {\n    const resolvedThing = resolveLocalIrisInThing(\n      graphAcc[thingIri],\n      resourceIri,\n    );\n\n    const resolvedThingIri = isLocalNodeIri(thingIri)\n      ? `${resourceIri}#${getLocalNodeName(thingIri)}`\n      : thingIri;\n    const updatedGraph = { ...graphAcc };\n    delete updatedGraph[thingIri];\n    updatedGraph[resolvedThingIri] = resolvedThing;\n    return freeze(updatedGraph);\n  }, defaultGraph);\n\n  const updatedGraphs = freeze({\n    ...solidDataset.graphs,\n    default: updatedDefaultGraph,\n  });\n\n  return freeze({\n    ...solidDataset,\n    graphs: updatedGraphs,\n  });\n}\n\nfunction resolveLocalIrisInThing(\n  thing: Thing,\n  baseIri: IriString,\n): ThingPersisted {\n  const predicateIris = Object.keys(thing.predicates);\n  const updatedPredicates = predicateIris.reduce(\n    (predicatesAcc, predicateIri) => {\n      const namedNodes = predicatesAcc[predicateIri].namedNodes ?? [];\n      if (namedNodes.every((namedNode) => !isLocalNodeIri(namedNode))) {\n        // This Predicate has no local node Objects, so return it unmodified:\n        return predicatesAcc;\n      }\n      const updatedNamedNodes = freeze(\n        namedNodes.map((namedNode) =>\n          isLocalNodeIri(namedNode)\n            ? `${baseIri}#${getLocalNodeName(namedNode)}`\n            : namedNode,\n        ),\n      );\n      const updatedPredicate = freeze({\n        ...predicatesAcc[predicateIri],\n        namedNodes: updatedNamedNodes,\n      });\n      return freeze({\n        ...predicatesAcc,\n        [predicateIri]: updatedPredicate,\n      });\n    },\n    thing.predicates,\n  );\n\n  return freeze({\n    ...thing,\n    predicates: updatedPredicates,\n    url: isLocalNodeIri(thing.url)\n      ? `${baseIri}#${getLocalNodeName(thing.url)}`\n      : thing.url,\n  });\n}\n\n/**\n * @hidden\n *\n * Fetch a SolidDataset containing information about the capabilities of the\n * storage server that hosts the given resource URL. For more information,\n * please see the [ESS\n * Documentation](https://docs.inrupt.com/ess/latest/services/discovery-endpoint/#well-known-solid).\n *\n * ```typescript\n * const wellKnown = await getWellKnownSolid(resource);\n *\n * // The wellKnown dataset uses a blank node for the subject all of its predicates,\n * // such that we need to call getThingAll with acceptBlankNodes set to true to\n * // retrieve back predicates contained within the dataset\n * const wellKnownSubjects = getThingAll(wellKnown, {\n *   acceptBlankNodes: true,\n * });\n * const wellKnownSubject = wellKnownSubjects[0];\n *\n * // Retrieve a value from the wellKnown dataset:\n * let notificationGateway = getIri(\n *   wellKnownSubject,\n *   \"http://www.w3.org/ns/solid/terms#notificationGateway\"\n * );\n * ```\n *\n *\n * @param url URL of a Resource.\n * @returns Promise resolving to a [[SolidDataset]] containing the data at\n * '.well-known/solid' for the given Resource, or rejecting if fetching it\n * failed.\n * @since 1.12.0\n */\nexport async function getWellKnownSolid(\n  url: UrlString | Url,\n): Promise<SolidDataset & WithServerResourceInfo> {\n  const urlString = internal_toIriString(url);\n\n  // Try to fetch the well-known solid dataset from the server's root\n  try {\n    const wellKnownSolidUrl = new URL(\n      \"/.well-known/solid\",\n      new URL(urlString).origin,\n    ).href;\n\n    return await getSolidDataset(wellKnownSolidUrl);\n  } catch {\n    throw new Error(\n      \"Could not determine storage root or well-known solid resource.\",\n    );\n  }\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type {\n  Url,\n  UrlString,\n  SolidDataset,\n  File,\n  WithServerResourceInfo,\n} from \"../interfaces\";\nimport { internal_toIriString } from \"../interfaces.internal\";\nimport type { getSolidDataset } from \"./solidDataset\";\nimport { createSolidDataset } from \"./solidDataset\";\nimport type { getFile } from \"./file\";\nimport { FetchError } from \"./resource\";\n\ntype Unpromisify<T> = T extends Promise<infer R> ? R : T;\n\n/**\n * ```{warning}\n * Do not use this function in production code. For use in **unit tests**.\n * ```\n *\n * This function initialises a new [[SolidDataset]] with metadata as though the\n * SolidDataset has been retrieved from the given URL. The mock SolidDataset can be used in\n * unit tests that require persisted SolidDatasets; e.g., unit tests that call [[getSourceUrl]].\n *\n * @param url The URL from which the returned SolidDataset appears to be retrieved.\n * @returns A mock SolidDataset that appears to be retrieved from the `url`.\n * @since 0.2.0\n */\nexport function mockSolidDatasetFrom(\n  url: Url | UrlString,\n): Unpromisify<ReturnType<typeof getSolidDataset>> {\n  const solidDataset = createSolidDataset();\n  const solidDatasetWithResourceInfo: SolidDataset & WithServerResourceInfo = {\n    ...solidDataset,\n    internal_resourceInfo: {\n      sourceIri: internal_toIriString(url),\n      isRawData: false,\n      contentType: \"text/turtle\",\n      linkedResources: {},\n    },\n  };\n\n  return solidDatasetWithResourceInfo;\n}\n\n/**\n * ```{warning}\n * Do not use this function in production code. For use in **unit tests**.\n * ```\n *\n * This function initialises a new Container [[SolidDataset]] with metadata as though the\n * Container has been retrieved from the given URL. The mock SolidDataset can be used in\n * unit tests that require persisted Containers; e.g., unit tests that call [[isContainer]].\n *\n * @param url The URL from which the returned Container appears to be retrieved. The `url` must end in a slash.\n * @returns A mock SolidDataset that appears to be retrieved from the `url`.\n * @since 0.2.0\n */\nexport function mockContainerFrom(\n  url: Url | UrlString,\n): Unpromisify<ReturnType<typeof getSolidDataset>> {\n  const sourceIri = internal_toIriString(url);\n  if (!sourceIri.endsWith(\"/\")) {\n    throw new Error(\n      \"A Container's URL should end in a slash. Please update your tests.\",\n    );\n  }\n\n  return mockSolidDatasetFrom(sourceIri);\n}\n\n/**\n * ```{warning}\n * Do not use this function in production code. For use in **unit tests**.\n * ```\n *\n * This function initialises a new File with metadata as though the\n * File has been retrieved from the given URL. The mock File can be used in\n * unit tests that require persisted Files; e.g. unit tests that call [[getSourceUrl]].\n *\n * @param url The URL from which the returned File appears to be retrieved.\n * @returns A mock File that appears to be retrieved from the `url`.\n * @since 0.2.0\n */\nexport function mockFileFrom(\n  url: Url | UrlString,\n  options?: Partial<{\n    contentType: WithServerResourceInfo[\"internal_resourceInfo\"][\"contentType\"];\n  }>,\n): Unpromisify<ReturnType<typeof getFile>> {\n  const file = new Blob();\n  const fileWithResourceInfo: File & WithServerResourceInfo = Object.assign(\n    file,\n    {\n      internal_resourceInfo: {\n        sourceIri: internal_toIriString(url),\n        isRawData: true,\n        contentType: options?.contentType,\n        linkedResources: {},\n      },\n    },\n  );\n\n  return fileWithResourceInfo;\n}\n\n/**\n * ```{warning}\n * Do not use this function in production code. For use in **unit tests**.\n * ```\n *\n * This function initialises a new Error object with metadata as though the\n * it was the result of getting a 404 when trying to fetch the Resource at the\n * given URL. The mock Error can be used in unit tests that require functions\n * that fetch Resources (like [[getSolidDataset]]) to fail.\n *\n * @param url The URL of the Resource that could not be fetched according to the error.\n * @param statusCode Optional status code (defaults to 404) that caused the error.\n * @returns A mock Error that represents not having been able to fetch the Resource at `url` due to a 404 Response.\n * @since 1.1.0\n */\nexport function mockFetchError(\n  fetchedUrl: UrlString,\n  statusCode = 404,\n  statusText = \"Not Found\",\n): FetchError {\n  // The Response constructor in Node 14 makes an empty status text undefined.\n  const failedResponse = new Response(undefined, {\n    status: statusCode,\n    statusText,\n  }) as Response & { ok: false };\n  return new FetchError(\n    `Fetching the Resource at [${fetchedUrl}] failed: [${failedResponse.status}] [${failedResponse.statusText}].`,\n    failedResponse,\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Literal, NamedNode, Quad_Object } from \"@rdfjs/types\";\nimport type { UrlString, Url, Thing, IriString } from \"../interfaces\";\nimport { internal_throwIfNotThing } from \"./thing.internal\";\nimport type { XmlSchemaTypeIri, Time } from \"../datatypes\";\nimport {\n  serializeBoolean,\n  serializeDatetime,\n  serializeDate,\n  serializeDecimal,\n  serializeInteger,\n  normalizeLocale,\n  xmlSchemaTypes,\n  internal_isValidUrl,\n  isNamedNode,\n  serializeTime,\n} from \"../datatypes\";\nimport {\n  asIri,\n  isThing,\n  isThingLocal,\n  ValidPropertyUrlExpectedError,\n  ValidValueUrlExpectedError,\n} from \"./thing\";\nimport { internal_toIriString } from \"../interfaces.internal\";\nimport { freeze, getBlankNodeId } from \"../rdf.internal\";\n\n/**\n * Create a new Thing with a URL added for a Property.\n *\n * This preserves existing values for the given Property. To replace them, see [[setUrl]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to add a URL value to.\n * @param property Property for which to add the given URL value.\n * @param url URL to add to `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value added for the given Property.\n */\nexport const addUrl: AddOfType<Url | UrlString | Thing> = (\n  thing,\n  property,\n  url,\n) => {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  if (!isThing(url) && !internal_isValidUrl(url)) {\n    throw new ValidValueUrlExpectedError(url);\n  }\n\n  const predicateIri = internal_toIriString(property);\n\n  const existingPredicate = thing.predicates[predicateIri] ?? {};\n  const existingNamedNodes = existingPredicate.namedNodes ?? [];\n\n  let iriToAdd: IriString;\n  if (isNamedNode(url)) {\n    iriToAdd = url.value;\n  } else if (typeof url === \"string\") {\n    iriToAdd = url;\n  } else if (isThingLocal(url)) {\n    iriToAdd = url.url;\n  } else {\n    iriToAdd = asIri(url);\n  }\n  const updatedNamedNodes = freeze(\n    existingNamedNodes.concat(internal_toIriString(iriToAdd)),\n  );\n\n  const updatedPredicate = freeze({\n    ...existingPredicate,\n    namedNodes: updatedNamedNodes,\n  });\n  const updatedPredicates = freeze({\n    ...thing.predicates,\n    [predicateIri]: updatedPredicate,\n  });\n  const updatedThing = freeze({\n    ...thing,\n    predicates: updatedPredicates,\n  });\n\n  return updatedThing;\n};\n/** @hidden Alias for [[addUrl]] for those who prefer IRI terminology. */\nexport const addIri = addUrl;\n\n/**\n * Create a new Thing with a boolean added for a Property.\n *\n * This preserves existing values for the given Property. To replace them, see [[setBoolean]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to add a boolean value to.\n * @param property Property for which to add the given boolean value.\n * @param value Boolean to add to `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value added for the given Property.\n */\nexport const addBoolean: AddOfType<boolean> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return addLiteralOfType(\n    thing,\n    property,\n    serializeBoolean(value),\n    xmlSchemaTypes.boolean,\n  );\n};\n\n/**\n * Create a new Thing with a datetime added for a Property.\n *\n * This preserves existing values for the given Property. To replace them, see [[setDatetime]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to add a datetime value to.\n * @param property Property for which to add the given datetime value.\n * @param value Datetime to add to `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value added for the given Property.\n */\nexport const addDatetime: AddOfType<Date> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return addLiteralOfType(\n    thing,\n    property,\n    serializeDatetime(value),\n    xmlSchemaTypes.dateTime,\n  );\n};\n\n/**\n * Create a new Thing with a date added for a Property.\n *\n * This preserves existing values for the given Property. To replace them, see [[setDate]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to add a date value to.\n * @param property Property for which to add the given date value.\n * @param value Date to add to `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value added for the given Property.\n * @since 1.10.0\n */\nexport const addDate: AddOfType<Date> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return addLiteralOfType(\n    thing,\n    property,\n    serializeDate(value),\n    xmlSchemaTypes.date,\n  );\n};\n\n/**\n * Create a new Thing with a time added for a Property.\n *\n * This preserves existing values for the given Property. To replace them, see [[setDatetime]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to add a datetime value to.\n * @param property Property for which to add the given datetime value.\n * @param value time to add to `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value added for the given Property.\n * @since 1.10.0\n */\nexport const addTime: AddOfType<Time> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return addLiteralOfType(\n    thing,\n    property,\n    serializeTime(value),\n    xmlSchemaTypes.time,\n  );\n};\n\n/**\n * Create a new Thing with a decimal added for a Property.\n *\n * This preserves existing values for the given Property. To replace them, see [[setDecimal]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to add a decimal value to.\n * @param property Property for which to add the given decimal value.\n * @param value Decimal to add to `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value added for the given Property.\n */\nexport const addDecimal: AddOfType<number> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return addLiteralOfType(\n    thing,\n    property,\n    serializeDecimal(value),\n    xmlSchemaTypes.decimal,\n  );\n};\n\n/**\n * Create a new Thing with an integer added for a Property.\n *\n * This preserves existing values for the given Property. To replace them, see [[setInteger]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to add an integer value to.\n * @param property Property for which to add the given integer value.\n * @param value Integer to add to `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value added for the given Property.\n */\nexport const addInteger: AddOfType<number> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return addLiteralOfType(\n    thing,\n    property,\n    serializeInteger(value),\n    xmlSchemaTypes.integer,\n  );\n};\n\n/**\n * Create a new Thing with an English string added for a Property.\n *\n * This preserves existing values for the given Property. To replace them, see [[setStringEnglish]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to add a localised string value to.\n * @param property Property for which to add the given string value.\n * @param value String to add to `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value added for the given Property.\n * @since 1.13.0\n */\nexport function addStringEnglish<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: string,\n): T {\n  return addStringWithLocale(thing, property, value, \"en\");\n}\n\n/**\n * Create a new Thing with a localised string added for a Property.\n *\n * This preserves existing values for the given Property. To replace them, see [[setStringWithLocale]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to add a localised string value to.\n * @param property Property for which to add the given string value.\n * @param value String to add to `thing` for the given `property`.\n * @param locale Locale of the added string.\n * @returns A new Thing equal to the input Thing with the given value added for the given Property.\n */\nexport function addStringWithLocale<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: string,\n  locale: string,\n): T {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n\n  const predicateIri = internal_toIriString(property);\n  const normalizedLocale = normalizeLocale(locale);\n\n  const existingPredicate = thing.predicates[predicateIri] ?? {};\n  const existingLangStrings = existingPredicate.langStrings ?? {};\n  const existingStringsInLocale = existingLangStrings[normalizedLocale] ?? [];\n\n  const updatedStringsInLocale = freeze(existingStringsInLocale.concat(value));\n  const updatedLangStrings = freeze({\n    ...existingLangStrings,\n    [normalizedLocale]: updatedStringsInLocale,\n  });\n  const updatedPredicate = freeze({\n    ...existingPredicate,\n    langStrings: updatedLangStrings,\n  });\n  const updatedPredicates = freeze({\n    ...thing.predicates,\n    [predicateIri]: updatedPredicate,\n  });\n  const updatedThing = freeze({\n    ...thing,\n    predicates: updatedPredicates,\n  });\n\n  return updatedThing;\n}\n\n/**\n * Create a new Thing with an unlocalised string added for a Property.\n *\n * This preserves existing values for the given Property. To replace them, see [[setStringNoLocale]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to add an unlocalised string value to.\n * @param property Property for which to add the given string value.\n * @param value String to add to `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value added for the given Property.\n */\nexport const addStringNoLocale: AddOfType<string> = (\n  thing,\n  property,\n  value,\n) => {\n  internal_throwIfNotThing(thing);\n  return addLiteralOfType(thing, property, value, xmlSchemaTypes.string);\n};\n\n/**\n * Create a new Thing with a Named Node added for a Property.\n *\n * This preserves existing values for the given Property. To replace them, see [[setNamedNode]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @ignore This should not be needed due to the other add*() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @param thing The [[Thing]] to add a Named Node to.\n * @param property Property for which to add a value.\n * @param value The Named Node to add.\n * @returns A new Thing equal to the input Thing with the given value added for the given Property.\n */\nexport function addNamedNode<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: NamedNode,\n): T {\n  return addUrl(thing, property, value.value);\n}\n\n/**\n * Create a new Thing with a Literal added for a Property.\n *\n * This preserves existing values for the given Property. To replace them, see [[setLiteral]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @ignore This should not be needed due to the other add*() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @param thing The [[Thing]] to add a Literal to.\n * @param property Property for which to add a value.\n * @param value The Literal to add.\n * @returns A new Thing equal to the input Thing with the given value added for the given Property.\n */\nexport function addLiteral<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: Literal,\n): T {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const typeIri = value.datatype.value;\n  if (typeIri === xmlSchemaTypes.langString) {\n    return addStringWithLocale(thing, property, value.value, value.language);\n  }\n\n  return addLiteralOfType(thing, property, value.value, value.datatype.value);\n}\n\n/**\n * Creates a new Thing with a Term added for a Property.\n *\n * This preserves existing values for the given Property. To replace them, see [[setTerm]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @ignore This should not be needed due to the other add*() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @param thing The [[Thing]] to add a Term to.\n * @param property Property for which to add a value.\n * @param value The Term to add.\n * @returns A new Thing equal to the input Thing with the given value added for the given Property.\n * @since 0.3.0\n */\nexport function addTerm<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: Quad_Object,\n): T {\n  if (value.termType === \"NamedNode\") {\n    return addNamedNode(thing, property, value);\n  }\n  if (value.termType === \"Literal\") {\n    return addLiteral(thing, property, value);\n  }\n\n  if (value.termType === \"BlankNode\") {\n    internal_throwIfNotThing(thing);\n    if (!internal_isValidUrl(property)) {\n      throw new ValidPropertyUrlExpectedError(property);\n    }\n\n    const predicateIri = internal_toIriString(property);\n\n    const existingPredicate = thing.predicates[predicateIri] ?? {};\n    const existingBlankNodes = existingPredicate.blankNodes ?? [];\n\n    const updatedBlankNodes = freeze(\n      existingBlankNodes.concat(getBlankNodeId(value)),\n    );\n    const updatedPredicate = freeze({\n      ...existingPredicate,\n      blankNodes: updatedBlankNodes,\n    });\n    const updatedPredicates = freeze({\n      ...thing.predicates,\n      [predicateIri]: updatedPredicate,\n    });\n    const updatedThing = freeze({\n      ...thing,\n      predicates: updatedPredicates,\n    });\n\n    return updatedThing;\n  }\n\n  throw new Error(\n    `Term type [${value.termType}] is not supported by @inrupt/solid-client.`,\n  );\n}\n\nfunction addLiteralOfType<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: string,\n  type: XmlSchemaTypeIri | UrlString,\n): T {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n\n  const predicateIri = internal_toIriString(property);\n\n  const existingPredicate = thing.predicates[predicateIri] ?? {};\n  const existingLiterals = existingPredicate.literals ?? {};\n  const existingValuesOfType = existingLiterals[type] ?? [];\n\n  const updatedValuesOfType = freeze(existingValuesOfType.concat(value));\n  const updatedLiterals = freeze({\n    ...existingLiterals,\n    [type]: updatedValuesOfType,\n  });\n  const updatedPredicate = freeze({\n    ...existingPredicate,\n    literals: updatedLiterals,\n  });\n  const updatedPredicates = freeze({\n    ...thing.predicates,\n    [predicateIri]: updatedPredicate,\n  });\n  const updatedThing = freeze({\n    ...thing,\n    predicates: updatedPredicates,\n  });\n\n  return updatedThing;\n}\n\n/**\n * @param thing Thing to add a value to.\n * @param property Property on which to add the given value.\n * @param value Value to add to `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n */\nexport type AddOfType<Type> = <T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: Type,\n) => T;\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Literal, NamedNode } from \"@rdfjs/types\";\nimport type { Url, UrlString, Thing, ThingPersisted } from \"../interfaces\";\nimport type { XmlSchemaTypeIri, Time } from \"../datatypes\";\nimport {\n  normalizeLocale,\n  xmlSchemaTypes,\n  deserializeBoolean,\n  deserializeDatetime,\n  deserializeDecimal,\n  deserializeInteger,\n  internal_isValidUrl,\n  deserializeDate,\n  deserializeTime,\n} from \"../datatypes\";\nimport { internal_throwIfNotThing } from \"./thing.internal\";\nimport {\n  isThing,\n  ValidPropertyUrlExpectedError,\n  ValidValueUrlExpectedError,\n  asIri,\n} from \"./thing\";\nimport { internal_toIriString } from \"../interfaces.internal\";\nimport { freeze } from \"../rdf.internal\";\n\n/**\n * Create a new Thing with all values removed for the given Property.\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing [[Thing]] to remove values from.\n * @param property Property for which to remove all values from the Thing.\n * @returns A new Thing equal to the input Thing with all values removed for the given Property.\n */\nexport function removeAll<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n): T;\nexport function removeAll(thing: Thing, property: Url | UrlString): Thing {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const predicateIri = internal_toIriString(property);\n  const newPredicates = { ...thing.predicates };\n  delete newPredicates[predicateIri];\n\n  return freeze({\n    ...thing,\n    predicates: freeze(newPredicates),\n  });\n}\n\n/**\n * Create a new Thing with the given URL removed for the given Property.\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to remove a URL value from.\n * @param property Property for which to remove the given URL value.\n * @param value URL to remove from `thing` for the given `Property`.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n */\nexport const removeUrl: RemoveOfType<Url | UrlString | ThingPersisted> = (\n  thing,\n  property,\n  value,\n) => {\n  internal_throwIfNotThing(thing);\n\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const predicateIri = internal_toIriString(property);\n\n  if (!isThing(value) && !internal_isValidUrl(value)) {\n    throw new ValidValueUrlExpectedError(value);\n  }\n\n  const iriToRemove = isThing(value)\n    ? asIri(value)\n    : internal_toIriString(value);\n\n  const updatedNamedNodes = freeze(\n    thing.predicates[predicateIri]?.namedNodes?.filter(\n      (namedNode) => namedNode.toLowerCase() !== iriToRemove.toLowerCase(),\n    ) ?? [],\n  );\n\n  const updatedPredicate = freeze({\n    ...thing.predicates[predicateIri],\n    namedNodes: updatedNamedNodes,\n  });\n\n  const updatedPredicates = freeze({\n    ...thing.predicates,\n    [predicateIri]: updatedPredicate,\n  });\n  return freeze({\n    ...thing,\n    predicates: updatedPredicates,\n  });\n};\n/** @hidden Alias of [[removeUrl]] for those who prefer IRI terminology. */\nexport const removeIri = removeUrl;\n\n/**\n * Create a new Thing with the given boolean removed for the given Property.\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to remove a boolean value from.\n * @param property Property for which to remove the given boolean value.\n * @param value Boolean to remove from `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n */\nexport const removeBoolean: RemoveOfType<boolean> = (\n  thing,\n  property,\n  value,\n) => {\n  internal_throwIfNotThing(thing);\n  return removeLiteralMatching(\n    thing,\n    property,\n    xmlSchemaTypes.boolean,\n    (foundBoolean) => deserializeBoolean(foundBoolean) === value,\n  );\n};\n\n/**\n * Create a new Thing with the given datetime removed for the given Property.\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to remove a datetime value from.\n * @param property Property for which to remove the given datetime value.\n * @param value Datetime to remove from `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n */\nexport const removeDatetime: RemoveOfType<Date> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return removeLiteralMatching(\n    thing,\n    property,\n    xmlSchemaTypes.dateTime,\n    (foundDatetime) =>\n      deserializeDatetime(foundDatetime)?.getTime() === value.getTime(),\n  );\n};\n\n/**\n * Create a new Thing with the given date removed for the given Property.\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to remove a date value from.\n * @param property Property for which to remove the given date value.\n * @param value Date to remove from `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n * @since 1.10.0\n */\nexport const removeDate: RemoveOfType<Date> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return removeLiteralMatching(\n    thing,\n    property,\n    xmlSchemaTypes.date,\n    function (foundDate) {\n      const deserializedDate = deserializeDate(foundDate);\n      if (deserializedDate) {\n        return (\n          deserializedDate.getFullYear() === value.getFullYear() &&\n          deserializedDate.getMonth() === value.getMonth() &&\n          deserializedDate.getUTCDate() === value.getUTCDate()\n        );\n      }\n      return false;\n    },\n  );\n};\n\n/**\n * Create a new Thing with the given datetime removed for the given Property.\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to remove a datetime value from.\n * @param property Property for which to remove the given datetime value.\n * @param value Time to remove from `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n * @since 1.10.0\n */\nexport const removeTime: RemoveOfType<Time> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return removeLiteralMatching(\n    thing,\n    property,\n    xmlSchemaTypes.time,\n    function (foundTime) {\n      const deserializedTime = deserializeTime(foundTime);\n      if (deserializedTime) {\n        return (\n          deserializedTime.hour === value.hour &&\n          deserializedTime.minute === value.minute &&\n          deserializedTime.second === value.second &&\n          deserializedTime.millisecond === value.millisecond &&\n          deserializedTime.timezoneHourOffset === value.timezoneHourOffset &&\n          deserializedTime.timezoneMinuteOffset === value.timezoneMinuteOffset\n        );\n      }\n      return false;\n    },\n  );\n};\n\n/**\n * Create a new Thing with the given decimal removed for the given Property.\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to remove a decimal value from.\n * @param property Property for which to remove the given decimal value.\n * @param value Decimal to remove from `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n */\nexport const removeDecimal: RemoveOfType<number> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return removeLiteralMatching(\n    thing,\n    property,\n    xmlSchemaTypes.decimal,\n    (foundDecimal) => deserializeDecimal(foundDecimal) === value,\n  );\n};\n\n/**\n * Create a new Thing with the given integer removed for the given Property.\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to remove an integer value from.\n * @param property Property for which to remove the given integer value.\n * @param value Integer to remove from `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n */\nexport const removeInteger: RemoveOfType<number> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return removeLiteralMatching(\n    thing,\n    property,\n    xmlSchemaTypes.integer,\n    (foundInteger) => deserializeInteger(foundInteger) === value,\n  );\n};\n\n/**\n * Create a new Thing with the given English string removed for the given Property.\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to remove a localised string value from.\n * @param property Property for which to remove the given localised string value.\n * @param value String to remove from `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n * @since 1.13.0\n */\nexport function removeStringEnglish<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: string,\n): T {\n  return removeStringWithLocale(thing, property, value, \"en\");\n}\n\n/**\n * Create a new Thing with the given localised string removed for the given Property.\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to remove a localised string value from.\n * @param property Property for which to remove the given localised string value.\n * @param value String to remove from `thing` for the given `property`.\n * @param locale Locale of the string to remove.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n */\nexport function removeStringWithLocale<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: string,\n  locale: string,\n): T {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n\n  const predicateIri = internal_toIriString(property);\n\n  const existingLangStrings = thing.predicates[predicateIri]?.langStrings ?? {};\n  const matchingLocale = Object.keys(existingLangStrings).find(\n    (existingLocale) =>\n      normalizeLocale(existingLocale) === normalizeLocale(locale) &&\n      Array.isArray(existingLangStrings[existingLocale]) &&\n      existingLangStrings[existingLocale].length > 0,\n  );\n\n  if (typeof matchingLocale !== \"string\") {\n    // Nothing to remove.\n    return thing;\n  }\n  const existingStringsInLocale = existingLangStrings[matchingLocale];\n\n  const updatedStringsInLocale = freeze(\n    existingStringsInLocale.filter(\n      (existingString) => existingString !== value,\n    ),\n  );\n  const updatedLangStrings = freeze({\n    ...existingLangStrings,\n    [matchingLocale]: updatedStringsInLocale,\n  });\n\n  const updatedPredicate = freeze({\n    ...thing.predicates[predicateIri],\n    langStrings: updatedLangStrings,\n  });\n\n  const updatedPredicates = freeze({\n    ...thing.predicates,\n    [predicateIri]: updatedPredicate,\n  });\n  return freeze({\n    ...thing,\n    predicates: updatedPredicates,\n  });\n}\n\n/**\n * Create a new Thing with the given unlocalised string removed for the given Property.\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to remove an unlocalised string value from.\n * @param property Property for which to remove the given string value.\n * @param value String to remove from `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n */\nexport const removeStringNoLocale: RemoveOfType<string> = (\n  thing,\n  property,\n  value,\n) => {\n  internal_throwIfNotThing(thing);\n  return removeLiteralMatching(\n    thing,\n    property,\n    xmlSchemaTypes.string,\n    (foundString) => foundString === value,\n  );\n};\n\n/**\n * @ignore This should not be needed due to the other remove*() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @param thing Thing to remove a NamedNode value from.\n * @param property Property for which to remove the given NamedNode value.\n * @param value NamedNode to remove from `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n */\nexport function removeNamedNode<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: NamedNode,\n): T {\n  return removeUrl(thing, property, value.value);\n}\n\n/**\n * @ignore This should not be needed due to the other remove*() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @param thing Thing to remove a Literal value from.\n * @param property Property for which to remove the given Literal value.\n * @param value Literal to remove from `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n */\nexport function removeLiteral<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: Literal,\n): T {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const typeIri = value.datatype.value;\n\n  if (typeIri === xmlSchemaTypes.langString) {\n    return removeStringWithLocale(thing, property, value.value, value.language);\n  }\n\n  const predicateIri = internal_toIriString(property);\n\n  const existingPredicateValues = thing.predicates[predicateIri] ?? {};\n  const existingLiterals = existingPredicateValues.literals ?? {};\n  const existingValuesOfType = existingLiterals[typeIri] ?? [];\n\n  const updatedValues = freeze(\n    existingValuesOfType.filter(\n      (existingValue) => existingValue !== value.value,\n    ),\n  );\n  const updatedLiterals = freeze({\n    ...existingLiterals,\n    [typeIri]: updatedValues,\n  });\n  const updatedPredicate = freeze({\n    ...existingPredicateValues,\n    literals: updatedLiterals,\n  });\n  const updatedPredicates = freeze({\n    ...thing.predicates,\n    [predicateIri]: updatedPredicate,\n  });\n  const updatedThing = freeze({\n    ...thing,\n    predicates: updatedPredicates,\n  });\n\n  return updatedThing;\n}\n\n/**\n * @param thing Thing to remove a Literal value from.\n * @param property Property for which to remove the given Literal value.\n * @param type Data type that the Literal should be stored as.\n * @param matcher Function that returns true if the given value is an equivalent serialisation of the value to remove. For example, when removing a `false` boolean, the matcher should return true for both \"0\" and \"false\".\n */\nfunction removeLiteralMatching<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  type: XmlSchemaTypeIri,\n  matcher: (serialisedValue: string) => boolean,\n): T {\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  const predicateIri = internal_toIriString(property);\n  const existingPredicateValues = thing.predicates[predicateIri] ?? {};\n  const existingLiterals = existingPredicateValues.literals ?? {};\n  const existingValuesOfType = existingLiterals[type] ?? [];\n\n  const updatedValues = freeze(\n    existingValuesOfType.filter((existingValue) => !matcher(existingValue)),\n  );\n  const updatedLiterals = freeze({\n    ...existingLiterals,\n    [type]: updatedValues,\n  });\n  const updatedPredicate = freeze({\n    ...existingPredicateValues,\n    literals: updatedLiterals,\n  });\n  const updatedPredicates = freeze({\n    ...thing.predicates,\n    [predicateIri]: updatedPredicate,\n  });\n  const updatedThing = freeze({\n    ...thing,\n    predicates: updatedPredicates,\n  });\n\n  return updatedThing;\n}\n\n/**\n * @param thing Thing to remove a value from.\n * @param property Property for which to remove the given value.\n * @param value Value to remove from `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with the given value removed for the given Property.\n */\nexport type RemoveOfType<Type> = <T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: Type,\n) => T;\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Literal, NamedNode, Quad_Object } from \"@rdfjs/types\";\nimport type { Thing, Url, UrlString } from \"../interfaces\";\nimport type { Time } from \"../datatypes\";\nimport { internal_isValidUrl } from \"../datatypes\";\nimport { internal_throwIfNotThing } from \"./thing.internal\";\nimport { removeAll } from \"./remove\";\nimport {\n  isThing,\n  ValidPropertyUrlExpectedError,\n  ValidValueUrlExpectedError,\n} from \"./thing\";\nimport {\n  addBoolean,\n  addDatetime,\n  addDate,\n  addDecimal,\n  addInteger,\n  addLiteral,\n  addNamedNode,\n  addStringNoLocale,\n  addStringWithLocale,\n  addTerm,\n  addTime,\n  addUrl,\n} from \"./add\";\n\n/**\n * Create a new Thing with existing values replaced by the given URL for the given Property.\n *\n * To preserve existing values, see [[addUrl]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to set a URL value on.\n * @param property Property for which to set the given URL value.\n * @param url URL to set on `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n */\nexport const setUrl: SetOfType<Url | UrlString | Thing> = (\n  thing,\n  property,\n  url,\n) => {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n  if (!isThing(url) && !internal_isValidUrl(url)) {\n    throw new ValidValueUrlExpectedError(url);\n  }\n\n  return addUrl(removeAll(thing, property), property, url);\n};\n/** @hidden Alias of [[setUrl]] for those who prefer IRI terminology. */\nexport const setIri = setUrl;\n\n/**\n * Create a new Thing with existing values replaced by the given boolean for the given Property.\n *\n * To preserve existing values, see [[addBoolean]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to set a boolean value on.\n * @param property Property for which to set the given boolean value.\n * @param value Boolean to set on `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n */\nexport const setBoolean: SetOfType<boolean> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return addBoolean(removeAll(thing, property), property, value);\n};\n\n/**\n * Create a new Thing with existing values replaced by the given datetime for the given Property.\n *\n * To preserve existing values, see [[addDatetime]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to set an datetime value on.\n * @param property Property for which to set the given datetime value.\n * @param value Datetime to set on `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n */\nexport const setDatetime: SetOfType<Date> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return addDatetime(removeAll(thing, property), property, value);\n};\n\n/**\n * Create a new Thing with existing values replaced by the given date for the given Property.\n *\n * To preserve existing values, see [[addDate]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to set an date value on.\n * @param property Property for which to set the given date value.\n * @param value Date to set on `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n * @since 1.10.0\n */\nexport const setDate: SetOfType<Date> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return addDate(removeAll(thing, property), property, value);\n};\n\n/**\n * Create a new Thing with existing values replaced by the given time for the given Property.\n *\n * To preserve existing values, see [[addTime]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to set an time value on.\n * @param property Property for which to set the given time value.\n * @param value time to set on `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n * @since 1.10.0\n */\nexport const setTime: SetOfType<Time> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return addTime(removeAll(thing, property), property, value);\n};\n\n/**\n * Create a new Thing with existing values replaced by the given decimal for the given Property.\n *\n * To preserve existing values, see [[addDecimal]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to set a decimal value on.\n * @param property Property for which to set the given decimal value.\n * @param value Decimal to set on `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n */\nexport const setDecimal: SetOfType<number> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return addDecimal(removeAll(thing, property), property, value);\n};\n\n/**\n * Create a new Thing with existing values replaced by the given integer for the given Property.\n *\n * To preserve existing values, see [[addInteger]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to set an integer value on.\n * @param property Property for which to set the given integer value.\n * @param value Integer to set on `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n */\nexport const setInteger: SetOfType<number> = (thing, property, value) => {\n  internal_throwIfNotThing(thing);\n  return addInteger(removeAll(thing, property), property, value);\n};\n\n/**\n * Create a new Thing with existing values replaced by the given English string for the given\n * Property.\n *\n * To preserve existing values, see [[addStringEnglish]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to set a localised string value on.\n * @param property Property for which to set the given localised string value.\n * @param value Localised string to set on `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n * @since 1.13.0\n */\nexport function setStringEnglish<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: string,\n): T {\n  return setStringWithLocale(thing, property, value, \"en\");\n}\n\n/**\n * Create a new Thing with existing values replaced by the given localised string for the given Property.\n *\n * To preserve existing values, see [[addStringWithLocale]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to set a localised string value on.\n * @param property Property for which to set the given localised string value.\n * @param value Localised string to set on `thing` for the given `property`.\n * @param locale Locale of the added string.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n */\nexport function setStringWithLocale<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: string,\n  locale: string,\n): T {\n  internal_throwIfNotThing(thing);\n  return addStringWithLocale(\n    removeAll(thing, property),\n    property,\n    value,\n    locale,\n  );\n}\n\n/**\n * Create a new Thing with existing values replaced by the given unlocalised string for the given Property.\n *\n * To preserve existing values, see [[addStringNoLocale]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to set an unlocalised string value on.\n * @param property Property for which to set the given unlocalised string value.\n * @param value Unlocalised string to set on `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n */\nexport const setStringNoLocale: SetOfType<string> = (\n  thing,\n  property,\n  value,\n) => {\n  internal_throwIfNotThing(thing);\n  return addStringNoLocale(removeAll(thing, property), property, value);\n};\n\n/**\n * Create a new Thing with existing values replaced by the given Named Node for the given Property.\n *\n * This replaces existing values for the given Property. To preserve them, see [[addNamedNode]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @ignore This should not be needed due to the other set*() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @param thing The [[Thing]] to set a NamedNode on.\n * @param property Property for which to set the value.\n * @param value The NamedNode to set on `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n */\nexport function setNamedNode<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: NamedNode,\n): T {\n  internal_throwIfNotThing(thing);\n  return addNamedNode(removeAll(thing, property), property, value);\n}\n\n/**\n * Create a new Thing with existing values replaced by the given Literal for the given Property.\n *\n * This replaces existing values for the given Property. To preserve them, see [[addLiteral]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @ignore This should not be needed due to the other set*() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @param thing The [[Thing]] to set a Literal on.\n * @param property Property for which to set the value.\n * @param value The Literal to set on `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n */\nexport function setLiteral<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: Literal,\n): T {\n  internal_throwIfNotThing(thing);\n  return addLiteral(removeAll(thing, property), property, value);\n}\n\n/**\n * Creates a new Thing with existing values replaced by the given Term for the given Property.\n *\n * This replaces existing values for the given Property. To preserve them, see [[addTerm]].\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @ignore This should not be needed due to the other set*() functions. If you do find yourself needing it, please file a feature request for your use case.\n * @param thing The [[Thing]] to set a Term on.\n * @param property Property for which to set the value.\n * @param value The raw RDF/JS value to set on `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n * @since 0.3.0\n */\nexport function setTerm<T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: Quad_Object,\n): T {\n  internal_throwIfNotThing(thing);\n  if (!internal_isValidUrl(property)) {\n    throw new ValidPropertyUrlExpectedError(property);\n  }\n\n  return addTerm(removeAll(thing, property), property, value);\n}\n\n/**\n * Create a new Thing with existing values replaced by the given value for the given Property.\n *\n * The original `thing` is not modified; this function returns a cloned Thing with updated values.\n *\n * @param thing Thing to set a value on.\n * @param property Property for which to set the given value.\n * @param value Value to set on `thing` for the given `property`.\n * @returns A new Thing equal to the input Thing with existing values replaced by the given value for the given Property.\n */\nexport type SetOfType<Type> = <T extends Thing>(\n  thing: T,\n  property: Url | UrlString,\n  value: Type,\n) => T;\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Literal, Quad_Object, NamedNode } from \"@rdfjs/types\";\nimport type { Time } from \"../datatypes\";\nimport type {\n  Thing,\n  ThingLocal,\n  ThingPersisted,\n  Url,\n  UrlString,\n} from \"../interfaces\";\nimport type { AddOfType } from \"./add\";\nimport {\n  addBoolean,\n  addDate,\n  addDatetime,\n  addTime,\n  addDecimal,\n  addInteger,\n  addIri,\n  addLiteral,\n  addNamedNode,\n  addStringNoLocale,\n  addStringWithLocale,\n  addTerm,\n  addUrl,\n} from \"./add\";\nimport type { RemoveOfType } from \"./remove\";\nimport {\n  removeAll,\n  removeBoolean,\n  removeDate,\n  removeDatetime,\n  removeTime,\n  removeDecimal,\n  removeInteger,\n  removeIri,\n  removeLiteral,\n  removeNamedNode,\n  removeStringNoLocale,\n  removeStringWithLocale,\n  removeUrl,\n} from \"./remove\";\nimport type { SetOfType } from \"./set\";\nimport {\n  setBoolean,\n  setDate,\n  setDatetime,\n  setTime,\n  setDecimal,\n  setInteger,\n  setIri,\n  setLiteral,\n  setNamedNode,\n  setStringNoLocale,\n  setStringWithLocale,\n  setTerm,\n  setUrl,\n} from \"./set\";\nimport type {\n  CreateThingLocalOptions,\n  CreateThingOptions,\n  CreateThingPersistedOptions,\n} from \"./thing\";\nimport { createThing, isThing } from \"./thing\";\n\ntype Adder<Type, T extends Thing> = (\n  property: Parameters<AddOfType<Type>>[1],\n  value: Parameters<AddOfType<Type>>[2],\n) => ThingBuilder<T>;\ntype Setter<Type, T extends Thing> = (\n  property: Parameters<SetOfType<Type>>[1],\n  value: Parameters<SetOfType<Type>>[2],\n) => ThingBuilder<T>;\ntype Remover<Type, T extends Thing> = (\n  property: Parameters<RemoveOfType<Type>>[1],\n  value: Parameters<RemoveOfType<Type>>[2],\n) => ThingBuilder<T>;\n\n// Unfortunately this interface has too many properties for TypeScript to infer,\n// hence the duplication between the interface and the implementation method names.\n/**\n * A Fluent interface to build a [[Thing]].\n *\n * Add, replace or remove property values using consecutive calls to `.add*()`,\n * `.set*()` and `.remove*()`, then finally generate a [[Thing]] with the given\n * properties using `.build()`.\n * @since 1.9.0\n */\nexport type ThingBuilder<T extends Thing> = {\n  build: () => T;\n  addUrl: Adder<Url | UrlString | Thing, T>;\n  addIri: Adder<Url | UrlString | Thing, T>;\n  addBoolean: Adder<boolean, T>;\n  addDatetime: Adder<Date, T>;\n  addDate: Adder<Date, T>;\n  addTime: Adder<Time, T>;\n  addDecimal: Adder<number, T>;\n  addInteger: Adder<number, T>;\n  addStringNoLocale: Adder<string, T>;\n  addStringEnglish: Adder<string, T>;\n  addStringWithLocale: (\n    property: Parameters<typeof addStringWithLocale>[1],\n    value: Parameters<typeof addStringWithLocale>[2],\n    locale: Parameters<typeof addStringWithLocale>[3],\n  ) => ThingBuilder<T>;\n  addNamedNode: Adder<NamedNode, T>;\n  addLiteral: Adder<Literal, T>;\n  addTerm: Adder<Quad_Object, T>;\n  setUrl: Setter<Url | UrlString | Thing, T>;\n  setIri: Setter<Url | UrlString | Thing, T>;\n  setBoolean: Setter<boolean, T>;\n  setDatetime: Setter<Date, T>;\n  setDate: Setter<Date, T>;\n  setTime: Setter<Time, T>;\n  setDecimal: Setter<number, T>;\n  setInteger: Setter<number, T>;\n  setStringNoLocale: Setter<string, T>;\n  setStringEnglish: Setter<string, T>;\n  setStringWithLocale: (\n    property: Parameters<typeof setStringWithLocale>[1],\n    value: Parameters<typeof setStringWithLocale>[2],\n    locale: Parameters<typeof setStringWithLocale>[3],\n  ) => ThingBuilder<T>;\n  setNamedNode: Setter<NamedNode, T>;\n  setLiteral: Setter<Literal, T>;\n  setTerm: Setter<Quad_Object, T>;\n  removeAll: (property: Parameters<typeof removeLiteral>[1]) => ThingBuilder<T>;\n  removeUrl: Remover<Url | UrlString | Thing, T>;\n  removeIri: Remover<Url | UrlString | Thing, T>;\n  removeBoolean: Remover<boolean, T>;\n  removeDatetime: Remover<Date, T>;\n  removeDate: Remover<Date, T>;\n  removeTime: Remover<Time, T>;\n  removeDecimal: Remover<number, T>;\n  removeInteger: Remover<number, T>;\n  removeStringNoLocale: Remover<string, T>;\n  removeStringEnglish: Remover<string, T>;\n  removeStringWithLocale: (\n    property: Parameters<typeof removeStringWithLocale>[1],\n    value: Parameters<typeof removeStringWithLocale>[2],\n    locale: Parameters<typeof removeStringWithLocale>[3],\n  ) => ThingBuilder<T>;\n  removeNamedNode: Remover<NamedNode, T>;\n  removeLiteral: Remover<Literal, T>;\n};\n\n/**\n * Modify a [[Thing]], setting multiple properties in a single expresssion.\n *\n * For example, you can initialise several properties of a given Thing as follows:\n *\n *     const me = buildThing(createThing({ name: \"profile-vincent\" }))\n *       .addUrl(rdf.type, schema.Person)\n *       .addStringNoLocale(schema.givenName, \"Vincent\")\n *       .build();\n *\n * Take note of the final call to `.build()` to obtain the actual Thing.\n *\n * @param init A Thing to modify.\n * @returns a [[ThingBuilder]], a Fluent API that allows you to set multiple properties in a single expression.\n * @since 1.9.0\n */\nexport function buildThing(init: ThingLocal): ThingBuilder<ThingLocal>;\n/**\n * Modify a [[Thing]], setting multiple properties in a single expresssion.\n *\n * For example, you can initialise several properties of a given Thing as follows:\n *\n *     const me = buildThing(createThing({ url: \"https://example.pod/profile#vincent\" }))\n *       .addUrl(rdf.type, schema.Person)\n *       .addStringNoLocale(schema.givenName, \"Vincent\")\n *       .build();\n *\n * Take note of the final call to `.build()` to obtain the actual Thing.\n *\n * @param init A Thing to modify.\n * @returns a [[ThingBuilder]], a Fluent API that allows you to set multiple properties in a single expression.\n * @since 1.9.0\n */\nexport function buildThing(init: ThingPersisted): ThingBuilder<ThingPersisted>;\n/**\n * Create a [[Thing]], setting multiple properties in a single expresssion.\n *\n * For example, you can create a new Thing and initialise several properties as follows:\n *\n *     const me = buildThing({ name: \"profile-vincent\" })\n *       .addUrl(rdf.type, schema.Person)\n *       .addStringNoLocale(schema.givenName, \"Vincent\")\n *       .build();\n *\n * Take note of the final call to `.build()` to obtain the actual Thing.\n *\n * @param init Options used to initialise a new Thing.\n * @returns a [[ThingBuilder]], a Fluent API that allows you to set multiple properties in a single expression.\n * @since 1.9.0\n */\nexport function buildThing(\n  init: CreateThingLocalOptions,\n): ThingBuilder<ThingLocal>;\n/**\n * Create a [[Thing]], setting multiple properties in a single expresssion.\n *\n * For example, you can create a new Thing and initialise several properties as follows:\n *\n *     const me = buildThing({ url: \"https://example.pod/profile#vincent\" })\n *       .addUrl(rdf.type, schema.Person)\n *       .addStringNoLocale(schema.givenName, \"Vincent\")\n *       .build();\n *\n * Take note of the final call to `.build()` to obtain the actual Thing.\n *\n * @param init Optionally pass an existing [[Thing]] to modify the properties of. If left empty, `buildThing` will initialise a new Thing.\n * @returns a [[ThingBuilder]], a Fluent API that allows you to set multiple properties in a single expression.\n * @since 1.9.0\n */\nexport function buildThing(\n  init: CreateThingPersistedOptions,\n): ThingBuilder<ThingPersisted>;\n/**\n * Create a [[Thing]], setting multiple properties in a single expresssion.\n *\n * For example, you can create a new Thing and initialise several properties as follows:\n *\n *     const me = buildThing()\n *       .addUrl(rdf.type, schema.Person)\n *       .addStringNoLocale(schema.givenName, \"Vincent\")\n *       .build();\n *\n * Take note of the final call to `.build()` to obtain the actual Thing.\n *\n * @returns a [[ThingBuilder]], a Fluent API that allows you to set multiple properties in a single expression.\n * @since 1.9.0\n */\nexport function buildThing(): ThingBuilder<ThingLocal>;\n/**\n * Create or modify a [[Thing]], setting multiple properties in a single expresssion.\n *\n * For example, you can create a new Thing and initialise several properties as follows:\n *\n *     const me = buildThing()\n *       .addUrl(rdf.type, schema.Person)\n *       .addStringNoLocale(schema.givenName, \"Vincent\")\n *       .build();\n *\n * Take note of the final call to `.build()` to obtain the actual Thing.\n *\n * @param init Optionally pass an existing [[Thing]] to modify the properties of. If left empty, `buildThing` will initialise a new Thing.\n * @returns a [[ThingBuilder]], a Fluent API that allows you to set multiple properties in a single expression.\n * @since 1.9.0\n */\nexport function buildThing(\n  init: Thing | CreateThingOptions = createThing(),\n): ThingBuilder<Thing> {\n  let thing = isThing(init) ? init : createThing(init);\n\n  function getAdder<Type>(adder: AddOfType<Type>) {\n    return (\n      property: Parameters<typeof adder>[1],\n      value: Parameters<typeof adder>[2],\n    ) => {\n      thing = adder(thing, property, value);\n      return builder;\n    };\n  }\n\n  function getSetter<Type>(setter: SetOfType<Type>) {\n    return (\n      property: Parameters<typeof setter>[1],\n      value: Parameters<typeof setter>[2],\n    ) => {\n      thing = setter(thing, property, value);\n      return builder;\n    };\n  }\n\n  function getRemover<Type>(remover: RemoveOfType<Type>) {\n    return (\n      property: Parameters<typeof remover>[1],\n      value: Parameters<typeof remover>[2],\n    ) => {\n      thing = remover(thing, property, value);\n      return builder;\n    };\n  }\n\n  const builder: ThingBuilder<Thing> = {\n    build: () => thing,\n    addUrl: getAdder(addUrl),\n    addIri: getAdder(addIri),\n    addBoolean: getAdder(addBoolean),\n    addDatetime: getAdder(addDatetime),\n    addDate: getAdder(addDate),\n    addTime: getAdder(addTime),\n    addDecimal: getAdder(addDecimal),\n    addInteger: getAdder(addInteger),\n    addStringNoLocale: getAdder(addStringNoLocale),\n    addStringEnglish: (\n      property: Parameters<typeof addStringWithLocale>[1],\n      value: Parameters<typeof addStringWithLocale>[2],\n    ) => {\n      thing = addStringWithLocale(thing, property, value, \"en\");\n      return builder;\n    },\n    addStringWithLocale: (\n      property: Parameters<typeof addStringWithLocale>[1],\n      value: Parameters<typeof addStringWithLocale>[2],\n      locale: Parameters<typeof addStringWithLocale>[3],\n    ) => {\n      thing = addStringWithLocale(thing, property, value, locale);\n      return builder;\n    },\n    addNamedNode: getAdder(addNamedNode),\n    addLiteral: getAdder(addLiteral),\n    addTerm: getAdder(addTerm),\n    setUrl: getSetter(setUrl),\n    setIri: getSetter(setIri),\n    setBoolean: getSetter(setBoolean),\n    setDatetime: getSetter(setDatetime),\n    setDate: getSetter(setDate),\n    setTime: getSetter(setTime),\n    setDecimal: getSetter(setDecimal),\n    setInteger: getSetter(setInteger),\n    setStringNoLocale: getSetter(setStringNoLocale),\n    setStringEnglish: (\n      property: Parameters<typeof setStringWithLocale>[1],\n      value: Parameters<typeof setStringWithLocale>[2],\n    ) => {\n      thing = setStringWithLocale(thing, property, value, \"en\");\n      return builder;\n    },\n    setStringWithLocale: (\n      property: Parameters<typeof setStringWithLocale>[1],\n      value: Parameters<typeof setStringWithLocale>[2],\n      locale: Parameters<typeof setStringWithLocale>[3],\n    ) => {\n      thing = setStringWithLocale(thing, property, value, locale);\n      return builder;\n    },\n    setNamedNode: getSetter(setNamedNode),\n    setLiteral: getSetter(setLiteral),\n    setTerm: getSetter(setTerm),\n    removeAll: (property: Parameters<typeof removeAll>[1]) => {\n      thing = removeAll(thing, property);\n      return builder;\n    },\n    removeUrl: getRemover(removeUrl),\n    removeIri: getRemover(removeIri),\n    removeBoolean: getRemover(removeBoolean),\n    removeDatetime: getRemover(removeDatetime),\n    removeDate: getRemover(removeDate),\n    removeTime: getRemover(removeTime),\n    removeDecimal: getRemover(removeDecimal),\n    removeInteger: getRemover(removeInteger),\n    removeStringNoLocale: getRemover(removeStringNoLocale),\n    removeStringEnglish: (\n      property: Parameters<typeof removeStringWithLocale>[1],\n      value: Parameters<typeof removeStringWithLocale>[2],\n    ) => buildThing(removeStringWithLocale(thing, property, value, \"en\")),\n    removeStringWithLocale: (\n      property: Parameters<typeof removeStringWithLocale>[1],\n      value: Parameters<typeof removeStringWithLocale>[2],\n      locale: Parameters<typeof removeStringWithLocale>[3],\n    ) => buildThing(removeStringWithLocale(thing, property, value, locale)),\n    removeNamedNode: getRemover(removeNamedNode),\n    removeLiteral: getRemover(removeLiteral),\n  };\n\n  return builder;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Url, UrlString, ThingPersisted } from \"../interfaces\";\nimport { internal_toIriString } from \"../interfaces.internal\";\n\n/**\n * Function for use in unit tests to mock a [[Thing]] with a given URL.\n *\n * Warning: do not use this function in actual production code.\n * This function initialises a new empty Thing and sets its URL to a given URL.\n * This is useful to mock a Thing in tests of code that call e.g.\n * [[asUrl]].\n *\n * @param url The URL that the mocked Thing pretends identifies it.\n * @returns A new Thing, pretending to be identified by the given URL.\n * @since 0.2.0\n */\nexport function mockThingFrom(url: Url | UrlString): ThingPersisted {\n  const iri = internal_toIriString(url);\n  const thing: ThingPersisted = {\n    type: \"Subject\",\n    predicates: {},\n    url: iri,\n  };\n\n  return thing;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport { acp } from \"../constants\";\nimport type { WithServerResourceInfo } from \"../interfaces\";\nimport { getLinkedResourceUrlAll } from \"../resource/resource\";\n\n/**\n * @param linkedAccessResource A Resource exposed via the Link header of another Resource with rel=\"acl\".\n * @returns Whether that Resource is an ACP ACR or not (in which case it's likely a WAC ACL).\n */\nexport function isAcr(linkedAccessResource: WithServerResourceInfo): boolean {\n  const relTypeLinks = getLinkedResourceUrlAll(linkedAccessResource).type;\n  return (\n    Array.isArray(relTypeLinks) &&\n    relTypeLinks.includes(acp.AccessControlResource)\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Quad } from \"@rdfjs/types\";\nimport { getSolidDataset } from \"../resource/solidDataset\";\nimport type {\n  IriString,\n  WithChangeLog,\n  Thing,\n  WithServerResourceInfo,\n} from \"../interfaces\";\nimport {\n  getSourceUrl,\n  getResourceInfo,\n  getSourceIri,\n} from \"../resource/resource\";\nimport { acl, rdf } from \"../constants\";\nimport { DataFactory, subjectToRdfJsQuads } from \"../rdfjs.internal\";\nimport {\n  createThing,\n  getThingAll,\n  removeThing,\n  setThing,\n} from \"../thing/thing\";\nimport { getIri, getIriAll } from \"../thing/get\";\nimport { setIri } from \"../thing/set\";\nimport { addIri } from \"../thing/add\";\nimport type {\n  Access,\n  AclDataset,\n  AclRule,\n  WithAccessibleAcl,\n  WithAcl,\n  WithFallbackAcl,\n  WithResourceAcl,\n} from \"./acl\";\nimport { hasAccessibleAcl } from \"./acl\";\nimport { removeAll, removeIri } from \"../thing/remove\";\nimport { freeze } from \"../rdf.internal\";\nimport { internal_cloneResource } from \"../resource/resource.internal\";\nimport { isAcr } from \"../acp/acp.internal\";\n\n/**\n * This (currently internal) function fetches the ACL indicated in the [[WithServerResourceInfo]]\n * attached to a resource.\n *\n * @internal\n * @param resourceInfo The Resource info with the ACL URL\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters).\n */\nexport async function internal_fetchAcl(\n  resourceInfo: WithServerResourceInfo,\n  options?: { fetch?: typeof fetch },\n): Promise<WithAcl[\"internal_acl\"]> {\n  if (!hasAccessibleAcl(resourceInfo)) {\n    return {\n      resourceAcl: null,\n      fallbackAcl: null,\n    };\n  }\n  try {\n    const resourceAcl = await internal_fetchResourceAcl(resourceInfo, options);\n\n    const acl =\n      resourceAcl === null\n        ? {\n            resourceAcl: null,\n            fallbackAcl: await internal_fetchFallbackAcl(resourceInfo, options),\n          }\n        : { resourceAcl, fallbackAcl: null };\n\n    return acl;\n  } catch (e: unknown) {\n    /* istanbul ignore else: fetchResourceAcl swallows all non-AclIsAcrErrors */\n    if (e instanceof AclIsAcrError) {\n      return {\n        resourceAcl: null,\n        fallbackAcl: null,\n      };\n    }\n    /* istanbul ignore next: fetchResourceAcl swallows all non-AclIsAcrErrors */\n    throw e;\n  }\n}\n\n/** @internal */\nexport async function internal_fetchResourceAcl(\n  dataset: WithServerResourceInfo,\n  options?: { fetch?: typeof fetch },\n): Promise<AclDataset | null> {\n  if (!hasAccessibleAcl(dataset)) {\n    return null;\n  }\n\n  try {\n    const aclSolidDataset = await getSolidDataset(\n      dataset.internal_resourceInfo.aclUrl,\n      options,\n    );\n    if (isAcr(aclSolidDataset)) {\n      throw new AclIsAcrError(dataset, aclSolidDataset);\n    }\n    return freeze({\n      ...aclSolidDataset,\n      internal_accessTo: getSourceUrl(dataset),\n    });\n  } catch (e) {\n    if (e instanceof AclIsAcrError) {\n      throw e;\n    }\n    // Since a Solid server adds a `Link` header to an ACL even if that ACL does not exist,\n    // failure to fetch the ACL is expected to happen - we just return `null` and let callers deal\n    // with it.\n    return null;\n  }\n}\n\n/** @internal */\nexport async function internal_fetchFallbackAcl(\n  resource: WithAccessibleAcl,\n  options?: { fetch?: typeof fetch },\n): Promise<AclDataset | null> {\n  const resourceUrl = new URL(getSourceUrl(resource));\n  const resourcePath = resourceUrl.pathname;\n  // Note: we're currently assuming that the Origin is the root of the Pod. However, it is not yet\n  //       set in stone that that will always be the case. We might need to check the Container's\n  //       metadata at some point in time to check whether it is actually the root of the Pod.\n  //       See: https://github.com/solid/specification/issues/153#issuecomment-624630022\n  if (resourcePath === \"/\") {\n    // We're already at the root, so there's no Container we can retrieve:\n    return null;\n  }\n\n  const containerPath = internal_getContainerPath(resourcePath);\n  const containerIri = new URL(containerPath, resourceUrl.origin).href;\n  const containerInfo = await getResourceInfo(containerIri, options);\n\n  if (!hasAccessibleAcl(containerInfo)) {\n    // If the current user does not have access to this Container's ACL,\n    // we cannot determine whether its ACL is the one that applies. Thus, return null:\n    return null;\n  }\n\n  const containerAcl = await internal_fetchResourceAcl(containerInfo, options);\n  if (containerAcl === null) {\n    return internal_fetchFallbackAcl(containerInfo, options);\n  }\n  return containerAcl;\n}\n\n/**\n * Given the path to a Resource, get the URL of the Container one level up in the hierarchy.\n * @param resourcePath The path of the Resource of which we need to determine the Container's path.\n * @hidden For internal use only.\n */\nexport function internal_getContainerPath(resourcePath: string): string {\n  const resourcePathWithoutTrailingSlash =\n    resourcePath.substring(resourcePath.length - 1) === \"/\"\n      ? resourcePath.substring(0, resourcePath.length - 1)\n      : resourcePath;\n\n  const containerPath = `${resourcePath.substring(\n    0,\n    resourcePathWithoutTrailingSlash.lastIndexOf(\"/\"),\n  )}/`;\n\n  return containerPath;\n}\n\n/** @internal */\nexport function internal_getAclRules(aclDataset: AclDataset): AclRule[] {\n  const things = getThingAll(aclDataset);\n  return things.filter(isAclRule);\n}\n\nfunction isAclRule(thing: Thing): thing is AclRule {\n  return getIriAll(thing, rdf.type).includes(acl.Authorization);\n}\n\n/** @internal */\nexport function internal_getResourceAclRules(aclRules: AclRule[]): AclRule[] {\n  return aclRules.filter(isResourceAclRule);\n}\n\nfunction isResourceAclRule(aclRule: AclRule): boolean {\n  return getIri(aclRule, acl.accessTo) !== null;\n}\n\n/** @internal */\nexport function internal_getResourceAclRulesForResource(\n  aclRules: AclRule[],\n  resource: IriString,\n): AclRule[] {\n  return aclRules.filter((rule) => appliesToResource(rule, resource));\n}\n\nfunction appliesToResource(aclRule: AclRule, resource: IriString): boolean {\n  return getIriAll(aclRule, acl.accessTo).includes(resource);\n}\n\n/** @internal */\nexport function internal_getDefaultAclRules(aclRules: AclRule[]): AclRule[] {\n  return aclRules.filter(isDefaultAclRule);\n}\n\nfunction isDefaultAclRule(aclRule: AclRule): boolean {\n  return (\n    getIri(aclRule, acl.default) !== null ||\n    getIri(aclRule, acl.defaultForNew) !== null\n  );\n}\n\n/** @internal */\nexport function internal_getDefaultAclRulesForResource(\n  aclRules: AclRule[],\n  resource: IriString,\n): AclRule[] {\n  return aclRules.filter((rule) => isDefaultForResource(rule, resource));\n}\n\nfunction isDefaultForResource(aclRule: AclRule, resource: IriString): boolean {\n  return (\n    getIriAll(aclRule, acl.default).includes(resource) ||\n    getIriAll(aclRule, acl.defaultForNew).includes(resource)\n  );\n}\n\n/** @internal */\nexport function internal_getAccess(rule: AclRule): Access {\n  const ruleAccessModes = getIriAll(rule, acl.mode);\n  const writeAccess = ruleAccessModes.includes(\n    internal_accessModeIriStrings.write,\n  );\n  return writeAccess\n    ? {\n        read: ruleAccessModes.includes(internal_accessModeIriStrings.read),\n        append: true,\n        write: true,\n        control: ruleAccessModes.includes(\n          internal_accessModeIriStrings.control,\n        ),\n      }\n    : {\n        read: ruleAccessModes.includes(internal_accessModeIriStrings.read),\n        append: ruleAccessModes.includes(internal_accessModeIriStrings.append),\n        write: false,\n        control: ruleAccessModes.includes(\n          internal_accessModeIriStrings.control,\n        ),\n      };\n}\n\n/** @internal */\nexport function internal_combineAccessModes(modes: Access[]): Access {\n  return modes.reduce(\n    (accumulator, current) => {\n      const writeAccess = accumulator.write || current.write;\n      return writeAccess\n        ? {\n            read: accumulator.read || current.read,\n            append: true,\n            write: true,\n            control: accumulator.control || current.control,\n          }\n        : {\n            read: accumulator.read || current.read,\n            append: accumulator.append || current.append,\n            write: false,\n            control: accumulator.control || current.control,\n          };\n    },\n    { read: false, append: false, write: false, control: false },\n  );\n}\n\n/** @internal */\nexport function internal_removeEmptyAclRules<Dataset extends AclDataset>(\n  aclDataset: Dataset,\n): Dataset {\n  const aclRules = internal_getAclRules(aclDataset);\n  const aclRulesToRemove = aclRules.filter(isEmptyAclRule);\n\n  // Is this too clever? It iterates over aclRulesToRemove, one by one removing them from aclDataset.\n  const updatedAclDataset = aclRulesToRemove.reduce(removeThing, aclDataset);\n\n  return updatedAclDataset;\n}\n\nfunction isEmptyAclRule(aclRule: AclRule): boolean {\n  // If there are Quads in there unrelated to Access Control,\n  // this is not an empty ACL rule that can be deleted:\n  if (\n    subjectToRdfJsQuads(\n      aclRule.predicates,\n      DataFactory.namedNode(aclRule.url),\n      DataFactory.defaultGraph(),\n    ).some((quad) => !isAclQuad(quad))\n  ) {\n    return false;\n  }\n\n  // If the rule does not apply to any Resource, it is no longer working:\n  if (\n    getIri(aclRule, acl.accessTo) === null &&\n    getIri(aclRule, acl.default) === null &&\n    getIri(aclRule, acl.defaultForNew) === null\n  ) {\n    return true;\n  }\n\n  // If the rule does not specify Access Modes, it is no longer working:\n  if (getIri(aclRule, acl.mode) === null) {\n    return true;\n  }\n\n  // If the rule does not specify whom it applies to, it is no longer working:\n  if (\n    getIri(aclRule, acl.agent) === null &&\n    getIri(aclRule, acl.agentGroup) === null &&\n    getIri(aclRule, acl.agentClass) === null\n  ) {\n    return true;\n  }\n\n  return false;\n}\n\nfunction isAclQuad(quad: Quad): boolean {\n  const { predicate } = quad;\n  const { object } = quad;\n  if (\n    predicate.equals(DataFactory.namedNode(rdf.type)) &&\n    object.equals(DataFactory.namedNode(acl.Authorization))\n  ) {\n    return true;\n  }\n  if (\n    predicate.equals(DataFactory.namedNode(acl.accessTo)) ||\n    predicate.equals(DataFactory.namedNode(acl.default)) ||\n    predicate.equals(DataFactory.namedNode(acl.defaultForNew))\n  ) {\n    return true;\n  }\n  if (\n    predicate.equals(DataFactory.namedNode(acl.mode)) &&\n    Object.values(internal_accessModeIriStrings).some((mode) =>\n      object.equals(DataFactory.namedNode(mode)),\n    )\n  ) {\n    return true;\n  }\n  if (\n    predicate.equals(DataFactory.namedNode(acl.agent)) ||\n    predicate.equals(DataFactory.namedNode(acl.agentGroup)) ||\n    predicate.equals(DataFactory.namedNode(acl.agentClass))\n  ) {\n    return true;\n  }\n  if (predicate.equals(DataFactory.namedNode(acl.origin))) {\n    return true;\n  }\n  return false;\n}\n\n/**\n * IRIs of potential Access Modes\n * @internal\n */\nexport const internal_accessModeIriStrings = {\n  read: \"http://www.w3.org/ns/auth/acl#Read\",\n  append: \"http://www.w3.org/ns/auth/acl#Append\",\n  write: \"http://www.w3.org/ns/auth/acl#Write\",\n  control: \"http://www.w3.org/ns/auth/acl#Control\",\n} as const;\n\n/** @internal\n * This function finds, among a set of ACL rules, the ones granting access to a given entity (the target)\n * and identifying it with a specific property (`acl:agent` or `acl:agentGroup`).\n * @param aclRules The set of rules to filter\n * @param targetIri The IRI of the target\n * @param targetType The property linking the rule to the target\n */\nexport function internal_getAclRulesForIri(\n  aclRules: AclRule[],\n  targetIri: IriString,\n  targetType: typeof acl.agent | typeof acl.agentGroup,\n): AclRule[] {\n  return aclRules.filter((rule) =>\n    getIriAll(rule, targetType).includes(targetIri),\n  );\n}\n\n/** @internal\n * This function transforms a given set of rules into a map associating the IRIs\n * of the entities to which permissions are granted by these rules, and the permissions\n * granted to them. Additionally, it filters these entities based on the predicate\n * that refers to them in the rule.\n */\nexport function internal_getAccessByIri(\n  aclRules: AclRule[],\n  targetType: typeof acl.agent | typeof acl.agentGroup,\n): Record<IriString, Access> {\n  const targetIriAccess: Record<IriString, Access> = {};\n\n  aclRules.forEach((rule) => {\n    const ruleTargetIri = getIriAll(rule, targetType);\n    const access = internal_getAccess(rule);\n\n    // A rule might apply to multiple agents. If multiple rules apply to the same agent, the Access\n    // Modes granted by those rules should be combined:\n    ruleTargetIri.forEach((targetIri) => {\n      targetIriAccess[targetIri] =\n        typeof targetIriAccess[targetIri] === \"undefined\"\n          ? access\n          : internal_combineAccessModes([targetIriAccess[targetIri], access]);\n    });\n  });\n  return targetIriAccess;\n}\n\n/**\n * Initialises a new ACL Rule that grants some access - but does not yet specify to whom.\n *\n * @hidden This is an internal utility function that should not be used directly by downstreams.\n * @param access Access mode that this Rule will grant\n */\nexport function internal_initialiseAclRule(access: Access): AclRule {\n  let newRule = createThing();\n  newRule = setIri(newRule, rdf.type, acl.Authorization);\n  if (access.read) {\n    newRule = addIri(newRule, acl.mode, internal_accessModeIriStrings.read);\n  }\n  if (access.append && !access.write) {\n    newRule = addIri(newRule, acl.mode, internal_accessModeIriStrings.append);\n  }\n  if (access.write) {\n    newRule = addIri(newRule, acl.mode, internal_accessModeIriStrings.write);\n  }\n  if (access.control) {\n    newRule = addIri(newRule, acl.mode, internal_accessModeIriStrings.control);\n  }\n  return newRule;\n}\n\n/**\n * Creates a new ACL Rule with the same ACL values as the input ACL Rule, but having a different IRI.\n *\n * Note that non-ACL values will not be copied over.\n *\n * @hidden This is an internal utility function that should not be used directly by downstreams.\n * @param sourceRule ACL rule to duplicate.\n */\nexport function internal_duplicateAclRule(sourceRule: AclRule): AclRule {\n  let targetRule = createThing();\n  targetRule = setIri(targetRule, rdf.type, acl.Authorization);\n\n  function copyIris(\n    inputRule: typeof sourceRule,\n    outputRule: typeof targetRule,\n    predicate: IriString,\n  ) {\n    return getIriAll(inputRule, predicate).reduce(\n      (outputRule, iriTarget) => addIri(outputRule, predicate, iriTarget),\n      outputRule,\n    );\n  }\n\n  targetRule = copyIris(sourceRule, targetRule, acl.accessTo);\n  targetRule = copyIris(sourceRule, targetRule, acl.default);\n  targetRule = copyIris(sourceRule, targetRule, acl.defaultForNew);\n  targetRule = copyIris(sourceRule, targetRule, acl.agent);\n  targetRule = copyIris(sourceRule, targetRule, acl.agentGroup);\n  targetRule = copyIris(sourceRule, targetRule, acl.agentClass);\n  targetRule = copyIris(sourceRule, targetRule, acl.origin);\n  targetRule = copyIris(sourceRule, targetRule, acl.mode);\n\n  return targetRule;\n}\n\n/**\n * Attach an ACL dataset to a Resource.\n *\n * @hidden This is an internal utility function that should not be used directly by downstreams.\n * @param resource The Resource to which an ACL is being attached\n * @param acl The ACL being attached to the Resource\n */\nexport function internal_setAcl<ResourceExt extends WithServerResourceInfo>(\n  resource: ResourceExt,\n  acl: WithResourceAcl[\"internal_acl\"],\n): ResourceExt & WithResourceAcl;\nexport function internal_setAcl<ResourceExt extends WithServerResourceInfo>(\n  resource: ResourceExt,\n  acl: WithFallbackAcl[\"internal_acl\"],\n): ResourceExt & WithFallbackAcl;\nexport function internal_setAcl<ResourceExt extends WithServerResourceInfo>(\n  resource: ResourceExt,\n  acl: WithAcl[\"internal_acl\"],\n): ResourceExt & WithAcl;\nexport function internal_setAcl<ResourceExt extends WithServerResourceInfo>(\n  resource: ResourceExt,\n  acl: WithAcl[\"internal_acl\"],\n): ResourceExt & WithAcl {\n  return Object.assign(internal_cloneResource(resource), { internal_acl: acl });\n}\n\nconst supportedActorPredicates = [\n  acl.agent,\n  acl.agentClass,\n  acl.agentGroup,\n  acl.origin,\n];\n/**\n * Union type of all relations defined in `knownActorRelations`.\n *\n * When the ACP spec evolves to support additional relations of Rules to Actors,\n * adding those relations to `knownActorRelations` will cause TypeScript to warn\n * us everywhere to update everywhere the ActorRelation type is used and that\n * needs additional work to handle it.\n */\ntype SupportedActorPredicate =\n  typeof supportedActorPredicates extends Array<infer E> ? E : never;\n\n/**\n * Given an ACL Rule, returns two new ACL Rules that cover all the input Rule's use cases,\n * except for giving the given Actor access to the given Resource.\n *\n * @param rule The ACL Rule that should no longer apply for a given Actor to a given Resource.\n * @param actor The Actor that should be removed from the Rule for the given Resource.\n * @param resourceIri The Resource to which the Rule should no longer apply for the given Actor.\n * @returns A tuple with the original ACL Rule without the given Actor, and a new ACL Rule for the given Actor for the remaining Resources, respectively.\n */\nfunction internal_removeActorFromRule(\n  rule: AclRule,\n  actor: IriString,\n  actorPredicate: SupportedActorPredicate,\n  resourceIri: IriString,\n  ruleType: \"resource\" | \"default\",\n): [AclRule, AclRule] {\n  // If the existing Rule does not apply to the given Actor, we don't need to split up.\n  // Without this check, we'd be creating a new rule for the given Actor (ruleForOtherTargets)\n  // that would give it access it does not currently have:\n  if (!getIriAll(rule, actorPredicate).includes(actor)) {\n    const emptyRule = internal_initialiseAclRule({\n      read: false,\n      append: false,\n      write: false,\n      control: false,\n    });\n    return [rule, emptyRule];\n  }\n  // The existing rule will keep applying to Actors other than the given one:\n  const ruleWithoutActor = removeIri(rule, actorPredicate, actor);\n  // The actor might have been given other access in the existing rule, so duplicate it...\n  let ruleForOtherTargets = internal_duplicateAclRule(rule);\n  // ...but remove access to the original Resource...\n  ruleForOtherTargets = removeIri(\n    ruleForOtherTargets,\n    ruleType === \"resource\" ? acl.accessTo : acl.default,\n    resourceIri,\n  );\n  // Prevents the legacy predicate 'acl:defaultForNew' to lead to privilege escalation\n  if (ruleType === \"default\") {\n    ruleForOtherTargets = removeIri(\n      ruleForOtherTargets,\n      acl.defaultForNew,\n      resourceIri,\n    );\n  }\n  // ...and only apply the new Rule to the given Actor (because the existing Rule covers the others):\n  ruleForOtherTargets = setIri(ruleForOtherTargets, actorPredicate, actor);\n  supportedActorPredicates\n    .filter((predicate) => predicate !== actorPredicate)\n    .forEach((predicate) => {\n      ruleForOtherTargets = removeAll(ruleForOtherTargets, predicate);\n    });\n\n  return [ruleWithoutActor, ruleForOtherTargets];\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n * Modifies the resource ACL (Access Control List) to set the Access Modes for the given Agent.\n * Specifically, the function returns a new resource ACL initialised with the given ACL and\n * new rules for the Actor's access.\n *\n * If rules for Actor's access already exist in the given ACL, in the returned ACL,\n * they are replaced by the new rules.\n *\n * This function does not modify:\n *\n * - Access Modes granted indirectly to Actors through other ACL rules, e.g., public or group-specific permissions.\n * - Access Modes granted to Actors for the child Resources if the associated Resource is a Container.\n * - The original ACL.\n *\n * @param aclDataset The SolidDataset that contains Access-Control List rules.\n * @param actor The Actor to grant specific Access Modes.\n * @param access The Access Modes to grant to the Actor for the Resource.\n * @returns A new resource ACL initialised with the given `aclDataset` and `access` for the `agent`.\n */\nexport function internal_setActorAccess(\n  aclDataset: AclDataset,\n  access: Access,\n  actorPredicate: SupportedActorPredicate,\n  accessType: \"default\" | \"resource\",\n  actor: IriString,\n): AclDataset & WithChangeLog {\n  // First make sure that none of the pre-existing rules in the given ACL SolidDataset\n  // give the Agent access to the Resource:\n  let filteredAcl = aclDataset;\n  getThingAll(aclDataset).forEach((aclRule) => {\n    // Obtain both the Rule that no longer includes the given Actor,\n    // and a new Rule that includes all ACL Quads\n    // that do not pertain to the given Actor-Resource combination.\n    // Note that usually, the latter will no longer include any meaningful statements;\n    // we'll clean them up afterwards.\n    const [filteredRule, remainingRule] = internal_removeActorFromRule(\n      aclRule,\n      actor,\n      actorPredicate,\n      aclDataset.internal_accessTo,\n      accessType,\n    );\n    filteredAcl = setThing(filteredAcl, filteredRule);\n    filteredAcl = setThing(filteredAcl, remainingRule);\n  });\n\n  // Create a new Rule that only grants the given Actor the given Access Modes:\n  let newRule = internal_initialiseAclRule(access);\n  newRule = setIri(\n    newRule,\n    accessType === \"resource\" ? acl.accessTo : acl.default,\n    aclDataset.internal_accessTo,\n  );\n  newRule = setIri(newRule, actorPredicate, actor);\n  const updatedAcl = setThing(filteredAcl, newRule);\n\n  // Remove any remaining Rules that do not contain any meaningful statements:\n  return internal_removeEmptyAclRules(updatedAcl);\n}\n\nexport function internal_setResourceAcl<\n  T extends WithServerResourceInfo & WithAcl,\n>(resource: T, acl: AclDataset): T & WithResourceAcl {\n  const newAcl: WithResourceAcl[\"internal_acl\"] = {\n    resourceAcl: acl,\n    fallbackAcl: null,\n  };\n  return internal_setAcl(resource, newAcl);\n}\n\nexport function internal_getResourceAcl(\n  resource: WithServerResourceInfo & WithResourceAcl,\n): AclDataset {\n  return resource.internal_acl.resourceAcl;\n}\n\n/**\n * This error indicates that, if we're following a Link with rel=\"acl\",\n * it does not result in a WAC ACL, but in an ACP ACR.\n */\nclass AclIsAcrError extends Error {\n  constructor(\n    sourceResource: WithServerResourceInfo,\n    aclResource: WithServerResourceInfo,\n  ) {\n    super(\n      `[${getSourceIri(\n        sourceResource,\n      )}] is governed by Access Control Policies in [${getSourceIri(\n        aclResource,\n      )}] rather than by Web Access Control.`,\n    );\n  }\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport { acl } from \"../constants\";\nimport {\n  createSolidDataset,\n  getSolidDataset,\n  saveSolidDatasetAt,\n} from \"../resource/solidDataset\";\nimport type {\n  WithResourceInfo,\n  File,\n  WithServerResourceInfo,\n  UrlString,\n  Url,\n  SolidDataset,\n  Thing,\n} from \"../interfaces\";\nimport { setThing } from \"../thing/thing\";\nimport { removeAll } from \"../thing/remove\";\nimport { setIri } from \"../thing/set\";\nimport { getResourceInfo, getSourceUrl } from \"../resource/resource\";\nimport { getFile } from \"../resource/file\";\nimport { internal_cloneResource } from \"../resource/resource.internal\";\nimport {\n  internal_fetchAcl,\n  internal_getAclRules,\n  internal_getDefaultAclRulesForResource,\n  internal_setAcl,\n} from \"./acl.internal\";\nimport { freeze } from \"../rdf.internal\";\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Verify whether a given SolidDataset was fetched together with its Access Control List.\n *\n * @param dataset A [[SolidDataset]] that may have its ACLs attached.\n * @returns True if `dataset` was fetched together with its ACLs.\n */\nexport function hasAcl<T extends object>(dataset: T): dataset is T & WithAcl {\n  const potentialAcl = dataset as T & WithAcl;\n  return typeof potentialAcl.internal_acl === \"object\";\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Verifies whether the given Resource has a resource ACL (Access Control List) attached.\n *\n * The [[hasResourceAcl]] function checks that:\n * - a given Resource has a resource ACL attached, and\n * - the user calling [[hasResourceAcl]] has Control access to the Resource.\n *\n * To retrieve a Resource with its ACLs, see [[getSolidDatasetWithAcl]].\n *\n * @param resource A Resource that might have an ACL attached.\n * @returns `true` if the Resource has a resource ACL attached that is accessible by the user.\n */\nexport function hasResourceAcl<\n  Resource extends WithAcl & WithServerResourceInfo,\n>(\n  resource: Resource,\n): resource is Resource & WithResourceAcl & WithAccessibleAcl {\n  return (\n    resource.internal_acl.resourceAcl !== null &&\n    getSourceUrl(resource) ===\n      resource.internal_acl.resourceAcl.internal_accessTo &&\n    resource.internal_resourceInfo.aclUrl ===\n      getSourceUrl(resource.internal_acl.resourceAcl)\n  );\n}\n\n/**\n * Experimental: fetch a SolidDataset and its associated Access Control List.\n *\n * This is an experimental function that fetches both a Resource, the linked ACL Resource (if\n * available), and the ACL that applies to it if the linked ACL Resource is not available. This can\n * result in many HTTP requests being executed, in lieu of the Solid spec mandating servers to\n * provide this info in a single request. Therefore, and because this function is still\n * experimental, prefer [[getSolidDataset]] instead.\n *\n * If the Resource does not advertise the ACL Resource (because the authenticated user does not have\n * access to it), the `acl` property in the returned value will be null. `acl.resourceAcl` will be\n * undefined if the Resource's linked ACL Resource could not be fetched (because it does not exist),\n * and `acl.fallbackAcl` will be null if the applicable Container's ACL is not accessible to the\n * authenticated user.\n *\n * @param url URL of the SolidDataset to fetch.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns A SolidDataset and the ACLs that apply to it, if available to the authenticated user.\n */\nexport async function getSolidDatasetWithAcl(\n  url: UrlString | Url,\n  options?: { fetch?: typeof fetch },\n): Promise<SolidDataset & WithServerResourceInfo & WithAcl> {\n  const solidDataset = await getSolidDataset(url, options);\n  const acl = await internal_fetchAcl(solidDataset, options);\n  return internal_setAcl(solidDataset, acl);\n}\n\n/**\n * ```{note} This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Retrieves a file, its resource ACL (Access Control List) if available,\n * and its fallback ACL from a URL and returns them as a blob.\n *\n * If the user calling the function does not have access to the file's resource ACL,\n * [[hasAccessibleAcl]] on the returned blob returns false.\n * If the user has access to the file's resource ACL but the resource ACL does not exist,\n * [[getResourceAcl]] on the returned blob returns null.\n * If the fallback ACL is inaccessible by the user,\n * [[getFallbackAcl]] on the returned blob returns null.\n *\n * ```{tip}\n * To retrieve the ACLs, the function results in multiple HTTP requests rather than a single\n * request as mandated by the Solid spec. As such, prefer [[getFile]] instead if you do not need the ACL.\n * ```\n *\n * @param url The URL of the fetched file\n * @param options Fetching options: a custom fetcher and/or headers.\n * @returns A file and its ACLs, if available to the authenticated user, as a blob.\n * @since 0.2.0\n */\nexport async function getFileWithAcl(\n  input: Url | UrlString,\n  options?: { fetch?: typeof fetch },\n): Promise<File & WithServerResourceInfo & WithAcl> {\n  const file = await getFile(input, options);\n  const acl = await internal_fetchAcl(file, options);\n  return internal_setAcl(file, acl);\n}\n\n/**\n * Experimental: fetch a Resource's metadata and its associated Access Control List.\n *\n * This is an experimental function that fetches both a Resource's metadata, the linked ACL Resource (if\n * available), and the ACL that applies to it if the linked ACL Resource is not available (if accessible). This can\n * result in many HTTP requests being executed, in lieu of the Solid spec mandating servers to\n * provide this info in a single request.\n *\n * If the Resource's linked ACL Resource could not be fetched (because it does not exist, or because\n * the authenticated user does not have access to it), `acl.resourceAcl` will be `null`. If the\n * applicable Container's ACL is not accessible to the authenticated user, `acl.fallbackAcl` will be\n * `null`.\n *\n * @param url URL of the SolidDataset to fetch.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns A Resource's metadata and the ACLs that apply to the Resource, if available to the authenticated user.\n */\nexport async function getResourceInfoWithAcl(\n  url: UrlString,\n  options?: { fetch?: typeof fetch },\n): Promise<WithServerResourceInfo & WithAcl> {\n  const resourceInfo = await getResourceInfo(url, options);\n  const acl = await internal_fetchAcl(resourceInfo, options);\n  return internal_setAcl(resourceInfo, acl);\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n * Returns the resource ACL (Access Control List) attached to a Resource.\n *\n * If the Resource has its resource ACL attached and is accessible by the user\n * (see [[hasResourceAcl]]), the function returns the resource ACL.\n * If the Resource does not have a resource ACL attached or is inaccessible by the user,\n * the function returns `null`.\n *\n * @param resource A Resource with potentially an ACL attached.\n * @returns The resource ACL if available and `null` if not.\n */\nexport function getResourceAcl(\n  resource: WithAcl & WithServerResourceInfo & WithResourceAcl,\n): AclDataset;\nexport function getResourceAcl(\n  resource: WithAcl & WithServerResourceInfo,\n): AclDataset | null;\nexport function getResourceAcl(\n  resource: WithAcl & WithServerResourceInfo,\n): AclDataset | null {\n  if (!hasResourceAcl(resource)) {\n    return null;\n  }\n  return resource.internal_acl.resourceAcl;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Verifies whether the given Resource has a fallback ACL (Access Control List) attached.\n *\n * A fallback ACL for a Resource is inherited from the Resource's parent Container\n * (or another of its ancestor Containers) and applies if the Resource does\n * not have its own resource ACL.\n *\n * The [[hasFallbackAcl]] function checks that:\n * - a given Resource has a fallback ACL attached, and\n * - the user calling [[hasFallbackAcl]] has Control access to the Container\n * from which the Resource inherits its ACL.\n *\n * To retrieve a Resource with its ACLs, see [[getSolidDatasetWithAcl]].\n *\n * @param resource A [[SolidDataset]] that might have a fallback ACL attached.\n *\n * @returns `true` if the Resource has a fallback ACL attached that is accessible to the user.\n */\nexport function hasFallbackAcl<Resource extends WithAcl>(\n  resource: Resource,\n): resource is Resource & WithFallbackAcl {\n  return resource.internal_acl.fallbackAcl !== null;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns the fallback ACL (Access Control List) attached to a Resource.\n *\n * If the Resource has a fallback ACL attached and is accessible by the user\n * (see [[hasFallbackAcl]]), the function returns the fallback ACL.\n * If the Resource does not hava a fallback ACL attached or is inaccessible by the user,\n * the function returns `null`.\n *\n * @param resource A Resource with potentially a fallback ACL attached.\n * @returns The fallback ACL if available or `null` if not.\n */\nexport function getFallbackAcl(resource: WithFallbackAcl): AclDataset;\nexport function getFallbackAcl(dataset: WithAcl): AclDataset | null;\nexport function getFallbackAcl(dataset: WithAcl): AclDataset | null {\n  if (!hasFallbackAcl(dataset)) {\n    return null;\n  }\n  return dataset.internal_acl.fallbackAcl;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Creates an empty resource ACL (Access Control List) for a given Resource.\n *\n * @param targetResource A Resource that does not have its own ACL yet (see [[hasResourceAcl]]).\n * @returns An empty resource ACL for the given Resource.\n */\nexport function createAcl(\n  targetResource: WithResourceInfo & WithAccessibleAcl,\n): AclDataset {\n  const emptyResourceAcl: AclDataset = freeze({\n    ...createSolidDataset(),\n    internal_accessTo: getSourceUrl(targetResource),\n    internal_resourceInfo: {\n      sourceIri: targetResource.internal_resourceInfo.aclUrl,\n      isRawData: false,\n      linkedResources: {},\n    },\n  });\n\n  return emptyResourceAcl;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Creates a resource ACL (Access Control List), initialised from the fallback ACL\n * inherited from the given Resource's Container (or another of its ancestor Containers).\n * That is, the new ACL has the same rules/entries as the fallback ACL that currently\n * applies to the Resource.\n *\n * @param resource A Resource without its own resource ACL (see [[hasResourceAcl]]) but with an accessible fallback ACL (see [[hasFallbackAcl]]).\n * @returns A resource ACL initialised with the rules/entries from the Resource's fallback ACL.\n */\nexport function createAclFromFallbackAcl(\n  resource: WithFallbackAcl & WithServerResourceInfo & WithAccessibleAcl,\n): AclDataset {\n  const emptyResourceAcl: AclDataset = createAcl(resource);\n\n  const fallbackAclRules = internal_getAclRules(\n    resource.internal_acl.fallbackAcl,\n  );\n  const defaultAclRules = internal_getDefaultAclRulesForResource(\n    fallbackAclRules,\n    resource.internal_acl.fallbackAcl.internal_accessTo,\n  );\n  const newAclRules = defaultAclRules.map((rule) => {\n    rule = removeAll(rule, acl.default);\n    rule = removeAll(rule, acl.defaultForNew);\n    rule = setIri(rule, acl.accessTo, getSourceUrl(resource));\n    rule = setIri(rule, acl.default, getSourceUrl(resource));\n    return rule;\n  });\n\n  // Iterate over every ACL Rule we want to import, inserting them into `emptyResourceAcl` one by one:\n  const initialisedResourceAcl = newAclRules.reduce(setThing, emptyResourceAcl);\n\n  return initialisedResourceAcl;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Saves the resource ACL for a Resource.\n *\n * @param resource The Resource to which the given resource ACL applies.\n * @param resourceAcl An [[AclDataset]] whose ACL Rules will apply to `resource`.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n */\nexport async function saveAclFor(\n  resource: WithAccessibleAcl,\n  resourceAcl: SolidDataset,\n  options?: { fetch?: typeof fetch },\n): Promise<AclDataset & WithResourceInfo> {\n  if (!hasAccessibleAcl(resource)) {\n    throw new Error(\n      `Could not determine the location of the ACL for the Resource at [${getSourceUrl(\n        resource,\n      )}]; possibly the current user does not have Control access to that Resource. Try calling \\`hasAccessibleAcl()\\` before calling \\`saveAclFor()\\`.`,\n    );\n  }\n  const savedDataset = await saveSolidDatasetAt(\n    resource.internal_resourceInfo.aclUrl,\n    resourceAcl,\n    options,\n  );\n  const savedAclDataset: AclDataset & typeof savedDataset = {\n    ...savedDataset,\n    internal_accessTo: getSourceUrl(resource),\n  };\n\n  return savedAclDataset;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Removes the resource ACL (Access Control List) from a Resource.\n *\n * Once the resource ACL is removed from the Resource, the Resource relies on the\n * fallback ACL inherited from the Resource's parent Container (or another of its ancestor Containers).\n *\n * @param resource The Resource for which you want to delete the ACL.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n */\nexport async function deleteAclFor<\n  Resource extends WithResourceInfo & WithAccessibleAcl,\n>(\n  resource: Resource,\n  options?: { fetch?: typeof fetch },\n): Promise<Resource & { acl: { resourceAcl: null } }> {\n  const response = await (options?.fetch ?? fetch)(\n    resource.internal_resourceInfo.aclUrl,\n    {\n      method: \"DELETE\",\n    },\n  );\n\n  if (!response.ok) {\n    throw new Error(\n      `Deleting the ACL of the Resource at [${getSourceUrl(\n        resource,\n      )}] failed: [${response.status}] [${response.statusText}].`,\n    );\n  }\n\n  const storedResource = Object.assign(internal_cloneResource(resource), {\n    acl: {\n      resourceAcl: null,\n    },\n  });\n\n  return storedResource;\n}\n\n/**\n * A [[SolidDataset]] containing Access Control rules for another SolidDataset.\n *\n * Please note that the Web Access Control specification is not yet finalised, and hence, this\n * function is still experimental and can change in a non-major release.\n */\nexport type AclDataset = SolidDataset &\n  WithResourceInfo & { internal_accessTo: UrlString };\n\n/**\n * @hidden Developers shouldn't need to directly access ACL rules. Instead, we provide our own functions that verify what access someone has.\n */\nexport type AclRule = Thing;\n\n/**\n * An object with the boolean properties `read`, `append`, `write` and `control`, representing the\n * respective Access Modes defined by the Web Access Control specification.\n *\n * Since that specification is not finalised yet, this interface is still experimental.\n */\nexport type Access =\n  // If someone has write permissions, they also have append permissions:\n  {\n    read: boolean;\n    append: boolean;\n    write: boolean;\n    control: boolean;\n  };\n\n/**\n * Please note that the Web Access Control specification is not yet finalised, and hence, this\n * function is still experimental and can change in a non-major release.\n *\n * @hidden Developers should use [[getResourceAcl]] and [[getFallbackAcl]] to access these.\n */\nexport type WithAcl = {\n  internal_acl:\n    | {\n        resourceAcl: AclDataset;\n        fallbackAcl: null;\n      }\n    | {\n        resourceAcl: null;\n        fallbackAcl: AclDataset | null;\n      };\n};\n\n/**\n * If this type applies to a Resource, an Access Control List that applies to it exists and is accessible to the currently authenticated user.\n *\n * Please note that the Web Access Control specification is not yet finalised, and hence, this\n * function is still experimental and can change in a non-major release.\n */\nexport type WithResourceAcl<ResourceExt extends WithAcl = WithAcl> =\n  ResourceExt & {\n    internal_acl: {\n      resourceAcl: Exclude<WithAcl[\"internal_acl\"][\"resourceAcl\"], null>;\n    };\n  };\n\n/**\n * If this type applies to a Resource, the Access Control List that applies to its nearest Container with an ACL is accessible to the currently authenticated user.\n *\n * Please note that the Web Access Control specification is not yet finalised, and hence, this\n * function is still experimental and can change in a non-major release.\n */\nexport type WithFallbackAcl<ResourceExt extends WithAcl = WithAcl> =\n  ResourceExt & {\n    internal_acl: {\n      fallbackAcl: Exclude<WithAcl[\"internal_acl\"][\"fallbackAcl\"], null>;\n    };\n  };\n\n/**\n * If this type applies to a Resource, its Access Control List, if it exists, is accessible to the currently authenticated user.\n *\n * Please note that the Web Access Control specification is not yet finalised, and hence, this\n * function is still experimental and can change in a non-major release.\n */\nexport type WithAccessibleAcl<\n  ResourceExt extends WithServerResourceInfo = WithServerResourceInfo,\n> = ResourceExt & {\n  internal_resourceInfo: {\n    aclUrl: Exclude<\n      WithServerResourceInfo[\"internal_resourceInfo\"][\"aclUrl\"],\n      undefined\n    >;\n  };\n};\n\n/**\n * Given a [[SolidDataset]], verify whether its Access Control List is accessible to the current user.\n *\n * This should generally only be true for SolidDatasets fetched by\n * [[getSolidDatasetWithAcl]].\n *\n * Please note that the Web Access Control specification is not yet finalised, and hence, this\n * function is still experimental and can change in a non-major release.\n *\n * @param dataset A [[SolidDataset]].\n * @returns Whether the given `dataset` has a an ACL that is accessible to the current user.\n */\nexport function hasAccessibleAcl<ResourceExt extends WithServerResourceInfo>(\n  dataset: ResourceExt,\n): dataset is WithAccessibleAcl<ResourceExt> {\n  return typeof dataset.internal_resourceInfo.aclUrl === \"string\";\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type {\n  WithServerResourceInfo,\n  WithChangeLog,\n  WebId,\n} from \"../interfaces\";\nimport { getIri } from \"../thing/get\";\nimport { acl } from \"../constants\";\nimport type { AclDataset, Access, AclRule, WithAcl } from \"./acl\";\nimport {\n  hasResourceAcl,\n  getResourceAcl,\n  hasFallbackAcl,\n  getFallbackAcl,\n} from \"./acl\";\nimport {\n  internal_combineAccessModes,\n  internal_getAccess,\n  internal_getAccessByIri,\n  internal_getAclRules,\n  internal_getAclRulesForIri,\n  internal_getDefaultAclRulesForResource,\n  internal_getResourceAclRulesForResource,\n  internal_setActorAccess,\n} from \"./acl.internal\";\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n */\nexport type AgentAccess = Record<WebId, Access>;\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns an Agent's explicitly-granted Access Modes for the given Resource.\n *\n * The function does not return Access Modes granted indirectly to the Agent through other\n * ACL rules, e.g., public or group-specific permissions.\n *\n * @param resourceInfo Information about the Resource to which the given Agent may have been granted access.\n * @param agent WebID of the Agent for which to retrieve what access it has to the Resource.\n * @returns Access Modes that have been explicitly granted to the Agent for the given Resource, or `null` if it could not be determined (e.g. because the current user does not have Control access to a given Resource or its Container).\n */\nexport function getAgentAccess(\n  resourceInfo: WithAcl & WithServerResourceInfo,\n  agent: WebId,\n): Access | null {\n  if (hasResourceAcl(resourceInfo)) {\n    return getAgentResourceAccess(resourceInfo.internal_acl.resourceAcl, agent);\n  }\n  if (hasFallbackAcl(resourceInfo)) {\n    return getAgentDefaultAccess(resourceInfo.internal_acl.fallbackAcl, agent);\n  }\n  return null;\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n * Returns all explicitly-granted Access Modes per Agent for the given Resource.\n *\n * The function does not return Access Modes granted indirectly to Agents through other\n * ACL rules, e.g., public or group-specific permissions.\n *\n * @param resourceInfo Information about the Resource to which Agents may have been granted access.\n * @returns Access Modes per Agent that have been explicitly granted for the given Resource, or `null` if it could not be determined (e.g. because the current user does not have Control access to a given Resource or its Container).\n */\nexport function getAgentAccessAll(\n  resourceInfo: WithAcl & WithServerResourceInfo,\n): AgentAccess | null {\n  if (hasResourceAcl(resourceInfo)) {\n    const resourceAcl = getResourceAcl(resourceInfo);\n    return getAgentResourceAccessAll(resourceAcl);\n  }\n  if (hasFallbackAcl(resourceInfo)) {\n    const fallbackAcl = getFallbackAcl(resourceInfo);\n    return getAgentDefaultAccessAll(fallbackAcl);\n  }\n  return null;\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns the Access Modes explicitly granted to an Agent for the Resource\n * associated with an ACL (Access ControlList).\n *\n * The function does not return:\n *\n * - Access Modes granted indirectly to the Agent through other ACL rules, e.g., public or group-specific permissions.\n * - Access Modes granted to the Agent for the child Resources if the associated Resource is a Container (see [[getAgentDefaultAccess]] instead).\n *\n * @param aclDataset The SolidDataset that contains ACL rules.\n * @param agent WebID of the Agent for which to retrieve what access it has to the Resource.\n * @returns Access Modes that have been explicitly granted to an Agent for the Resource associated with an ACL SolidDataset.\n */\nexport function getAgentResourceAccess(\n  aclDataset: AclDataset,\n  agent: WebId,\n): Access {\n  const allRules = internal_getAclRules(aclDataset);\n  const resourceRules = internal_getResourceAclRulesForResource(\n    allRules,\n    aclDataset.internal_accessTo,\n  );\n  const agentResourceRules = getAgentAclRulesForAgent(resourceRules, agent);\n  const agentAccessModes = agentResourceRules.map(internal_getAccess);\n  return internal_combineAccessModes(agentAccessModes);\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns the explicitly granted Access Modes per Agent for the Resource associated\n * with an ACL (Access Control List).\n *\n * The function does not return:\n *\n * - Access Modes granted indirectly to Agents through other ACL rules, e.g., public or group-specific permissions.\n * - Access Modes granted to Agents for the child Resources if the associated Resource is a Container.\n *\n * @param aclDataset The SolidDataset that contains ACL rules.\n * @returns Access Modes per Agent that have been explicitly granted for the Resource associated with an ACL SolidDataset.\n */\nexport function getAgentResourceAccessAll(aclDataset: AclDataset): AgentAccess {\n  const allRules = internal_getAclRules(aclDataset);\n  const resourceRules = internal_getResourceAclRulesForResource(\n    allRules,\n    aclDataset.internal_accessTo,\n  );\n  const agentResourceRules = getAgentAclRules(resourceRules);\n  return getAccessByAgent(agentResourceRules);\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n * Modifies the resource ACL (Access Control List) to set the Access Modes for the given Agent.\n * Specifically, the function returns a new resource ACL initialised with the given ACL and\n * new rules for the Agent's access.\n *\n * If rules for Agent's access already exist in the given ACL, in the returned ACL,\n * they are replaced by the new rules.\n *\n * This function does not modify:\n *\n * - Access Modes granted indirectly to Agents through other ACL rules, e.g., public or group-specific permissions.\n * - Access Modes granted to Agents for the child Resources if the associated Resource is a Container.\n * - The original ACL.\n *\n * @param aclDataset The SolidDataset that contains Access-Control List rules.\n * @param agent The Agent to grant specific Access Modes.\n * @param access The Access Modes to grant to the Agent for the Resource.\n * @returns A new resource ACL initialised with the given `aclDataset` and `access` for the `agent`.\n */\nexport function setAgentResourceAccess(\n  aclDataset: AclDataset,\n  agent: WebId,\n  access: Access,\n): AclDataset & WithChangeLog {\n  return internal_setActorAccess(\n    aclDataset,\n    access,\n    acl.agent,\n    \"resource\",\n    agent,\n  );\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns an Agent's Access Modes explicitly granted for the children of the\n * Container associated with the given ACL (Access Control List).\n *\n * The function does not return:\n * - Access Modes granted indirectly to the Agent through other ACL rules, e.g. public or group-specific permissions.\n * - Access Modes granted to the Agent for the Container Resource itself (see [[getAgentResourceAccess]] instead).\n *\n * @param aclDataset The SolidDataset that contains Access-Control List rules for a certain Container.\n * @param agent WebID of the Agent for which to retrieve what access it has to the Container's children.\n * @returns Access Modes that have been explicitly granted to an Agent for the children of the Container associated with the given ACL.\n */\nexport function getAgentDefaultAccess(\n  aclDataset: AclDataset,\n  agent: WebId,\n): Access {\n  const allRules = internal_getAclRules(aclDataset);\n  const resourceRules = internal_getDefaultAclRulesForResource(\n    allRules,\n    aclDataset.internal_accessTo,\n  );\n  const agentResourceRules = getAgentAclRulesForAgent(resourceRules, agent);\n  const agentAccessModes = agentResourceRules.map(internal_getAccess);\n  return internal_combineAccessModes(agentAccessModes);\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns the Access Modes, per Agent, that have been explicitly granted for the children\n * of the Container associated with the given ACL (Access Control List).\n *\n * The function does not return:\n *\n * - Access Modes granted indirectly to the Agents through other ACL rules, e.g. public or group-specific permissions.\n * - Access Modes granted to the Agents for the Container Resource itself (see [[getAgentResourceAccessAll]] instead).\n *\n * @param aclDataset The SolidDataset that contains Access-Control List rules.\n * @returns Access Modes, per Agent, that have been explicitly granted for the children of the Container associated with the given ACL.\n */\nexport function getAgentDefaultAccessAll(aclDataset: AclDataset): AgentAccess {\n  const allRules = internal_getAclRules(aclDataset);\n  const resourceRules = internal_getDefaultAclRulesForResource(\n    allRules,\n    aclDataset.internal_accessTo,\n  );\n  const agentResourceRules = getAgentAclRules(resourceRules);\n\n  return getAccessByAgent(agentResourceRules);\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Modifies the default ACL (Access Control List) to set an Agent's Access Modes for the Container's children.\n * Specifically, the function returns a new default ACL initialised with the given ACL and\n * new rules for the Agent's access.\n *\n * If rules already exist for the Agent in the given ACL, in the returned ACL, they are replaced by the new rules.\n *\n * This function does not modify:\n * - Access Modes granted indirectly to the Agent through other ACL rules, e.g., public or group-specific permissions.\n * - Access Modes granted to the Agent for the Container Resource itself.\n * - The original ACL.\n *\n * @param aclDataset The SolidDataset that contains Access-Control List rules.\n * @param agent The Agent to grant specific Access Modes.\n * @param access The Access Modes to grant to the Agent.\n * @returns A new default ACL initialised with the given `aclDataset` and `access` for the `agent`.\n */\nexport function setAgentDefaultAccess(\n  aclDataset: AclDataset,\n  agent: WebId,\n  access: Access,\n): AclDataset & WithChangeLog {\n  return internal_setActorAccess(\n    aclDataset,\n    access,\n    acl.agent,\n    \"default\",\n    agent,\n  );\n}\n\nfunction getAgentAclRulesForAgent(\n  aclRules: AclRule[],\n  agent: WebId,\n): AclRule[] {\n  return internal_getAclRulesForIri(aclRules, agent, acl.agent);\n}\n\nfunction getAgentAclRules(aclRules: AclRule[]): AclRule[] {\n  return aclRules.filter(isAgentAclRule);\n}\n\nfunction isAgentAclRule(aclRule: AclRule): boolean {\n  return getIri(aclRule, acl.agent) !== null;\n}\n\nfunction getAccessByAgent(aclRules: AclRule[]): AgentAccess {\n  return internal_getAccessByIri(aclRules, acl.agent);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type {\n  WithServerResourceInfo,\n  IriString,\n  UrlString,\n  WithChangeLog,\n} from \"../interfaces\";\nimport type { AclDataset, Access, AclRule, WithAcl } from \"./acl\";\nimport {\n  hasResourceAcl,\n  hasFallbackAcl,\n  getResourceAcl,\n  getFallbackAcl,\n} from \"./acl\";\nimport {\n  internal_getAclRules,\n  internal_getDefaultAclRulesForResource,\n  internal_getAccess,\n  internal_combineAccessModes,\n  internal_getResourceAclRulesForResource,\n  internal_getAclRulesForIri,\n  internal_getAccessByIri,\n  internal_setActorAccess,\n} from \"./acl.internal\";\n\nimport { acl } from \"../constants\";\n\n/**\n * ```{note} This function is still experimental and subject to change, even in a non-major release.\n * ```\n * Returns a Group's explicity-granted Access Modes for a given Resource.\n *\n * The function does not return Access Modes granted indirectly to the Group through other\n * ACL rules, e.g., public permissions.\n *\n * @param resourceInfo Information about the Resource to which the given Group may have been granted access.\n * @param group URL of the Group for which to retrieve what access it has to the Resource.\n * @returns Access Modes that have been explicitly granted to the `group` for the given Resource, or `null` if it could not be determined (e.g. because the current user does not have Control Access to a given Resource or its Container).\n */\nexport function getGroupAccess(\n  resourceInfo: WithAcl & WithServerResourceInfo,\n  group: UrlString,\n): Access | null {\n  if (hasResourceAcl(resourceInfo)) {\n    return getGroupResourceAccess(resourceInfo.internal_acl.resourceAcl, group);\n  }\n  if (hasFallbackAcl(resourceInfo)) {\n    return getGroupDefaultAccess(resourceInfo.internal_acl.fallbackAcl, group);\n  }\n  return null;\n}\n\n/**\n * ```{note} This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns all explicitly-granted Access Modes per Group for the given Resource.\n *\n * The function does not return Access Modes granted indirectly to the Group through other\n * ACL rules, e.g., public permissions.\n *\n * @param resourceInfo Information about the Resource to which the given Group may have been granted access.\n * @returns Access Modes per Group that have been explicitly granted for the given Resource, or `null` if it could not be determined (e.g. because the current user does not have Control Access to a given Resource or its Container).\n */\nexport function getGroupAccessAll(\n  resourceInfo: WithAcl & WithServerResourceInfo,\n): Record<IriString, Access> | null {\n  if (hasResourceAcl(resourceInfo)) {\n    const resourceAcl = getResourceAcl(resourceInfo);\n    return getGroupResourceAccessAll(resourceAcl);\n  }\n  if (hasFallbackAcl(resourceInfo)) {\n    const fallbackAcl = getFallbackAcl(resourceInfo);\n    return getGroupDefaultAccessAll(fallbackAcl);\n  }\n  return null;\n}\n\n/**\n * ```{note} This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns the Access Modes explicitly granted to a Group for the Resource\n * associated with an ACL (Access Control List).\n *\n * The function does not return:\n * - Access Modes granted indirectly to the Group through other ACL rules, e.g., public permissions.\n * - Access Modes granted to the Group for the child Resources if the associated Resource is a Container\n *   (see [[getGroupDefaultAccess]] instead).\n *\n * @param aclDataset The SolidDataset that contains Access Control List rules.\n * @param group URL of the Group for which to retrieve what access it has to the Resource.\n * @returns Access Modes explicitly granted to a Group for the Resource associated with an ACL.\n */\nexport function getGroupResourceAccess(\n  aclDataset: AclDataset,\n  group: UrlString,\n): Access {\n  const allRules = internal_getAclRules(aclDataset);\n  const resourceRules = internal_getResourceAclRulesForResource(\n    allRules,\n    aclDataset.internal_accessTo,\n  );\n  const groupResourceRules = getGroupAclRuleForGroup(resourceRules, group);\n  const groupAccessModes = groupResourceRules.map(internal_getAccess);\n  return internal_combineAccessModes(groupAccessModes);\n}\n\n/**\n * ```{note} This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns the explicitly granted Access Modes per Group for the Resource associated\n * with an ACL (Access Control List).\n *\n * The function does not return:\n * - Access Modes granted indirectly to the Group through other ACL rules, e.g., public permissions.\n * - Access Modes granted to Groups for the child Resources if the associated Resource is a Container.\n *\n * @param aclDataset The SolidDataset that contains Access Control List rules.\n * @returns Access Modes per Group that have been explicitly granted for the Resource associated with an ACL.\n */\nexport function getGroupResourceAccessAll(\n  aclDataset: AclDataset,\n): Record<UrlString, Access> {\n  const allRules = internal_getAclRules(aclDataset);\n  const resourceRules = internal_getResourceAclRulesForResource(\n    allRules,\n    aclDataset.internal_accessTo,\n  );\n  return getAccessByGroup(resourceRules);\n}\n\n/**\n * ```{note} This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns a Group's Access Modes explicitly granted for the children of the\n * Container associated with an ACL (Access ControlList).\n *\n * The function does not return:\n * - Access Modes granted indirectly to the Group through other ACL rules, e.g. public permissions.\n * - Access Modes granted to the Group for the Container Resource itself (see [[getGroupResourceAccess]] instead).\n *\n * @param aclDataset The SolidDataset that contains ACL rules for a certain Container.\n * @param group URL of the Group for which to retrieve what access it has to the child Resources of the given Container.\n * @returns Access Modes that have been explicitly granted to the Group for the children of the Container associated with the given ACL.\n */\nexport function getGroupDefaultAccess(\n  aclDataset: AclDataset,\n  group: UrlString,\n): Access {\n  const allRules = internal_getAclRules(aclDataset);\n  const defaultRules = internal_getDefaultAclRulesForResource(\n    allRules,\n    aclDataset.internal_accessTo,\n  );\n  const groupDefaultRules = getGroupAclRuleForGroup(defaultRules, group);\n  const groupAccessModes = groupDefaultRules.map(internal_getAccess);\n  return internal_combineAccessModes(groupAccessModes);\n}\n\n/**\n * ```{note} This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns the Access Modes, per Group, that have been explicitly granted for the children\n * of the Container associated with the given ACL (Access Control List).\n *\n * The function does not return:\n * - Access Modes granted indirectly to the Groups through other ACL rules, e.g. public permissions.\n * - Access Modes granted to the Groups for the Container Resource itself (see [[getGroupResourceAccessAll]] instead).\n *\n * @param aclDataset The SolidDataset that contains Access Control List rules for a certain Container.\n * @returns Access Modes per Group that have been explicitly granted for the children of the Container associated with the given ACL SolidDataset.\n */\nexport function getGroupDefaultAccessAll(\n  aclDataset: AclDataset,\n): Record<UrlString, Access> {\n  const allRules = internal_getAclRules(aclDataset);\n  const defaultRules = internal_getDefaultAclRulesForResource(\n    allRules,\n    aclDataset.internal_accessTo,\n  );\n  return getAccessByGroup(defaultRules);\n}\n\nfunction getGroupAclRuleForGroup(\n  rules: AclRule[],\n  group: UrlString,\n): AclRule[] {\n  return internal_getAclRulesForIri(rules, group, acl.agentGroup);\n}\n\nfunction getAccessByGroup(aclRules: AclRule[]): Record<IriString, Access> {\n  return internal_getAccessByIri(aclRules, acl.agentGroup);\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n * Modifies the resource ACL (Access Control List) to set the Access Modes for the given Group.\n * Specifically, the function returns a new resource ACL initialised with the given ACL and\n * new rules for the Group's access.\n *\n * If rules for Groups's access already exist in the given ACL, in the returned ACL,\n * they are replaced by the new rules.\n *\n * This function does not modify:\n *\n * - Access Modes granted indirectly to Groups through other ACL rules, e.g., public or Agent-specific permissions.\n * - Access Modes granted to Groups for the child Resources if the associated Resource is a Container.\n * - The original ACL.\n *\n * @param aclDataset The SolidDataset that contains Access-Control List rules.\n * @param group The Group to grant specific Access Modes.\n * @param access The Access Modes to grant to the Group for the Resource.\n * @returns A new resource ACL initialised with the given `aclDataset` and `access` for the `group`.\n * @since 1.4.0\n */\nexport function setGroupResourceAccess(\n  aclDataset: AclDataset,\n  group: UrlString,\n  access: Access,\n): AclDataset & WithChangeLog {\n  return internal_setActorAccess(\n    aclDataset,\n    access,\n    acl.agentGroup,\n    \"resource\",\n    group,\n  );\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Modifies the default ACL (Access Control List) to set a Group's Access Modes for the Container's children.\n * Specifically, the function returns a new default ACL initialised with the given ACL and\n * new rules for the Group's access.\n *\n * If rules already exist for the Group in the given ACL, in the returned ACL, they are replaced by the new rules.\n *\n * This function does not modify:\n * - Access Modes granted indirectly to the Group through other ACL rules, e.g., public or Agent-specific permissions.\n * - Access Modes granted to the Group for the Container Resource itself.\n * - The original ACL.\n *\n * @param aclDataset The SolidDataset that contains Access-Control List rules.\n * @param group The Group to grant specific Access Modes.\n * @param access The Access Modes to grant to the Group.\n * @returns A new default ACL initialised with the given `aclDataset` and `access` for the `group`.\n * @since 1.4.0\n */\nexport function setGroupDefaultAccess(\n  aclDataset: AclDataset,\n  group: UrlString,\n  access: Access,\n): AclDataset & WithChangeLog {\n  return internal_setActorAccess(\n    aclDataset,\n    access,\n    acl.agentGroup,\n    \"default\",\n    group,\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type {\n  IriString,\n  WithServerResourceInfo,\n  WithChangeLog,\n} from \"../interfaces\";\nimport { acl, foaf } from \"../constants\";\nimport { getIriAll } from \"../thing/get\";\nimport type { Access, AclDataset, AclRule, WithAcl } from \"./acl\";\nimport { hasResourceAcl, hasFallbackAcl } from \"./acl\";\nimport {\n  internal_getAclRules,\n  internal_getResourceAclRulesForResource,\n  internal_getDefaultAclRulesForResource,\n  internal_getAccess,\n  internal_combineAccessModes,\n  internal_setActorAccess,\n} from \"./acl.internal\";\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns the Access Modes granted to the public in general for a Resource.\n *\n * This function does not return Access Modes granted to specific Agents\n * through other ACL (Access Control List) rules, e.g., agent- or group-specific permissions.\n *\n * @param resourceInfo Information about the Resource to which the given Agent may have been granted access.\n * @returns Access Modes granted to the public in general for the Resource, or `null` if it could not be determined (e.g. because the current user does not have Control Access to a given Resource or its Container).\n */\nexport function getPublicAccess(\n  resourceInfo: WithAcl & WithServerResourceInfo,\n): Access | null {\n  if (hasResourceAcl(resourceInfo)) {\n    return getPublicResourceAccess(resourceInfo.internal_acl.resourceAcl);\n  }\n  if (hasFallbackAcl(resourceInfo)) {\n    return getPublicDefaultAccess(resourceInfo.internal_acl.fallbackAcl);\n  }\n  return null;\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns the Access Modes granted to the public in general for the Resource\n * associated with an ACL (Access Control List).\n *\n * This function does not return:\n * - Access Modes granted to specific Agents through other ACL rules, e.g., agent- or group-specific permissions.\n * - Access Modes to child Resources if the associated Resource is a Container (see [[getPublicDefaultAccess]] instead).\n *\n * @param aclDataset The SolidDataset that contains Access Control List rules.\n * @returns Access Modes granted to the public in general for the Resource associated with the `aclDataset`.\n */\nexport function getPublicResourceAccess(aclDataset: AclDataset): Access {\n  const allRules = internal_getAclRules(aclDataset);\n  const resourceRules = internal_getResourceAclRulesForResource(\n    allRules,\n    aclDataset.internal_accessTo,\n  );\n  const publicResourceRules = getClassAclRulesForClass(\n    resourceRules,\n    foaf.Agent,\n  );\n  const publicAccessModes = publicResourceRules.map(internal_getAccess);\n  return internal_combineAccessModes(publicAccessModes);\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Returns the Access Modes granted to the public in general for the child Resources\n * of the Container associated with an ACL (Access Control List).\n *\n * This function does not return:\n * - Access Modes granted to Agents through other ACL rules, e.g., agent- or group-specific permissions.\n * - Access Modes to the Container Resource itself (see [[getPublicResourceAccess]] instead).\n *\n * @param aclDataset The SolidDataset that contains Access Control List rules for a certain Container.\n * @returns Access Modes granted to the public in general for the children of the Container associated with the given `aclDataset`.\n */\nexport function getPublicDefaultAccess(aclDataset: AclDataset): Access {\n  const allRules = internal_getAclRules(aclDataset);\n  const resourceRules = internal_getDefaultAclRulesForResource(\n    allRules,\n    aclDataset.internal_accessTo,\n  );\n  const publicResourceRules = getClassAclRulesForClass(\n    resourceRules,\n    foaf.Agent,\n  );\n  const publicAccessModes = publicResourceRules.map(internal_getAccess);\n  return internal_combineAccessModes(publicAccessModes);\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Modifies the resource ACL (Access Control List) to set the Access Modes for the public.\n * Specifically, the function returns a new resource ACL (Access Control List) initialised\n * with the given resource ACL and new rules for the given public access.\n *\n * If rules for public access already exist in the given ACL, in the *returned* ACL,\n * they are replaced by the new rules.\n *\n * This function does not modify:\n * - Access Modes granted to Agents through other ACL rules, e.g., agent- or group-specific permissions.\n * - Access Modes to child Resources if the associated Resource is a Container.\n * - The original ACL.\n *\n * @param aclDataset The SolidDataset that contains Access Control List rules.\n * @param access The Access Modes to grant to the public.\n * @returns A new resource ACL initialised with the given `aclDataset` and public `access`.\n */\nexport function setPublicResourceAccess(\n  aclDataset: AclDataset,\n  access: Access,\n): AclDataset & WithChangeLog {\n  return internal_setActorAccess(\n    aclDataset,\n    access,\n    acl.agentClass,\n    \"resource\",\n    foaf.Agent,\n  );\n}\n\n/**\n * ```{note}\n * This function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Modifies the default ACL (Access Control List) to set the public's default Access Modes\n * to child resources. Specifically, the function returns a new default ACL initialised\n * with the given default ACL and new rules for the given public access.\n *\n * If rules for public access already exist in the given ACL, in the *returned* ACL,\n * they are replaced by the new rules.\n *\n * This function does not modify:\n * - Access Modes granted to Agents through other ACL rules, e.g., agent- or group-specific permissions.\n * - Access Modes to Container Resource itself.\n * - The original ACL.\n *\n * @param aclDataset The SolidDataset that contains Access Control List rules.\n * @param access The Access Modes to grant to the public.\n * @returns A new default ACL initialised with the given `aclDataset` and public `access`.\n */\nexport function setPublicDefaultAccess(\n  aclDataset: AclDataset,\n  access: Access,\n): AclDataset & WithChangeLog {\n  return internal_setActorAccess(\n    aclDataset,\n    access,\n    acl.agentClass,\n    \"default\",\n    foaf.Agent,\n  );\n}\n\nfunction getClassAclRulesForClass(\n  aclRules: AclRule[],\n  agentClass: IriString,\n): AclRule[] {\n  return aclRules.filter((rule) => appliesToClass(rule, agentClass));\n}\n\nfunction appliesToClass(aclRule: AclRule, agentClass: IriString): boolean {\n  return getIriAll(aclRule, acl.agentClass).includes(agentClass);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type {\n  IriString,\n  SolidDataset,\n  Thing,\n  UrlString,\n  WithResourceInfo,\n  WithServerResourceInfo,\n} from \"../interfaces\";\nimport { internal_cloneResource } from \"../resource/resource.internal\";\nimport { addIri } from \"../thing/add\";\nimport { createThing, getThing, setThing } from \"../thing/thing\";\nimport type { Access, AclDataset, WithAccessibleAcl } from \"./acl\";\n\nexport function addMockAclRuleQuads(\n  aclDataset: SolidDataset & WithResourceInfo,\n  agent: IriString,\n  resource: IriString,\n  access: Access,\n  type: \"resource\" | \"default\" | \"legacyDefault\",\n  ruleIri?: IriString,\n  targetType:\n    | \"http://www.w3.org/ns/auth/acl#agent\"\n    | \"http://www.w3.org/ns/auth/acl#agentGroup\"\n    | \"http://www.w3.org/ns/auth/acl#agentClass\"\n    | \"http://www.w3.org/ns/auth/acl#origin\" = \"http://www.w3.org/ns/auth/acl#agent\",\n): AclDataset {\n  let newControl: Thing = createThing({\n    name: encodeURIComponent(agent) + Math.random(),\n  });\n  if (typeof ruleIri === \"string\") {\n    newControl = getThing(aclDataset, ruleIri) ?? createThing({ url: ruleIri });\n  }\n  newControl = addIri(\n    newControl,\n    \"http://www.w3.org/1999/02/22-rdf-syntax-ns#type\",\n    \"http://www.w3.org/ns/auth/acl#Authorization\",\n  );\n  let resourceRelation: IriString = \"http://www.w3.org/ns/auth/acl#accessTo\";\n  if (type === \"default\") {\n    resourceRelation = \"http://www.w3.org/ns/auth/acl#default\";\n  }\n  if (type === \"legacyDefault\") {\n    resourceRelation = \"http://www.w3.org/ns/auth/acl#defaultForNew\";\n  }\n  newControl = addIri(newControl, resourceRelation, resource);\n  newControl = addIri(newControl, targetType, agent);\n  if (access.read) {\n    newControl = addIri(\n      newControl,\n      \"http://www.w3.org/ns/auth/acl#mode\",\n      \"http://www.w3.org/ns/auth/acl#Read\",\n    );\n  }\n  if (access.append) {\n    newControl = addIri(\n      newControl,\n      \"http://www.w3.org/ns/auth/acl#mode\",\n      \"http://www.w3.org/ns/auth/acl#Append\",\n    );\n  }\n  if (access.write) {\n    newControl = addIri(\n      newControl,\n      \"http://www.w3.org/ns/auth/acl#mode\",\n      \"http://www.w3.org/ns/auth/acl#Write\",\n    );\n  }\n  if (access.control) {\n    newControl = addIri(\n      newControl,\n      \"http://www.w3.org/ns/auth/acl#mode\",\n      \"http://www.w3.org/ns/auth/acl#Control\",\n    );\n  }\n\n  aclDataset = setThing(aclDataset, newControl);\n  return { ...aclDataset, internal_accessTo: resource };\n}\n\nexport function setMockAclUrl<T extends WithServerResourceInfo>(\n  resource: T,\n  aclUrl: UrlString,\n): T & WithAccessibleAcl {\n  const resourceWithAclUrl: typeof resource & WithAccessibleAcl = Object.assign(\n    internal_cloneResource(resource),\n    {\n      internal_resourceInfo: {\n        ...resource.internal_resourceInfo,\n        aclUrl,\n      },\n    },\n  );\n\n  return resourceWithAclUrl;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { WithServerResourceInfo } from \"../interfaces\";\nimport { getSourceIri } from \"../resource/resource\";\nimport { internal_cloneResource } from \"../resource/resource.internal\";\nimport type {\n  WithAccessibleAcl,\n  WithFallbackAcl,\n  WithResourceAcl,\n} from \"./acl\";\nimport { createAcl } from \"./acl\";\nimport { internal_getContainerPath, internal_setAcl } from \"./acl.internal\";\nimport { mockContainerFrom } from \"../resource/mock\";\nimport { setMockAclUrl } from \"./mock.internal\";\n\n/**\n * ```{warning}\n * Do not use this function in production code. For use in **unit tests** that\n * require a [[SolidDataset]] with a resource ACL (Access Control List).\n * ```\n *\n * Initialises a new empty ACL and attaches it to a given [[SolidDataset]] for use\n * in **unit tests**; e.g., unit tests that call [[getResourceAcl]].\n *\n * @param resource The Resource to mock up with a new resource ACL.\n * @returns The input Resource with an empty resource ACL attached.\n * @since 0.2.0\n */\nexport function addMockResourceAclTo<T extends WithServerResourceInfo>(\n  resource: T,\n): T & WithResourceAcl {\n  const aclUrl =\n    resource.internal_resourceInfo.aclUrl ?? \"https://your.pod/mock-acl.ttl\";\n  const resourceWithAclUrl: typeof resource & WithAccessibleAcl = Object.assign(\n    internal_cloneResource(resource),\n    {\n      internal_resourceInfo: {\n        ...resource.internal_resourceInfo,\n        aclUrl,\n      },\n    },\n  );\n  const aclDataset = createAcl(resourceWithAclUrl);\n\n  const resourceWithResourceAcl = internal_setAcl(resourceWithAclUrl, {\n    resourceAcl: aclDataset,\n    fallbackAcl: null,\n  });\n\n  return resourceWithResourceAcl;\n}\n\n/**\n *\n * ```{warning}\n * Do not use this function in production code.  For use in **unit tests** that require a\n * [[SolidDataset]] with a fallback ACL (Access Control List).\n * ```\n *\n * Initialises a new empty fallback ACL and attaches it to a given [[SolidDataset]] for use\n * in **unit tests**; e.g., unit tests that call [[getFallbackAcl]].\n *\n * @param resource The Resource to mock up with new fallback ACL.\n * @returns The input Resource with an empty fallback ACL attached.\n * @since 0.2.0\n */\nexport function addMockFallbackAclTo<T extends WithServerResourceInfo>(\n  resource: T,\n): T & WithFallbackAcl {\n  const containerUrl = internal_getContainerPath(getSourceIri(resource));\n  const aclUrl = `${containerUrl}.acl`;\n  const mockContainer = setMockAclUrl(mockContainerFrom(containerUrl), aclUrl);\n  const aclDataset = createAcl(mockContainer);\n\n  const resourceWithFallbackAcl = internal_setAcl(\n    internal_cloneResource(resource),\n    {\n      resourceAcl: null,\n      fallbackAcl: aclDataset,\n    },\n  );\n\n  return resourceWithFallbackAcl;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport { security } from \"../constants\";\nimport type {\n  Iri,\n  IriString,\n  Jwk,\n  Jwks,\n  SolidDataset,\n  ThingPersisted,\n  UrlString,\n  WebId,\n  WithResourceInfo,\n} from \"../interfaces\";\nimport { overwriteFile } from \"../resource/file\";\nimport { getSourceUrl } from \"../resource/resource\";\nimport { getSolidDataset } from \"../resource/solidDataset\";\nimport { getUrl } from \"../thing/get\";\nimport { setIri } from \"../thing/set\";\nimport { getThing, setThing } from \"../thing/thing\";\n\nfunction getProfileFromProfileDoc(\n  profileDataset: SolidDataset,\n  webId: WebId,\n): ThingPersisted {\n  const profile = getThing(profileDataset, webId);\n  if (profile === null) {\n    throw new Error(\n      `Profile document [${getSourceUrl(\n        profileDataset,\n      )}] does not include WebID [${webId}]`,\n    );\n  }\n  return profile;\n}\n\n/**\n * Set a JWKS IRI associated with a WebID in a profile document.\n *\n * @param profileDocument The profile document dataset.\n * @param webId The WebID associated with the profile document.\n * @param jwksIri The JWKS IRI to be set.\n * @returns A modified copy of the profile document, with the JWKS IRI set.\n * @since 1.12.0\n */\nexport function setProfileJwks<Dataset extends SolidDataset>(\n  profileDocument: Dataset,\n  webId: WebId,\n  jwksIri: Iri | IriString,\n): Dataset {\n  return setThing(\n    profileDocument,\n    setIri(\n      getProfileFromProfileDoc(profileDocument, webId),\n      security.publicKey,\n      jwksIri,\n    ),\n  );\n}\n\n/**\n * Look for a JWKS IRI optionally advertized from a profile document.\n *\n * @param profileDocument The profile document.\n * @param webId The WebID featured in the profile document.\n * @returns The JWKS IRI associated with the WebID, if any.\n * @since 1.12.0\n */\nexport function getProfileJwksIri(\n  profileDocument: SolidDataset,\n  webId: WebId,\n): UrlString | null {\n  return getUrl(\n    getProfileFromProfileDoc(profileDocument, webId),\n    security.publicKey,\n  );\n}\n\nconst isJwks = (jwksDocument: Jwks | unknown): jwksDocument is Jwks => {\n  return typeof (jwksDocument as Jwks).keys !== \"undefined\";\n};\n\n/**\n * Fetch a JWKS at a given IRI, and add the given JWK to the obtained key set.\n *\n * @param jwk The JWK to add to the set.\n * @param jwksIri The IRI where the key set should be looked up.\n * @param options @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns Promise resolving to a JWKS where the given key has been added.\n * @since 1.12.0\n */\nexport async function addJwkToJwks(\n  jwk: Jwk,\n  jwksIri: IriString,\n  options?: { fetch?: typeof fetch },\n): Promise<Jwks> {\n  const jwksResponse = await (options?.fetch ?? fetch)(jwksIri);\n  if (!jwksResponse.ok) {\n    throw new Error(\n      `Fetching [${jwksIri}] returned an error: ${jwksResponse.status} ${jwksResponse.statusText}`,\n    );\n  }\n  try {\n    const jwksDocument = await jwksResponse.json();\n    if (!isJwks(jwksDocument)) {\n      throw new Error(\n        `[${jwksIri}] does not dereference to a valid JWKS: ${JSON.stringify(\n          jwksDocument,\n        )}`,\n      );\n    }\n    return {\n      keys: [...jwksDocument.keys, jwk],\n    };\n  } catch (e) {\n    throw new Error(`Parsing the document at [${jwksIri}] failed: ${e}`);\n  }\n}\n\n/**\n * Adds a public key to the JWKS listed in the profile associated to the given WebID.\n * Retrieves the profile document for the specified WebID and looks up the associated\n * JWKS. Having added the given key to the JWKS, this function overwrites the\n * previous JWKS so that the new version is saved. This assumes the JWKS is hosted\n * at a read-write IRI, such as in a Solid Pod.\n *\n * @param publicKey The public key value to set.\n * @param webId The WebID whose profile document references the key set to which we wish to add the specified public key.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @since 1.12.0\n */\nexport async function addPublicKeyToProfileJwks(\n  publicKey: Jwk,\n  webId: WebId,\n  options: { fetch?: typeof fetch } = {},\n): Promise<Blob & WithResourceInfo> {\n  const profileDataset = await getSolidDataset(webId, options);\n  if (profileDataset === null) {\n    throw new Error(\n      `The profile document associated with WebID [${webId}] could not be retrieved.`,\n    );\n  }\n\n  const jwksIri = getProfileJwksIri(profileDataset, webId);\n\n  if (jwksIri === null) {\n    throw new Error(\n      `No key set is declared for the property [${security.publicKey}] in the profile of [${webId}]`,\n    );\n  }\n\n  const updatedJwks = await addJwkToJwks(publicKey, jwksIri, options);\n\n  return overwriteFile(jwksIri, new Blob([JSON.stringify(updatedJwks)]), {\n    contentType: \"application/json\",\n    fetch: options.fetch,\n  });\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type {\n  SolidDataset,\n  UrlString,\n  WebId,\n  WithServerResourceInfo,\n} from \"..\";\nimport { asIri, getIriAll, getSolidDataset, getThing, getThingAll } from \"..\";\nimport { foaf, pim, rdfs } from \"../constants\";\nimport { getSourceIri } from \"../resource/resource\";\n\nexport type ProfileAll<T extends SolidDataset & WithServerResourceInfo> = {\n  webIdProfile: T;\n  altProfileAll: Array<SolidDataset & WithServerResourceInfo>;\n};\n\n/**\n * List all the alternative profiles IRI found in a given WebID profile.\n *\n * Note that some of these profiles may be private, and you may not have access to\n * the resulting resource.\n *\n * @param webId The WebID of the user's whose alternative profiles you are discovering.\n * @param webIdProfile The WebID profile obtained dereferencing the provided WebID.\n * @returns A list of URLs of the user's alternative profiles.\n * @since 1.20.0\n */\nexport function getAltProfileUrlAllFrom(\n  webId: WebId,\n  webIdProfile: SolidDataset,\n): UrlString[] {\n  const webIdThing = getThing(webIdProfile, webId);\n\n  const altProfileUrlAll = getThingAll(webIdProfile)\n    .filter((thing) => getIriAll(thing, foaf.primaryTopic).length > 0)\n    .map(asIri)\n    .concat(webIdThing ? getIriAll(webIdThing, rdfs.seeAlso) : [])\n    .concat(webIdThing ? getIriAll(webIdThing, foaf.isPrimaryTopicOf) : [])\n    .filter((profileIri) => profileIri !== getSourceIri(webIdProfile));\n\n  // Deduplicate the results.\n  return Array.from(new Set(altProfileUrlAll));\n}\n\n/**\n * Get all the Profile Resources discoverable from a WebID Profile.\n *\n * A WebID Profile may be any RDF resource on the Web, it doesn't have\n * to be a Solid resource. That is why, in order to expose a Solid-enabled part\n * of their profile, some WebID profiles link to one or more Extended Profile Resources,\n * which may are Solid resources. A WebID resource should be public, so `getProfileAll` will\n * issue an unauthenticated request to the WebID, and only use the provided\n * authenticated `fetch` (if any) to access extended profile documents.\n *\n * @param webId WebID of the agent you want the profile of.\n * @param options Optional parameter\n *  - `options.webIdProfile`: The data retrieved when looking up the WebID. This\n *    will be fetched if not provided.\n *  - `options.fetch`: An alternative `fetch` function to make the HTTP request,\n *    compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns Promise resolving to an array of [[SolidDataset]], each corresponding\n *  to a personal profile document discoverable from the WebID Profile Document.\n *  If none are found, the WebID profile document itself is returned.\n * @since 1.16.0\n */\nexport async function getProfileAll<\n  T extends SolidDataset & WithServerResourceInfo,\n>(\n  webId: WebId,\n  options?: {\n    fetch?: typeof fetch;\n    webIdProfile?: T;\n  },\n): Promise<ProfileAll<T>>;\nexport async function getProfileAll(\n  webId: WebId,\n  options?: { fetch?: typeof fetch; webIdProfile: undefined },\n): Promise<ProfileAll<SolidDataset & WithServerResourceInfo>>;\nexport async function getProfileAll<\n  T extends SolidDataset & WithServerResourceInfo,\n>(\n  webId: WebId,\n  options?: {\n    fetch?: typeof fetch;\n    webIdProfile?: T;\n  },\n): Promise<ProfileAll<T | (SolidDataset & WithServerResourceInfo)>> {\n  const authFetch = options?.fetch ?? fetch;\n  const webIdProfile =\n    options?.webIdProfile ??\n    // This should always use an unauthenticated fetch.\n    (await getSolidDataset(webId));\n  const altProfileAll = (\n    await Promise.allSettled(\n      getAltProfileUrlAllFrom(webId, webIdProfile).map((uniqueProfileIri) =>\n        getSolidDataset(uniqueProfileIri, { fetch: authFetch }),\n      ),\n    )\n  )\n    // Ignore the alternative profiles lookup which failed.\n    .filter(\n      (result): result is PromiseFulfilledResult<T> =>\n        result.status === \"fulfilled\",\n    )\n    .map((successfulResult) => successfulResult.value);\n\n  return {\n    webIdProfile,\n    altProfileAll,\n  };\n}\n\n/**\n * Discover the Pods an agent advertises for in their profile resources. Both the\n * agent's WebID and alternative profiles are fetched. Note that this function will\n * only return URLs of Pods linked to using the `pim:storage`, i.e. a triple\n * looking like <myWebid, pim:storage, myPodUrl> should appear in the profile\n * resources.\n *\n * @param webId The WebID of the agent whose Pods should be discovered\n * @param options Optional parameter\n * - `options.fetch`: An alternative `fetch` function to make the HTTP request,\n *    compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns a Promise resolving to an array containing the URLs of all the Pods\n * linked from the agent's profile resource using the `pim:storage` predicate.\n * @since 1.18.0\n */\nexport async function getPodUrlAll(\n  webId: WebId,\n  options?: { fetch?: typeof fetch },\n): Promise<UrlString[]> {\n  const profiles = await getProfileAll(webId, options);\n  return getPodUrlAllFrom(profiles, webId);\n}\n\n/**\n * Discover the Pods advertised for in the provided profile resources. Note that\n * this function will only return URLs of Pods linked to using the `pim:storage`\n * predicate, i.e. a triple looking like <myWebid, pim:storage, myPodUrl>\n * should appear in the profile resources.\n *\n * @param profiles The profile resources in which the Pods should be discovered\n * @param webId The WebID of the agent whose Pods should be discovered\n * @returns An array containing the URLs of all the Pods linked from the agent's\n * profile resource using the `pim:storage` predicate.\n * @since 1.18.0\n */\nexport function getPodUrlAllFrom(\n  profiles: ProfileAll<SolidDataset & WithServerResourceInfo>,\n  webId: WebId,\n): UrlString[] {\n  const result: Set<string> = new Set();\n  [profiles.webIdProfile, ...profiles.altProfileAll].forEach(\n    (profileResource) => {\n      const webIdThing = getThing(profileResource, webId);\n      if (webIdThing !== null) {\n        getIriAll(webIdThing, pim.storage).forEach((podIri) =>\n          result.add(podIri),\n        );\n      }\n    },\n  );\n  return Array.from(result);\n}\n\n/**\n * Get the WebID Profile document dataset.\n *\n * @example\n * ```\n * const webId = \"https://example.org/people/me\";\n * const profile = await getWebIdDataset(webId);\n * const podRoot = getPodUrlAllFrom({ webIdProfile: profile, altProfileAll: [] }, webId);\n * const profileThing = getThing(profile, webId);\n * const name = getStringNoLocale(profileThing, FOAF.name);\n * ```\n *\n * @param webId The WebID of the agent whose WebID Profile dataset is to be fetched.\n * @returns a SolidDataset for the WebID Profile document.\n * @since 1.24.0\n */\nexport async function getWebIdDataset(\n  webId: WebId,\n): Promise<ReturnType<typeof getSolidDataset>> {\n  return getSolidDataset(webId);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { WithServerResourceInfo } from \"../interfaces\";\nimport type { DefaultOptions } from \"../acp/type/DefaultOptions\";\nimport { getResourceInfo } from \"../resource/resource\";\n\n/**\n * Retrieve the Server Resource Info of Resource expressing access control over\n * another resource it is linked to. It applies in both ACP and WAC contexts:\n * the Access Control Resource is discovered consistently using a Link header\n * with `rel=acl`.\n *\n * @param {WithServerResourceInfo} resource The Resource for which ACL we want\n * to retrieve the Server Resource Info.\n * @param {DefaultOptions} options\n * @returns The Server Resource Info if available, null otherwise.\n * @since 1.19.0\n */\nexport async function getAclServerResourceInfo(\n  resource: WithServerResourceInfo,\n  options?: DefaultOptions,\n): Promise<WithServerResourceInfo | null> {\n  if (typeof resource.internal_resourceInfo.aclUrl !== \"string\") {\n    return null;\n  }\n  try {\n    return await getResourceInfo(\n      resource.internal_resourceInfo.aclUrl,\n      options,\n    );\n  } catch {\n    // A WAC-governed resource may have a link to a non-existant ACL (by design).\n    // The absence of an ACL at the target URL is a useful information that is\n    // used by the universal API to pick between ACR and WAC.\n    return null;\n  }\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\n/** @hidden */\nexport const ACP_NAMESPACE = \"http://www.w3.org/ns/solid/acp#\";\n\n/** @hidden */\nexport const ACP = {\n  AccessControl: ACP_NAMESPACE.concat(\"AccessControl\"),\n  AccessControlResource: ACP_NAMESPACE.concat(\"AccessControlResource\"),\n  AuthenticatedAgent: ACP_NAMESPACE.concat(\"AuthenticatedAgent\"),\n  CreatorAgent: ACP_NAMESPACE.concat(\"CreatorAgent\"),\n  Matcher: ACP_NAMESPACE.concat(\"Matcher\"),\n  Policy: ACP_NAMESPACE.concat(\"Policy\"),\n  PublicAgent: ACP_NAMESPACE.concat(\"PublicAgent\"),\n  access: ACP_NAMESPACE.concat(\"access\"),\n  accessControl: ACP_NAMESPACE.concat(\"accessControl\"),\n  agent: ACP_NAMESPACE.concat(\"agent\"),\n  allOf: ACP_NAMESPACE.concat(\"allOf\"),\n  allow: ACP_NAMESPACE.concat(\"allow\"),\n  anyOf: ACP_NAMESPACE.concat(\"anyOf\"),\n  apply: ACP_NAMESPACE.concat(\"apply\"),\n  client: ACP_NAMESPACE.concat(\"client\"),\n  deny: ACP_NAMESPACE.concat(\"deny\"),\n  memberAccessControl: ACP_NAMESPACE.concat(\"memberAccessControl\"),\n  noneOf: ACP_NAMESPACE.concat(\"noneOf\"),\n  vc: ACP_NAMESPACE.concat(\"vc\"),\n};\n\n/** @hidden */\nexport const ACL_NAMESPACE = \"http://www.w3.org/ns/auth/acl#\";\n\n/** @hidden */\nexport const ACL = {\n  Append: ACL_NAMESPACE.concat(\"Append\"),\n  Control: ACL_NAMESPACE.concat(\"Control\"),\n  Read: ACL_NAMESPACE.concat(\"Read\"),\n  Write: ACL_NAMESPACE.concat(\"Write\"),\n};\n\n/** @hidden */\nexport const VC_ACCESS_GRANT = \"http://www.w3.org/ns/solid/vc#SolidAccessGrant\";\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport { acp } from \"../constants\";\nimport type {\n  SolidDataset,\n  Thing,\n  ThingPersisted,\n  Url,\n  UrlString,\n  WithResourceInfo,\n  WithServerResourceInfo,\n} from \"../interfaces\";\nimport { hasServerResourceInfo } from \"../interfaces\";\nimport { getSourceUrl } from \"../resource/resource\";\nimport { addIri } from \"../thing/add\";\nimport { getIriAll, getUrlAll } from \"../thing/get\";\nimport { removeAll, removeIri } from \"../thing/remove\";\nimport { createThing, getThing, setThing } from \"../thing/thing\";\nimport type { WithAccessibleAcr } from \"./acp\";\nimport {\n  internal_addMemberPolicyUrl,\n  internal_addPolicyUrl,\n  internal_getAcr,\n  internal_getControlAll,\n  internal_getInitialisedControl,\n  internal_getMemberPolicyUrlAll,\n  internal_getPolicyUrlAll,\n  internal_removeMemberPolicyUrl,\n  internal_removeMemberPolicyUrlAll,\n  internal_removePolicyUrl,\n  internal_removePolicyUrlAll,\n  internal_setAcr,\n  internal_setControl,\n} from \"./control.internal\";\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Given a Resource, check whether it is governed by Access Policies.\n * (Specifically, a Resource that is governed by Access Policies will refer to exactly one Access\n * Control Resource, and expose that to users who are allowed to see or modify access to the given\n * Resource.)\n *\n * @param resource Resource which may or may not be governed by Access Policies.\n * @returns True if the Resource refers to an Access Control Resource and is hence governed by Access Policies, or false if it does not.\n * @since 1.6.0\n */\nexport function hasLinkedAcr<Resource extends WithServerResourceInfo>(\n  resource: Resource,\n): resource is WithLinkedAcr<Resource> {\n  return (\n    hasServerResourceInfo(resource) &&\n    Array.isArray(\n      resource.internal_resourceInfo.linkedResources[acp.accessControl],\n    ) &&\n    resource.internal_resourceInfo.linkedResources[acp.accessControl].length ===\n      1\n  );\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * An Access Control Resource, containing [[Control]]s specifying which [[Policy]]'s\n * apply to the Resource this Access Control Resource is linked to.\n * @since 1.6.0\n */\nexport type AccessControlResource = SolidDataset &\n  WithResourceInfo & { accessTo: UrlString };\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * A Control, usually contained in an [[AccessControlResource]]. It describes which\n * [[Policy]]'s apply to a Resource.\n * @since 1.6.0\n */\nexport type Control = Thing;\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * If this type applies to a Resource, it is governed by an Access Control Resource,\n * and thus not the Web Access Control spec.\n * It does not indicate that this Access Control Resource will also be accessible to the current\n * user.\n * @since 1.6.0\n */\nexport type WithLinkedAcr<\n  Resource extends WithServerResourceInfo = WithServerResourceInfo,\n> = Resource & {\n  internal_resourceInfo: {\n    linkedResources: {\n      [acp.accessControl]: [string];\n    };\n  };\n};\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Add a [[Policy]] to an Access Control Resource such that that [[Policy]] applies to the Access\n * Control Resource itself, rather than the Resource it governs.\n *\n * @param resourceWithAcr The Resource with an Access Control Resource to which the ACR Policy should be added.\n * @param policyUrl URL of the Policy that should apply to the given Access Control Resource.\n * @returns A Resource with a new Access Control Resource equal to the original ACR, but with the given ACR Policy added to it.\n * @since 1.6.0\n */\nexport function addAcrPolicyUrl<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  policyUrl: Url | UrlString | ThingPersisted,\n): ResourceExt {\n  const acr = internal_getAcr(resourceWithAcr);\n  const acrUrl = getSourceUrl(acr);\n\n  let acrThing = getThing(acr, acrUrl) ?? createThing({ url: acrUrl });\n  acrThing = addIri(acrThing, acp.access, policyUrl);\n  const updatedAcr = setThing(acr, acrThing);\n\n  const updatedResource = internal_setAcr(resourceWithAcr, updatedAcr);\n  return updatedResource;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Add a [[Policy]] to a Resource's Access Control Resource such that that\n * Policy applies to the Access Control Resources of child Resources.\n *\n * @param resourceWithAcr The Resource with an Access Control Resource to which the ACR Policy should be added.\n * @param policyUrl URL of the Policy that should apply to the given Access Control Resources of children of the Resource.\n * @returns A Resource with a new Access Control Resource equal to the original ACR, but with the given ACR Policy added to it.\n * @since 1.6.0\n */\nexport function addMemberAcrPolicyUrl<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  policyUrl: Url | UrlString | ThingPersisted,\n): ResourceExt {\n  const acr = internal_getAcr(resourceWithAcr);\n  const acrUrl = getSourceUrl(acr);\n\n  let acrThing = getThing(acr, acrUrl) ?? createThing({ url: acrUrl });\n  acrThing = addIri(acrThing, acp.accessMembers, policyUrl);\n  const updatedAcr = setThing(acr, acrThing);\n\n  const updatedResource = internal_setAcr(resourceWithAcr, updatedAcr);\n  return updatedResource;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get the URLs of the Access Policies that apply to an Access Control Resource itself, rather than\n * to the Resource it governs.\n *\n * @param resourceWithAcr The Resource with the Access Control Resource of which to get the URLs of the Policies that govern access to it.\n * @returns URLs of the Policies that govern access to the given Access Control Resource.\n * @since 1.6.0\n */\nexport function getAcrPolicyUrlAll<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n): UrlString[] {\n  const acr = internal_getAcr(resourceWithAcr);\n  const acrUrl = getSourceUrl(acr);\n\n  const acrThing = getThing(acr, acrUrl);\n  if (acrThing === null) {\n    return [];\n  }\n  return getIriAll(acrThing, acp.access);\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get the URLs of the Access Policies that apply to the Access Control Resources of the Resource's\n * children.\n *\n * @param resourceWithAcr The Resource with the Access Control Resource of which to get the URLs of the Policies that govern access to its children.\n * @returns URLs of the Policies that govern access to the Access Control Resources of the given Resource's children.\n * @since 1.6.0\n */\nexport function getMemberAcrPolicyUrlAll<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n): UrlString[] {\n  const acr = internal_getAcr(resourceWithAcr);\n  const acrUrl = getSourceUrl(acr);\n\n  const acrThing = getThing(acr, acrUrl);\n  if (acrThing === null) {\n    return [];\n  }\n  return getIriAll(acrThing, acp.accessMembers);\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Stop the URL of a given [[Policy]] from applying to an Access Control Resource itself.\n *\n * @param resourceWithAcr The Resource with the Access Control Resource to which the given URL of a Policy should no longer apply.\n * @param policyUrl The URL of the Policy that should no longer apply.\n * @returns A Resource with a new Access Control Resource equal to the original ACR, but with the given ACR Policy removed from it.\n * @since 1.6.0\n */\nexport function removeAcrPolicyUrl<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  policyUrl: Url | UrlString | ThingPersisted,\n): ResourceExt {\n  const acr = internal_getAcr(resourceWithAcr);\n  const acrUrl = getSourceUrl(acr);\n\n  const acrThing = getThing(acr, acrUrl);\n  if (acrThing === null) {\n    return resourceWithAcr;\n  }\n  if (!getIriAll(acrThing, acp.access).includes(policyUrl.toString())) {\n    return resourceWithAcr;\n  }\n  const updatedAcrThing = removeIri(acrThing, acp.access, policyUrl);\n  const updatedAcr = setThing(acr, updatedAcrThing);\n\n  return internal_setAcr(resourceWithAcr, updatedAcr);\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Stop the URL of a given [[Policy]] from applying to the Access Control Resources of the\n * Resource's children.\n *\n * @param resourceWithAcr The Resource with the Access Control Resource to whose children's ACRs the given URL of a Policy should no longer apply.\n * @param policyUrl The URL of the Policy that should no longer apply.\n * @returns A Resource with a new Access Control Resource equal to the original ACR, but with the given member ACR Policy removed from it.\n * @since 1.6.0\n */\nexport function removeMemberAcrPolicyUrl<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  policyUrl: Url | UrlString | ThingPersisted,\n): ResourceExt {\n  const acr = internal_getAcr(resourceWithAcr);\n  const acrUrl = getSourceUrl(acr);\n\n  const acrThing = getThing(acr, acrUrl);\n  if (acrThing === null) {\n    return resourceWithAcr;\n  }\n  if (!getIriAll(acrThing, acp.accessMembers).includes(policyUrl.toString())) {\n    return resourceWithAcr;\n  }\n  const updatedAcrThing = removeIri(acrThing, acp.accessMembers, policyUrl);\n  const updatedAcr = setThing(acr, updatedAcrThing);\n\n  return internal_setAcr(resourceWithAcr, updatedAcr);\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Stop all URL of Access Policies from applying to an Access Control Resource itself.\n *\n * @param resourceWithAcr The Resource with the Access Control Resource to which no more Policies should apply.\n * @returns A Resource with a new Access Control Resource equal to the original ACR, but without any Policy applying to it.\n * @since 1.6.0\n */\nexport function removeAcrPolicyUrlAll<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n): ResourceExt {\n  const acr = internal_getAcr(resourceWithAcr);\n  const acrUrl = getSourceUrl(acr);\n\n  const acrThing = getThing(acr, acrUrl);\n  if (acrThing === null) {\n    return resourceWithAcr;\n  }\n  const updatedAcrThing = removeAll(acrThing, acp.access);\n  const updatedAcr = setThing(acr, updatedAcrThing);\n\n  return internal_setAcr(resourceWithAcr, updatedAcr);\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Stop all URL of Access Policies from applying to the Access Control Resources of the Resource's\n * children.\n *\n * @param resourceWithAcr The Resource with the Access Control Resource that should no longer apply Policies to its children's ACRs.\n * @returns A Resource with a new Access Control Resource equal to the original ACR, but without any Policy applying to its children's ACRs.\n * @since 1.6.0\n */\nexport function removeMemberAcrPolicyUrlAll<\n  ResourceExt extends WithAccessibleAcr,\n>(resourceWithAcr: ResourceExt): ResourceExt {\n  const acr = internal_getAcr(resourceWithAcr);\n  const acrUrl = getSourceUrl(acr);\n\n  const acrThing = getThing(acr, acrUrl);\n  if (acrThing === null) {\n    return resourceWithAcr;\n  }\n  const updatedAcrThing = removeAll(acrThing, acp.accessMembers);\n  const updatedAcr = setThing(acr, updatedAcrThing);\n\n  return internal_setAcr(resourceWithAcr, updatedAcr);\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Add a [[Policy]] to an Access Control Resource such that that [[Policy]] applies to that Resource.\n *\n * @param resourceWithAcr The Resource to which the ACR Policy should be added.\n * @param policyUrl URL of the Policy that should apply to the given Resource.\n * @returns A Resource with a new Access Control Resource equal to the original ACR, but with the given Policy added to it.\n * @since 1.6.0\n */\nexport function addPolicyUrl<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  policyUrl: Url | UrlString,\n): ResourceExt {\n  const control = internal_getInitialisedControl(resourceWithAcr);\n  const updatedControl = internal_addPolicyUrl(control, policyUrl);\n  const updatedResource = internal_setControl(resourceWithAcr, updatedControl);\n  return updatedResource;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Add a [[Policy]] to a Resource's Access Control Resource such that that\n * Policy applies to that Resource's children.\n *\n * @param resourceWithAcr The Resource to whose Access Control Resource the Policy should be added.\n * @param policyUrl URL of the Policy that should apply to the given Resource's children.\n * @returns A new Resource equal to the given Resource, but with the given Member Policy added to its Access Control Resource.\n * @since 1.6.0\n */\nexport function addMemberPolicyUrl<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  policyUrl: Url | UrlString,\n): ResourceExt {\n  const control = internal_getInitialisedControl(resourceWithAcr);\n  const updatedControl = internal_addMemberPolicyUrl(control, policyUrl);\n  const updatedResource = internal_setControl(resourceWithAcr, updatedControl);\n  return updatedResource;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get the URLs of the Access Policies that apply to a Resource.\n *\n * @param resourceWithAcr The Resource with the Access Control Resource of which to get the URLs of the Policies that govern access to it.\n * @returns URLs of the Policies that govern access to the given Resource.\n * @since 1.6.0\n */\nexport function getPolicyUrlAll<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n): UrlString[] {\n  const controls = internal_getControlAll(resourceWithAcr);\n  const policyUrlsByControl = controls.map((control) =>\n    internal_getPolicyUrlAll(control),\n  );\n  const uniquePolicyUrls = new Set<UrlString>();\n  policyUrlsByControl.forEach((policyUrls) => {\n    policyUrls.forEach((url) => uniquePolicyUrls.add(url));\n  });\n  return Array.from(uniquePolicyUrls);\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get the URLs of the Access Policies that apply to a Resource's children.\n *\n * @param resourceWithAcr The Resource with the Access Control Resource of which to get the URLs of the Policies that govern access to its children.\n * @returns URLs of the Policies that govern access to the given Resource's children.\n * @since 1.6.0\n */\nexport function getMemberPolicyUrlAll<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n): UrlString[] {\n  const controls = internal_getControlAll(resourceWithAcr);\n  const memberPolicyUrlsByControl = controls.map((control) =>\n    internal_getMemberPolicyUrlAll(control),\n  );\n  const uniquePolicyUrls = new Set<UrlString>();\n  memberPolicyUrlsByControl.forEach((policyUrls) => {\n    policyUrls.forEach((url) => uniquePolicyUrls.add(url));\n  });\n  return Array.from(uniquePolicyUrls);\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Stop the URL of a given [[Policy]] from applying to a Resource.\n *\n * @param resourceWithAcr The Resource, with its Access Control Resource, to which the given URL of a Policy should no longer apply.\n * @param policyUrl The URL of the Policy that should no longer apply.\n * @returns A Resource with a new Access Control Resource equal to the original ACR, but with the given Policy removed from it.\n * @since 1.6.0\n */\nexport function removePolicyUrl<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  policyUrl: Url | UrlString | ThingPersisted,\n): ResourceExt {\n  const controls = internal_getControlAll(resourceWithAcr);\n  return controls\n    .filter((control) => getUrlAll(control, acp.apply).length > 0)\n    .map((control) => internal_removePolicyUrl(control, policyUrl))\n    .reduce(internal_setControl, resourceWithAcr);\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Stop the URL of a given [[Policy]] from applying to the Resource's children.\n *\n * @param resourceWithAcr The Resource with the Access Control Resource to whose children the given URL of a Policy should no longer apply.\n * @param policyUrl The URL of the Policy that should no longer apply.\n * @returns A Resource with a new Access Control Resource equal to the original ACR, but with the given Member Policy removed from it.\n * @since 1.6.0\n */\nexport function removeMemberPolicyUrl<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  policyUrl: Url | UrlString | ThingPersisted,\n): ResourceExt {\n  const controls = internal_getControlAll(resourceWithAcr);\n  const updatedControls = controls.map((control) =>\n    internal_removeMemberPolicyUrl(control, policyUrl),\n  );\n  const updatedResource = updatedControls.reduce(\n    internal_setControl,\n    resourceWithAcr,\n  );\n  return updatedResource;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Stop all URL of Access Policies from applying to a Resource.\n *\n * @param resourceWithAcr The Resource, with its Access Control Resource, to which no more Policies should apply.\n * @returns A Resource with a new Access Control Resource equal to the original ACR, but without any Policy applying to the Resource.\n * @since 1.6.0\n */\nexport function removePolicyUrlAll<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n): ResourceExt {\n  const controls = internal_getControlAll(resourceWithAcr);\n  const updatedControls = controls.map((control) =>\n    internal_removePolicyUrlAll(control),\n  );\n  const updatedResource = updatedControls.reduce(\n    internal_setControl,\n    resourceWithAcr,\n  );\n  return updatedResource;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Stop all URL of Access Policies from applying to the Resource's children.\n *\n * @param resourceWithAcr The Resource with the Access Control Resource that should no longer apply Policies to its children.\n * @returns A Resource with a new Access Control Resource equal to the original ACR, but without any Policy applying to the Resource's children.\n * @since 1.6.0\n */\nexport function removeMemberPolicyUrlAll<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n): ResourceExt {\n  const controls = internal_getControlAll(resourceWithAcr);\n  const updatedControls = controls.map((control) =>\n    internal_removeMemberPolicyUrlAll(control),\n  );\n  const updatedResource = updatedControls.reduce(\n    internal_setControl,\n    resourceWithAcr,\n  );\n  return updatedResource;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { getSourceUrl } from \"../..\";\nimport { internal_getAcr as getAccessControlResource } from \"../control.internal\";\n\n/** @hidden */\nexport type DefaultAccessControlName =\n  | typeof DEFAULT_ACCESS_CONTROL\n  | typeof DEFAULT_ACR_ACCESS_CONTROL\n  | typeof DEFAULT_MEMBER_ACCESS_CONTROL\n  | typeof DEFAULT_MEMBER_ACR_ACCESS_CONTROL;\n\n/** @hidden */\nexport const DEFAULT_ACCESS_CONTROL = \"defaultAccessControl\";\n\n/** @hidden */\nexport const DEFAULT_ACR_ACCESS_CONTROL = \"defaultAcrAccessControl\";\n\n/** @hidden */\nexport const DEFAULT_MEMBER_ACCESS_CONTROL = \"defaultMemberAccessControl\";\n\n/** @hidden */\nexport const DEFAULT_MEMBER_ACR_ACCESS_CONTROL =\n  \"defaultMemberAcrAccessControl\";\n\n/** @hidden */\nexport function getDefaultAccessControlUrl(\n  resource: WithAccessibleAcr,\n  name: DefaultAccessControlName,\n): string {\n  const acr = getAccessControlResource(resource);\n  const acrUrl = getSourceUrl(acr);\n  return acrUrl.concat(\"#\").concat(name);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { ThingPersisted } from \"../..\";\nimport { createThing, getThing } from \"../..\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { internal_getAcr as getAccessControlResource } from \"../control.internal\";\nimport type { DefaultAccessControlName } from \"./getDefaultAccessControlUrl\";\nimport { getDefaultAccessControlUrl } from \"./getDefaultAccessControlUrl\";\n\n/** @hidden */\nexport function getDefaultAccessControlThing(\n  resource: WithAccessibleAcr,\n  name: DefaultAccessControlName,\n): ThingPersisted {\n  const acr = getAccessControlResource(resource);\n  const defaultAccessControlUrl = getDefaultAccessControlUrl(resource, name);\n\n  const accessControlThing = getThing(acr, defaultAccessControlUrl);\n\n  if (\n    accessControlThing === null ||\n    typeof accessControlThing === \"undefined\"\n  ) {\n    return createThing({ url: defaultAccessControlUrl });\n  }\n\n  return accessControlThing;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes, ThingPersisted } from \"../../interfaces\";\nimport type { ACP } from \"../constants\";\nimport { ACL } from \"../constants\";\nimport { getIriAll } from \"../../thing/get\";\n\n/** @hidden */\nexport type ModeType = typeof ACP.allow | typeof ACP.deny;\n\n/** @hidden */\nexport function getModes<T extends ThingPersisted>(\n  policy: T,\n  type: ModeType,\n): AccessModes {\n  const modes = getIriAll(policy, type);\n\n  return {\n    read: modes.includes(ACL.Read),\n    append: modes.includes(ACL.Append),\n    write: modes.includes(ACL.Write),\n    controlRead: false,\n    controlWrite: false,\n  };\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport { internal_cloneResource } from \"../../resource/resource.internal\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport type { AccessControlResource } from \"../type/AccessControlResource\";\n\n/**\n * @hidden\n *\n * Internal function that attaches an ACR to a Resource. Prefer using this than\n * setting the internal values manually (easier to refactor when changing the internals).\n */\nexport function setAcr<T extends WithAccessibleAcr>(\n  resource: T,\n  acr: AccessControlResource,\n): T {\n  return Object.assign(internal_cloneResource(resource), {\n    internal_acp: {\n      acr,\n    },\n  });\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes, ThingPersisted } from \"../../interfaces\";\nimport { removeAll } from \"../../thing/remove\";\nimport { addIri } from \"../../thing/add\";\nimport { ACL } from \"../constants\";\nimport type { ModeType } from \"./getModes\";\n\n/** @hidden */\nexport function setModes<T extends ThingPersisted>(\n  policy: T,\n  modes: AccessModes,\n  type: ModeType,\n): T {\n  let newPolicy = removeAll(policy, type);\n\n  if (modes.read || modes.controlRead) {\n    newPolicy = addIri(newPolicy, type, ACL.Read);\n  }\n\n  if (modes.append) {\n    newPolicy = addIri(newPolicy, type, ACL.Append);\n  }\n\n  if (modes.write || modes.controlWrite) {\n    newPolicy = addIri(newPolicy, type, ACL.Write);\n  }\n\n  return newPolicy;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { SolidDataset, Thing } from \"../..\";\nimport {\n  addIri,\n  asIri,\n  buildThing,\n  createThing,\n  getIriAll,\n  getSourceIri,\n  getThing,\n  setThing,\n} from \"../..\";\nimport { rdf } from \"../../constants\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP, VC_ACCESS_GRANT } from \"../constants\";\nimport { internal_getAcr } from \"../control.internal\";\nimport { getAccessControlResourceThing } from \"../internal/getAccessControlResourceThing\";\nimport { getDefaultAccessControlThing } from \"../internal/getDefaultAccessControlThing\";\nimport { getModes } from \"../internal/getModes\";\nimport { setAcr } from \"../internal/setAcr\";\nimport { setModes } from \"../internal/setModes\";\nimport type { AccessModes } from \"../../interfaces\";\n\nexport const DEFAULT_VC_POLICY_NAME = \"defaultVcPolicy\";\nexport const DEFAULT_VC_MATCHER_NAME = \"defaultVcMatcher\";\n\nfunction createVcPolicy(\n  acr: SolidDataset,\n  policyIri: string,\n  matcherIri: string,\n  access: Partial<AccessModes>,\n): { policy: Thing; matcher: Thing } {\n  let vcPolicy = getThing(acr, policyIri);\n  if (vcPolicy === null) {\n    // If the policy does not exist, create it and link the default Access Control to it.\n    vcPolicy = buildThing({ url: policyIri })\n      .addIri(rdf.type, ACP.Policy)\n      .addIri(ACP.anyOf, matcherIri)\n      .build();\n  }\n  const vcMatcher: Thing =\n    getThing(acr, matcherIri) ??\n    buildThing({ url: matcherIri })\n      .addIri(rdf.type, ACP.Matcher)\n      .addIri(ACP.vc, VC_ACCESS_GRANT)\n      .build();\n\n  const currentModes = getModes(vcPolicy, ACP.allow);\n  // Only change the modes which are set in `access`, and preserve the others.\n  vcPolicy = setModes(vcPolicy, { ...currentModes, ...access }, ACP.allow);\n  return {\n    matcher: vcMatcher,\n    policy: vcPolicy,\n  };\n}\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Set the maximum access modes that are allowed for a VC holder for a given resource.\n * If the resource owner issued an Access Grant for the resource, the agent that\n * has been granted access will have at most the permissions set by this function.\n * The Access Grant may be more restrictive.\n *\n * Note that additional access may have been set if the ACR has been manipulated\n * not using this library, which is currently out of scope. In this case, the access\n * set by this function may not apply.\n *\n * @param resourceWithAcr The resource for which the access modes are being set for VC holders.\n * @param access The access modes to set. Setting a mode to `true` will enable it, to `false`\n * will disable it, and to `undefined` will leave it unchanged compared to what was previously\n * set.\n * @param options An option object to customize the function behavior:\n *  - inherit: if set to `true`, the access set to the target resource cascades\n *    to its contained resources.\n * @returns A copy of the resource and its attached ACR, updated to the new access modes.\n * @since 1.17.0\n */\nexport function setVcAccess(\n  resourceWithAcr: WithAccessibleAcr,\n  access: Partial<AccessModes>,\n  options: {\n    inherit: boolean;\n  } = { inherit: false },\n): WithAccessibleAcr {\n  let acr = internal_getAcr(resourceWithAcr);\n  const defaultVcPolicyIri = `${getSourceIri(acr)}#${DEFAULT_VC_POLICY_NAME}`;\n  const defaultVcMatcherIri = `${getSourceIri(acr)}#${DEFAULT_VC_MATCHER_NAME}`;\n\n  const { policy, matcher } = createVcPolicy(\n    acr,\n    defaultVcPolicyIri,\n    defaultVcMatcherIri,\n    access,\n  );\n\n  let accessControl = getDefaultAccessControlThing(\n    resourceWithAcr,\n    \"defaultAccessControl\",\n  );\n  if (!getIriAll(accessControl, ACP.apply).includes(asIri(policy))) {\n    // Case when the ACR Thing existed, but did not include a link to the default Access Control.\n    accessControl = addIri(accessControl, ACP.apply, policy);\n  }\n\n  let memberAccessControl = getDefaultAccessControlThing(\n    resourceWithAcr,\n    \"defaultMemberAccessControl\",\n  );\n\n  let acrThing =\n    getAccessControlResourceThing(resourceWithAcr) ??\n    createThing({ url: getSourceIri(acr) });\n\n  if (!getIriAll(acrThing, ACP.accessControl).includes(asIri(accessControl))) {\n    // Case when the ACR Thing existed, but did not include a link to the default Access Control.\n    acrThing = addIri(acrThing, ACP.accessControl, accessControl);\n  }\n\n  // Write the changed access control, policy and matchers in the ACR\n  acr = [acrThing, accessControl, policy, matcher].reduce(setThing, acr);\n\n  if (options.inherit) {\n    // Add triples to the member access control and link it to the ACR only\n    // if the VC access is recursive if they don't exist already.\n    if (!getIriAll(memberAccessControl, ACP.apply).includes(asIri(policy))) {\n      memberAccessControl = addIri(memberAccessControl, ACP.apply, policy);\n    }\n    if (\n      !getIriAll(acrThing, ACP.memberAccessControl).includes(\n        asIri(memberAccessControl),\n      )\n    ) {\n      acrThing = addIri(acrThing, ACP.memberAccessControl, memberAccessControl);\n    }\n\n    acr = [acrThing, memberAccessControl].reduce(setThing, acr);\n  }\n\n  return setAcr(resourceWithAcr, acr);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Thing, UrlString } from \"../..\";\nimport { getSourceIri } from \"../../resource/resource\";\nimport { getIriAll } from \"../../thing/get\";\nimport { asIri, getThing } from \"../../thing/thing\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { internal_getAcr } from \"../control.internal\";\nimport { getAccessControlResourceThing } from \"../internal/getAccessControlResourceThing\";\nimport { getDefaultAccessControlThing } from \"../internal/getDefaultAccessControlThing\";\nimport { getModes } from \"../internal/getModes\";\nimport type { AccessModes } from \"../../interfaces\";\nimport { DEFAULT_VC_MATCHER_NAME, DEFAULT_VC_POLICY_NAME } from \"./setVcAccess\";\n\nconst DEFAULT_NO_ACCESS: AccessModes = {\n  read: false,\n  append: false,\n  write: false,\n  controlRead: false,\n  controlWrite: false,\n};\n\nconst linkExists = (\n  subject: Thing,\n  predicate: UrlString,\n  object: Thing,\n): boolean => getIriAll(subject, predicate).includes(asIri(object));\n\n// TODO: It should be possible to write a `chainExists` function, taking in a chain\n// of Thing, predicate, Thing, predicate... and checks whether such chain exists\n// in a given dataset. It would make the following function much easier to read,\n// instead of checking at each link that it isn't null and it is connected to the\n// next link.\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Get the maximum access modes that are allowed for a VC holder for a given resource.\n * If the resource owner issued an Access Grant for the resource, the agent that\n * has been granted access will have at most the permissions returned by this function.\n * The Access Grant may be more restrictive.\n *\n * Note that only the modes set using [[setVcAccess]] will be returned by this function.\n * Additional access may have been set if the ACR has been manipulated not using this\n * library, which is currently out of scope.\n *\n * @param resourceWithAcr The resource for which the VC access modes are looked up.\n * @returns The access modes available to a VC holder.\n * @since 1.17.0\n */\nexport function getVcAccess(resourceWithAcr: WithAccessibleAcr): AccessModes {\n  const acr = internal_getAcr(resourceWithAcr);\n\n  const accessControl = getDefaultAccessControlThing(\n    resourceWithAcr,\n    \"defaultAccessControl\",\n  );\n\n  const acrThing = getAccessControlResourceThing(resourceWithAcr);\n\n  if (\n    acrThing === null ||\n    !linkExists(acrThing, ACP.accessControl, accessControl)\n  ) {\n    return DEFAULT_NO_ACCESS;\n  }\n\n  const defaultVcPolicyIri = `${getSourceIri(acr)}#${DEFAULT_VC_POLICY_NAME}`;\n  const vcPolicy = getThing(acr, defaultVcPolicyIri);\n  if (vcPolicy === null || !linkExists(accessControl, ACP.apply, vcPolicy)) {\n    return DEFAULT_NO_ACCESS;\n  }\n\n  const defaultVcMatcherIri = `${getSourceIri(acr)}#${DEFAULT_VC_MATCHER_NAME}`;\n  const vcMatcher = getThing(acr, defaultVcMatcherIri);\n  if (vcMatcher === null || !linkExists(vcPolicy, ACP.anyOf, vcMatcher)) {\n    return DEFAULT_NO_ACCESS;\n  }\n\n  return getModes(vcPolicy, ACP.allow);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport { acp } from \"../constants\";\nimport type {\n  SolidDataset,\n  File,\n  Url,\n  UrlString,\n  WithServerResourceInfo,\n  WithResourceInfo,\n} from \"../interfaces\";\nimport { hasServerResourceInfo } from \"../interfaces\";\nimport { internal_toIriString } from \"../interfaces.internal\";\nimport { getFile } from \"../resource/file\";\nimport { getResourceInfo, getSourceUrl } from \"../resource/resource\";\nimport type { WithAcl } from \"../acl/acl\";\nimport { hasAccessibleAcl } from \"../acl/acl\";\nimport { internal_fetchAcl, internal_setAcl } from \"../acl/acl.internal\";\nimport { getSolidDataset, saveSolidDatasetAt } from \"../resource/solidDataset\";\nimport type { AccessControlResource } from \"./control\";\nimport {\n  getAcrPolicyUrlAll,\n  getMemberAcrPolicyUrlAll,\n  getMemberPolicyUrlAll,\n  getPolicyUrlAll,\n  hasLinkedAcr,\n} from \"./control\";\nimport { internal_getAcr, internal_setAcr } from \"./control.internal\";\nimport { normalizeServerSideIri } from \"../resource/iri.internal\";\nimport { isAcr } from \"./acp.internal\";\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Fetch a SolidDataset and its associated Access Control Resource (if available to the current user).\n *\n * @param url URL of the SolidDataset to fetch.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns A SolidDataset and the ACR that applies to it, if available to the authenticated user.\n * @since 1.6.0\n */\nexport async function getSolidDatasetWithAcr(\n  url: Url | UrlString,\n  options?: { fetch?: typeof fetch },\n): Promise<SolidDataset & WithServerResourceInfo & WithAcp> {\n  const urlString = internal_toIriString(url);\n  const solidDataset = await getSolidDataset(urlString, options);\n  const acp = await fetchAcr(solidDataset, options);\n  return { ...solidDataset, ...acp };\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Fetch a file and its associated Access Control Resource (if available to the current user).\n *\n * @param url URL of the file to fetch.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns A file and the ACR that applies to it, if available to the authenticated user.\n * @since 1.6.0\n */\nexport async function getFileWithAcr(\n  url: Url | UrlString,\n  options?: { fetch: typeof fetch },\n): Promise<File & WithAcp> {\n  const urlString = internal_toIriString(url);\n\n  const file = await getFile(urlString, options);\n  const acp = await fetchAcr(file, options);\n  return Object.assign(file, acp);\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Retrieve information about a Resource and its associated Access Control Resource (if available to\n * the current user), without fetching the Resource itself.\n *\n * @param url URL of the Resource about which to fetch its information.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns Metadata describing a Resource, and the ACR that applies to it, if available to the authenticated user.\n * @since 1.6.0\n */\nexport async function getResourceInfoWithAcr(\n  url: Url | UrlString,\n  options?: { fetch?: typeof fetch },\n): Promise<WithServerResourceInfo & WithAcp> {\n  const urlString = internal_toIriString(url);\n  const resourceInfo = await getResourceInfo(urlString, options);\n  const acp = await fetchAcr(resourceInfo, options);\n  return { ...resourceInfo, ...acp };\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Fetch a SolidDataset, and:\n * - if the Resource is governed by an ACR: its associated Access Control Resource (if available to\n *                                          the current user), and all the Access Control Policies\n *                                          referred to therein, if available to the current user.\n * - if the Resource is governed by an ACL: its associated Resource ACL (if available to the current\n *                                          user), or its Fallback ACL if it does not exist.\n *\n * @param url URL of the SolidDataset to fetch.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns A SolidDataset and either the ACL access data or the ACR access data, if available to the current user.\n * @since 1.6.0\n */\nexport async function getSolidDatasetWithAccessDatasets(\n  url: Url | UrlString,\n  options?: { fetch?: typeof fetch },\n): Promise<SolidDataset & (WithAcp | WithAcl)> {\n  const urlString = internal_toIriString(url);\n  const solidDataset = await getSolidDataset(urlString, options);\n  if (hasAccessibleAcl(solidDataset)) {\n    const acl = await internal_fetchAcl(solidDataset, options);\n    return internal_setAcl(solidDataset, acl);\n  }\n  const acr = await fetchAcr(solidDataset, options);\n  return { ...solidDataset, ...acr };\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Fetch a File, and:\n * - if the Resource is governed by an ACR: its associated Access Control Resource (if available to\n *                                          the current user), and all the Access Control Policies\n *                                          referred to therein, if available to the current user.\n * - if the Resource is governed by an ACL: its associated Resource ACL (if available to the current\n *                                          user), or its Fallback ACL if it does not exist.\n *\n * @param url URL of the File to fetch.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns A File and either the ACL access data or the ACR access data, if available to the current user.\n * @since 1.6.0\n */\nexport async function getFileWithAccessDatasets(\n  url: Url | UrlString,\n  options?: { fetch?: typeof fetch },\n): Promise<File & (WithAcp | WithAcl)> {\n  const urlString = internal_toIriString(url);\n  const file = await getFile(urlString, options);\n  if (hasAccessibleAcl(file)) {\n    const acl = await internal_fetchAcl(file, options);\n    return internal_setAcl(file, acl);\n  }\n  const acr = await fetchAcr(file, options);\n  return Object.assign(file, acr);\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Fetch information about a Resource, and:\n * - if the Resource is governed by an ACR: its associated Access Control Resource (if available to\n *                                          the current user), and all the Access Control Policies\n *                                          referred to therein, if available to the current user.\n * - if the Resource is governed by an ACL: its associated Resource ACL (if available to the current\n *                                          user), or its Fallback ACL if it does not exist.\n *\n * @param url URL of the Resource information about which to fetch.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns Information about a Resource and either the ACL access data or the ACR access data, if available to the current user.\n * @since 1.6.0\n */\nexport async function getResourceInfoWithAccessDatasets(\n  url: Url | UrlString,\n  options?: { fetch?: typeof fetch },\n): Promise<WithServerResourceInfo & (WithAcp | WithAcl)> {\n  const urlString = internal_toIriString(url);\n  const resourceInfo = await getResourceInfo(urlString, options);\n  if (hasAccessibleAcl(resourceInfo)) {\n    const acl = await internal_fetchAcl(resourceInfo, options);\n    return internal_setAcl(resourceInfo, acl);\n  }\n  const acr = await fetchAcr(resourceInfo, options);\n  return { ...resourceInfo, ...acr };\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Save a Resource's Access Control Resource.\n *\n * @param resource Resource with an Access Control Resource that should be saved.\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @since 1.6.0\n */\nexport async function saveAcrFor<ResourceExt extends WithAccessibleAcr>(\n  resource: ResourceExt,\n  options?: { fetch?: typeof fetch },\n): Promise<ResourceExt> {\n  const acr = internal_getAcr(resource);\n  const savedAcr = await saveSolidDatasetAt(getSourceUrl(acr), acr, options);\n  return internal_setAcr(resource, savedAcr);\n}\n\n/**\n * The Access Control Resource of Resources that conform to this type were attempted to be fetched together with those Resources. This might not have been successful; see [[hasAccessibleAcr]] to check.\n * @since 1.6.0\n */\nexport type WithAcp = {\n  internal_acp: {\n    acr: AccessControlResource | null;\n  };\n};\n/**\n * Resources that conform to this type have an Access Control Resource attached. See [[hasAccessibleAcr]].\n * @since 1.6.0\n */\nexport type WithAccessibleAcr = WithAcp & {\n  internal_acp: {\n    acr: Exclude<WithAcp[\"internal_acp\"][\"acr\"], null>;\n  };\n};\n\n/**\n * @param resource Resource of which to check whether it has an Access Control Resource attached.\n * @returns Boolean representing whether the given Resource has an Access Control Resource attached for use in e.g. [[getPolicyUrlAll]].\n * @since 1.6.0\n */\nexport function hasAccessibleAcr(\n  resource: WithAcp,\n): resource is WithAccessibleAcr {\n  return (\n    typeof resource.internal_acp === \"object\" &&\n    resource.internal_acp !== null &&\n    typeof resource.internal_acp.acr === \"object\" &&\n    resource.internal_acp.acr !== null\n  );\n}\n\nasync function fetchAcr(\n  resource: WithServerResourceInfo,\n  options?: { fetch?: typeof fetch },\n): Promise<WithAcp> {\n  let acrUrl: UrlString | undefined;\n  if (hasLinkedAcr(resource)) {\n    // Whereas a Resource can generally have multiple linked Resources for the same relation,\n    // it can only have one Access Control Resource for that ACR to be valid.\n    // Hence the accessing of [0] directly:\n    const { linkedResources } = resource.internal_resourceInfo;\n    [acrUrl] = linkedResources[acp.accessControl];\n  } else if (hasAccessibleAcl(resource)) {\n    // The ACP proposal will be updated to expose the Access Control Resource\n    // via a Link header with rel=\"acl\", just like WAC. That means that if\n    // an ACL is advertised, we can still fetch its metadata — if that indicates\n    // that it's actually an ACP Access Control Resource, then we can fetch that\n    // instead.\n    let aclResourceInfo;\n    try {\n      aclResourceInfo = await getResourceInfo(\n        resource.internal_resourceInfo.aclUrl,\n        options,\n      );\n    } catch {\n      // Since both ACL and ACR will be discovered through the same header, we\n      // need to ignore errors here so that in the case of ACL not found, the\n      // code can resume and a new ACL can be initialized. The case for ACR is\n      // covered in the code below, since in this case the ACR is always present\n    }\n\n    if (aclResourceInfo && isAcr(aclResourceInfo)) {\n      acrUrl = getSourceUrl(aclResourceInfo);\n    }\n  }\n  // If the Resource doesn't advertise an ACR via the old Link header,\n  // nor via a rel=\"acl\" header, then return, indicating that no ACR could be\n  // fetched:\n  if (typeof acrUrl !== \"string\") {\n    return {\n      internal_acp: {\n        acr: null,\n      },\n    };\n  }\n  let acr: SolidDataset & WithResourceInfo;\n  try {\n    acr = await getSolidDataset(acrUrl, options);\n  } catch {\n    return {\n      internal_acp: {\n        acr: null,\n      },\n    };\n  }\n\n  const acrDataset: AccessControlResource = {\n    ...acr,\n    accessTo: getSourceUrl(resource),\n  };\n  const acpInfo: WithAccessibleAcr = {\n    internal_acp: {\n      acr: acrDataset,\n    },\n  };\n  return acpInfo;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * To make it easy to fetch all the relevant Access Policy Resources,\n * this function returns all referenced Access Policy Resources referenced in an\n * Access Control Resource.\n * In other words, if Access Controls refer to different Policies in the same\n * Access Policy Resource, this function will only return that Access Policy\n * Resource's URL once.\n *\n * @param withAcr A Resource with an Access Control Resource attached.\n * @returns List of all unique Access Policy Resources that are referenced in the given Access Control Resource.\n * @since 1.6.0\n */\nexport function getReferencedPolicyUrlAll(\n  withAcr: WithAccessibleAcr,\n): UrlString[] {\n  const policyUrls: UrlString[] = getPolicyUrlAll(withAcr)\n    .map(normalizeServerSideIri)\n    .concat(getMemberPolicyUrlAll(withAcr).map(normalizeServerSideIri))\n    .concat(getAcrPolicyUrlAll(withAcr).map(normalizeServerSideIri))\n    .concat(getMemberAcrPolicyUrlAll(withAcr).map(normalizeServerSideIri));\n\n  const uniqueUrls = Array.from(new Set(policyUrls));\n  return uniqueUrls;\n}\n\n/**\n * Verify whether the access to the given resource is controlled using the ACP\n * system.\n * @param resource The target resource\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns True if the access to the resource is controlled using ACP, false otherwise.\n * @since 1.14.0.\n */\nexport async function isAcpControlled(\n  resource: Url | UrlString,\n  options?: { fetch?: typeof fetch },\n): Promise<boolean> {\n  const urlString = internal_toIriString(resource);\n  const resourceInfo = await getResourceInfo(urlString, options);\n  return hasAccessibleAcr(await fetchAcr(resourceInfo, options));\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Given a Resource, find out the URL of its governing Access Control Resource.\n *\n * @param resource Resource which should be governed by Access Policies.\n * @returns The URL of the Access Control Resource, or undefined if not ACR is found.\n * @since 1.15.0\n */\nexport function getLinkedAcrUrl<Resource extends WithServerResourceInfo>(\n  resource: Resource,\n): UrlString | undefined {\n  if (!hasServerResourceInfo(resource)) {\n    return undefined;\n  }\n  // Two rels types are acceptable to indicate a link to an ACR.\n  const acrLinks = [acp.accessControl, \"acl\"].map((rel) => {\n    if (\n      Array.isArray(resource.internal_resourceInfo.linkedResources[rel]) &&\n      resource.internal_resourceInfo.linkedResources[rel].length === 1\n    ) {\n      return resource.internal_resourceInfo.linkedResources[rel][0];\n    }\n\n    return undefined;\n  });\n  return acrLinks.find((x) => x !== undefined);\n}\n\n// This file currently acts as an index for the `acp` module.\nexport { getVcAccess } from \"./util/getVcAccess\";\nexport { setVcAccess } from \"./util/setVcAccess\";\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport { acp, rdf } from \"../constants\";\nimport type { ThingPersisted, Url, UrlString } from \"../interfaces\";\nimport { getSourceUrl } from \"../resource/resource\";\nimport { internal_cloneResource } from \"../resource/resource.internal\";\nimport { addIri } from \"../thing/add\";\nimport { getIriAll, getUrlAll } from \"../thing/get\";\nimport { removeAll, removeIri } from \"../thing/remove\";\nimport { setIri } from \"../thing/set\";\nimport {\n  asIri,\n  createThing,\n  getThing,\n  getThingAll,\n  setThing,\n} from \"../thing/thing\";\nimport type { WithAccessibleAcr, WithAcp } from \"./acp\";\nimport { hasAccessibleAcr } from \"./acp\";\nimport type { AccessControlResource, Control } from \"./control\";\n\n/** @hidden */\nexport function internal_getAcr(\n  resource: WithAccessibleAcr,\n): AccessControlResource {\n  if (!hasAccessibleAcr(resource)) {\n    throw new Error(\n      `An Access Control Resource for [${getSourceUrl(\n        resource,\n      )}] is not available. This could be because the current user is not allowed to see it, or because their Pod Server does not support Access Control Resources.`,\n    );\n  }\n  return resource.internal_acp.acr;\n}\n\n/** @hidden */\nexport function internal_setAcr<ResourceExt extends WithAcp>(\n  resource: ResourceExt,\n  acr: AccessControlResource,\n): ResourceExt & WithAccessibleAcr {\n  return Object.assign(internal_cloneResource(resource), {\n    internal_acp: {\n      ...resource.internal_acp,\n      acr,\n    },\n  });\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Initialise a new [[Control]].\n * @hidden Developers don't need to care about initialising Controls - they can just add Policies directly.\n * @deprecated\n */\nexport function internal_createControl(\n  options?: Parameters<typeof createThing>[0],\n): Control {\n  let control = createThing(options);\n  control = setIri(control, rdf.type, acp.AccessControl);\n  return control;\n}\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Find an [[Control]] with a given URL in a given Resource with an Access Control Resource.\n *\n * @returns The requested Access Control, or `null` if it could not be found.\n * @hidden Developers don't need to care about initialising Controls - they can just add Policies directly.\n * @deprecated\n */\nexport function internal_getControl(\n  withAccessControlResource: WithAccessibleAcr,\n  url: Parameters<typeof getThing>[1],\n  options?: Parameters<typeof getThing>[2],\n): Control | null {\n  const acr = internal_getAcr(withAccessControlResource);\n  const foundThing = getThing(acr, url, options);\n  if (\n    foundThing === null ||\n    !getIriAll(foundThing, rdf.type).includes(acp.AccessControl)\n  ) {\n    return null;\n  }\n\n  return foundThing;\n}\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get all [[Control]]s in the Access Control Resource of a given Resource.\n * @hidden Developers don't need to care about initialising Controls - they can just add Policies directly.\n * @deprecated\n */\nexport function internal_getControlAll(\n  withAccessControlResource: WithAccessibleAcr,\n  options?: Parameters<typeof getThingAll>[1],\n): Control[] {\n  const acr = internal_getAcr(withAccessControlResource);\n  const foundThings = getThingAll(acr, options);\n\n  const explicitAccessControl = foundThings.filter((foundThing) =>\n    getIriAll(foundThing, rdf.type).includes(acp.AccessControl),\n  );\n\n  const implicitAccessControl = foundThings\n    .filter((foundThing) => getIriAll(foundThing, acp.accessControl).length > 0)\n    .map((thingWithAccessControl) => {\n      // The initial filter ensures that at least one AccessControl will be found.\n      const controlIri = getIriAll(\n        thingWithAccessControl,\n        acp.accessControl,\n      )[0];\n      // The found control is only an object in the current dataset, so we create the\n      // associated thing in order to possibly make it a subject.\n      return createThing({ url: controlIri });\n    });\n\n  return explicitAccessControl.concat(implicitAccessControl);\n}\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Insert an [[Control]] into the [[AccessControlResource]] of a Resource, replacing previous\n * instances of that Access Control.\n *\n * @param withAccessControlResource A Resource with the Access Control Resource into which to insert an Access Control.\n * @param control The Control to insert into the Access Control Resource.\n * @returns The given Resource with a new Access Control Resource equal to the original Access Control Resource, but with the given Access Control.\n * @hidden Developers don't need to care about initialising Controls - they can just add Policies directly.\n * @deprecated\n */\nexport function internal_setControl<ResourceExt extends WithAccessibleAcr>(\n  withAccessControlResource: ResourceExt,\n  control: Control,\n): ResourceExt {\n  const acr = internal_getAcr(withAccessControlResource);\n  let updatedAcr = setThing(acr, control);\n  const acrSubj = getThing(updatedAcr, getSourceUrl(acr));\n  // If the ACR has an anchor node, link the Access Control.\n  if (\n    acrSubj !== null &&\n    getUrlAll(acrSubj, acp.accessControl).every(\n      (object) => object.toString() !== asIri(control, getSourceUrl(acr)),\n    )\n  ) {\n    updatedAcr = setThing(\n      updatedAcr,\n      addIri(acrSubj, acp.accessControl, asIri(control, getSourceUrl(acr))),\n    );\n  }\n  const updatedResource = internal_setAcr(\n    withAccessControlResource,\n    updatedAcr,\n  );\n  return updatedResource;\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Add a [[Policy]] to an [[Control]] such that that Policy applies to the Resource to which\n * the [[Control]] is linked.\n *\n * @param accessControl The [[Control]] to which the Policy should be added.\n * @param policyUrl URL of the Policy that should apply to the Resource to which the [[Control]] is linked.\n * @returns A new [[Control]] equal to the given [[Control]], but with the given policy added to it.\n * @hidden Developers don't need to care about working with Controls - they can just add Policies to the Resource directly.\n * @deprecated\n */\nexport function internal_addPolicyUrl(\n  accessControl: Control,\n  policyUrl: Url | UrlString | ThingPersisted,\n): Control {\n  return addIri(accessControl, acp.apply, policyUrl);\n}\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get all Policies that apply to the Resource to which the given [[Control]] is linked, and\n * which can be removed by anyone with Write access to the Access Control Resource that contains the\n * [[Control]].\n *\n * @param accessControl The [[Control]] of which to get the Policies.\n * @returns The Policies that are listed in this [[Control]] as applying to the Resource it is linked to, and as removable by anyone with Write access to the Access Control Resource.\n * @hidden Developers don't need to care about working with Controls - they can just add Policies to the Resource directly.\n * @deprecated\n */\nexport function internal_getPolicyUrlAll(accessControl: Control): UrlString[] {\n  return getIriAll(accessControl, acp.apply);\n}\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Remove a given Policy that applies to the Resource to which the given [[Control]] is linked,\n * and which can be removed by anyone with Write access to the Access Control Resource that contains\n * the Access Control.\n *\n * @param accessControl The [[Control]] of which to remove the Policies.\n * @param policyUrl URL of the Policy that should no longer apply to the Resource to which the [[Control]] is linked.\n * @returns A new [[Control]] equal to the given [[Control]], but with the given Policy removed from it.\n * @hidden Developers don't need to care about working with Controls - they can just add Policies to the Resource directly.\n * @deprecated\n */\nexport function internal_removePolicyUrl(\n  accessControl: Control,\n  policyUrl: Url | UrlString | ThingPersisted,\n): Control {\n  return removeIri(accessControl, acp.apply, policyUrl);\n}\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Remove all Policies that apply to the Resource to which the given [[Control]] is linked, and\n * which can be removed by anyone with Write access to the Access Control Resource that contains the\n * [[Control]].\n *\n * @param accessControl The [[Control]] of which to remove the Policies.\n * @returns A new [[Control]] equal to the given [[Control]], but with all Policies removed from it.\n * @hidden Developers don't need to care about working with Controls - they can just add Policies to the Resource directly.\n * @deprecated\n */\nexport function internal_removePolicyUrlAll(accessControl: Control): Control {\n  return removeAll(accessControl, acp.apply);\n}\n\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Add a [[Policy]] to an [[Control]] such that that Policy applies to the children of the\n * Resource to which the [[Control]] is linked.\n *\n * @param accessControl The [[Control]] to which the Policy should be added.\n * @param policyUrl URL of the Policy that should apply to the children of the Resource to which the [[Control]] is linked.\n * @returns A new [[Control]] equal to the given [[Control]], but with the given policy added to it as a Member Policy.\n * @hidden Developers don't need to care about working with Controls - they can just add Policies to the Resource directly.\n * @deprecated\n */\nexport function internal_addMemberPolicyUrl(\n  accessControl: Control,\n  policyUrl: Url | UrlString | ThingPersisted,\n): Control {\n  return addIri(accessControl, acp.applyMembers, policyUrl);\n}\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get all Policies that apply to the children of the Resource to which the given [[Control]] is\n * linked, and which can be removed by anyone with Write access to the Access Control Resource that\n * contains the [[Control]].\n *\n * @param accessControl The [[Control]] of which to get the Policies.\n * @returns The Policies that are listed in this [[Control]] as applying to the children of the Resource it is linked to, and as removable by anyone with Write access to the Access Control Resource.\n * @hidden Developers don't need to care about working with Controls - they can just add Policies to the Resource directly.\n * @deprecated\n */\nexport function internal_getMemberPolicyUrlAll(\n  accessControl: Control,\n): UrlString[] {\n  return getIriAll(accessControl, acp.applyMembers);\n}\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Remove a given Policy that applies to the children of the Resource to which the given Access\n * Control is linked, and which can be removed by anyone with Write access to the Access Control\n * Resource that contains the Access Control.\n *\n * @param accessControl The [[Control]] of which to remove the Member Policy.\n * @param policyUrl URL of the Member Policy that should no longer apply to the Resource to which the [[Control]] is linked.\n * @returns A new [[Control]] equal to the given [[Control]], but with the given Member Policy removed from it.\n * @hidden Developers don't need to care about working with Controls - they can just add Policies to the Resource directly.\n * @deprecated\n */\nexport function internal_removeMemberPolicyUrl(\n  accessControl: Control,\n  policyUrl: Url | UrlString | ThingPersisted,\n): Control {\n  return removeIri(accessControl, acp.applyMembers, policyUrl);\n}\n/**\n * ```{note} The Web Access Control specification is not yet finalised. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Remove all Policies that apply to the children of the Resource to which the given Access Control\n * is linked, and which can be removed by anyone with Write access to the Access Control Resource\n * that contains the Access Control.\n *\n * @param accessControl The [[Control]] of which to remove the Member Policies.\n * @returns A new [[Control]] equal to the given [[Control]], but with all Member Policies removed from it.\n * @hidden Developers don't need to care about working with Controls - they can just add Policies to the Resource directly.\n * @deprecated\n */\nexport function internal_removeMemberPolicyUrlAll(\n  accessControl: Control,\n): Control {\n  return removeAll(accessControl, acp.applyMembers);\n}\n\nexport function internal_getInitialisedControl(\n  resourceWithAcr: WithAccessibleAcr,\n): Control {\n  const allControls = internal_getControlAll(resourceWithAcr);\n  return allControls.length === 0 ? internal_createControl() : allControls[0];\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { ThingPersisted } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { getSourceUrl } from \"../../resource/resource\";\nimport { getThing } from \"../../thing/thing\";\nimport { internal_getAcr as getAccessControlResource } from \"../control.internal\";\n\n/** @hidden */\nexport function getAccessControlResourceThing(\n  resource: WithAccessibleAcr,\n): ThingPersisted | null {\n  const acr = getAccessControlResource(resource);\n  const acrUrl = getSourceUrl(acr);\n\n  return getThing(acr, acrUrl);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport { ACP } from \"../constants\";\nimport type { UrlString } from \"../../interfaces\";\nimport { getIriAll } from \"../../thing/get\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { getAccessControlResourceThing } from \"../internal/getAccessControlResourceThing\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Get the URL of all access controls linked to the given resource's ACR.\n *\n * @param resourceWithAcr The resource for which to retrieve URLs of access\n * controls applying to it.\n * @returns Access Control URL array\n * @since 1.6.0\n */\nexport function getAccessControlUrlAll(\n  resourceWithAcr: WithAccessibleAcr,\n): UrlString[] {\n  const acrThing = getAccessControlResourceThing(resourceWithAcr);\n\n  if (acrThing === null) {\n    return [];\n  }\n\n  return getIriAll(acrThing, ACP.accessControl);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { UrlString } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport type { ACP } from \"../constants\";\nimport { getIriAll } from \"../../thing/get\";\nimport { getThing } from \"../../thing/thing\";\nimport { internal_getAcr as getAccessControlResource } from \"../control.internal\";\n\n/** @hidden */\ntype PolicyType = typeof ACP.apply | typeof ACP.access;\n\n/** @hidden */\nexport function getPolicyUrls(\n  resource: WithAccessibleAcr,\n  accessControlUrls: UrlString[],\n  type: PolicyType,\n): string[] {\n  const acr = getAccessControlResource(resource);\n\n  return Array.from(\n    new Set(\n      accessControlUrls\n        .map((accessControlUrl) => {\n          const accessControlThing = getThing(acr, accessControlUrl);\n          // istanbul ignore next\n          if (accessControlThing !== null) {\n            return getIriAll(accessControlThing, type);\n          }\n          // istanbul ignore next\n          return [];\n        })\n        .reduce(\n          (previousValue, currentValue) => previousValue.concat(currentValue),\n          [],\n        ),\n    ),\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { UrlString } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { getAccessControlUrlAll } from \"../accessControl/getAccessControlUrlAll\";\nimport { getPolicyUrls } from \"../internal/getPolicyUrls\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Get the URLs of policies applying to the given resource.\n *\n * @param resourceWithAcr The resource for which to retrieve URLs of policies\n * applying to it.\n * @returns Policy URL array.\n * @since 1.16.1\n */\nexport function getPolicyUrlAll(\n  resourceWithAcr: WithAccessibleAcr,\n): UrlString[] {\n  return getPolicyUrls(\n    resourceWithAcr,\n    getAccessControlUrlAll(resourceWithAcr),\n    ACP.apply,\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { UrlString } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { getAccessControlUrlAll } from \"../accessControl/getAccessControlUrlAll\";\nimport { getPolicyUrls } from \"../internal/getPolicyUrls\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Get the URLs of policies applying to the ACR of the given resource.\n *\n * @param resourceWithAcr The resource for which to retrieve URLs of policies\n * applying to its access control resource.\n * @returns Policy URL array.\n * @since 1.16.1\n */\nexport function getAcrPolicyUrlAll<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n): UrlString[] {\n  return getPolicyUrls(\n    resourceWithAcr,\n    getAccessControlUrlAll(resourceWithAcr),\n    ACP.access,\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes, ThingPersisted } from \"../../interfaces\";\nimport { ACP } from \"../constants\";\nimport { getModes } from \"../internal/getModes\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Policies allow or deny access modes over resources and their associated\n * access control resource.\n *\n * @param policy The Policy Thing which allows retrieved access modes.\n * @returns Policy URL array.\n * @since 1.16.1\n */\nexport function getAllowModes<T extends ThingPersisted>(\n  policy: T,\n): AccessModes {\n  return getModes(policy, ACP.allow);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes, ThingPersisted } from \"../../interfaces\";\nimport { ACP } from \"../constants\";\nimport { getModes } from \"../internal/getModes\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Policies allow or deny access modes over resources and their associated\n * access control resource.\n *\n * @param policy The Policy Thing which denies retrieved access modes.\n * @returns Policy URL array.\n * @since 1.16.1\n */\nexport function getDenyModes<T extends ThingPersisted>(policy: T): AccessModes {\n  return getModes(policy, ACP.deny);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes, WebId } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { getPolicyUrlAll } from \"../policy/getPolicyUrlAll\";\nimport type { ThingPersisted } from \"../..\";\nimport { getThing, getUrlAll } from \"../..\";\nimport { internal_getAcr } from \"../control.internal\";\nimport { getAcrPolicyUrlAll } from \"../policy/getAcrPolicyUrlAll\";\nimport { ACP } from \"../constants\";\nimport { getAllowModes } from \"../policy/getAllowModes\";\nimport { getDenyModes } from \"../policy/getDenyModes\";\n\n/** @hidden */\nfunction isAgentMatched(\n  acr: WithAccessibleAcr,\n  policy: ThingPersisted,\n  webId: string,\n): boolean {\n  // TODO: Proper solution\n  // Finalise, release and use the TypeScript ACP Solid library\n  // internal_getActorAccess in acp_v2:96 doesn't reduce the policies properly\n  // policyAppliesTo in acp_v2:256 assumes that every matcher is an agent matcher\n  //\n  // TODO: Stopgap solution\n  // Implement a simplistic reduce function that\n  // matches policies where the agent is present in the matchers\n  const allOfMatchers = getUrlAll(policy, ACP.allOf)\n    .map((url) => getThing(internal_getAcr(acr), url))\n    .filter((thing): thing is ThingPersisted => thing !== null);\n\n  const allOfMatched = allOfMatchers.every((thing) => {\n    return getUrlAll(thing, ACP.agent).includes(webId);\n  });\n\n  const anyOfMatchers = getUrlAll(policy, ACP.anyOf)\n    .map((url) => getThing(internal_getAcr(acr), url))\n    .filter((thing): thing is ThingPersisted => thing !== null);\n\n  const anyOfMatched = anyOfMatchers.some((thing) => {\n    return getUrlAll(thing, ACP.agent).includes(webId);\n  });\n\n  const noneOfMatchers = getUrlAll(policy, ACP.noneOf)\n    .map((url) => getThing(internal_getAcr(acr), url))\n    .filter((thing): thing is ThingPersisted => thing !== null);\n\n  const noneOfMatched = noneOfMatchers.some((thing) => {\n    return getUrlAll(thing, ACP.agent).includes(webId);\n  });\n\n  return (\n    allOfMatchers.length + anyOfMatchers.length > 0 &&\n    (allOfMatchers.length === 0 || allOfMatched) &&\n    (anyOfMatchers.length === 0 || anyOfMatched) &&\n    (noneOfMatchers.length === 0 || !noneOfMatched)\n  );\n}\n\n/** @hidden */\nfunction reduceModes(\n  policy: ThingPersisted,\n  modes: AccessModes,\n  type: \"control\" | \"resource\",\n): AccessModes {\n  const allowed = getAllowModes(policy);\n  const denied = getDenyModes(policy);\n\n  if (type === \"control\") {\n    return {\n      read: modes.read,\n      append: modes.append,\n      write: modes.write,\n      controlRead: (modes.controlRead || allowed.read) && !denied.read,\n      controlWrite: (modes.controlWrite || allowed.write) && !denied.write,\n    };\n  }\n  return {\n    read: (modes.read || allowed.read) && !denied.read,\n    append: (modes.append || allowed.append) && !denied.append,\n    write: (modes.write || allowed.write) && !denied.write,\n    controlRead: modes.controlRead,\n    controlWrite: modes.controlWrite,\n  };\n}\n\n/**\n * Get an overview of what access is defined for a given Agent.\n *\n * @param resourceWithAcr URL of the Resource you want to read the access for.\n * @param webId WebID of the Agent you want to get the access for.\n * @since 1.16.0\n */\nexport async function getAgentAccess<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n  webId: WebId,\n): Promise<AccessModes> {\n  // TODO: add support for external resources\n  let resourceAccess = {\n    read: false,\n    append: false,\n    write: false,\n    controlRead: false,\n    controlWrite: false,\n  };\n\n  const policyAll = getPolicyUrlAll(resourceWithAcr)\n    .map((url) => getThing(internal_getAcr(resourceWithAcr), url))\n    .filter((policy): policy is ThingPersisted => policy !== null);\n\n  policyAll.forEach((policy) => {\n    if (isAgentMatched(resourceWithAcr, policy, webId)) {\n      resourceAccess = reduceModes(policy, resourceAccess, \"resource\");\n    }\n  });\n\n  const acrPolicyAll = getAcrPolicyUrlAll(resourceWithAcr)\n    .map((url) => getThing(internal_getAcr(resourceWithAcr), url))\n    .filter((policy): policy is ThingPersisted => policy !== null);\n\n  acrPolicyAll.forEach((policy) => {\n    if (isAgentMatched(resourceWithAcr, policy, webId)) {\n      resourceAccess = reduceModes(policy, resourceAccess, \"control\");\n    }\n  });\n\n  return resourceAccess;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport {\n  internal_fetchAcl,\n  internal_getResourceAcl,\n  internal_setAcl,\n  internal_setResourceAcl,\n} from \"../acl/acl.internal\";\nimport {\n  getAgentAccess as getAgentAccessWac,\n  getAgentAccessAll as getAgentAccessAllWac,\n  setAgentResourceAccess as setAgentResourceAccessWac,\n} from \"../acl/agent\";\nimport {\n  getGroupAccess as getGroupAccessWac,\n  getGroupAccessAll as getGroupAccessAllWac,\n  setGroupResourceAccess as setGroupResourceAccessWac,\n} from \"../acl/group\";\nimport {\n  getPublicAccess as getPublicAccessWac,\n  setPublicResourceAccess as setPublicResourceAccessWac,\n} from \"../acl/class\";\nimport type {\n  IriString,\n  UrlString,\n  WebId,\n  WithServerResourceInfo,\n} from \"../interfaces\";\nimport type {\n  Access as AclAccess,\n  AclDataset,\n  WithAccessibleAcl,\n  WithResourceAcl,\n} from \"../acl/acl\";\nimport {\n  createAclFromFallbackAcl,\n  getResourceAcl,\n  hasAccessibleAcl,\n  hasFallbackAcl,\n  hasResourceAcl,\n  saveAclFor,\n} from \"../acl/acl\";\n\ninterface Access {\n  read: boolean;\n  append: boolean;\n  write: boolean;\n  controlRead: boolean;\n  controlWrite: boolean;\n}\nexport type WacAccess = (\n  | { controlRead: true; controlWrite: true }\n  | { controlRead: false; controlWrite: false }\n) & {\n  read: boolean;\n  append: boolean;\n  write: boolean;\n};\n\nfunction universalAccessToAcl(\n  newAccess: Partial<WacAccess>,\n  previousAccess: AclAccess,\n): AclAccess {\n  // Universal access is aligned on ACP, which means there is a distinction between\n  // controlRead and controlWrite. This split doesn't exist in WAC, which is why\n  // the type for the input variable of this function is a restriction on the\n  // universal Access type.\n  if (newAccess.controlRead !== newAccess.controlWrite) {\n    throw new Error(\n      \"For Pods using Web Access Control, controlRead and controlWrite must be equal.\",\n    );\n  }\n  return {\n    read: newAccess.read ?? previousAccess.read,\n    append: newAccess.append ?? previousAccess.append,\n    write: newAccess.write ?? previousAccess.write,\n    control: newAccess.controlRead ?? previousAccess.control,\n  };\n}\n\nfunction aclAccessToUniversal(access: AclAccess): WacAccess {\n  // In ACL, denying access to an actor is a notion that doesn't exist, so an\n  // access is either granted or not for a given mode.\n  // This creates a misalignment with the ACP notion of an access being granted,\n  // denied, or simply not mentioned. Here, we convert the boolean vision of\n  // ACL into the boolean or undefined vision of ACP.\n  return {\n    read: access.read,\n    write: access.write,\n    append: access.append,\n    controlRead: access.control,\n    controlWrite: access.control,\n  } as WacAccess;\n}\n\nasync function getActorAccess(\n  resource: WithServerResourceInfo,\n  actor: IriString,\n  accessEvaluationCallback: typeof getAgentAccessWac,\n  options?: { fetch?: typeof fetch },\n): Promise<Access | null> {\n  const resourceAcl = await internal_fetchAcl(resource, options);\n  const wacAccess = accessEvaluationCallback(\n    internal_setAcl(resource, resourceAcl),\n    actor,\n  );\n  if (wacAccess === null) {\n    return null;\n  }\n  return aclAccessToUniversal(wacAccess);\n}\n\nasync function getActorClassAccess(\n  resource: WithServerResourceInfo,\n  accessEvaluationCallback: typeof getPublicAccessWac,\n  options?: { fetch?: typeof fetch },\n): Promise<Access | null> {\n  const resourceAcl = await internal_fetchAcl(resource, options);\n  const wacAccess = accessEvaluationCallback(\n    internal_setAcl(resource, resourceAcl),\n  );\n  if (wacAccess === null) {\n    return null;\n  }\n  return aclAccessToUniversal(wacAccess);\n}\n\nasync function getActorAccessAll(\n  resource: WithServerResourceInfo,\n  accessEvaluationCallback: typeof getAgentAccessAllWac,\n  options?: { fetch?: typeof fetch },\n): Promise<Record<WebId, WacAccess> | null> {\n  const resourceAcl = await internal_fetchAcl(resource, options);\n  const wacAgentAccess = accessEvaluationCallback(\n    internal_setAcl(resource, resourceAcl),\n  );\n  if (wacAgentAccess === null) {\n    return null;\n  }\n  const result: Record<WebId, WacAccess> = {};\n  for (const [webId, wacAccess] of Object.entries(wacAgentAccess)) {\n    result[webId] = aclAccessToUniversal(wacAccess);\n  }\n  return result;\n}\n\n/**\n * For a given Resource, look up its metadata, and read the Access permissions\n * granted to the given Agent.\n *\n * Note that this only lists permissions granted to the given Agent individually,\n * and will not exhaustively list modes the given Agent may have access to because\n * they apply to everyone, or because they apply to the Agent through a group for\n * instance.\n *\n * @param resource The URL of the Resource for which we want to list Access\n * @param agent The Agent for which the Access is granted\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns What Access modes are granted to the given Agent explicitly, or null if it could not be determined.\n */\nexport function getAgentAccess(\n  resource: WithServerResourceInfo,\n  agent: WebId,\n  options?: { fetch?: typeof fetch },\n): Promise<Access | null> {\n  return getActorAccess(resource, agent, getAgentAccessWac, options);\n}\n\n/**\n * For a given Resource, look up its metadata, and read the Access permissions\n * granted to the given Group.\n *\n * Note that this only lists permissions granted to the given Group individually,\n * and will not exhaustively list modes the given Group may have access to because\n * they apply to everyone, or because they apply to the Group through another\n * Group that may contain it for instance.\n *\n * @param resource The URL of the Resource for which we want to list Access\n * @param group The Group for which the Access is granted\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns What Access modes are granted to the given Group explicitly, or null if it could not be determined.\n */\nexport function getGroupAccess(\n  resource: WithServerResourceInfo,\n  group: UrlString,\n  options?: { fetch?: typeof fetch },\n): Promise<Access | null> {\n  return getActorAccess(resource, group, getGroupAccessWac, options);\n}\n\n/**\n * For a given Resource, look up its metadata, and read the Access permissions\n * granted to everyone.\n *\n * Note that this only lists permissions explicitly granted to everyone as a whole,\n * and will not exhaustively list modes any individual Agent or Group may have\n * access to because they specifically apply to them only.\n *\n * @param resource The URL of the Resource for which we want to list public Access\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns What Access modes are granted to the everyone explicitly, or null if it could not be determined.\n */\nexport function getPublicAccess(\n  resource: WithServerResourceInfo,\n  options?: { fetch?: typeof fetch },\n): Promise<Access | null> {\n  return getActorClassAccess(resource, getPublicAccessWac, options);\n}\n\n/**\n * For a given Resource, look up its metadata, and read the Access permissions\n * granted explicitly to each individual Agent.\n *\n * Note that this only lists permissions granted to each Agent individually,\n * and will not exhaustively list modes any Agent may have access to because\n * they apply to everyone, or because they apply to an Agent through a group for\n * instance.\n *\n * @param resource The URL of the Resource for which we want to list Agents Access\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns A map of Agent WebIDs and the access granted to them, or null if it could not be determined.\n */\nexport function getAgentAccessAll(\n  resource: WithServerResourceInfo,\n  options?: { fetch?: typeof fetch },\n): Promise<Record<WebId, WacAccess> | null> {\n  return getActorAccessAll(resource, getAgentAccessAllWac, options);\n}\n\n/**\n * For a given Resource, look up its metadata, and read the Access permissions\n * granted explicitly to each individual Group.\n *\n * Note that this only lists permissions granted to each Group individually,\n * and will not exhaustively list modes any Group may have access to because\n * they apply individually to all of the Agents in the Group, or to everyone\n * for instance.\n *\n * @param resource The URL of the Resource for which we want to list Agents Access\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns A map of Group URLs and the access granted to them, or null if it could not be determined.\n */\nexport function getGroupAccessAll(\n  resource: WithServerResourceInfo,\n  options?: { fetch?: typeof fetch },\n): Promise<Record<WebId, WacAccess> | null> {\n  return getActorAccessAll(resource, getGroupAccessAllWac, options);\n}\n\nasync function prepareResourceAcl<T extends WithServerResourceInfo>(\n  resource: T,\n  options?: { fetch?: typeof fetch },\n): Promise<(T & WithResourceAcl & WithAccessibleAcl) | null> {\n  if (!hasAccessibleAcl(resource)) {\n    return null;\n  }\n  const acl = await internal_fetchAcl(resource, options);\n  const resourceWithAcl = internal_setAcl(resource, acl);\n  let resourceAcl: AclDataset;\n  if (hasResourceAcl(resourceWithAcl)) {\n    // This is the simple case, where the Resource ACL we need to update already\n    // exists.\n    resourceAcl = internal_getResourceAcl(resourceWithAcl);\n  } else if (hasFallbackAcl(resourceWithAcl)) {\n    // In this case, the Resource ACL needs to be created first, and then updated.\n    resourceAcl = createAclFromFallbackAcl(resourceWithAcl);\n  } else {\n    return null;\n  }\n\n  return internal_setResourceAcl(resourceWithAcl, resourceAcl);\n}\n\nasync function saveUpdatedAcl<\n  T extends WithServerResourceInfo & WithAccessibleAcl & WithResourceAcl,\n>(\n  resource: T,\n  acl: AclDataset,\n  options?: { fetch?: typeof fetch },\n): Promise<T | null> {\n  let savedAcl: AclDataset | null = null;\n  try {\n    savedAcl = await saveAclFor(resource, acl, options);\n    return internal_setResourceAcl(resource, savedAcl);\n  } catch {\n    return null;\n  }\n}\n\nasync function setActorClassAccess<T extends WithServerResourceInfo>(\n  resource: T,\n  access: Partial<WacAccess>,\n  getAccess: typeof getPublicAccessWac,\n  setAccess: typeof setPublicResourceAccessWac,\n  options?: { fetch?: typeof fetch },\n): Promise<(T & WithResourceAcl) | null> {\n  const resourceWithOldAcl = await prepareResourceAcl(resource, options);\n\n  if (resourceWithOldAcl === null) {\n    return null;\n  }\n\n  const resourceAcl = getResourceAcl(resourceWithOldAcl);\n  const currentAccess = getAccess(resourceWithOldAcl) as AclAccess;\n  const wacAccess = universalAccessToAcl(access, currentAccess);\n  const updatedResourceAcl = setAccess(resourceAcl, wacAccess);\n\n  return saveUpdatedAcl(resourceWithOldAcl, updatedResourceAcl, options);\n}\n\nasync function setActorAccess<T extends WithServerResourceInfo>(\n  resource: T,\n  actor: UrlString,\n  access: Partial<WacAccess>,\n  getAccess: typeof getAgentAccessWac,\n  setAccess: typeof setAgentResourceAccessWac,\n  options?: { fetch?: typeof fetch },\n): Promise<(T & WithResourceAcl) | null> {\n  const resourceWithOldAcl = await prepareResourceAcl(resource, options);\n\n  if (resourceWithOldAcl === null) {\n    return null;\n  }\n\n  const currentAccess = getAccess(resourceWithOldAcl, actor) as AclAccess;\n  const resourceAcl = getResourceAcl(resourceWithOldAcl);\n  const wacAccess = universalAccessToAcl(access, currentAccess);\n  const updatedResourceAcl = setAccess(resourceAcl, actor, wacAccess);\n\n  return saveUpdatedAcl(resourceWithOldAcl, updatedResourceAcl, options);\n}\n\n/**\n * Set the Access modes for a given Agent to a given Resource.\n *\n * Important note: if the target resource did not have a Resource ACL, and its\n * Access was regulated by its Fallback ACL, said Fallback ACL is copied to create\n * a new Resource ACL. This has the side effect that the next time the Fallback\n * ACL is updated, the changes _will not impact_ the target resource.\n *\n * If the target Resource's Access mode cannot be determined, e.g. the user does\n * not have Read and Write access to the target Resource's ACL, or to its\n * fallback ACL if it does not have a Resource ACL, then `null` is returned.\n *\n * @param resource The Resource for which Access is being set\n * @param agent The Agent for whom Access is being set\n * @param access The Access being set\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns The Resource, with its ACL updated, or null if the new Access could not\n * be set.\n */\nexport async function setAgentResourceAccess<T extends WithServerResourceInfo>(\n  resource: T,\n  agent: WebId,\n  access: Partial<WacAccess>,\n  options?: { fetch?: typeof fetch },\n): Promise<(T & WithResourceAcl) | null> {\n  return setActorAccess(\n    resource,\n    agent,\n    access,\n    getAgentAccessWac,\n    setAgentResourceAccessWac,\n    options,\n  );\n}\n\n/**\n * Set the Access modes for a given Group to a given Resource.\n *\n * Important note: if the target resource did not have a Resource ACL, and its\n * Access was regulated by its Fallback ACL, said Fallback ACL is copied to create\n * a new Resource ACL. This has the side effect that the next time the Fallback\n * ACL is updated, the changes _will not impact_ the target resource.\n *\n * If the target Resource's Access mode cannot be determined, e.g. the user does\n * not have Read and Write access to the target Resource's ACL, or to its\n * fallback ACL if it does not have a Resource ACL, then `null` is returned.\n *\n * @param resource The Resource for which Access is being set\n * @param agent The Group for which Access is being set\n * @param access The Access being set\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns The Resource, with its ACL updated, or null if the new Access could not\n * be set.\n */\nexport async function setGroupResourceAccess<T extends WithServerResourceInfo>(\n  resource: T,\n  group: UrlString,\n  access: Partial<WacAccess>,\n  options?: { fetch?: typeof fetch },\n): Promise<(T & WithResourceAcl) | null> {\n  return setActorAccess(\n    resource,\n    group,\n    access,\n    getGroupAccessWac,\n    setGroupResourceAccessWac,\n    options,\n  );\n}\n\n/**\n * Set the Access modes for everyone to a given Resource.\n *\n * Important note: if the target resource did not have a Resource ACL, and its\n * Access was regulated by its Fallback ACL, said Fallback ACL is copied to create\n * a new Resource ACL. This has the side effect that the next time the Fallback\n * ACL is updated, the changes _will not impact_ the target resource.\n *\n * If the target Resource's Access mode cannot be determined, e.g. the user does\n * not have Read and Write access to the target Resource's ACL, or to its\n * fallback ACL if it does not have a Resource ACL, then `null` is returned.\n *\n * @param resource The Resource for which Access is being set\n * @param access The Access being set\n * @param options Optional parameter `options.fetch`: An alternative `fetch` function to make the HTTP request, compatible with the browser-native [fetch API](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters).\n * @returns The Resource, with its ACL updated, or null if the new Access could not\n * be set.\n */\nexport async function setPublicResourceAccess<T extends WithServerResourceInfo>(\n  resource: T,\n  access: Partial<WacAccess>,\n  options?: { fetch?: typeof fetch },\n): Promise<(T & WithResourceAcl) | null> {\n  return setActorClassAccess(\n    resource,\n    access,\n    getPublicAccessWac,\n    setPublicResourceAccessWac,\n    options,\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { UrlString, WithServerResourceInfo } from \"../../interfaces\";\nimport type { DefaultOptions } from \"../type/DefaultOptions\";\nimport { ACP } from \"../constants\";\nimport { getLinkedResourceUrlAll, getSourceUrl } from \"../../resource/resource\";\nimport { getAclServerResourceInfo } from \"../../universal/getAclServerResourceInfo\";\n\n/**\n * Retrieve the URL of an Access Control Resource as per the ACP Draft\n * specification.\n *\n * @param resource The Resource for which to retrieve the URL of the Access\n * Control Resource if it is accessible.\n * @returns The URL of the ACR or null.\n */\nexport async function getAcrUrl(\n  resource: WithServerResourceInfo,\n  options?: DefaultOptions,\n): Promise<UrlString | null> {\n  // The ACP Draft mandates a link rel=\"type\" header identifies Access Control Resources\n  const aclServerResourceInfo = await getAclServerResourceInfo(\n    resource,\n    options,\n  );\n\n  if (aclServerResourceInfo === null) {\n    return null;\n  }\n\n  const relTypeLinks = getLinkedResourceUrlAll(aclServerResourceInfo).type;\n  if (\n    Array.isArray(relTypeLinks) &&\n    relTypeLinks.includes(ACP.AccessControlResource)\n  ) {\n    return getSourceUrl(aclServerResourceInfo);\n  }\n\n  return null;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { SolidDataset, WithServerResourceInfo } from \"../../interfaces\";\nimport type { DefaultOptions } from \"../type/DefaultOptions\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { getAcrUrl } from \"./getAcrUrl\";\nimport { getSolidDataset } from \"../../resource/solidDataset\";\nimport { getSourceUrl } from \"../../resource/resource\";\n\n/**\n * Retrieve the Access Control Resource of a Resource as per the ACP Draft\n * specification.\n *\n * @param resource The Resource for which to retrieve the URL of the Access\n * Control Resource if it is accessible.\n * @param options Default Options such as a fetch function.\n * @returns The URL of the ACR or null.\n */\nexport async function getResourceAcr<T extends WithServerResourceInfo>(\n  resource: T,\n  options?: DefaultOptions,\n): Promise<(T & WithAccessibleAcr) | null> {\n  const acrUrl = await getAcrUrl(resource, options);\n  if (acrUrl === null) {\n    return null;\n  }\n\n  let acr: SolidDataset & WithServerResourceInfo;\n  try {\n    acr = await getSolidDataset(acrUrl, options);\n  } catch {\n    return null;\n  }\n\n  return {\n    ...resource,\n    internal_acp: {\n      acr: {\n        ...acr,\n        accessTo: getSourceUrl(resource),\n      },\n    },\n  };\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes, UrlString, WebId } from \"../interfaces\";\nimport type { DefaultOptions } from \"../acp/type/DefaultOptions\";\nimport { getResourceInfo } from \"../resource/resource\";\nimport { getAgentAccess as getAgentAccessAcp } from \"../acp/util/getAgentAccess\";\nimport { getAgentAccess as getAgentAccessWac } from \"../access/wac\";\nimport { getResourceAcr } from \"../acp/util/getResourceAcr\";\n\n/**\n * Get an overview of what access is defined for a given Agent.\n *\n * This function works with Solid Pods that implement either the Web Access\n * Control spec or the Access Control Policies proposal, with some caveats:\n *\n * - If access to the given Resource has been set using anything other than the\n *   functions in this module, it is possible that it has been set in a way that\n *   prevents this function from reliably reading access.\n * - It will only return access specified explicitly for the given Agent within\n *   the ACL linked to the resource. If additional restrictions or external\n *   resources are used, those will not be reflected in the return value of this\n *   function.\n * - It will only return access specified explicitly for the given Resource.\n *   In other words, if the Resource is a Container, the returned Access may not\n *   apply to contained Resources.\n * - If the current user does not have permission to view access for the given\n *   Resource, this function will resolve to `null`.\n *\n * @param resourceUrl URL of the Resource you want to read the access for.\n * @param webId WebID of the Agent you want to get the access for.\n * @param options Default Options such as a fetch function.\n * @since 1.19.0\n */\nexport async function getAgentAccess(\n  resourceUrl: UrlString,\n  webId: WebId,\n  options?: DefaultOptions,\n): Promise<AccessModes | null> {\n  const resourceInfo = await getResourceInfo(resourceUrl, options);\n  const acr = await getResourceAcr(resourceInfo, options);\n\n  if (acr === null) {\n    return getAgentAccessWac(resourceInfo, webId, options);\n  }\n\n  return getAgentAccessAcp(acr, webId);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { internal_getAcr } from \"../control.internal\";\nimport { ACP } from \"../constants\";\nimport { getThingAll, getUrlAll } from \"../..\";\n\n/** @hidden */\nexport function getAgentUrlAll(acr: WithAccessibleAcr): string[] {\n  return Array.from(\n    new Set(\n      getThingAll(internal_getAcr(acr))\n        .map((thing) => {\n          return getUrlAll(thing, ACP.agent);\n        })\n        .reduce((flatArray, agentArray) => {\n          return flatArray.concat(agentArray);\n        }, []),\n    ),\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes } from \"../../interfaces\";\nimport { getAgentAccess } from \"./getAgentAccess\";\nimport { getAgentUrlAll } from \"./getAgentUrlAll\";\nimport type { WithAccessibleAcr } from \"../acp\";\n\n/**\n * Get an overview of what access is defined for agents.\n *\n * This function works with Solid Pods that implement either the Web Access\n * Control spec or the Access Control Policies proposal, with some caveats:\n *\n * - If access to the given Resource has been set using anything other than the\n *   functions in this module, it is possible that it has been set in a way that\n *   prevents this function from reliably reading access.\n * - It will only return access specified explicitly for the given Agent within\n *   the ACL linked to the resource. If additional restrictions or external\n *   resources are used, those will not be reflected in the return value of this\n *   function.\n * - It will only return access specified explicitly for the given Resource.\n *   In other words, if the Resource is a Container, the returned Access may not\n *   apply to contained Resources.\n * - If the current user does not have permission to view access for the given\n *   Resource, this function will resolve to `null`.\n *\n * @param resourceUrl URL of the Resource you want to read the access for.\n * @param options Default Options such as a fetch function.\n * @since 1.21.0\n */\nexport async function getAgentAccessAll<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n): Promise<Record<string, AccessModes> | null> {\n  return (\n    await Promise.all(\n      getAgentUrlAll(resourceWithAcr).map(async (agent) => ({\n        [agent]: await getAgentAccess(resourceWithAcr, agent),\n      })),\n    )\n  ).reduce(\n    (agentAccessAll, currentAgentAccess) => ({\n      ...agentAccessAll,\n      ...currentAgentAccess,\n    }),\n    {},\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes, UrlString } from \"../interfaces\";\nimport type { DefaultOptions } from \"../acp/type/DefaultOptions\";\nimport { getResourceInfo } from \"../resource/resource\";\nimport { getAgentAccessAll as getAgentAccessAllAcp } from \"../acp/util/getAgentAccessAll\";\nimport { getAgentAccessAll as getAgentAccessAllWac } from \"../access/wac\";\nimport { getResourceAcr } from \"../acp/util/getResourceAcr\";\n\n/**\n * Get an overview of what access is defined for agents.\n *\n * This function works with Solid Pods that implement either the Web Access\n * Control spec or the Access Control Policies proposal, with some caveats:\n *\n * - If access to the given Resource has been set using anything other than the\n *   functions in this module, it is possible that it has been set in a way that\n *   prevents this function from reliably reading access.\n * - It will only return access specified explicitly for the given Agent within\n *   the ACL linked to the resource. If additional restrictions or external\n *   resources are used, those will not be reflected in the return value of this\n *   function.\n * - It will only return access specified explicitly for the given Resource.\n *   In other words, if the Resource is a Container, the returned Access may not\n *   apply to contained Resources.\n * - If the current user does not have permission to view access for the given\n *   Resource, this function will resolve to `null`.\n *\n * @param resourceUrl URL of the Resource you want to read the access for.\n * @param options Default Options such as a fetch function.\n * @since 1.21.0\n */\nexport async function getAgentAccessAll(\n  resourceUrl: UrlString,\n  options?: DefaultOptions,\n): Promise<Record<string, AccessModes> | null> {\n  const resourceInfo = await getResourceInfo(resourceUrl, options);\n  const acr = await getResourceAcr(resourceInfo, options);\n\n  if (acr === null) {\n    return getAgentAccessAllWac(resourceInfo, options);\n  }\n\n  return getAgentAccessAllAcp(acr);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { getAgentAccess } from \"./getAgentAccess\";\n\n/**\n * Get an overview of what access is given to the public.\n *\n * @param resourceWithAcr URL of the Resource you want to read the access for.\n * @since 1.16.0\n */\nexport async function getPublicAccess<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n): Promise<AccessModes> {\n  return getAgentAccess(resourceWithAcr, ACP.PublicAgent);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes, UrlString } from \"../interfaces\";\nimport type { DefaultOptions } from \"../acp/type/DefaultOptions\";\nimport { getResourceInfo } from \"../resource/resource\";\nimport { getPublicAccess as getPublicAccessAcp } from \"../acp/util/getPublicAccess\";\nimport { getPublicAccess as getPublicAccessWac } from \"../access/wac\";\nimport { getResourceAcr } from \"../acp/util/getResourceAcr\";\n\n/**\n * Get an overview of what access is defined for the Public.\n *\n * This function works with Solid Pods that implement either the Web Access\n * Control spec or the Access Control Policies proposal, with some caveats:\n *\n * - If access to the given Resource has been set using anything other than the\n *   functions in this module, it is possible that it has been set in a way that\n *   prevents this function from reliably reading access.\n * - It will only return access specified explicitly for the given Agent within\n *   the ACL linked to the resource. If additional restrictions or external\n *   resources are used, those will not be reflected in the return value of this\n *   function.\n * - It will only return access specified explicitly for the given Resource.\n *   In other words, if the Resource is a Container, the returned Access may not\n *   apply to contained Resources.\n * - If the current user does not have permission to view access for the given\n *   Resource, this function will resolve to `null`.\n *\n * @param resourceUrl URL of the Resource you want to read the access for.\n * @param options Default Options such as a fetch function.\n * @since 1.19.0\n */\nexport async function getPublicAccess(\n  resourceUrl: UrlString,\n  options?: DefaultOptions,\n): Promise<AccessModes | null> {\n  const resourceInfo = await getResourceInfo(resourceUrl, options);\n  const acr = await getResourceAcr(resourceInfo, options);\n\n  if (acr === null) {\n    return getPublicAccessWac(resourceInfo, options);\n  }\n\n  return getPublicAccessAcp(acr);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { WithAccessibleAcr } from \"../acp\";\nimport type { ThingPersisted } from \"../..\";\nimport { setThing } from \"../..\";\nimport { internal_cloneResource as cloneResource } from \"../../resource/resource.internal\";\n\n/** @hidden */\nexport function setAccessControlResourceThing<T extends WithAccessibleAcr>(\n  resource: T,\n  thing: ThingPersisted,\n): T {\n  return Object.assign(cloneResource(resource), {\n    internal_acp: {\n      ...resource.internal_acp,\n      acr: setThing(resource.internal_acp.acr, thing),\n    },\n  });\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { WithAccessibleAcr } from \"../acp\";\nimport type { AccessModes } from \"../../interfaces\";\nimport type { DefaultAccessControlName } from \"./getDefaultAccessControlUrl\";\nimport { getDefaultAccessControlUrl } from \"./getDefaultAccessControlUrl\";\n\n/** @hidden */\nexport function getDefaultAgentMatcherPolicyUrl(\n  resource: WithAccessibleAcr,\n  name: DefaultAccessControlName,\n  mode: keyof AccessModes,\n): string {\n  return getDefaultAccessControlUrl(resource, name)\n    .concat(\"AgentMatcher\")\n    .concat(mode.charAt(0).toUpperCase() + mode.slice(1))\n    .concat(\"Policy\");\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { buildThing, createThing, getIriAll, getSourceUrl } from \"../..\";\nimport { ACP } from \"../constants\";\nimport { internal_getAcr as getAccessControlResource } from \"../control.internal\";\nimport { getAccessControlResourceThing } from \"./getAccessControlResourceThing\";\nimport type { DefaultAccessControlName } from \"./getDefaultAccessControlUrl\";\nimport { getDefaultAccessControlUrl } from \"./getDefaultAccessControlUrl\";\nimport { setAccessControlResourceThing } from \"./setAccessControlResourceThing\";\n\nfunction getAccessControlTypeFromDefaultAccessControlName(\n  name: DefaultAccessControlName,\n): string {\n  if (name.includes(\"Member\")) {\n    return ACP.memberAccessControl;\n  }\n  return ACP.accessControl;\n}\n\n/** @hidden */\nexport function setDefaultAccessControlThingIfNotExist<\n  T extends WithAccessibleAcr,\n>(resource: T, name: DefaultAccessControlName): T {\n  const defaultAccessControlThingUrl = getDefaultAccessControlUrl(\n    resource,\n    name,\n  );\n  const acr = getAccessControlResource(resource);\n\n  // Get the Access Control Resource Thing or create it\n  let accessControlResourceThing = getAccessControlResourceThing(resource);\n  if (\n    accessControlResourceThing === null ||\n    typeof accessControlResourceThing === \"undefined\"\n  ) {\n    accessControlResourceThing = createThing({ url: getSourceUrl(acr) });\n  }\n\n  // Get the Default Access Control Thing or create it and return\n  const accessControlUrlAll = getIriAll(\n    accessControlResourceThing,\n    getAccessControlTypeFromDefaultAccessControlName(name),\n  );\n\n  if (!accessControlUrlAll.includes(defaultAccessControlThingUrl)) {\n    accessControlResourceThing = buildThing(accessControlResourceThing)\n      .addUrl(\n        getAccessControlTypeFromDefaultAccessControlName(name),\n        defaultAccessControlThingUrl,\n      )\n      .build();\n\n    return setAccessControlResourceThing(resource, accessControlResourceThing);\n  }\n\n  // Return the original resource if the ACR and Default AC exist\n  return resource;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Url, UrlString } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { buildThing } from \"../../thing/build\";\nimport { getDefaultAccessControlThing } from \"../internal/getDefaultAccessControlThing\";\nimport { DEFAULT_ACR_ACCESS_CONTROL } from \"../internal/getDefaultAccessControlUrl\";\nimport { setAccessControlResourceThing } from \"../internal/setAccessControlResourceThing\";\nimport { setDefaultAccessControlThingIfNotExist } from \"../internal/setDefaultAccessControlThingIfNotExist\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Add a policy applying to the ACR of the given resource.\n *\n * @param resourceWithAcr The resource for which to add the URL of a policy\n * applying to its access control resource.\n * @param policyUrl A Policy URL.\n * @returns The resource with its ammended access control resource.\n * @since 1.16.1\n */\nexport function addAcrPolicyUrl<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n  policyUrl: Url | UrlString,\n): T {\n  const resourceWithAcrContainingDefaultAccessControl =\n    setDefaultAccessControlThingIfNotExist(\n      resourceWithAcr,\n      DEFAULT_ACR_ACCESS_CONTROL,\n    );\n\n  const defaultAccessControlThing = getDefaultAccessControlThing(\n    resourceWithAcrContainingDefaultAccessControl,\n    DEFAULT_ACR_ACCESS_CONTROL,\n  );\n\n  return setAccessControlResourceThing(\n    resourceWithAcrContainingDefaultAccessControl,\n    buildThing(defaultAccessControlThing).addUrl(ACP.access, policyUrl).build(),\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Url, UrlString } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { buildThing } from \"../../thing/build\";\nimport { getDefaultAccessControlThing } from \"../internal/getDefaultAccessControlThing\";\nimport { DEFAULT_ACCESS_CONTROL } from \"../internal/getDefaultAccessControlUrl\";\nimport { setAccessControlResourceThing } from \"../internal/setAccessControlResourceThing\";\nimport { setDefaultAccessControlThingIfNotExist } from \"../internal/setDefaultAccessControlThingIfNotExist\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Add a policy applying to the given resource.\n *\n * @param resourceWithAcr The resource for which to add the URL of a policy\n * applying to it.\n * @param policyUrl A Policy URL.\n * @returns The resource with its ammended access control resource.\n * @since 1.16.1\n */\nexport function addPolicyUrl<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n  policyUrl: Url | UrlString,\n): T {\n  const resourceWithAcrContainingDefaultAccessControl =\n    setDefaultAccessControlThingIfNotExist(\n      resourceWithAcr,\n      DEFAULT_ACCESS_CONTROL,\n    );\n\n  const defaultAccessControlThing = getDefaultAccessControlThing(\n    resourceWithAcrContainingDefaultAccessControl,\n    DEFAULT_ACCESS_CONTROL,\n  );\n\n  return setAccessControlResourceThing(\n    resourceWithAcrContainingDefaultAccessControl,\n    buildThing(defaultAccessControlThing).addUrl(ACP.apply, policyUrl).build(),\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { WithAccessibleAcr } from \"../acp\";\nimport type { AccessModes } from \"../../interfaces\";\nimport type { DefaultAccessControlName } from \"./getDefaultAccessControlUrl\";\nimport { getDefaultAgentMatcherPolicyUrl } from \"./getDefaultAgentMatcherPolicyUrl\";\nimport { addAcrPolicyUrl } from \"../policy/addAcrPolicyUrl\";\nimport { addPolicyUrl } from \"../policy/addPolicyUrl\";\n\n/** @hidden */\nexport function setDefaultAgentMatcherPolicyThingIfNotExist<\n  T extends WithAccessibleAcr,\n>(resource: T, name: DefaultAccessControlName, mode: keyof AccessModes): T {\n  const policyUrl = getDefaultAgentMatcherPolicyUrl(resource, name, mode);\n\n  // TODO: Re-enable when we support setting agent access on member resources\n  // if (policyUrl.includes(\"Member\") && policyUrl.includes(\"Acr\")) {\n  //   return addMemberAcrPolicyUrl(resource, policyUrl);\n  // }\n\n  // if (policyUrl.includes(\"Member\")) {\n  //   return addMemberPolicyUrl(resource, policyUrl);\n  // }\n\n  if (policyUrl.includes(\"Acr\")) {\n    return addAcrPolicyUrl(resource, policyUrl);\n  }\n\n  return addPolicyUrl(resource, policyUrl);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { WithAccessibleAcr } from \"../acp\";\nimport type { AccessModes } from \"../../interfaces\";\nimport type { DefaultAccessControlName } from \"./getDefaultAccessControlUrl\";\nimport { getDefaultAgentMatcherPolicyUrl } from \"./getDefaultAgentMatcherPolicyUrl\";\n\n/** @hidden */\nexport function getDefaultAgentMatcherPolicyMatcherUrl(\n  resource: WithAccessibleAcr,\n  name: DefaultAccessControlName,\n  mode: keyof AccessModes,\n): string {\n  return getDefaultAgentMatcherPolicyUrl(resource, name, mode).concat(\n    \"Matcher\",\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { WithAccessibleAcr } from \"../acp\";\nimport type { AccessModes } from \"../../interfaces\";\nimport { buildThing, createThing, getIriAll, getThing } from \"../..\";\nimport { ACP } from \"../constants\";\nimport { internal_getAcr as getAccessControlResource } from \"../control.internal\";\nimport type { DefaultAccessControlName } from \"./getDefaultAccessControlUrl\";\nimport { setAccessControlResourceThing } from \"./setAccessControlResourceThing\";\nimport { getDefaultAgentMatcherPolicyUrl } from \"./getDefaultAgentMatcherPolicyUrl\";\nimport { setDefaultAgentMatcherPolicyThingIfNotExist } from \"./setDefaultAgentMatcherPolicyThingIfNotExist\";\nimport { getDefaultAgentMatcherPolicyMatcherUrl } from \"./getDefaultAgentMatcherPolicyMatcherUrl\";\nimport { setModes } from \"./setModes\";\n\n/** @hidden */\nexport const DEFAULT_POLICY_MATCHER_PREDICATE = ACP.anyOf;\n\n/**\n * This functions scaffolds the default elements required for giving access to\n * an agent:\n * 1. If the Access Control Resource is empty, create the AccessControlResource\n *    element;\n * 2. If the current default Access Control doesn't exist (the one applying to\n *    one of: the Resource, the ACR, the Member Resources or the ACR of members)\n *    create it;\n * 3. If the default Policy for allowing the Access Modes for the current\n *    default Access Control doesn't exist, create it;\n * 4. If the default \"anyOf\" Agent Matcher for the current Policy creates it;\n * 5. Returns an ACR with a Matcher ready to add to.\n * @hidden\n * */\nexport function setDefaultAgentMatcherPolicyMatcherThingIfNotExist<\n  T extends WithAccessibleAcr,\n>(resource: T, name: DefaultAccessControlName, mode: keyof AccessModes): T {\n  const policyUrl = getDefaultAgentMatcherPolicyUrl(resource, name, mode);\n  const matcherUrl = getDefaultAgentMatcherPolicyMatcherUrl(\n    resource,\n    name,\n    mode,\n  );\n\n  let defaultAgentMatcherPolicyThing = getThing(\n    getAccessControlResource(resource),\n    policyUrl,\n  );\n\n  if (!defaultAgentMatcherPolicyThing) {\n    resource = setDefaultAgentMatcherPolicyThingIfNotExist(\n      resource,\n      name,\n      mode,\n    );\n    defaultAgentMatcherPolicyThing = createThing({ url: policyUrl });\n    defaultAgentMatcherPolicyThing = setModes(\n      defaultAgentMatcherPolicyThing,\n      { [mode]: true } as unknown as AccessModes,\n      ACP.allow,\n    );\n  }\n\n  // Get the Default Access Control Agent Matcher Policy Matcher Thing or create it and return\n  const agentMatcherPolicyUrlAll = getIriAll(\n    defaultAgentMatcherPolicyThing,\n    DEFAULT_POLICY_MATCHER_PREDICATE,\n  );\n\n  if (!agentMatcherPolicyUrlAll.includes(matcherUrl)) {\n    defaultAgentMatcherPolicyThing = buildThing(defaultAgentMatcherPolicyThing)\n      .addUrl(DEFAULT_POLICY_MATCHER_PREDICATE, matcherUrl)\n      .build();\n\n    return setAccessControlResourceThing(\n      resource,\n      defaultAgentMatcherPolicyThing,\n    );\n  }\n\n  return resource;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport { acp, rdf, solid } from \"../constants\";\nimport { internal_isValidUrl, isNamedNode } from \"../datatypes\";\nimport type {\n  SolidDataset,\n  Thing,\n  ThingPersisted,\n  Url,\n  UrlString,\n  WebId,\n} from \"../interfaces\";\nimport { internal_toIriString } from \"../interfaces.internal\";\nimport { getSourceUrl } from \"../resource/resource\";\nimport { addIri, addStringNoLocale } from \"../thing/add\";\nimport { getIriAll, getStringNoLocaleAll } from \"../thing/get\";\nimport { removeIri, removeStringNoLocale } from \"../thing/remove\";\nimport { setIri, setUrl } from \"../thing/set\";\nimport {\n  asUrl,\n  createThing,\n  getThing,\n  getThingAll,\n  removeThing,\n  setThing,\n} from \"../thing/thing\";\nimport type { WithAccessibleAcr } from \"./acp\";\nimport { internal_getAcr, internal_setAcr } from \"./control.internal\";\nimport type { Policy, ResourcePolicy } from \"./policy\";\n\n/**\n * A Matcher can be applied to a [[Policy]] to determine under what circumstances that Policy is applied to a Resource.\n * @since Not released yet.\n */\nexport type Matcher = ThingPersisted;\n/**\n * A ResourceMatcher is like a [[Matcher]], but applied to a [[ResourcePolicy]] and therefore not re-used across different Resources, but only used for a single Resource and stored in that Resource's Access Control Resource.\n * @since Not released yet.\n */\nexport type ResourceMatcher = ThingPersisted;\n\n/**\n * @param thing the [[Thing]] to check to see if it's an ACP Matcher or not\n */\nfunction isMatcher(thing: Thing): thing is Matcher {\n  return getIriAll(thing, rdf.type).includes(acp.Matcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Add a Matcher that refines the scope of a given the [[Policy]]. If an agent\n * requesting access to a resource is **not** present in **any** of the \"All Of\" Matchers,\n * they will not be granted access.\n *\n * Also see [[addAnyOfMatcherUrl]] and [[addNoneOfMatcherUrl]].\n *\n * @param policy The [[Policy]] to which the Matcher should be added.\n * @param matcher The Matcher to add to the policy.\n * @returns A new [[Policy]] clone of the original one, with the new Matcher added.\n * @since Not released yet.\n */\nexport function addAllOfMatcherUrl<P extends Policy | ResourcePolicy>(\n  policy: P,\n  matcher: Matcher | Url | UrlString,\n): P {\n  return addIri(policy, acp.allOf, matcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Removes a Matcher that refines the scope of a given the [[Policy]]. If an agent\n * requesting access to a resource is **not** present in **any** of the \"All Of\" Matchers,\n * they will not be granted access.\n * @param policy The [[Policy]] from which the Matcher should be removed.\n * @param matcher The Matcher to remove from the policy.\n * @returns A new [[Policy]] clone of the original one, with the Matcher removed.\n * @since Not released yet.\n */\nexport function removeAllOfMatcherUrl<P extends Policy | ResourcePolicy>(\n  policy: P,\n  matcher: Matcher | Url | UrlString,\n): P {\n  return removeIri(policy, acp.allOf, matcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Overwrites the Matcher refining the scope of a given the [[Policy]]. If an agent\n * requesting access to a resource is **not** present in **any** of the \"All Of\" Matchers,\n * they will not be granted access.\n * @param policy The [[Policy]] to which the Matcher should be added.\n * @param matcher The Matcher to set for the Policy.\n * @returns A new [[Policy]] clone of the original one, with the \"All Of\" Matchers replaced.\n * @since Not released yet.\n */\nexport function setAllOfMatcherUrl<P extends Policy | ResourcePolicy>(\n  policy: P,\n  matcher: Matcher | Url | UrlString,\n): P {\n  return setIri(policy, acp.allOf, matcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get the \"All Of\" [[Matcher]]s for the given [[Policy]]\n * @param policy The [[policy]] from which the Matchers should be read.\n * @returns A list of the \"All Of\" [[Matcher]]s\n * @since Not released yet.\n */\nexport function getAllOfMatcherUrlAll<P extends Policy | ResourcePolicy>(\n  policy: P,\n): UrlString[] {\n  return getIriAll(policy, acp.allOf);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Add a Matcher that extends the scope of a given the [[Policy]]. If an agent\n * requesting access to a resource is present in **any** of the \"Any Of\" Matchers,\n * they will be granted access.\n *\n * Also see [[addAllOfMatcherUrl]] and [[addNoneOfMatcherUrl]].\n *\n * @param policy The [[Policy]] to which the Matcher should be added.\n * @param matcher The Matcher to add to the policy.\n * @returns A new [[Policy]] clone of the original one, with the new Matcher added.\n * @since Not released yet.\n */\nexport function addAnyOfMatcherUrl<P extends Policy | ResourcePolicy>(\n  policy: P,\n  matcher: Matcher | Url | UrlString,\n): P {\n  return addIri(policy, acp.anyOf, matcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Removes a Matcher that extends the scope of a given the [[Policy]]. If an agent\n * requesting access to a resource is present in **any** of the \"Any Of\" Matchers,\n * they will be granted access.\n * @param policy The [[Policy]] from which the Matcher should be removed.\n * @param matcher The Matcher to remove from the policy.\n * @returns A new [[Policy]] clone of the original one, with the Matcher removed.\n * @since Not released yet.\n */\nexport function removeAnyOfMatcherUrl<P extends Policy | ResourcePolicy>(\n  policy: P,\n  matcher: Matcher | Url | UrlString,\n): P {\n  return removeIri(policy, acp.anyOf, matcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Overwrite the Matcher extending the scope of a given the [[Policy]]. If an agent\n * requesting access to a resource is present in **any** of the \"Any Of\" Matchers,\n * they will be granted access.\n * @param policy The [[Policy]] to which the Matcher should be added.\n * @param matcher The Matcher to set for the Policy.\n * @returns A new [[Policy]] clone of the original one, with the \"Any Of\" Matchers replaced.\n * @since Not released yet.\n */\nexport function setAnyOfMatcherUrl<P extends Policy | ResourcePolicy>(\n  policy: P,\n  matcher: Matcher | Url | UrlString,\n): P {\n  return setIri(policy, acp.anyOf, matcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get the \"Any Of\" [[Matcher]]s for the given [[Policy]]\n * @param policy The [[policy]] from which the Matchers should be read.\n * @returns A list of the \"Any Of\" [[Matcher]]s\n * @since Not released yet.\n */\nexport function getAnyOfMatcherUrlAll<P extends Policy | ResourcePolicy>(\n  policy: P,\n): UrlString[] {\n  return getIriAll(policy, acp.anyOf);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Add a Matcher that restricts the scope of a given the [[Policy]]. If an agent\n * requesting access to a resource is matched by another Matcher, but **also**\n * by the given Matcher, they will **not** be granted access.\n *\n * Also see [[addAllOfMatcherUrl]] and [[addAnyOfMatcherUrl]].\n *\n * @param policy The [[Policy]] to which the Matcher should be added.\n * @param matcher The Matcher to add to the policy.\n * @returns A new [[Policy]] clone of the original one, with the new Matcher added.\n * @since Not released yet.\n */\nexport function addNoneOfMatcherUrl<P extends Policy | ResourcePolicy>(\n  policy: P,\n  matcher: Matcher | Url | UrlString,\n): P {\n  return addIri(policy, acp.noneOf, matcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Removes a Matcher that restricts the scope of a given the [[Policy]]. If an agent\n * requesting access to a resource is matched by another Matcher, but **also**\n * in any of the \"None Of\" Matchers, they will **not** be granted access.\n *\n * @param policy The [[Policy]] from which the Matcher should be removed.\n * @param matcher The Matcher to remove from the policy.\n * @returns A new [[Policy]] clone of the original one, with the Matcher removed.\n * @since Not released yet.\n */\nexport function removeNoneOfMatcherUrl<P extends Policy | ResourcePolicy>(\n  policy: P,\n  matcher: Matcher | Url | UrlString,\n): P {\n  return removeIri(policy, acp.noneOf, matcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Set the Matchers restricting the scope of a given [[Policy]]. If an agent\n * requesting access to a resource is matched by another Matcher, but **also**\n * by any of the \"None Of\" Matchers, they will not be granted access.\n *\n * @param policy The [[Policy]] to which the Matcher should be added.\n * @param matcher The Matcher to set for the Policy.\n * @returns A new [[Policy]] clone of the original one, with the \"None Of\" Matchers replaced.\n * @since Not released yet.\n */\nexport function setNoneOfMatcherUrl<P extends Policy | ResourcePolicy>(\n  policy: P,\n  matcher: Matcher | Url | UrlString,\n): P {\n  return setIri(policy, acp.noneOf, matcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get the \"None Of\" [[Matcher]]s for the given [[Policy]]\n * @param policy The [[policy]] from which the Matchers should be read.\n * @returns A list of the forbidden [[Matcher]]s\n * @since Not released yet.\n */\nexport function getNoneOfMatcherUrlAll<P extends Policy | ResourcePolicy>(\n  policy: P,\n): UrlString[] {\n  return getIriAll(policy, acp.noneOf);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Initialise a new, empty [[Matcher]].\n *\n * @param url URL that identifies this [[Matcher]].\n * @since Not released yet.\n */\nexport function createMatcher(url: Url | UrlString): Matcher {\n  const stringUrl = internal_toIriString(url);\n  let matcherThing = createThing({ url: stringUrl });\n  matcherThing = setUrl(matcherThing, rdf.type, acp.Matcher);\n  return matcherThing;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Initialise a new, empty [[ResourceMatcher]] for the given Resource.\n *\n * @param resourceWithAcr The Resource to which the new Matcher is to apply.\n * @param name Name that identifies this [[Matcher]].\n * @since Not released yet.\n */\nexport function createResourceMatcherFor(\n  resourceWithAcr: WithAccessibleAcr,\n  name: string,\n): ResourceMatcher {\n  const acr = internal_getAcr(resourceWithAcr);\n  const url = new URL(getSourceUrl(acr));\n  url.hash = `#${name}`;\n  let matcherThing = createThing({ url: url.href });\n  matcherThing = setUrl(matcherThing, rdf.type, acp.Matcher);\n  return matcherThing;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get the [[Matcher]] with the given URL from an [[SolidDataset]].\n *\n * @param matcherResource The Resource that contains the given [[Matcher]].\n * @param url URL that identifies this [[Matcher]].\n * @returns The requested [[Matcher]], if it exists, or `null` if it does not.\n * @since Not released yet.\n */\nexport function getMatcher(\n  matcherResource: SolidDataset,\n  url: Url | UrlString,\n): Matcher | null {\n  const foundThing = getThing(matcherResource, url);\n  if (foundThing === null || !isMatcher(foundThing)) {\n    return null;\n  }\n  return foundThing;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get the [[ResourceMatcher]] with the given name from an Resource's Access Control\n * Resource.\n *\n * @param resourceWithAcr The Resource whose Access Control Resource contains the given [[ResourceMatcher]].\n * @param name Name that identifies this [[ResourceMatcher]].\n * @returns The requested [[ResourceMatcher]], if it exists, or `null` if it does not.\n * @since Not released yet.\n */\nexport function getResourceMatcher(\n  resourceWithAcr: WithAccessibleAcr,\n  name: string,\n): ResourceMatcher | null {\n  const acr = internal_getAcr(resourceWithAcr);\n  const acrUrl = getSourceUrl(acr);\n  const url = new URL(acrUrl);\n  url.hash = `#${name}`;\n  const foundThing = getThing(acr, url.href);\n  if (foundThing === null || !isMatcher(foundThing)) {\n    return null;\n  }\n  return foundThing;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Gets the [[Matcher]]s from a [[SolidDataset]].\n *\n * @param matcherResource The Resource that contains (zero or more) [[Matcher]]s.\n * @returns The [[Matcher]]s contained in this resource.\n * @since Not released yet.\n */\nexport function getMatcherAll(matcherResource: SolidDataset): Matcher[] {\n  const things = getThingAll(matcherResource);\n  return things.filter(isMatcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Gets the [[ResourceMatcher]]s from a Resource's Access Control Resource.\n *\n * @param resourceWithAcr The Resource whose Access Control Resource contains (zero or more) [[ResourceMatcher]]s.\n * @returns The [[ResourceMatcher]]s contained in this Resource's Access Control Resource.\n * @since Not released yet.\n */\nexport function getResourceMatcherAll(\n  resourceWithAcr: WithAccessibleAcr,\n): ResourceMatcher[] {\n  const acr = internal_getAcr(resourceWithAcr);\n  const things = getThingAll(acr);\n  return things.filter(isMatcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Removes the given [[Matcher]] from the given [[SolidDataset]].\n *\n * @param matcherResource The Resource that contains (zero or more) [[Matcher]]s.\n * @returns A new SolidDataset equal to the given Matcher Resource, but without the given Matcher.\n * @since Not released yet.\n */\nexport function removeMatcher<Dataset extends SolidDataset>(\n  matcherResource: Dataset,\n  matcher: Url | UrlString | Matcher,\n): Dataset {\n  return removeThing(matcherResource, matcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Removes the given [[ResourceMatcher]] from the given Resource's Access Control Resource.\n *\n * @param resourceWithAcr The Resource whose Access Control Resource contains (zero or more) [[ResourceMatcher]]s.\n * @returns A new Resource equal to the given Resource, but without the given Matcher in its ACR.\n * @since Not released yet.\n */\nexport function removeResourceMatcher<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  matcher: string | Url | UrlString | ResourceMatcher,\n): ResourceExt {\n  const acr = internal_getAcr(resourceWithAcr);\n  let matcherToRemove: UrlString;\n  if (typeof matcher === \"string\") {\n    if (internal_isValidUrl(matcher)) {\n      matcherToRemove = matcher;\n    } else {\n      // If the given Matcher to remove is the name of the Matcher,\n      // resolve it to its full URL — developers usually refer to either the\n      // Matcher itself, or by its name, as they do not have access to the ACR\n      // directly.\n      const matcherUrl = new URL(getSourceUrl(acr));\n      matcherUrl.hash = `#${matcher}`;\n      matcherToRemove = matcherUrl.href;\n    }\n  } else if (isNamedNode(matcher)) {\n    matcherToRemove = internal_toIriString(matcher);\n  } else {\n    matcherToRemove = asUrl(matcher);\n  }\n\n  // Check whether the actual Matcher (i.e. with the Matcher type) exists:\n  const matchingMatcher = getResourceMatcher(\n    resourceWithAcr,\n    new URL(matcherToRemove).hash.substring(1),\n  );\n  if (matchingMatcher === null) {\n    // No such Matcher exists yet, so return the Resource+ACR unchanged:\n    return resourceWithAcr;\n  }\n\n  const updatedAcr = removeThing(acr, matchingMatcher);\n  const updatedResource = internal_setAcr(resourceWithAcr, updatedAcr);\n  return updatedResource;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Insert the given [[Matcher]] into the given [[SolidDataset]], replacing previous\n * instances of that Matcher.\n *\n * @param matcherResource The Resource that contains (zero or more) [[Matcher]]s.\n * @returns A new SolidDataset equal to the given Matcher Resource, but with the given Matcher.\n * @since Not released yet.\n */\nexport function setMatcher<Dataset extends SolidDataset>(\n  matcherResource: Dataset,\n  matcher: Matcher,\n): Dataset {\n  return setThing(matcherResource, matcher);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Insert the given [[ResourceMatcher]] into the given Resource's Access Control Resource,\n * replacing previous instances of that Matcher.\n *\n * @param resourceWithAcr The Resource whose Access Control Resource contains (zero or more) [[ResourceMatcher]]s.\n * @returns A new Resource equal to the given Resource, but with the given Matcher in its ACR.\n * @since Not released yet.\n */\nexport function setResourceMatcher<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  matcher: ResourceMatcher,\n): ResourceExt {\n  const acr = internal_getAcr(resourceWithAcr);\n  const updatedAcr = setThing(acr, matcher);\n  const updatedResource = internal_setAcr(resourceWithAcr, updatedAcr);\n  return updatedResource;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * List all the agents a [[Matcher]] applies **directly** to. This will not include agents\n * that are matched on a property other than their WebID.\n *\n * @param matcher The matcher from which agents are read.\n * @returns A list of the WebIDs of agents included in the matcher.\n * @since Not released yet.\n */\nexport function getAgentAll(matcher: Matcher): WebId[] {\n  return getIriAll(matcher, acp.agent).filter(\n    (agent: WebId) =>\n      agent !== acp.PublicAgent &&\n      agent !== acp.AuthenticatedAgent &&\n      agent !== acp.CreatorAgent,\n  );\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Overwrite the agents the [[Matcher]] applies to with the provided agents.\n *\n * @param matcher The matcher for which agents are set.\n * @param agent The agent the matcher should apply to.\n * @returns A copy of the input matcher, applying to a different set of agents.\n * @since Not released yet.\n */\nexport function setAgent(matcher: Matcher, agent: WebId): Matcher {\n  // Preserve the special agent classes authenticated and public, which we\n  // don't want to overwrite with this function.\n  const isPublic = hasPublic(matcher);\n  const isAuthenticated = hasAuthenticated(matcher);\n  const isCreator = hasCreator(matcher);\n  let result = setIri(matcher, acp.agent, agent);\n  // Restore public and authenticated\n  if (isPublic) {\n    result = setPublic(result);\n  }\n  if (isAuthenticated) {\n    result = setAuthenticated(result);\n  }\n  if (isCreator) {\n    result = setCreator(result);\n  }\n  return result;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Apply the [[Matcher]] to an additional agent.\n *\n * @param matcher The [[Matcher]] to be applied to an additional agent.\n * @param agent The agent the [[Matcher]] should apply to.\n * @returns A copy of the [[Matcher]], applying to an additional agent.\n * @since Not released yet.\n */\nexport function addAgent(matcher: Matcher, agent: WebId): Matcher {\n  return addIri(matcher, acp.agent, agent);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Prevent the [[Matcher]] from applying to a given agent directly. This will not\n * prevent the agent from matching on other properties than its WebID.\n *\n * @param matcher The [[Matcher]] that should no longer apply to a given agent.\n * @param agent The agent the Matcher should no longer apply to.\n * @returns A copy of the Matcher, not applying to the given agent.\n * @since Not released yet.\n */\nexport function removeAgent(matcher: Matcher, agent: WebId): Matcher {\n  return removeIri(matcher, acp.agent, agent);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Check if the Matcher applies to any agent.\n *\n * @param matcher The Matcher checked for public access.\n * @returns Whether the Matcher applies to any agent or not.\n * @since Not released yet.\n */\nexport function hasPublic(matcher: Matcher): boolean {\n  return (\n    getIriAll(matcher, acp.agent).filter((agent) => agent === acp.PublicAgent)\n      .length > 0\n  );\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Set a Matcher to apply to any Agent.\n *\n * @param matcher The Matcher being modified.\n * @returns A copy of the Matcher, updated to apply to any agent.\n * @since Not released yet.\n */\nexport function setPublic(matcher: Matcher): Matcher {\n  // The second argument should not be part of the function signature,\n  // so it's not in the parameter list:\n  // eslint-disable-next-line prefer-rest-params\n  if (typeof arguments === \"object\" && typeof arguments[1] === \"boolean\") {\n    throw new Error(\n      \"The function `setPublic` no longer takes a second parameter. It is now used together with `removePublic` instead.\",\n    );\n  }\n  return addIri(matcher, acp.agent, acp.PublicAgent);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Set a Matcher to no longer apply to any Agent.\n *\n * @param matcher The Matcher being modified.\n * @returns A copy of the Matcher, updated to no longer apply to any agent.\n * @since Not released yet.\n */\nexport function removePublic(matcher: Matcher): Matcher {\n  return removeIri(matcher, acp.agent, acp.PublicAgent);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Check if the Matcher applies to any authenticated agent.\n *\n * @param matcher The Matcher checked for authenticated access.\n * @returns Whether the Matcher applies to any authenticated agent or not.\n * @since Not released yet.\n */\nexport function hasAuthenticated(matcher: Matcher): boolean {\n  return (\n    getIriAll(matcher, acp.agent).filter(\n      (agent) => agent === acp.AuthenticatedAgent,\n    ).length > 0\n  );\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Set a Matcher to apply to any authenticated Agent.\n *\n * @param matcher The Matcher being modified.\n * @returns A copy of the Matcher, updated to apply to any authenticated Agent.\n * @since Not released yet.\n */\nexport function setAuthenticated(matcher: Matcher): Matcher {\n  // The second argument should not be part of the function signature,\n  // so it's not in the parameter list:\n  // eslint-disable-next-line prefer-rest-params\n  if (typeof arguments === \"object\" && typeof arguments[1] === \"boolean\") {\n    throw new Error(\n      \"The function `setAuthenticated` no longer takes a second parameter. It is now used together with `removeAuthenticated` instead.\",\n    );\n  }\n  return addIri(matcher, acp.agent, acp.AuthenticatedAgent);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Set a Matcher to no longer apply to any authenticated Agent.\n *\n * @param matcher The Matcher being modified.\n * @returns A copy of the Matcher, updated to apply/not apply to any authenticated agent.\n * @since Not released yet.\n */\nexport function removeAuthenticated(matcher: Matcher): Matcher {\n  return removeIri(matcher, acp.agent, acp.AuthenticatedAgent);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Check if the Matcher applies to the creator of the Resource.\n *\n * @param matcher The Matcher checked for authenticated access.\n * @returns Whether the Matcher applies to the creator of the Resource or not.\n * @since Not released yet.\n */\nexport function hasCreator(matcher: Matcher): boolean {\n  return (\n    getIriAll(matcher, acp.agent).filter((agent) => agent === acp.CreatorAgent)\n      .length > 0\n  );\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Set a Matcher to apply to the creator of a Resource.\n *\n * @param matcher The Matcher being modified.\n * @returns A copy of the Matcher, updated to apply to the creator of a Resource.\n * @since Not released yet.\n */\nexport function setCreator(matcher: Matcher): Matcher {\n  // The second argument should not be part of the function signature,\n  // so it's not in the parameter list:\n  // eslint-disable-next-line prefer-rest-params\n  if (typeof arguments === \"object\" && typeof arguments[1] === \"boolean\") {\n    throw new Error(\n      \"The function `setCreator` no longer takes a second parameter. It is now used together with `removeCreator` instead.\",\n    );\n  }\n  return addIri(matcher, acp.agent, acp.CreatorAgent);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Set a Matcher to no longer apply to the creator of a Resource.\n *\n * @param matcher The Matcher being modified.\n * @returns A copy of the Matcher, updated to apply/not apply to the creator of a Resource.\n * @since Not released yet.\n */\nexport function removeCreator(matcher: Matcher): Matcher {\n  return removeIri(matcher, acp.agent, acp.CreatorAgent);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * List all the clients a [[Matcher]] applies **directly** to. This will not include\n * specific client classes, such as public clients.\n *\n * @param matcher The Matcher from which clients are read.\n * @returns A list of the WebIDs of clients included in the Matcher.\n * @since Not released yet.\n */\nexport function getClientAll(matcher: Matcher): WebId[] {\n  return getIriAll(matcher, acp.client)\n    .filter((client: WebId) => client !== solid.PublicOidcClient)\n    .concat(getStringNoLocaleAll(matcher, acp.client));\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Overwrite the clients the [[Matcher]] applies to with the provided Client.\n *\n * @param matcher The Matcher for which clients are set.\n * @param client The Client the Matcher should apply to.\n * @returns A copy of the input Matcher, applying to a different set of Clients.\n */\nexport function setClient(matcher: Matcher, client: Url | string): Matcher {\n  // Preserve the special \"any client\" class, which we\n  // don't want to overwrite with this function.\n  const anyClientEnabled = hasAnyClient(matcher);\n  let result = setIri(matcher, acp.client, client);\n  // Restore the \"any client\" class\n  if (anyClientEnabled) {\n    result = setAnyClient(result);\n  }\n  return result;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Apply the [[Matcher]] to an additional Client.\n *\n * @param matcher The [[Matcher]] to be applied to an additional Client.\n * @param client The Client the [[Matcher]] should apply to.\n * @returns A copy of the [[Matcher]], applying to an additional Client.\n * @since Not released yet.\n */\nexport function addClient(matcher: Matcher, client: Url | string): Matcher {\n  if (!internal_isValidUrl(client)) {\n    return addStringNoLocale(matcher, acp.client, client);\n  }\n  return addIri(matcher, acp.client, client);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Prevent the [[Matcher]] from applying to a given Client directly.\n *\n * @param matcher The [[Matcher]] that should no longer apply to a given Client.\n * @param client The Client the Matcher should no longer apply to.\n * @returns A copy of the Matcher, not applying to the given Client.\n * @since Not released yet.\n */\nexport function removeClient(matcher: Matcher, client: Url | string): Matcher {\n  if (!internal_isValidUrl(client)) {\n    return removeStringNoLocale(matcher, acp.client, client);\n  }\n  return removeIri(matcher, acp.client, client);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Check if the Matcher applies to any client, i.e. all the applications\n * regardless of their identifier.\n *\n * @param matcher The Matcher checked for authenticated access.\n * @returns Whether the Matcher applies to public clients.\n * @since Not released yet.\n * @deprecated\n */\nexport function hasAnyClient(matcher: Matcher): boolean {\n  return (\n    getIriAll(matcher, acp.client).filter(\n      (client) => client === solid.PublicOidcClient,\n    ).length > 0\n  );\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Make the [[Matcher]] apply to any client application.\n *\n * @param matcher The Matcher for which clients are set.\n * @returns A copy of the Matcher, updated to apply to any client\n * @since Not released yet.\n * @deprecated\n */\nexport function setAnyClient(matcher: Matcher): Matcher {\n  return addIri(matcher, acp.client, solid.PublicOidcClient);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Make the [[Matcher]] no longer apply to any client application.\n *\n * @param matcher The Matcher for which clients are set.\n * @returns A copy of the Matcher, updated to no longer apply to any client\n * @since Not released yet.\n * @deprecated\n */\nexport function removeAnyClient(matcher: Matcher): Matcher {\n  return removeIri(matcher, acp.client, solid.PublicOidcClient);\n}\n\n/**\n * Gets a human-readable representation of the given [[Matcher]] to aid debugging.\n *\n * Note that changes to the exact format of the return value are not considered a breaking change;\n * it is intended to aid in debugging, not as a serialisation method that can be reliably parsed.\n *\n * @param matcher The Matcher to get a human-readable representation of.\n * @since Not released yet.\n * @deprecated\n */\nexport function matcherAsMarkdown(matcher: Matcher): string {\n  let markdown = `## Matcher: ${asUrl(matcher)}\\n\\n`;\n\n  let targetEnumeration = \"\";\n  if (hasPublic(matcher)) {\n    targetEnumeration += \"- Everyone\\n\";\n  }\n  if (hasAuthenticated(matcher)) {\n    targetEnumeration += \"- All authenticated agents\\n\";\n  }\n  if (hasCreator(matcher)) {\n    targetEnumeration += \"- The creator of this resource\\n\";\n  }\n  if (hasAnyClient(matcher)) {\n    targetEnumeration += \"- Users of any client application\\n\";\n  }\n  const targetAgents = getAgentAll(matcher);\n  if (targetAgents.length > 0) {\n    targetEnumeration += \"- The following agents:\\n  - \";\n    targetEnumeration += `${targetAgents.join(\"\\n  - \")}\\n`;\n  }\n  const targetClients = getClientAll(matcher);\n  if (targetClients.length > 0) {\n    targetEnumeration += \"- Users of the following client applications:\\n  - \";\n    targetEnumeration += `${targetClients.join(\"\\n  - \")}\\n`;\n  }\n\n  markdown +=\n    targetEnumeration.length > 0\n      ? `This Matcher matches:\\n${targetEnumeration}`\n      : \"<empty>\\n\";\n\n  return markdown;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes, WebId } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { createThing, getThing } from \"../..\";\nimport { internal_getAcr as getAccessControlResource } from \"../control.internal\";\nimport { getAgentAccess } from \"./getAgentAccess\";\nimport { setDefaultAgentMatcherPolicyMatcherThingIfNotExist } from \"../internal/setDefaultAgentMatcherPolicyMatcherThingIfNotExist\";\nimport type { DefaultAccessControlName } from \"../internal/getDefaultAccessControlUrl\";\nimport {\n  DEFAULT_ACCESS_CONTROL,\n  DEFAULT_ACR_ACCESS_CONTROL,\n} from \"../internal/getDefaultAccessControlUrl\";\nimport { getDefaultAgentMatcherPolicyMatcherUrl } from \"../internal/getDefaultAgentMatcherPolicyMatcherUrl\";\nimport { addAgent, removeAgent } from \"../matcher\";\nimport { setAccessControlResourceThing } from \"../internal/setAccessControlResourceThing\";\n\n/** @hidden */\nfunction setAgentAccessMode<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n  webId: WebId,\n  name: DefaultAccessControlName,\n  mode: keyof AccessModes,\n  operation: \"add\" | \"remove\",\n): T {\n  const matcherUrl = getDefaultAgentMatcherPolicyMatcherUrl(\n    resourceWithAcr,\n    name,\n    mode,\n  );\n\n  // Set default Matcher if not exists\n  const resourceWithDefaultAgentMatcher =\n    setDefaultAgentMatcherPolicyMatcherThingIfNotExist(\n      resourceWithAcr,\n      name,\n      mode,\n    );\n\n  const defaultAgentMatcherThing =\n    getThing(\n      getAccessControlResource(resourceWithDefaultAgentMatcher),\n      matcherUrl,\n    ) ?? createThing({ url: matcherUrl });\n\n  return setAccessControlResourceThing<T>(\n    resourceWithDefaultAgentMatcher,\n    operation === \"add\"\n      ? addAgent(defaultAgentMatcherThing, webId)\n      : removeAgent(defaultAgentMatcherThing, webId),\n  );\n}\n\n/**\n * Set access for a given Agent.\n *\n * @param resourceWithAcr URL of the Resource you want to set the access for.\n * @param webId WebID of the Agent you want to set the access for.\n * @param access Access Modes you want to set for the agent.\n * @since 1.16.0\n */\nexport async function setAgentAccess<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n  webId: WebId,\n  access: Partial<AccessModes>,\n): Promise<T> {\n  const agentAccessModes = await getAgentAccess(resourceWithAcr, webId);\n\n  // Add Agent to Default Matchers (including member) if access mode is different from what exists\n  if (\n    typeof access.read === \"boolean\" &&\n    agentAccessModes.read !== access.read\n  ) {\n    resourceWithAcr = setAgentAccessMode(\n      resourceWithAcr,\n      webId,\n      DEFAULT_ACCESS_CONTROL,\n      \"read\",\n      access.read ? \"add\" : \"remove\",\n    );\n  }\n  if (\n    typeof access.append === \"boolean\" &&\n    agentAccessModes.append !== access.append\n  ) {\n    resourceWithAcr = setAgentAccessMode(\n      resourceWithAcr,\n      webId,\n      DEFAULT_ACCESS_CONTROL,\n      \"append\",\n      access.append ? \"add\" : \"remove\",\n    );\n  }\n  if (\n    typeof access.write === \"boolean\" &&\n    agentAccessModes.write !== access.write\n  ) {\n    resourceWithAcr = setAgentAccessMode(\n      resourceWithAcr,\n      webId,\n      DEFAULT_ACCESS_CONTROL,\n      \"write\",\n      access.write ? \"add\" : \"remove\",\n    );\n  }\n  if (\n    typeof access.controlRead === \"boolean\" &&\n    agentAccessModes.controlRead !== access.controlRead\n  ) {\n    resourceWithAcr = setAgentAccessMode(\n      resourceWithAcr,\n      webId,\n      DEFAULT_ACR_ACCESS_CONTROL,\n      \"controlRead\",\n      access.controlRead ? \"add\" : \"remove\",\n    );\n  }\n  if (\n    typeof access.controlWrite === \"boolean\" &&\n    agentAccessModes.controlWrite !== access.controlWrite\n  ) {\n    resourceWithAcr = setAgentAccessMode(\n      resourceWithAcr,\n      webId,\n      DEFAULT_ACR_ACCESS_CONTROL,\n      \"controlWrite\",\n      access.controlWrite ? \"add\" : \"remove\",\n    );\n  }\n\n  return resourceWithAcr;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes, UrlString, WebId } from \"../interfaces\";\nimport type { DefaultOptions } from \"../acp/type/DefaultOptions\";\nimport { getResourceInfo } from \"../resource/resource\";\nimport { setAgentAccess as setAgentAccessAcp } from \"../acp/util/setAgentAccess\";\nimport type { WacAccess } from \"../access/wac\";\nimport {\n  setAgentResourceAccess as setAgentAccessWac,\n  getAgentAccess as getAgentAccessWac,\n} from \"../access/wac\";\nimport { getResourceAcr } from \"../acp/util/getResourceAcr\";\nimport { saveAcrFor } from \"../acp/acp\";\nimport { getAgentAccess } from \"./getAgentAccess\";\n\n/**\n * Set access to a resource for a given Agent.\n *\n * This function works with Solid Pods that implement either the Web Access\n * Control spec or the Access Control Policies proposal, with some caveats:\n *\n * - If access to the given Resource has been set using anything other than the\n *   functions in this module, it is possible that it has been set in a way that\n *   prevents this function from reliably setting access.\n * - It will only set access explicitly for the given Agent. In other words,\n *   additional restrictions could be present that further restrict or loosen\n *   what access the given Agent has in particular circumstances.\n * - The provided access will only apply to the given Resource. In other words,\n *   if the Resource is a Container, the configured Access will not apply to\n *   contained Resources.\n * - If the current user does not have permission to view or change access for\n *   the given Resource, this function will resolve to `null`.\n *\n * Additionally, two caveats apply to users with a Pod server that uses WAC:\n * - If the Resource did not have an ACL yet, a new one will be initialised.\n *   This means that changes to the ACL of a parent Container can no longer\n *   affect access people have to this Resource, although existing access will\n *   be preserved.\n * - Setting different values for `controlRead` and `controlWrite` is not\n *   supported, and **will throw an error**. If you expect (some of) your users\n *   to have Pods implementing WAC, be sure to pass the same value for both.\n *\n * @param resourceUrl URL of the Resource you want to set access for.\n * @param webId WebID of the Agent you want to set access for.\n * @param access The Access Modes to add (true) or remove (false).\n * @param options Default Options such as a fetch function.\n * @since 1.19.0\n */\nexport async function setAgentAccess(\n  resourceUrl: UrlString,\n  webId: WebId,\n  access: Partial<AccessModes>,\n  options?: DefaultOptions,\n): Promise<AccessModes | null> {\n  // TODO: Change the standard getAgentAccess signatures to all take a  T extends WithAcl\n  const resourceInfo = await getResourceInfo(resourceUrl, options);\n  const acr = await getResourceAcr(resourceInfo, options);\n\n  if (acr === null) {\n    await setAgentAccessWac(resourceInfo, webId, access as WacAccess, options);\n    return getAgentAccessWac(resourceInfo, webId, options);\n  }\n\n  // TODO: Make sure both setAgentAccessWac and setAgentAccessAcp don't save within the function, expose one standard saveAclFor function that is universal.\n  try {\n    await saveAcrFor(await setAgentAccessAcp(acr, webId, access), options);\n    return await getAgentAccess(resourceUrl, webId, options);\n  } catch {\n    return null;\n  }\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { setAgentAccess } from \"./setAgentAccess\";\n\n/**\n * Set access for the public.\n *\n * @param resourceWithAcr URL of the Resource you want to read the access for.\n * @param access Access Modes you want to set for the agent.\n * @since 1.16.0\n */\nexport async function setPublicAccess<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n  access: Partial<AccessModes>,\n): Promise<T> {\n  return setAgentAccess(resourceWithAcr, ACP.PublicAgent, access);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { AccessModes, UrlString } from \"../interfaces\";\nimport type { DefaultOptions } from \"../acp/type/DefaultOptions\";\nimport { getResourceInfo } from \"../resource/resource\";\nimport { setPublicAccess as setPublicAccessAcp } from \"../acp/util/setPublicAccess\";\nimport type { WacAccess } from \"../access/wac\";\nimport {\n  setPublicResourceAccess as setPublicAccessWac,\n  getPublicAccess as getPublicAccessWac,\n} from \"../access/wac\";\nimport { getResourceAcr } from \"../acp/util/getResourceAcr\";\nimport { saveAcrFor } from \"../acp/acp\";\nimport { getPublicAccess as getPublicAccessAcp } from \"./getPublicAccess\";\n\n/**\n * Set access to a resource for the public.\n *\n * This function works with Solid Pods that implement either the Web Access\n * Control spec or the Access Control Policies proposal, with some caveats:\n *\n * - If access to the given Resource has been set using anything other than the\n *   functions in this module, it is possible that it has been set in a way that\n *   prevents this function from reliably setting access.\n * - It will only set access explicitly for the given Agent. In other words,\n *   additional restrictions could be present that further restrict or loosen\n *   what access the given Agent has in particular circumstances.\n * - The provided access will only apply to the given Resource. In other words,\n *   if the Resource is a Container, the configured Access will not apply to\n *   contained Resources.\n * - If the current user does not have permission to view or change access for\n *   the given Resource, this function will resolve to `null`.\n *\n * Additionally, two caveats apply to users with a Pod server that uses WAC:\n * - If the Resource did not have an ACL yet, a new one will be initialised.\n *   This means that changes to the ACL of a parent Container can no longer\n *   affect access people have to this Resource, although existing access will\n *   be preserved.\n * - Setting different values for `controlRead` and `controlWrite` is not\n *   supported, and **will throw an error**. If you expect (some of) your users\n *   to have Pods implementing WAC, be sure to pass the same value for both.\n *\n * @param resourceUrl URL of the Resource you want to set access for.\n * @param access The Access Modes to add (true) or remove (false).\n * @param options Default Options such as a fetch function.\n * @since 1.19.0\n */\nexport async function setPublicAccess(\n  resourceUrl: UrlString,\n  access: Partial<AccessModes>,\n  options?: DefaultOptions,\n): Promise<AccessModes | null> {\n  const resourceInfo = await getResourceInfo(resourceUrl, options);\n  const acr = await getResourceAcr(resourceInfo, options);\n\n  if (acr === null) {\n    await setPublicAccessWac(resourceInfo, access as WacAccess, options);\n    return getPublicAccessWac(resourceInfo, options);\n  }\n\n  try {\n    await saveAcrFor(await setPublicAccessAcp(acr, access), options);\n    return await getPublicAccessAcp(resourceUrl, options);\n  } catch {\n    return null;\n  }\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Url, UrlString } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { buildThing } from \"../../thing/build\";\nimport { getDefaultAccessControlThing } from \"../internal/getDefaultAccessControlThing\";\nimport { DEFAULT_MEMBER_ACR_ACCESS_CONTROL } from \"../internal/getDefaultAccessControlUrl\";\nimport { setAccessControlResourceThing } from \"../internal/setAccessControlResourceThing\";\nimport { setDefaultAccessControlThingIfNotExist } from \"../internal/setDefaultAccessControlThingIfNotExist\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Add a policy applying to the ACRs of the given resource's children.\n *\n * @param resourceWithAcr The resource for which to add the URL of a policy\n * applying to its children's access control resources.\n * @param policyUrl A Policy URL.\n * @returns The resource with its ammended access control resource.\n * @since 1.16.1\n */\nexport function addMemberAcrPolicyUrl<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n  policyUrl: Url | UrlString,\n): T {\n  const resourceWithAcrContainingDefaultAccessControl =\n    setDefaultAccessControlThingIfNotExist(\n      resourceWithAcr,\n      DEFAULT_MEMBER_ACR_ACCESS_CONTROL,\n    );\n\n  const defaultAccessControlThing = getDefaultAccessControlThing(\n    resourceWithAcrContainingDefaultAccessControl,\n    DEFAULT_MEMBER_ACR_ACCESS_CONTROL,\n  );\n\n  return setAccessControlResourceThing(\n    resourceWithAcrContainingDefaultAccessControl,\n    buildThing(defaultAccessControlThing).addUrl(ACP.access, policyUrl).build(),\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Url, UrlString } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { buildThing } from \"../../thing/build\";\nimport { getDefaultAccessControlThing } from \"../internal/getDefaultAccessControlThing\";\nimport { DEFAULT_MEMBER_ACCESS_CONTROL } from \"../internal/getDefaultAccessControlUrl\";\nimport { setAccessControlResourceThing } from \"../internal/setAccessControlResourceThing\";\nimport { setDefaultAccessControlThingIfNotExist } from \"../internal/setDefaultAccessControlThingIfNotExist\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Add a policy applying to the given resource's children.\n *\n * @param resourceWithAcr The resource for which to add the URL of a policy\n * applying to its children.\n * @param policyUrl A Policy URL.\n * @returns The resource with its ammended access control resource.\n * @since 1.16.1\n */\nexport function addMemberPolicyUrl<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n  policyUrl: Url | UrlString,\n): T {\n  const resourceWithAcrContainingDefaultMemberAccessControl =\n    setDefaultAccessControlThingIfNotExist(\n      resourceWithAcr,\n      DEFAULT_MEMBER_ACCESS_CONTROL,\n    );\n  const defaultMemberAccessControlThing = getDefaultAccessControlThing(\n    resourceWithAcrContainingDefaultMemberAccessControl,\n    DEFAULT_MEMBER_ACCESS_CONTROL,\n  );\n\n  return setAccessControlResourceThing(\n    resourceWithAcrContainingDefaultMemberAccessControl,\n    buildThing(defaultMemberAccessControlThing)\n      .addUrl(ACP.apply, policyUrl)\n      .build(),\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport { ACP } from \"../constants\";\nimport type { UrlString } from \"../../interfaces\";\nimport { getIriAll } from \"../../thing/get\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { getAccessControlResourceThing } from \"../internal/getAccessControlResourceThing\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Get the URL of all member access controls linked to the given resource's ACR.\n *\n * @param resourceWithAcr The resource for which to retrieve URLs of access\n * controls inherited by its children.\n * @returns Access Control URL array\n * @since 1.6.0\n */\nexport function getMemberAccessControlUrlAll(\n  resourceWithAcr: WithAccessibleAcr,\n): UrlString[] {\n  const acrThing = getAccessControlResourceThing(resourceWithAcr);\n\n  if (acrThing === null) {\n    return [];\n  }\n\n  return getIriAll(acrThing, ACP.memberAccessControl);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { UrlString } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { getMemberAccessControlUrlAll } from \"../accessControl/getMemberAccessControlUrlAll\";\nimport { getPolicyUrls } from \"../internal/getPolicyUrls\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Get the URLs of policies applying to the ACRs of the given resource's\n * children.\n *\n * @param resourceWithAcr The resource for which to retrieve URLs of policies\n * applying to its children's access control resources.\n * @returns Policy URL array.\n * @since 1.16.1\n */\nexport function getMemberAcrPolicyUrlAll<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n): UrlString[] {\n  return getPolicyUrls(\n    resourceWithAcr,\n    getMemberAccessControlUrlAll(resourceWithAcr),\n    ACP.access,\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { UrlString } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { getMemberAccessControlUrlAll } from \"../accessControl/getMemberAccessControlUrlAll\";\nimport { getPolicyUrls } from \"../internal/getPolicyUrls\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Get the URLs of policies applying to the given resource's children.\n *\n * @param resourceWithAcr The resource for which to retrieve URLs policies\n * applying to its children.\n * @returns Policy URL array.\n * @since 1.16.1\n */\nexport function getMemberPolicyUrlAll<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n): UrlString[] {\n  return getPolicyUrls(\n    resourceWithAcr,\n    getMemberAccessControlUrlAll(resourceWithAcr),\n    ACP.apply,\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Url, UrlString } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { getDefaultAccessControlThing } from \"../internal/getDefaultAccessControlThing\";\nimport { DEFAULT_ACR_ACCESS_CONTROL } from \"../internal/getDefaultAccessControlUrl\";\nimport { setAccessControlResourceThing } from \"../internal/setAccessControlResourceThing\";\nimport { removeIri } from \"../../thing/remove\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Remove a policy applying to the ACR of the given resource.\n *\n * @param resourceWithAcr The resource for which to remove the URL of a policy\n * applying to its access control resource.\n * @param policyUrl A Policy URL.\n * @returns The resource with its ammended access control resource.\n * @since 1.16.1\n */\nexport function removeAcrPolicyUrl<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n  policyUrl: Url | UrlString,\n): T {\n  const defaultAccessControlThing = getDefaultAccessControlThing(\n    resourceWithAcr,\n    DEFAULT_ACR_ACCESS_CONTROL,\n  );\n\n  return setAccessControlResourceThing(\n    resourceWithAcr,\n    removeIri(defaultAccessControlThing, ACP.access, policyUrl),\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Url, UrlString } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { getDefaultAccessControlThing } from \"../internal/getDefaultAccessControlThing\";\nimport { DEFAULT_MEMBER_ACR_ACCESS_CONTROL } from \"../internal/getDefaultAccessControlUrl\";\nimport { setAccessControlResourceThing } from \"../internal/setAccessControlResourceThing\";\nimport { removeIri } from \"../../thing/remove\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Remove a policy applying to the ACRs of the given resource's children.\n *\n * @param resourceWithAcr The resource for which to remove the URL of a policy\n * applying to its children's access control resources.\n * @param policyUrl A Policy URL.\n * @returns The resource with its ammended access control resource.\n * @since 1.16.1\n */\nexport function removeMemberAcrPolicyUrl<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n  policyUrl: Url | UrlString,\n): T {\n  const defaultAccessControlThing = getDefaultAccessControlThing(\n    resourceWithAcr,\n    DEFAULT_MEMBER_ACR_ACCESS_CONTROL,\n  );\n\n  return setAccessControlResourceThing(\n    resourceWithAcr,\n    removeIri(defaultAccessControlThing, ACP.access, policyUrl),\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Url, UrlString } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { getDefaultAccessControlThing } from \"../internal/getDefaultAccessControlThing\";\nimport { DEFAULT_MEMBER_ACCESS_CONTROL } from \"../internal/getDefaultAccessControlUrl\";\nimport { setAccessControlResourceThing } from \"../internal/setAccessControlResourceThing\";\nimport { removeIri } from \"../../thing/remove\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Remove a policy applying to the given resource's children.\n *\n * @param resourceWithAcr The resource for which to remove the URL of a policy\n * applying to its children.\n * @param policyUrl A Policy URL.\n * @returns The resource with its ammended access control resource.\n * @since 1.16.1\n */\nexport function removeMemberPolicyUrl<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n  policyUrl: Url | UrlString,\n): T {\n  const defaultAccessControlThing = getDefaultAccessControlThing(\n    resourceWithAcr,\n    DEFAULT_MEMBER_ACCESS_CONTROL,\n  );\n\n  return setAccessControlResourceThing(\n    resourceWithAcr,\n    removeIri(defaultAccessControlThing, ACP.apply, policyUrl),\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Url, UrlString } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { ACP } from \"../constants\";\nimport { getDefaultAccessControlThing } from \"../internal/getDefaultAccessControlThing\";\nimport { DEFAULT_ACCESS_CONTROL } from \"../internal/getDefaultAccessControlUrl\";\nimport { setAccessControlResourceThing } from \"../internal/setAccessControlResourceThing\";\nimport { removeIri } from \"../../thing/remove\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Remove a policy applying to the given resource.\n *\n * @param resourceWithAcr The resource for which to remove the URL of a policy\n * applying to it.\n * @param policyUrl A Policy URL.\n * @returns The resource with its ammended access control resource.\n * @since 1.16.1\n */\nexport function removePolicyUrl<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n  policyUrl: Url | UrlString,\n): T {\n  const defaultAccessControlThing = getDefaultAccessControlThing(\n    resourceWithAcr,\n    DEFAULT_ACCESS_CONTROL,\n  );\n\n  return setAccessControlResourceThing(\n    resourceWithAcr,\n    removeIri(defaultAccessControlThing, ACP.apply, policyUrl),\n  );\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { ThingPersisted } from \"../../interfaces\";\nimport type { WithAccessibleAcr } from \"../acp\";\nimport { setAccessControlResourceThing } from \"../internal/setAccessControlResourceThing\";\n\n/**\n * ```{note}\n * The ACP specification is a draft. As such, this function is experimental and\n * subject to change, even in a non-major release.\n * See also: https://solid.github.io/authorization-panel/acp-specification/\n * ```\n *\n * Insert the given [[ResourcePolicy]] into the given Resource's Acccess Control\n * Resource, replacing previous instances of that Policy.\n *\n * @param resourceWithAcr The Resource whose Access Control Resource contains Access Policies.\n * @param policy The Policy to insert into the Resource's Access Control Resource.\n * @returns A new Resource equal to the given Resource, but with the given Policy in its Access Control Resource.\n * @since 1.18.0\n */\nexport function setResourcePolicy<T extends WithAccessibleAcr>(\n  resourceWithAcr: T,\n  policy: ThingPersisted,\n): T {\n  return setAccessControlResourceThing(resourceWithAcr, policy);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { Quad_Object } from \"@rdfjs/types\";\nimport { internal_accessModeIriStrings } from \"../acl/acl.internal\";\nimport { acp, rdf } from \"../constants\";\nimport { internal_isValidUrl, isNamedNode } from \"../datatypes\";\nimport {\n  SolidClientError,\n  type SolidDataset,\n  type Thing,\n  type ThingPersisted,\n  type Url,\n  type UrlString,\n} from \"../interfaces\";\nimport { internal_toIriString } from \"../interfaces.internal\";\nimport { getSourceUrl } from \"../resource/resource\";\nimport { addIri } from \"../thing/add\";\nimport { getIriAll, getTermAll } from \"../thing/get\";\nimport { removeAll } from \"../thing/remove\";\nimport { setUrl } from \"../thing/set\";\nimport {\n  asUrl,\n  createThing,\n  getThing,\n  getThingAll,\n  isThingLocal,\n  removeThing,\n  setThing,\n} from \"../thing/thing\";\nimport type { WithAccessibleAcr } from \"./acp\";\nimport {\n  addAcrPolicyUrl,\n  addPolicyUrl,\n  getAcrPolicyUrlAll,\n  getPolicyUrlAll,\n  removeAcrPolicyUrl,\n  removePolicyUrl,\n} from \"./control\";\nimport { internal_getAcr, internal_setAcr } from \"./control.internal\";\nimport type { BlankNodeId } from \"../rdf.internal\";\n\n/**\n * A Policy can be applied to Resources to grant or deny [[AccessModes]] to users who match the Policy's [[Rule]]s.\n * @since 1.6.0\n */\nexport type Policy = ThingPersisted;\n/**\n * A Resource Policy is like a regular [[Policy]], but rather than being re-used for different Resources, it is used for a single Resource and is stored in that Resource's Access Control Resource.\n * @since 1.6.0\n */\nexport type ResourcePolicy = ThingPersisted;\n/**\n * A Resource Policy is like a regular [[Policy]], but rather than being re-used for different Resources, it is used for a single Resource and is stored in that Resource's Access Control Resource.\n * @since 1.6.0\n */\nexport type AnonymousResourcePolicy = Thing & { url: BlankNodeId };\n/**\n * The different Access Modes that a [[Policy]] can allow or deny for a Resource.\n * @since 1.6.0\n */\nexport type AccessModes = {\n  read: boolean;\n  append: boolean;\n  write: boolean;\n};\n\n/**\n * @param thing the [[Thing]] to check to see if it's an ACP Policy or not\n */\nfunction isPolicy(thing: ThingPersisted): thing is Policy {\n  return getIriAll(thing, rdf.type).includes(acp.Policy);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Initialise a new, empty [[Policy]].\n *\n * @param url URL that identifies this Policy.\n * @since 1.6.0\n */\nexport function createPolicy(url: Url | UrlString): Policy {\n  const stringUrl = internal_toIriString(url);\n  let policyThing = createThing({ url: stringUrl });\n  policyThing = setUrl(policyThing, rdf.type, acp.Policy);\n\n  return policyThing;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get the [[Policy]] with the given URL from an [[SolidDataset]].\n *\n * @param policyResource The Resource that contains the given Policy.\n * @param url URL that identifies this Policy.\n * @returns The requested Policy, if it exists, or `null` if it does not.\n * @since 1.6.0\n */\nexport function getPolicy(\n  policyResource: SolidDataset,\n  url: Url | UrlString,\n): Policy | null {\n  const foundThing = getThing(policyResource, url);\n  if (foundThing === null || !isPolicy(foundThing)) {\n    return null;\n  }\n\n  return foundThing;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get all [[Policy]]'s in a given [[SolidDataset]].\n *\n * @param policyResource The Resource that contains Access Policies.\n * @since 1.6.0\n */\nexport function getPolicyAll(policyResource: SolidDataset): Policy[] {\n  const foundThings = getThingAll(policyResource);\n  const foundPolicies = foundThings.filter(\n    (thing) => !isThingLocal(thing) && isPolicy(thing),\n  ) as Policy[];\n  return foundPolicies;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Remove the given [[Policy]] from the given [[SolidDataset]].\n *\n * @param policyResource The Resource that contains Access Policies.\n * @param policy The Policy to remove from the resource.\n * @since 1.6.0\n */\nexport function removePolicy<Dataset extends SolidDataset>(\n  policyResource: Dataset,\n  policy: Url | UrlString | Policy,\n): Dataset {\n  return removeThing(policyResource, policy);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Insert the given [[Policy]] into the given [[SolidDataset]], replacing previous instances of that Policy.\n *\n * @param policyResource The Resource that contains Access Policies.\n * @param policy The Policy to insert into the Resource.\n * @returns A new dataset equal to the given resource, but with the given Policy.\n * @since 1.6.0\n */\nexport function setPolicy<Dataset extends SolidDataset>(\n  policyResource: Dataset,\n  policy: Policy,\n): Dataset {\n  return setThing(policyResource, policy);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Given a [[Policy]] and a set of [[AccessModes]], return a new Policy based on the given\n * Policy, but with the given Access Modes allowed on it.\n *\n * @param policy The Policy on which to set the modes to allow.\n * @param modes Modes to allow for this Policy.\n * @since Not released yet.\n */\nexport function setAllowModesV2<P extends Policy | ResourcePolicy>(\n  policy: P,\n  modes: AccessModes,\n): P {\n  let newPolicy = removeAll(policy, acp.allow);\n\n  if (modes.read === true) {\n    newPolicy = addIri(\n      newPolicy,\n      acp.allow,\n      internal_accessModeIriStrings.read,\n    );\n  }\n  if (modes.append === true) {\n    newPolicy = addIri(\n      newPolicy,\n      acp.allow,\n      internal_accessModeIriStrings.append,\n    );\n  }\n  if (modes.write === true) {\n    newPolicy = addIri(\n      newPolicy,\n      acp.allow,\n      internal_accessModeIriStrings.write,\n    );\n  }\n\n  return newPolicy;\n}\n/**\n * See [[setAllowModesV2]].\n */\nexport const setAllowModes = setAllowModesV2;\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Given a [[Policy]], return which [[AccessModes]] it allows.\n *\n * @param policy The Policy for which you want to know the Access Modes it allows.\n * @since Not released yet.\n */\nexport function getAllowModesV2<P extends Policy | ResourcePolicy>(\n  policy: P,\n): AccessModes {\n  const allowedModes = getIriAll(policy, acp.allow);\n  return {\n    read: allowedModes.includes(internal_accessModeIriStrings.read),\n    append: allowedModes.includes(internal_accessModeIriStrings.append),\n    write: allowedModes.includes(internal_accessModeIriStrings.write),\n  };\n}\n\n/**\n * See [[getAllowModesV2]].\n */\nexport const getAllowModes = getAllowModesV2;\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Given a [[Policy]] and a set of [[AccessModes]], return a new Policy based on the given\n * Policy, but with the given Access Modes disallowed on it.\n *\n * @param policy The Policy on which to set the modes to disallow.\n * @param modes Modes to disallow for this Policy.\n * @since Not released yet.\n */\nexport function setDenyModesV2<P extends Policy | ResourcePolicy>(\n  policy: P,\n  modes: AccessModes,\n): P {\n  let newPolicy = removeAll(policy, acp.deny);\n\n  if (modes.read === true) {\n    newPolicy = addIri(newPolicy, acp.deny, internal_accessModeIriStrings.read);\n  }\n  if (modes.append === true) {\n    newPolicy = addIri(\n      newPolicy,\n      acp.deny,\n      internal_accessModeIriStrings.append,\n    );\n  }\n  if (modes.write === true) {\n    newPolicy = addIri(\n      newPolicy,\n      acp.deny,\n      internal_accessModeIriStrings.write,\n    );\n  }\n\n  return newPolicy;\n}\n\n/**\n * See [[setDenyModesV2]].\n */\nexport const setDenyModes = setDenyModesV2;\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Given a [[Policy]], return which [[AccessModes]] it disallows.\n *\n * @param policy The Policy on which you want to know the Access Modes it disallows.\n * @since Not released yet.\n */\nexport function getDenyModesV2<P extends Policy | ResourcePolicy>(\n  policy: P,\n): AccessModes {\n  const deniedModes = getIriAll(policy, acp.deny);\n  return {\n    read: deniedModes.includes(internal_accessModeIriStrings.read),\n    append: deniedModes.includes(internal_accessModeIriStrings.append),\n    write: deniedModes.includes(internal_accessModeIriStrings.write),\n  };\n}\n\n/**\n * See [[getDenyModesV2]].\n */\nexport const getDenyModes = getDenyModesV2;\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Initialise a new, empty [[ResourcePolicy]] for the given Resource.\n *\n * @param resourceWithAcr The Resource to which the Policy is to apply.\n * @param name The name that identifies this Policy.\n * @since 1.6.0\n */\nexport function createResourcePolicyFor(\n  resourceWithAcr: WithAccessibleAcr,\n  name: string,\n): ResourcePolicy {\n  const acr = internal_getAcr(resourceWithAcr);\n  const url = new URL(getSourceUrl(acr));\n  url.hash = `#${name}`;\n  let policyThing = createThing({ url: url.href });\n  policyThing = setUrl(policyThing, rdf.type, acp.Policy);\n\n  return policyThing;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get the [[ResourcePolicy]] with the given name that applies to a Resource\n * from its Access Control Resource.\n *\n * @param resourceWithAcr The Resource whose ACR contains the given Policy.\n * @param name The name that identifies this Policy.\n * @returns The requested Policy, if it exists and applies to the given Resource, or `null` if it does not.\n * @since 1.6.0\n */\nexport function getResourcePolicy(\n  resourceWithAcr: WithAccessibleAcr,\n  name: string,\n): ResourcePolicy | null {\n  const acr = internal_getAcr(resourceWithAcr);\n  const acrUrl = getSourceUrl(acr);\n  const url = new URL(acrUrl);\n  url.hash = `#${name}`;\n  const foundThing = getThing(acr, url.href);\n  if (\n    !getPolicyUrlAll(resourceWithAcr).includes(url.href) ||\n    foundThing === null ||\n    !isPolicy(foundThing)\n  ) {\n    return null;\n  }\n\n  return foundThing;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get the [[ResourcePolicy]] with the given name that applies to a Resource's\n * Access Control Resource from that Access Control Resource.\n *\n * @param resourceWithAcr The Resource whose ACR contains the given Policy.\n * @param name The name that identifies this Policy.\n * @returns The requested Policy, if it exists and applies to the Resource's ACR, or `null` if it does not.\n * @since 1.6.0\n */\nexport function getResourceAcrPolicy(\n  resourceWithAcr: WithAccessibleAcr,\n  name: string,\n): ResourcePolicy | null {\n  const acr = internal_getAcr(resourceWithAcr);\n  const acrUrl = getSourceUrl(acr);\n  const url = new URL(acrUrl);\n  url.hash = `#${name}`;\n  const foundThing = getThing(acr, url.href);\n  if (\n    !getAcrPolicyUrlAll(resourceWithAcr).includes(url.href) ||\n    foundThing === null ||\n    !isPolicy(foundThing)\n  ) {\n    return null;\n  }\n\n  return foundThing;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get all [[ResourcePolicy]]'s that apply to a Resource in its Access Control\n * Resource.\n *\n * @param resourceWithAcr The Resource whose Access Control Resource contains Access Policies applying to it.\n * @since 1.6.0\n */\nexport function getResourcePolicyAll(\n  resourceWithAcr: WithAccessibleAcr,\n): ResourcePolicy[];\nexport function getResourcePolicyAll(\n  resourceWithAcr: WithAccessibleAcr,\n  options: { acceptBlankNodes: true },\n): (ResourcePolicy | AnonymousResourcePolicy)[];\nexport function getResourcePolicyAll(\n  resourceWithAcr: WithAccessibleAcr,\n  options: { acceptBlankNodes: false },\n): ResourcePolicy[];\nexport function getResourcePolicyAll(\n  resourceWithAcr: WithAccessibleAcr,\n  options: { acceptBlankNodes: boolean },\n): (ResourcePolicy | AnonymousResourcePolicy)[];\nexport function getResourcePolicyAll(\n  resourceWithAcr: WithAccessibleAcr,\n  options: { acceptBlankNodes: boolean } = { acceptBlankNodes: false },\n): (ResourcePolicy | AnonymousResourcePolicy)[] {\n  const acr = internal_getAcr(resourceWithAcr);\n  const acrUrl = getSourceUrl(acr);\n  const acrSubj = getThing(acr, acrUrl);\n  if (acrSubj === null) {\n    throw new SolidClientError(\n      `The provided ACR graph does not have an anchor node matching its URL ${acrUrl}`,\n    );\n  }\n  // Follow the links from acr -acp:accessControl> Acccess Control -acp:apply> Policy.\n  return (\n    // List all candidate Access Controls\n    getTermAll(acrSubj, acp.accessControl)\n      // For each candidate, check whether it is a subject with associated triples.\n      .map((accessControlId) => getThing(acr, accessControlId.value))\n      // Eliminate non-subject Access Control Candidates\n      .filter(\n        (accessControlSubject): accessControlSubject is ThingPersisted =>\n          accessControlSubject !== null,\n      )\n      // For all subject Access Control candidates, list all the policies they apply.\n      .reduce((policies, accessControlSubj) => {\n        const accessControlPolicies = getTermAll(\n          accessControlSubj,\n          acp.apply,\n        ).filter(\n          // If the option is set, all candidate policies are acceptable.\n          (policy) =>\n            options.acceptBlankNodes ? true : policy.termType === \"NamedNode\",\n        );\n        return [...policies, ...accessControlPolicies];\n      }, [] as Quad_Object[])\n      // Get all the triples for the found policies subjects.\n      .map((policyId) => {\n        if (policyId.termType === \"BlankNode\") {\n          // policyId.value removes the _: prefix,\n          // which we rely on for matching.\n          return getThing(acr, `_:${policyId.value}`);\n        }\n        return getThing(acr, policyId.value);\n      })\n      .filter((thing): thing is Thing => thing !== null)\n  );\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Get all [[ResourcePolicy]]'s that apply to a given Resource's Access Control\n * Resource from that Access Control Resource.\n *\n * @param resourceWithAcr The Resource whose Access Control Resource contains Access Policies.\n * @since 1.6.0\n */\nexport function getResourceAcrPolicyAll(\n  resourceWithAcr: WithAccessibleAcr,\n): ResourcePolicy[] {\n  const acr = internal_getAcr(resourceWithAcr);\n  const policyUrls = getAcrPolicyUrlAll(resourceWithAcr);\n  const foundThings = policyUrls.map((policyUrl) => getThing(acr, policyUrl));\n  const foundPolicies = foundThings.filter(\n    (thing) => thing !== null && isPolicy(thing),\n  ) as ResourcePolicy[];\n  return foundPolicies;\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Remove the given [[ResourcePolicy]] from the given Resource's Access Control\n * Resource.\n *\n * @param resourceWithAcr The Resource whose Access Control Resource contains Access Policies.\n * @param policy The Policy to remove from the Resource's Access Control Resource.\n * @since 1.6.0\n */\nexport function removeResourcePolicy<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  policy: string | Url | UrlString | ResourcePolicy,\n): ResourceExt {\n  const acr = internal_getAcr(resourceWithAcr);\n  let policyToRemove = policy;\n  if (typeof policyToRemove === \"string\") {\n    if (internal_isValidUrl(policyToRemove) === false) {\n      // If the given Policy to remove is the name of the Policy,\n      // resolve it to its full URL — developers usually refer to either the\n      // Policy itself, or by its name, as they do not have access to the ACR\n      // directly.\n      const policyUrl = new URL(getSourceUrl(acr));\n      policyUrl.hash = `#${policy}`;\n      policyToRemove = policyUrl.href;\n    }\n  }\n  let policyUrlString: UrlString;\n  if (typeof policyToRemove === \"string\") {\n    policyUrlString = policyToRemove;\n  } else if (isNamedNode(policyToRemove)) {\n    policyUrlString = internal_toIriString(policyToRemove);\n  } else {\n    policyUrlString = asUrl(policyToRemove, getSourceUrl(acr));\n  }\n\n  // Check whether the actual Policy (i.e. with the Policy type) exists:\n  const matchingRule = getResourcePolicy(\n    resourceWithAcr,\n    new URL(policyUrlString).hash.substring(1),\n  );\n  if (matchingRule === null) {\n    // No such Policy exists yet, so return the Resource+ACR unchanged:\n    return resourceWithAcr;\n  }\n\n  const updatedAcr = removeThing(acr, policyToRemove);\n  const updatedResource = internal_setAcr(resourceWithAcr, updatedAcr);\n  return removePolicyUrl(updatedResource, policyUrlString);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Remove the given [[ResourcePolicy]] that applies to a given Resource's Access\n * Control Resource from that Access Control Resource.\n *\n * @param resourceWithAcr The Resource whose Access Control Resource contains Access Policies.\n * @param policy The ACR Policy to remove from the Resource's Access Control Resource.\n * @since 1.6.0\n */\nexport function removeResourceAcrPolicy<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  policy: string | Url | UrlString | ResourcePolicy,\n): ResourceExt {\n  const acr = internal_getAcr(resourceWithAcr);\n  let policyToRemove = policy;\n  if (typeof policyToRemove === \"string\") {\n    if (internal_isValidUrl(policyToRemove) === false) {\n      // If the given Policy to remove is the name of the Policy,\n      // resolve it to its full URL — developers usually refer to either the\n      // Policy itself, or by its name, as they do not have access to the ACR\n      // directly.\n      const policyUrl = new URL(getSourceUrl(acr));\n      policyUrl.hash = `#${policy}`;\n      policyToRemove = policyUrl.href;\n    }\n  }\n\n  let policyUrlString: string;\n  if (typeof policyToRemove === \"string\") {\n    policyUrlString = policyToRemove;\n  } else if (isNamedNode(policyToRemove)) {\n    policyUrlString = internal_toIriString(policyToRemove);\n  } else {\n    policyUrlString = asUrl(policyToRemove, getSourceUrl(acr));\n  }\n\n  // Check whether the actual Policy (i.e. with the Policy type) exists:\n  const matchingRule = getResourceAcrPolicy(\n    resourceWithAcr,\n    new URL(policyUrlString).hash.substring(1),\n  );\n  if (matchingRule === null) {\n    // No such Policy exists yet, so return the Resource+ACR unchanged:\n    return resourceWithAcr;\n  }\n\n  const updatedAcr = removeThing(acr, policyToRemove);\n  const updatedResource = internal_setAcr(resourceWithAcr, updatedAcr);\n  return removeAcrPolicyUrl(updatedResource, policyUrlString);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Insert the given [[ResourcePolicy]] into the given Resource's Acccess Control\n * Resource, replacing previous instances of that Policy.\n *\n * @param resourceWithAcr The Resource whose Access Control Resource contains Access Policies.\n * @param policy The Policy to insert into the Resource's Access Control Resource.\n * @returns A new Resource equal to the given Resource, but with the given Policy in its Access Control Resource.\n * @since 1.6.0\n */\nexport function setResourcePolicy<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  policy: ResourcePolicy,\n): ResourceExt {\n  const acr = internal_getAcr(resourceWithAcr);\n  const updatedAcr = setThing(acr, policy);\n  const updatedResource = internal_setAcr(resourceWithAcr, updatedAcr);\n  const policyUrl = asUrl(policy, getSourceUrl(acr));\n  return addPolicyUrl(updatedResource, policyUrl);\n}\n\n/**\n * ```{note} There is no Access Control Policies specification yet. As such, this\n * function is still experimental and subject to change, even in a non-major release.\n * ```\n *\n * Insert the given [[ResourcePolicy]] into the given Resource's Acccess Control\n * Resource, replacing previous instances of that Policy, to apply to the Access\n * Control Resource itself.\n *\n * @param resourceWithAcr The Resource whose Access Control Resource contains Access Policies.\n * @param policy The Policy to insert into the Resource's Access Control Resource.\n * @returns A new Resource equal to the given Resource, but with the given Policy in its Access Control Resource, applying to that Access Control Resource.\n * @since 1.6.0\n */\nexport function setResourceAcrPolicy<ResourceExt extends WithAccessibleAcr>(\n  resourceWithAcr: ResourceExt,\n  policy: ResourcePolicy,\n): ResourceExt {\n  const acr = internal_getAcr(resourceWithAcr);\n  const updatedAcr = setThing(acr, policy);\n  const updatedResource = internal_setAcr(resourceWithAcr, updatedAcr);\n  const policyUrl = asUrl(policy, getSourceUrl(acr));\n  return addAcrPolicyUrl(updatedResource, policyUrl);\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport type { UrlString, WithResourceInfo } from \"../interfaces\";\nimport { mockSolidDatasetFrom } from \"../resource/mock\";\nimport { getSourceUrl } from \"../resource/resource\";\nimport { internal_cloneResource } from \"../resource/resource.internal\";\nimport { createThing, setThing } from \"../thing/thing\";\nimport type { WithAccessibleAcr } from \"./acp\";\nimport type { AccessControlResource } from \"./control\";\n\n/**\n *\n * ```{warning}\n * Do not use this function in production code.  For use in **unit tests** that require a\n * [[AccessControlResource]].\n * ```\n *\n * Initialises a new empty Access Control Resource for a given Resource for use\n * in **unit tests**.\n *\n * @param resourceUrl The URL of the Resource to which the mocked ACR should apply.\n * @returns The mocked empty Access Control Resource for the given Resource.\n * @since 1.6.0\n */\nexport function mockAcrFor(\n  resourceUrl: UrlString,\n  acrUrl?: UrlString,\n): AccessControlResource {\n  const finalAcrUrl =\n    acrUrl ?? new URL(\"access-control-resource\", resourceUrl).href;\n  const acr: AccessControlResource = {\n    ...setThing(\n      mockSolidDatasetFrom(finalAcrUrl),\n      createThing({ url: finalAcrUrl }),\n    ),\n    accessTo: resourceUrl,\n  };\n\n  return acr;\n}\n\n/**\n * ```{warning}\n * Do not use this function in production code.  For use in **unit tests** that require a\n * Resource with an [[AccessControlResource]].\n * ```\n *\n * Attaches an Access Control Resource to a given [[SolidDataset]] for use\n * in **unit tests**; e.g., unit tests that call [[getPolicyUrlAll]].\n *\n * @param resource The Resource to mock up with a new resource ACL.\n * @param accessControlResource The Access Control Resource to attach to the given Resource.\n * @returns The input Resource with an empty resource ACL attached.\n * @since 1.6.0\n */\nexport function addMockAcrTo<T extends WithResourceInfo>(\n  resource: T,\n  accessControlResource: AccessControlResource = mockAcrFor(\n    getSourceUrl(resource),\n  ),\n): T & WithAccessibleAcr {\n  const resourceWithAcr: typeof resource & WithAccessibleAcr = Object.assign(\n    internal_cloneResource(resource),\n    {\n      internal_acp: {\n        acr: accessControlResource,\n        aprs: {},\n      },\n    },\n  );\n\n  return resourceWithAcr;\n}\n","// Copyright Inrupt Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the\n// Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nimport * as formats from \"./formats\";\n\nexport {\n  isContainer,\n  isRawData,\n  getSourceUrl,\n  getSourceIri,\n  getContentType,\n  getResourceInfo,\n  getPodOwner,\n  isPodOwner,\n  getLinkedResourceUrlAll,\n  getEffectiveAccess,\n  responseToResourceInfo,\n  FetchError,\n} from \"./resource/resource\";\nexport {\n  getFile,\n  deleteFile,\n  saveFileInContainer,\n  overwriteFile,\n} from \"./resource/file\";\nexport {\n  createSolidDataset,\n  getSolidDataset,\n  saveSolidDatasetAt,\n  deleteSolidDataset,\n  createContainerAt,\n  saveSolidDatasetInContainer,\n  createContainerInContainer,\n  deleteContainer,\n  getContainedResourceUrlAll,\n  validateContainedResourceAll,\n  solidDatasetAsMarkdown,\n  changeLogAsMarkdown,\n  Parser,\n  ParseOptions,\n  responseToSolidDataset,\n  getWellKnownSolid,\n} from \"./resource/solidDataset\";\nexport {\n  mockSolidDatasetFrom,\n  mockContainerFrom,\n  mockFileFrom,\n  mockFetchError,\n} from \"./resource/mock\";\nexport {\n  getThing,\n  getThingAll,\n  setThing,\n  removeThing,\n  createThing,\n  isThing,\n  isThingLocal,\n  asUrl,\n  asIri,\n  thingAsMarkdown,\n  ThingExpectedError,\n} from \"./thing/thing\";\nexport {\n  getPropertyAll,\n  getUrl,\n  getIri,\n  getBoolean,\n  getDatetime,\n  getDate,\n  getTime,\n  getDecimal,\n  getInteger,\n  getStringEnglish,\n  getStringWithLocale,\n  getStringNoLocale,\n  getUrlAll,\n  getIriAll,\n  getBooleanAll,\n  getDatetimeAll,\n  getDateAll,\n  getTimeAll,\n  getDecimalAll,\n  getIntegerAll,\n  getStringEnglishAll,\n  getStringWithLocaleAll,\n  getStringByLocaleAll,\n  getStringNoLocaleAll,\n  getLiteral,\n  getNamedNode,\n  getTerm,\n  getLiteralAll,\n  getNamedNodeAll,\n  getTermAll,\n} from \"./thing/get\";\nexport {\n  addUrl,\n  addIri,\n  addBoolean,\n  addDatetime,\n  addDate,\n  addTime,\n  addDecimal,\n  addInteger,\n  addStringEnglish,\n  addStringWithLocale,\n  addStringNoLocale,\n  addLiteral,\n  addNamedNode,\n  addTerm,\n} from \"./thing/add\";\nexport {\n  setUrl,\n  setIri,\n  setBoolean,\n  setDatetime,\n  setDate,\n  setTime,\n  setDecimal,\n  setInteger,\n  setStringWithLocale,\n  setStringNoLocale,\n  setLiteral,\n  setNamedNode,\n  setTerm,\n} from \"./thing/set\";\nexport {\n  removeAll,\n  removeUrl,\n  removeIri,\n  removeBoolean,\n  removeDatetime,\n  removeDate,\n  removeTime,\n  removeDecimal,\n  removeInteger,\n  removeStringEnglish,\n  removeStringWithLocale,\n  removeStringNoLocale,\n  removeLiteral,\n  removeNamedNode,\n} from \"./thing/remove\";\nexport { buildThing, ThingBuilder } from \"./thing/build\";\nexport { mockThingFrom } from \"./thing/mock\";\nexport {\n  hasAcl,\n  hasFallbackAcl,\n  getFallbackAcl,\n  hasResourceAcl,\n  getResourceAcl,\n  getSolidDatasetWithAcl,\n  getFileWithAcl,\n  getResourceInfoWithAcl,\n  createAcl,\n  createAclFromFallbackAcl,\n  saveAclFor,\n  deleteAclFor,\n  hasAccessibleAcl,\n  WithAccessibleAcl,\n  WithAcl,\n  WithFallbackAcl,\n  WithResourceAcl,\n  AclDataset,\n  AclRule as internal_AclRule,\n  Access,\n} from \"./acl/acl\";\nexport { WithAcp, WithAccessibleAcr } from \"./acp/acp\";\nexport {\n  AgentAccess,\n  getAgentAccess,\n  getAgentAccessAll,\n  getAgentResourceAccess,\n  getAgentResourceAccessAll,\n  setAgentResourceAccess,\n  getAgentDefaultAccess,\n  getAgentDefaultAccessAll,\n  setAgentDefaultAccess,\n} from \"./acl/agent\";\nexport {\n  getGroupAccess,\n  getGroupAccessAll,\n  getGroupResourceAccess,\n  getGroupResourceAccessAll,\n  getGroupDefaultAccess,\n  getGroupDefaultAccessAll,\n  setGroupDefaultAccess,\n  setGroupResourceAccess,\n} from \"./acl/group\";\nexport {\n  getPublicAccess,\n  getPublicResourceAccess,\n  getPublicDefaultAccess,\n  setPublicResourceAccess,\n  setPublicDefaultAccess,\n} from \"./acl/class\";\nexport { addMockResourceAclTo, addMockFallbackAclTo } from \"./acl/mock\";\nexport {\n  Url,\n  Iri,\n  UrlString,\n  IriString,\n  WebId,\n  SolidDataset,\n  Thing,\n  ThingPersisted,\n  ThingLocal,\n  LocalNode,\n  hasResourceInfo,\n  hasServerResourceInfo,\n  WithResourceInfo,\n  WithChangeLog,\n  WithServerResourceInfo,\n  UploadRequestInit,\n  SolidClientError,\n  AccessModes,\n} from \"./interfaces\";\nexport { fromRdfJsDataset, toRdfJsDataset } from \"./rdfjs\";\nexport { Time } from \"./datatypes\";\nexport {\n  addJwkToJwks,\n  addPublicKeyToProfileJwks,\n  getProfileJwksIri,\n  setProfileJwks,\n} from \"./profile/jwks\";\nexport {\n  getProfileAll,\n  ProfileAll,\n  getPodUrlAll,\n  getPodUrlAllFrom,\n  getAltProfileUrlAllFrom,\n  getWebIdDataset,\n} from \"./profile/webid\";\n\n// Export the different formats methods from @inrupt/solid-client import, these\n// are not part of our Public API, but are needed to be exported for usage from\n// our other packages.\n//\n// NOTE: We have to export like this, otherwise rollup does some sort of\n// tree-shaking and breaks the build where `dist/formats/index.mjs` is no longer\n// built, and this causes the `@inrupt/solid-client/formats` subpath export to\n// no longer work.\nexport const { getJsonLdParser, getTurtleParser, solidDatasetAsTurtle } =\n  formats;\n\n/**\n * This API is still experimental, and subject to change. It builds on top of both\n * ACP and WAC, aiming at being adaptable to any Access Control system that may be\n * implemented in Solid. That is why it is purely Resource-centric: the library\n * discovers metadata associated with the Resource itself, and calls the appropriate\n * underlying API to deal with the Access Control in place for the target Resource.\n *\n * As it is still under development, the following export is *only* intended for experimentation\n * by early adopters, and is not recommended yet for production applications. Because\n * of this, all of the Access-related API's are exported on a single object, which does\n * not facilitate tree-shaking: if you use one ACP-related API, all of them will be\n * included in your bundle.\n *\n * Note that the following object is exposed to be available for environments not\n * supporting export maps. For developers using Node 12+, Webpack 5+, or any tool\n * or environment with support for export maps, we recommend you import these\n * functions directly from @inrupt/solid-client/universal.\n */\nexport * as universalAccess from \"./universal\";\n\n/**\n * The Access Control Policies proposal has not yet been reviewed for inclusion in the Solid spec.\n * To enable early experimentation, solid-client exposes a low-level API. However, this API can and\n * will include breaking changes in non-major releases. Additionally, for most applications, a\n * higher-level API that is planned will be more applicable.\n * Thus, the following export is *only* intended for experimentation by early adopters, and is not\n * recommended for production applications. Because of this, all ACP-related API's are exported on a\n * single object, which does not facilitate tree-shaking: if you use one ACP-related API, all of\n * them will be included in your bundle.\n *\n * This version of the APIs contains changes that have not been implemented by a server yet. Only\n * switch to it when servers are updated.\n */\nexport * as acp_ess_2 from \"./acp/ess2\";\n"]}